Bug 29984 - viewport for first frame after win creation is wrong if win resized before drawing
Summary: viewport for first frame after win creation is wrong if win resized before dr...
Status: RESOLVED FIXED
Alias: None
Product: Mesa
Classification: Unclassified
Component: Drivers/DRI/i965 (show other bugs)
Version: git
Hardware: Other All
: medium normal
Assignee: Kristian Høgsberg
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-09-02 15:38 UTC by bob@o-hand.com
Modified: 2013-03-20 22:26 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
Tests resizing window after creating, but before first frame (7.32 KB, text/x-csrc)
2010-09-02 15:38 UTC, bob@o-hand.com
Details
Patch to invalidate drawable buffers immediately after binding. (1.48 KB, patch)
2010-09-08 08:41 UTC, Kristian Høgsberg
Details | Splinter Review

Description bob@o-hand.com 2010-09-02 15:38:47 UTC
Created attachment 38391 [details]
Tests resizing window after creating, but before first frame

If I create a window at say 600x600 and before I draw the first frame I
resize it to 800x800 then when I issue a swap buffers it will always be clipped
to 600x600. (I am calling glViewport with the latest size before drawing)

I reliably get the wrong result for the very first frame after creating a window, but it also sometimes happens for later frames too.

I'm running with XSynchronize TRUE and since the resizing is being done by the test itself not by the WM, all interaction with X should be synchronous.

This is something that is affecting Clutter since we are starting to use clipped redraws + glXCopySubBuffer a lot more and assuming that the untouched parts of the front buffer are initialized after the first frame.

I've attached a test that reproduces the problem. It starts creating a window @ 640x480 then just before drawing the first frame it make the win 10px wider+higher and stops. Tapping space will run another frame and the window will be resized by 10px again before drawing. The artifact sometimes shows up
with later frames but not reliably.

I was testing with mostly stock ubuntu components but with git master for libdrm and mesa:

OpenGL renderer string: Mesa DRI Intel(R) 965GM GEM 20100330 DEVELOPMENT x86/MMX/SSE2
OpenGL version string: 2.1 Mesa 7.9-devel

2.6.32-24-generic

X.Org X Server 1.7.6
Comment 1 Kristian Høgsberg 2010-09-08 08:34:54 UTC
This should work either with a newer X server or with an older mesa.  But you're using an older mesa that relies on a newer X server that sends DRI2 invalidate events, to ask the DRI driver to requery for buffers.

In that case we fallback to invalidating buffers on every glXSwapBuffer.  However when you make a drawable current we do a roundtrip to get buffers (for the initial viewport) which marks the drawable buffers as valid.  The XResizeWindow doesn't cause an invalidate event and the buffers remain valid until the glXSwapBuffer at the end of the frame.

I'm not sure why it shows up on later frames - perhaps there's a race between getting the configure event in your event handler (which sets width and height) and incrementing width and height in the redraw function.  If that's the case, then we just need to fix the initial case, which would be a matter of just invalidating the drawable immediately after making it current.  I'll attach a patch to do that.

On a related note:  For new servers, the DRI2 invalidate event is sent out before the configure event corresponding to the resize.  This means if you repaint in the configure handler (or later, in an idle handler scheduled from the configure handler), the DRI driver will have received the invalidate notification and the repaint will happen to the new buffers  I assume that's what you're doing in clutter.  If you want to do XResizeWindow and then repaint, you have to do an XSync() (or run synchronously) to get the correct behavior.
Comment 2 Kristian Høgsberg 2010-09-08 08:41:01 UTC
Created attachment 38560 [details] [review]
Patch to invalidate drawable buffers immediately after binding.
Comment 3 bob@o-hand.com 2010-09-08 09:00:27 UTC
(In reply to comment #2)
> Created an attachment (id=38560) [details]
> Patch to invalidate drawable buffers immediately after binding.

Thanks, I can confirm that this patch fixes the first frame for me; though I still sometimes see the problem for later frames.
Comment 4 Eric Anholt 2011-07-12 08:40:55 UTC
So, is this still an issue with current server and Mesa?
Comment 5 Eric Anholt 2013-03-20 22:26:34 UTC
commit 86a1938aa56c02d7da137b09e579d24d7da50d9e
Author: Kristian Høgsberg <krh@bitplanet.net>
Date:   Wed Sep 22 17:34:00 2010 -0400

    glx: Invalidate buffers after binding a drawable
    
    If the server doesn't send invalidate events, we may miss a
    resize before the rendering starts.  Invalidate the buffers now
    so the driver will recheck before rendering starts.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=29984
    https://bugs.freedesktop.org/show_bug.cgi?id=30155


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.