Re: New version of synchronization changes - windows not redirected



On Fri, 2013-04-05 at 16:15 +1300, Karl Tomlinson wrote:
Thank you, Owen and the others who contributed, for sorting this
out and writing it up in a way we can follow.

Hi Karl -

Thanks for taking a look at the spec addition.

I'm pleased to see this even addresses the issue of synchronizing
drawing after map, which could have been handled by the basic
frame counter in _NET_WM_SYNC_REQUEST_COUNTER but wasn't. [1]

I have a question re fullscreen windows:

With extended synchronization, the application does not need to
double-buffer its drawing, and so can use a window with a
single-buffered visual.

In theory this is possible. I'm not yet sure it's a good idea:

 - What freezing drawing on a window means is that the compositor
   should not redraw the window when it receives damage events
   *for* that window.

   But if the compositor needs to redraw that area of the screen
   for some other reason, the user could see an intermediate state,
   especially in the case where things are slow and it's taking the
   application longer than a few milliseconds to redraw.

 - There will be substantial traffic generated - each
   time libGL does any drawing, it needs to to send damage to the
   X server - the X server may or may not send events to the 
   compositor depending on the way that the compositor is using
   the Composite extension (e.g., mutter uses DamageReportBoundingBox)

 - Front buffer rendering is only grudgingly supported for 
   direct-rendering GLX - basically for conformance not performance.

Plus, as you say, the question of what happens if your window is
redirected.

In the slightly longer-term, I have hopes that the ongoing DRI3000
work will give most of the performance advantage that you would
get by using a single buffered visual to a double-buffered application -
the main thing that it would be desirable to avoid is the *copy* from
the back buffer to the front buffer, and if we do a swap of what
buffer is acting as the "front buffer" for the window, we avoid that.
   
Some window managers disable compositing for fullscreen windows.
Should an application assume that a window manager advertising
_NET_WM_FRAME_DRAWN will always composite the window?  Perhaps it
should use _NET_WM_DONT_BYPASS_COMPOSITOR?  Or should the
application try to detect when compositing of a single toplevel
window is disabled?

I don't have a great answer for this. My assumption general feeling
is that if a compositor unredirects a window, but the application
continues marking frames using the sync counter protocol, then
what applies is the part of the spec:

  The window manager SHOULD redraw the window and send the messages even
  if no damage events were received. 

  Rational: the reason for redrawing the window even if no damage events
  have been received is so that there is consistent timing for each
  frame, even if one frame happens to involve no changes to the window.
  It is recommended to behave as if a damage event was received
  containing only a single pixel. 

The compositor is supposed to send _NET_WM_FRAME_DRAWN messages with
some sort of reasonable timing that is throttled to 1 frame per refresh
and not just send the application a reply immediately. 

If the compositor implements this, then the application will continue
working OK. I'd like to have some reliable way for applications to know
if they are unredirected, however, so they do better.

There's something else I should point out in this context - the protocol
in the spec doesn't work correctly with the NVIDIA binary drivers
for GLX applications since there Damage events are currently reported
asynchronously and not coordinated with the X protocol stream.

An application can easily detect when a Screen is no longer
composited, but fullscreen usually means full-monitor rather than
full-Screeen and I don't know of a good way to detect whether a
single window's contents have been redirected to offscreen
storage.

Even if an application could detect when its window is no longer
being composited, I expect is not appropriate (even if it may
work) to start using a double-buffered fbconfig for a window with
a single-buffered visual, and I assume it is not possible to
change a window's visual.  Is there a way to draw to a
single-buffered window during vblank?

In theory, you could draw to a FBO, then use the appropriate GLX
extensions to block for the VBlank and at point draw across - I would
strongly recommend against this, as you will prevent any page-flipping
optimization.

My current recommendations:

 * If you are drawing with Xlib/RENDER, use the extended sync
   request method for synchronization if available. You may want to
   disable compositor bypass, since compositor bypassing can
   result in tearing and other artifacts of unsynchronized drawing.

 * If you are drawing with GLX, use standard GLX techniques for
   VBlank synchronization, and don't yet use the protocols here.
   We'll eventually get things sorted out with respect to the
   NVIDIA issue mentioned above so that GLX clients will be able 
   to get flicker-free map and resize.

 * If you are drawing with a mix of Xlib and GLX -
   use the extended sync request method for synchronization. 
   You will potentially have some inefficiency with the NVIDIA drivers,
   but the appearance will be corrrect.

In all cases I would recommend double buffering - the freezing stuff
is good for prevent flickering on map, on resize, when scrolling
with a CopyArea/redraw pair, but if you just completely turn off
double buffering, I would expect that some amount of flicker is
going to sneak through.

(If people wanted to experiment and see what the performance gain
from avoiding double buffering is, that could be interesting
to see.)

- Owen




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]