开发者

How does glClear() improve performance?

开发者 https://www.devze.com 2022-12-24 19:54 出处:网络
Apple\'s Technical Q&A on addressing flickering (QA1650) includes the following paragraph. (Emphasis mine.)

Apple's Technical Q&A on addressing flickering (QA1650) includes the following paragraph. (Emphasis mine.)

You must provide a color to every pixel on the screen. At the beginning of your drawing code, it is a good i开发者_JS百科dea to use glClear() to initialize the color buffer. A full-screen clear of each of your color, depth, and stencil buffers (if you're using them) at the start of a frame can also generally improve your application's performance.

On other platforms, I've always found it to be an optimization to not clear the color buffer if you're going to draw to every pixel. (Why waste time filling the color buffer if you're just going to overwrite that clear color?)

How can a call to glClear() improve performance?


It is most likely related to tile-based rendering, which divides the whole viewport to tiles (smaller windows, can be typically of size 32x32) and these tiles are kept in faster memories. The copy operations between this smaller memory and the real framebuffer can take some time (memory operations are a lot slower than arithmetic operations). By issuing a glClear command, you are telling the hardware that you do not need previous buffer content, thus it does not need to copy the color/depth/whatever from the framebuffer to the smaller tile memory.


With the long perspective of official comments on iOS 4, which postdates the accepted answer...

I think that should be read in conjunction with Apple's comments about the GL_EXT_discard_framebuffer extension, which should always be used at the end of a frame if possible (and indeed elsewhere). When you discard a frame buffer you put its contents into an undefined state. The benefit of that is that when you next bind some other frame buffer, there's never any need to store the current contents of your buffer out to somewhere, and similarly when you next restore your buffer there's no need to retrieve them. Those should all be GPU memory copies and so quite cheap, but they're far from free and the iPhone's shared memory architecture presumably means that even more complicated considerations can crop up.

Based on the compositing model of iOS it's reasonable to assume that that even if your app doesn't bind and unbind frame buffers in its context, the GPU has to do those tasks implicitly at least once for each of your frames.

I would dare guess that the driver is smart enough that if the first thing you do is a clear, you get half the benefit of the discard extension without actually using it.


Try decreasing the size of your framebuffer in the glSurface attributes that you pass to ChooseConfig.

For example, set attributes to 0 for minimum or omit them completely to use defaults unless you have a specific requirement.


I can definitely confirm that you have to provide a color to every pixel on the screen.

I've verified this in a bare bones test app built on XCode's iPhone OpenGL template:

[context presentRenderbuffer:GL_RENDERBUFFER];  
glClear( GL_COLOR_BUFFER_BIT );

If I leave out the glClear line (or move it further down in the loop, after some other OpenGL calls), the thread (running via CADisplayLink) is hardly getting any updates anymore. It seems as if CPU/GPU synchronization goes haywire and the thread gets blocked. Pretty scary stuff if you ask me, and totally not in line with my expectations.

BTW, you don't neccessarily have to use glClear(), just drawing a fullscreen quad seems to have the same effect (obviously, a textured quad is more expensive). It seems you just have to invalidate all the tiles.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号