[cairo] IncludeInferiors, Pixmap/Window distinction

Karl Tomlinson cairo at karlt.net
Thu Jul 22 04:19:29 PDT 2010


_cairo_xlib_surface_composite is taking different paths according
to whether it knows that the Drawable is a Pixmap.  Most of the
time it doesn't know whether the Drawable is a Window or Pixmap,
so it is taking the less favored path unnecessarily.  I'm looking
for and suggesting a solution so that cairo can make a better
decision here.

The reasoning for not taking the preferred path is described in
the commit that introduced (or perhaps restored) the difference in
behavior.
http://cgit.freedesktop.org/cairo/commit/?id=40aefac5d714bf7536632ed38c7a8ee05049f30b

Summary is: when Windows are used as sources, the core operations
don't give the desired results and so render (or fallback, for old
servers) is used.

Including subwindows when surfaces are used as sources started here:
http://cgit.freedesktop.org/cairo/commit/?id=0c5d28a4e5ce5e4dd72c0f416ce5e960e92b808b

At that time, render supported including subwindows in sources in
some situations.  Behavior was always undefined for subwindows of
different depths, and probably not the desired behavior if Visuals
or Colormaps differed in other ways.

That changed about a year ago; now the behavior of render for
*any* subwindow regions in sources is undefined.
http://cgit.freedesktop.org/xorg/proto/renderproto/commit/?id=2c5e931d5e5b5af88bcf8aaed8b10d799fd47b1e

The change means that, to continue to support the old behavior,
cairo will need to always CopyArea to a Pixmap (instead of or
before using render).  For the destination surface, cairo would
again want to know whether it is a Pixmap or Window (as it would
need a scratch surface for Windows).  (In this situation though it
is more likely that cairo_surface_create_similar is used and, if
so, cairo will know that it is a Pixmap.)

I'm actually not advocating trying to keep the old
IncludeInferiors behavior.  To really get things right, cairo
would need to iterate down the Window hierarchy using the
appropriate Visuals, and this doesn't seem to be what cairo is
designed for.  However, some have wanted the behavior and it has
worked well enough for them, so I'm trying to avoid throwing this
out unnecessarily.

Asking the server whether the Drawable is a Pixmap would be an
unwanted round trip.  (I guess the less favored path could be
taken until we get an async reply using dpy->async_handlers, but
that is more complex than ideal.)

I think what cairo really wants to know is whether the client
needs the IncludeInferiors behavior.  A client may wish to use
Windows as sources and doesn't need IncludeInferiors.  A common
situation is scrolling the contents of a Window.  XCopyArea will
do this right straight up, but, with render, a ping-pong from a
scratch surface is needed.

So, I'm noting that the IncludeInferiors behavior was only ever
documented on cairo_xlib_surface_create (with Visual) and not in
the _with_xrender_format variant.

Would it be acceptable if we skipped trying to achieve the
IncludeInferiors behavior for source surfaces from
cairo_xlib_surface_create_with_render_format?

Having a difference in behavior between the two create functions
may seem a bit quirky, but all Windows have a Visual, so
cairo_xlib_surface_create is the natural function for creating
surfaces for Windows.

Karl.


More information about the cairo mailing list