GlTexSubImage2D работает медленнее с пиксельными буферами

Я использую PBO в opengl es3 на Android, но после их использования производительность распаковки данных ухудшилась. Пожалуйста, помогите мне найти ошибку в коде. Справочная информация. Мое приложение состоит из модуля, который генерирует изображения с очень высокой скоростью. Эти изображения загружаются в текстуры, которые, наконец, нарисованы на 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 мс

Мое предположение заключалось в использовании PBOs. GlTexSubImage2D должен возвращаться мгновенно (или, по крайней мере, в <5 мс), потому что данные изображения уже находятся в VRAM, но на самом деле он занимает гораздо больше времени на Nexus 6. В качестве эксперимента я помещал std :: this_thread :: sleep_for (Std :: chrono :: миллисекунды (100)); Между glUnmapBuffer и glTexSubImage2d, чтобы узнать, не имеет ли разница во времени, затрачиваемом только glTexSubImage2D, но оставалось таким же.

Intereting Posts
Java: должен ли я использовать конструктор, чтобы сделать больше, чем просто инициализировать переменные Google Play показывает неявное разрешение READ_EXTERNAL_STORAGE Дополнительные приложения для Android о распознавании речи не работают Как добавить отслеживание / тайминги экрана в Firebase Analytics? Ускорение системы координат устройства в абсолютную систему координат Android – Интеграция ffmpeg и android-ndk-r9c Как CountDownTimer обращается к пользовательскому интерфейсу внутри метода OnTick? Android: отображение содержимого списка скрытых скинов Не удается завершить установку из-за конфликтной зависимости. Местоположение Android SDK не настроено в настройках Как установить GridView внутри ScrollView Формат в файле строковых ресурсов Galaxy s3 имеет датчик температуры? Как возобновить работу медиаплеер? Android: Может ли стороннее приложение использовать AT-команды для автоматического ответа на телефонный звонок …? Что произойдет, если я вызову startService после вызова bindService в классе обслуживания?