我在Android上的opengl es3中使用PBO,但在使用它们之后,数据解包的性能降低了。请帮我找出代码中的错误。 背景:我的应用程序包含一个以非常快的速度生成图像的模块。这些图像被上传到最终在TextureView上绘制的纹理。我的应用程序中的瓶颈是将图像上传到纹理所花费的时间。 我决定尝试PBO来改善这个性能。以下是我的代码:
一次初始化
CheckGLErr( glGenTextures( 1, &texName ) );
if( usePBO )
{
CheckGLErr( glGenBuffers( 1, &pboId ) );
CheckGLErr( glBindBuffer( GL_PIXEL_UNPACK_BUFFER, pboId ) );
CheckGLErr( glBufferData( GL_PIXEL_UNPACK_BUFFER, textureSize, 0, GL_STREAM_DRAW ) );
CheckGLErr( glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 ) );
}
glBindTexture( GL_TEXTURE_2D, texName );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, windowWidth, windowHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
glBindTexture( GL_TEXTURE_2D, 0 );
RenderLoop:
CheckGLErr(glClearColor(0, 1.0f, 0, 1));
CheckGLErr(glClear(GL_COLOR_BUFFER_BIT));
glBindTexture( GL_TEXTURE_2D, texName );
if( usePBO )
{
CheckGLErr(glBindBuffer( GL_PIXEL_UNPACK_BUFFER, pboId ));
void* pBuff = ::glMapBufferRange( GL_PIXEL_UNPACK_BUFFER, 0, textureSize , GL_MAP_WRITE_BIT );
memcpy( pBuff, buffer.get(), textureSize );
CheckGLErr(glUnmapBuffer( GL_PIXEL_UNPACK_BUFFER ));
}
//std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, windowWidth, windowHeight, GL_RGBA, GL_UNSIGNED_BYTE, usePBO ? 0 : buffer.get() );
// Setup texture properties.
CheckGLErr(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
CheckGLErr(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
CheckGLErr(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
CheckGLErr(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
CheckGLErr( glUseProgram( programObject ) );
// Enable position vertex attribute. Its size is 3 floats corresponding for co-ordinates in three directions.
CheckGLErr(glEnableVertexAttribArray(0));
CheckGLErr(glVertexAttribPointer(0, 3, GL_FLOAT, false, 5 * sizeof(float)/*vertexStride*/, (const GLvoid *)0));
// Enable UV vertex attribute which starts after position. Hence offset = 3 floats.
CheckGLErr(glEnableVertexAttribArray(1));
CheckGLErr(glVertexAttribPointer(1, 2, GL_FLOAT, false, 5 * sizeof(float)/*vertexStride*/, (const GLvoid *)(3*sizeof(float))/*offset worth position*/));
// Setup ViewPort
CheckGLErr(glViewport(0, 0, windowWidth, windowHeight));
if(usePBO )
CheckGLErr( glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 ) );
CheckGLErr(glDrawElements(GL_TRIANGLE_STRIP, _countof(indices), GL_UNSIGNED_SHORT, (const GLvoid *)0x00000000));
eglSwapBuffers(eglDisplay, eglWindowSurface);
测量完成:
在Nexus 7(4.4.4)Adreno GPU上
屏幕尺寸= 1624 * 1200像素
没有PBO:17毫秒
使用PBO:18毫秒(缓冲区数量约为5毫秒,glTexSubImage2D调用休息)
在Nexus 6(5.0)上
屏幕尺寸= 2042 * 1440像素
没有PBO:6毫秒
使用PBO:20毫秒
我的假设是使用PBO glTexSubImage2D应该立即返回(或者至少在< 5ms内),因为图像数据已经在VRAM中,但事实上它在Nexus 6上需要更长的时间。 作为实验,我把std :: this_thread :: sleep_for(std :: chrono :: milliseconds(100));在glUnmapBuffer和glTexSubImage2d之间看看它是否只对glTexSubImage2D所用的时间有所不同,但它保持不变。