使用Pixel Buffer Objects时,glTexSubImage2D速度较慢

时间:2015-10-07 13:37:43

标签: android opengl-es

我在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所用的时间有所不同,但它保持不变。

0 个答案:

没有答案