Re: Freezing updates for compositing managers

On Mon, 2009-06-29 at 10:10 +0200, Denis Dzyubenko wrote:
> Hi Owen,
> Owen Taylor wrote:
> > Fixing this really requires application intervention - when the
> > compositor receives the MapNotify for the window the window might
> > have drawn yet, or might not, and there's no way that the
> > compositor can know.
> > 
> > This is actually a symptom of a more general situation - an
> > application wants to make multiple X requests (here a map and
> > then the redraw) and not have the compositor draw until it is done.
> > 
> > Thinking of it that way - that gives a pretty straightforward
> > solution - the app can set a property that says "don't update me" -
> > say _NET_WM_FREEZE_UPDATES - and then remove it when it is ready
> > to be painted again.
> Sounds like an excellent idea, however it also sounds similar to 
> something that the wm-spec already have - can we use the existing 
> _NET_WM_SYNC_REQUEST protocol for that? Since compositing manager might 
> already support it, it could be pretty straightforward to implement the 
> same protocol for the case when a client window is initially mapped. For 
> example, when the compositor receives the MapNotify, it might send the 
> _NET_WM_SYNC_REQUEST client message and delay showing the window until 
> the client responds by setting a _NET_WM_SYNC_REQUEST_COUNTER.

I was originally going to respond and say "it sounds related, but it
isn't related."

But then I had an idea. You can't really use _NET_WM_SYNC_REQUEST
unmodified - it's inherently initiated from the window manager and not
from the client. And this needs to be initiated from the client. (*)

But what if we turned _NET_WM_SYNC_REQUEST_COUNTER into a more
general frame counter. With the following handling:

 - When the client starts drawing a frame, it increments the counter to
   an odd value to freeze updates.
 - When the client finishes drawing, it increments the counter to an
   even value to thaw updates.
 - When the window manager wants to do a sync, it picks an even value
   at least a 100 [arbitrary] values ahead of the last value it
   received from the client and sends _NET_WM_SYNC_REQUEST to the
   client with that value. The client then uses that value on the
   frame completion after processing the resize.

Advantages of this:

 - It has the same race-condition-free-startup and no-round-trip on
   updates as my proposal.

 - It integrates with the sync request system in an aesthetically
   pleasing fashion.

 - It has a very useful extension:

    After redrawing a frame, the window manager sends a
    _NET_WM_FRAME_REDRAWN client message to all clients updating 
    the frame counter since the last redraw. The message contains
    the frame value (and maybe some timing information.)

   Voila: properly throttled application updates in a composited

Disadvantages of this:

 - Compatibility is tricky; if the window manager is expecting the
   old _NET_WM_SYNC_REQUEST_COUNTER behavior, spontaneous client
   updates will break the WM's use of _NET_WM_SYNC_REQUEST as far
   as I can tell.

   Having the client adapt its behavior is tricky because:

    - Switching between compositing managers and window managers
      in the fly.
    - The possibility of a standalone compositor that wants the
      frame counter with an old window manager that expects the
      old sync counter behavior.

   So, I don't really see how to avoid having the application expose
   two separate counters. [ Applications could, of course, choose to
   only support the new method ... we could deprecate the old way]

 - The Sync extension is not fun to understand and use; it's much
   harder to implement the above as compared to my 
   _NET_WM_FREEZE_UPDATES. Toolkits and window managers have however,
   already figured out much of this to handle _NET_WM_SYNC_REQUEST.

- Owen

(*) Even if you accept the extra WM <=> client round trip, I don't
think it works out without toolkit modifications to have the window
manager to spontaneously ask for a sync - it's specified currently
to be tied to a ConfigureNotify. Plus, it doesn't extend to the
other uses cases like atomic frame updates.

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