Hello,
I profiled my application’s cpu usage and it is as the following according to algorithms:
algorithm performRenderBuffer16
: 6-7% CPU usage from glMapBufferRange
,glUnmapBuffer
function calls
and %2 by memcpy()
.
algorithm doReadbackFAST
16: 5-6% CPU usage from glGetBufferSubData
function.
1.It seems to me glBlitFramebuffer
not adding too much cpu load.
2.I tried to export __GL_YIELD=USLEEP
, export __GL_YIELD=
and export __GL_YIELD=NOTHING
for performRenderBuffer16()
algorithm above and export __GL_YIELD=USLEEP
is the best fit
and reducing the Total cpu usage up to 12-16%.
Note that for performRenderBuffer16()
algorithm, I added following modifications:
glBindBuffer(GL_PIXEL_PACK_BUFFER, pboIds[0]);
glBindFramebuffer( GL_FRAMEBUFFER, frameBuffer16);
//glReadBuffer(frameBuffer16); // frameBuffer16 also works
//glBindBuffer(GL_PIXEL_PACK_BUFFER, pboIds[0]);
glReadPixels( 0, 0, mWinWidth, mWinHeight, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
for doReadbackFAST16
algorithms I observed that I forget to add
glBindFramebuffer(GL_FRAMEBUFFER,frameBuffer16);
call before glReadPixels
and now Total cpu usage with this algorithm is 13-17%.
When I added export __GL_YIELD=USLEEP
, export __GL_YIELD=
and export __GL_YIELD=NOTHING
for doReadbackFAST16
algorithms they all have similar results for total Cpu usage 13-16%.
So It seems to me I need to use export __GL_YIELD=USLEEP
.
- I have implemented a function as the following for reading 24bit colors and 16bit colors back to back as you suggested
with blocking glReadPixels
:
void WaylandEgl::createDarkRenderBuffers()
{
if (!buffCreated)
{
qDebug() << "Heiht" << mWinHeight << "Width" << mWinWidth;
pbo_size16 = mWinHeight * mWinWidth * 2;
pbo_size24 = mWinHeight * mWinWidth * 3;
nBytesPerLine = mWinWidth ;
Readback_buf24 = (GLchar *) malloc( pbo_size24 );
Readback_buf16 = (GLchar *) malloc( pbo_size16 );
glGenRenderbuffers( 1, &darkRenderBuffer16 );
glBindRenderbuffer( GL_RENDERBUFFER, darkRenderBuffer16 );
glRenderbufferStorage( GL_RENDERBUFFER, GL_RGB565, mWinWidth, mWinHeight );
glBindRenderbuffer(GL_RENDERBUFFER, 0);
if (glGetError()==GL_NO_ERROR)
{
qDebug() << "Render buff storage is OK" << glGetError();
}
else
{
qDebug() << "Render buff storage error is " << glGetError();
}
glGenFramebuffers( 1, &darkFrameBuffer16 );
glBindFramebuffer( GL_FRAMEBUFFER, darkFrameBuffer16);
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, darkRenderBuffer16);
if( glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
qDebug() << "Framebuffer error is " << glGetError();
}
else
{
qDebug() << "Framebuffer is OK" << glGetError();
}
glGenRenderbuffers( 1, &darkRenderBuffer24 );
glBindRenderbuffer( GL_RENDERBUFFER, darkRenderBuffer24 );
glRenderbufferStorage( GL_RENDERBUFFER, GL_RGB565, mWinWidth, mWinHeight );
glBindRenderbuffer(GL_RENDERBUFFER, 0);
if (glGetError()==GL_NO_ERROR)
{
qDebug() << "Render buff storage is OK" << glGetError();
}
else
{
qDebug() << "Render buff storage error is " << glGetError();
}
glGenFramebuffers( 1, &darkFrameBuffer24 );
glBindFramebuffer( GL_FRAMEBUFFER, darkFrameBuffer24);
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, darkRenderBuffer24);
if( glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
qDebug() << "Framebuffer error is " << glGetError();
}
else
{
qDebug() << "Framebuffer is OK" << glGetError();
}
buffCreated = true;
int rowL;
glGetIntegerv(GL_PACK_ROW_LENGTH, &rowL);
qDebug() << "Rowl before" << rowL;
glPixelStorei( GL_PACK_ALIGNMENT, 1 );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glPixelStorei(GL_PACK_ROW_LENGTH,nBytesPerLine);
qDebug() << "Pixel st" << glGetError();
glGetIntegerv(GL_PACK_ROW_LENGTH, &rowL);
qDebug() << "Rowl after" << rowL;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}
void WaylandEgl::performDarkRenderBuffers()
{
Timer t1;
createDarkRenderBuffers();
glFinish();
t1.start();
glBindFramebuffer(GL_READ_FRAMEBUFFER,mwindow->openglContext()->defaultFramebufferObject());
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,darkFrameBuffer24);
glBlitFramebuffer(0, 0, mWinWidth, mWinHeight, 0, 0, mWinWidth, mWinHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
t1.stop();
blitTime = t1.getElapsedTimeInMilliSec();
t1.start();
glBindFramebuffer( GL_FRAMEBUFFER, darkFrameBuffer24);
glReadPixels( 0, 0, mWinWidth, mWinHeight, GL_RGB, GL_UNSIGNED_BYTE, Readback_buf24);
t1.stop();
readTime = t1.getElapsedTimeInMilliSec();
qDebug() << "Blit Time1 is: " << blitTime;
qDebug() << "Read Time1 is: " << readTime;
t1.start();
glBindFramebuffer(GL_READ_FRAMEBUFFER,mwindow->openglContext()->defaultFramebufferObject());
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,darkFrameBuffer16);
glBlitFramebuffer(0, 0, mWinWidth, mWinHeight, 0, 0, mWinWidth, mWinHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
t1.stop();
blitTime = t1.getElapsedTimeInMilliSec();
t1.start();
glBindFramebuffer( GL_FRAMEBUFFER, darkFrameBuffer16);
glReadPixels( 0, 0, mWinWidth, mWinHeight, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, Readback_buf16);
t1.stop();
readTime = t1.getElapsedTimeInMilliSec();
qDebug() << "Blit Time2 is: " << blitTime;
qDebug() << "Read Time2 is: " << readTime;
}
As you told all the time 2nd takes significantly less time such as:
Read Time1 is: 4.531 ms
Read Time2 is: 1.144 ms
So for this pipeline “flush” behavior should I do anything ?
- Previously I did not use glGetTexImage and I think I need to find out how I can reach qt’s default GL_TEXTURE_2D.
When I try to get already binded texture object from qt as the following:
void WaylandEgl::performTextureStaff()
{
if (!buffCreated)
{
int sizeX, sizeY;
GLenum format;
glGetIntegerv ( GL_TEXTURE_BINDING_2D, (int *) &boundTex );
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &sizeX);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &sizeY);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&format);
qDebug() << "Size x" << sizeX << "size y" << sizeY << "format" << format;
qDebug() << "Text id " << boundTex;
qDebug() << "Heiht" << mWinHeight << "Width" << mWinWidth;
pbo_size = mWinHeight * mWinWidth * 4;
nBytesPerLine = mWinWidth ;
Readback_buf = (GLchar *) malloc( pbo_size );
buffCreated = true;
}
Timer t1;
glFinish();
t1.start();
glBindTexture ( GL_TEXTURE_2D, boundTex );
qDebug() << "Bind error is " << glGetError();
glGetTexImage ( GL_TEXTURE_2D, 0, GL_RGBA , GL_UNSIGNED_BYTE, Readback_buf );
qDebug() << "glGetTexImage error is " << glGetError();
t1.stop();
readTime = t1.getElapsedTimeInMilliSec();
//qDebug() << "Read Text time" << readTime;
}
I do not have correct result for width and height and have only black screen.So need to check this.
- I need to check EGL lock surface extensions on xavier and will update here.
Regards