Freezing updates for compositing managers

View: New views
6 Messages — Rating Filter:   Alert me  

Freezing updates for compositing managers

by Owen Taylor :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

There is a long-standing problem where when an initially mapped
override-redirect window (for example, menu or tooltip) it can
be displayed by a compositor before the application has a chance
to draw the contents.

This is most acute when the application has unset the background
to try and avoid an initial flash, since the contents of the
pixmap are then garbage.

(There's hack-around for this in the Xorg code where if you
map a background-none window, the contents of the composite pixmap
are initialized from the server's guess at what is under the
window. This code is commented out of at least the Fedora packages
because of undesirable side-effects.)

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.

Making the property have that meaning just by its presence is a
little unusual compared to existing practice, but has some nice
properties:

 - because its a property, the window manager can figure out the
   status on a newly mapped window without race conditions by
   first selecting for PropertyNotify then checking if the property
   exists.

 - because we don't care what's in the property, PropertyNotify
   events are enough fore subsequent updates - just check whether
   XPropertyEvent.state is PropertyNewValue or PropertyDelete

The same mechanism could be reused for freezing updates while a
window is shown:

 - To make a scroll (with CopyArea) and then repainting the
   newly scrolled in area atomic.

 - To allow not using a backing pixmap at all for redraws when
   a compositor is present! (caveat: depending on how the compositor
   is selecting for damage, it might get flooded with events
   hurting performance.)

Patch implementing this for GTK+ for newly mapped windows:

 http://bugzilla.gnome.org/show_bug.cgi?id=587247

Patch implementing it for Mutter:

 http://bugzilla.gnome.org/show_bug.cgi?id=587255

Main question for me is whether this belongs in the wm-spec and
should be called _NET_WM_* ... it's clearly compositing-manager
specific not window manager-specific, but there's not really
(as far as know) a good alternate location.

- Owen


_______________________________________________
wm-spec-list mailing list
wm-spec-list@...
http://mail.gnome.org/mailman/listinfo/wm-spec-list

Re: Freezing updates for compositing managers

by Denis Dzyubenko-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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.

--
Denis Dzyubenko
Software Engineer
Nokia, Qt Software
_______________________________________________
wm-spec-list mailing list
wm-spec-list@...
http://mail.gnome.org/mailman/listinfo/wm-spec-list

Re: Freezing updates for compositing managers

by Soeren Sandmann-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Owen Taylor <otaylor@...> writes:

> Main question for me is whether this belongs in the wm-spec and
> should be called _NET_WM_* ... it's clearly compositing-manager
> specific not window manager-specific, but there's not really
> (as far as know) a good alternate location.

There is already some compositing manager specific text in the draft
spec:

    http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#id2552725

That is still a draft though, so maybe it's time for someone to look
at making a new release.



Soren
_______________________________________________
wm-spec-list mailing list
wm-spec-list@...
http://mail.gnome.org/mailman/listinfo/wm-spec-list

Re: Freezing updates for compositing managers

by Owen Taylor :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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
   environment.

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.


_______________________________________________
wm-spec-list mailing list
wm-spec-list@...
http://mail.gnome.org/mailman/listinfo/wm-spec-list

Re: Freezing updates for compositing managers

by Lubos Lunak :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Monday 29 of June 2009, Soeren Sandmann wrote:

> Owen Taylor <otaylor@...> writes:
> > Main question for me is whether this belongs in the wm-spec and
> > should be called _NET_WM_* ... it's clearly compositing-manager
> > specific not window manager-specific, but there's not really
> > (as far as know) a good alternate location.
>
> There is already some compositing manager specific text in the draft
> spec:
>
>     http://standards.freedesktop.org/wm-spec/wm-spec-latest.html#id2552725
>
> That is still a draft though, so maybe it's time for someone to look
> at making a new release.

 I think the prevailing opinion last time this was discussed [*] was that
compositing stuff should be in a separate spec. No actual action has taken
place though.

[*] http://mail.gnome.org/archives/wm-spec-list/2008-January/msg00014.html

--
Lubos Lunak
KDE developer
--------------------------------------------------------------
SUSE LINUX, s.r.o.   e-mail: l.lunak@... , l.lunak@...
Lihovarska 1060/12   tel: +420 284 084 672
190 00 Prague 9      fax: +420 284 028 951
Czech Republic       http://www.suse.cz
_______________________________________________
wm-spec-list mailing list
wm-spec-list@...
http://mail.gnome.org/mailman/listinfo/wm-spec-list

Re: Freezing updates for compositing managers

by Denis Dzyubenko-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Owen,

Sorry for the late reply. Now when things settled up and I thought a bit
about it your last solution sounds almost perfect.

Owen Taylor wrote:

> 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.

In your email you mentioned a possible need for the second counter - so
what if we extend the NET_WM_SYNC_REQUEST specification to include a
second counter, so that the NET_WM_SYNC_REQUEST_COUNTER property will
contain two counters.

* The first counter should be set by the client as a response to the
_NET_WM_SYNC_REQUEST client message (all according to the current
specification).
* The second counter is set by the client when it wants to freeze
updates and its value can be arbitrary (i.e. doesn't depend on the
ConfigureNotify/ClientMessage pair).

This way we maintain backward compatibility - if the
windowmanager/compositor doesn't know about the second counter, they'll
just ignore it and get only the first counter with a
XGetWindowProperty() call.

It should also be completely safe if the client doesn't support having
two counters, but the window manager does - the GetWindowProperty() will
just return the first item and the window manager can easily check how
many counter are actually there.

> 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.

The same advantages apply and I can only see one possible disadvantage -
if the wm/compositor doesn't handle counter updates that are done not in
the response to the ConfigureNotify, but I'd expect window managers to
handle this case pretty well since there is always a possibility of
broken client that doesn't use the NET_WM_SYNC_REQUEST protocol properly.


I've made a test implementation of this for Qt:
http://pastebin.ca/1498362?nomobile=1
(the patch is against Qt master (trunk) which has already introduced
support for the original _NET_WM_SYNC_REQUEST protocol).

--
Denis Dzyubenko
Software Engineer
Nokia, Qt Software
_______________________________________________
wm-spec-list mailing list
wm-spec-list@...
http://mail.gnome.org/mailman/listinfo/wm-spec-list