Hello,

I'm a Qt developer.

We want all Qt rendering to be done using OpenGL 2. We have this working 
pretty well (a few artifacts still here and there). However, we've found some 
fundamental problems using GL for regular widget rendering. Normally I 
wouldn't bother this list, but I've recently seen that someone's writing a new 
GL back end to Cairo, so I guess those guys are going to hit the exact same 
issues.

The problem is partial updates. From what we've seen it's typical for 
applications to only update a small region of their top-level-widget at a time 
(E.g. a flashing cursor in a text edit). As Qt only creates a single X window 
per top-level widget, this means a sub-region of a single X window.

When using glX, we have no guarantee over what state the back buffer will be in 
after swap buffers. So, whenever an application needs to update, it must re-
render the entire window. This makes things slow (we have to invoke every 
child widget's paint event). To overcome this, we try to use a 3rd buffer as a 
back buffer, usually a multi-sampled FBO or PBuffer. We direct rendering to the 
FBO/PBuffer, bind it as a texture (after blitting it to a non multi-sampled FBO 
if needed), draw the whole buffer to the window's back buffer then call swap 
buffers. Eughhh! But at least the PBuffer/FBO contents aren't destroyed. What 
would be really nice is to be able to have an EGL_SWAP_BEHAVIOR == 
EGL_BUFFER_PRESERVED equivalent on glX. I notice there's an EGL implementation 
being worked on in Mesa trunk so perhaps we should switch to EGL rather than 
glX?

Anyway, lets assume that swap buffers keeps the contents of the back buffer. 
There's another issue, although not as detrimental as the first. When we issue 
swap buffers, glX/EGL has to assume the entire window's contents has changed. 
That has 2 effects: 1) XDamage regions are generated for the whole window: When 
a composition manager is running, this means it has to re-compose the entire 
window, even though only a few pixels may have changed (which it might have to 
do anyway, see above :-)). 2) I'm led to believe that DRI2 implements swap 
buffers as a blit and so must blit the entire back buffer to the front.

I think I can work around this by making a glx context current on a GLXPixamp 
(from a XPixmap). Pixmaps are single buffered and so don't get destroyed on 
swap buffers (in fact I don't even call swap buffers). I can then post updates 
using XCopyArea which will also cause the Xserver to generate an appropriate 
XDamage region for the compositor. The only down side is that I have to 
glFinish before calling XCopyArea. While I have this working, it seems a 
little hacky and isn't widely supported (I have it working on 1 driver build 
for 1 bit of hardware).

It seems like a glXSwapPartialBuffers which takes an array of dirty rects would 
be preferable. The implementation could ignore the rects completely if it so 
chooses or only use them to generate the damage region. Or, if it's on DRI2, 
it can choose to only copy the sub-region from the back to the front. 
Eventually it could also use the rects as a metric to figure out if it should 
flip or blit (flip if there's >30% region changed, blit otherwise).


Cheers,

Tom

PS: Scrolling is also an issue... :-/



------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
--
_______________________________________________
Dri-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to