monitoring the contents of the screen -- bug#14648

Owen Taylor otaylor at
Fri Sep 12 13:03:45 PDT 2008

On Sat, 2008-08-16 at 19:19 -0700, Nathaniel Smith wrote:
> There hasn't been any activity on this bug after 6 months, so I
> thought I'd send a note to the list asking for advice on how to get it
> fixed...
> The full description of the problem is here:
> but basically, the issue is that Damage has this "clever" code -- I
> guess intended to help make things async-safe, but as far as I can
> tell, any code that would be helped is already irreparably broken --
> that makes it impossible to write efficient screen-monitoring programs
> (think like x11vnc or screencast recorders).  You have to forgo
> Damage's ability to compress out redundant damage events (meaning that
> if something is drawing quickly to a particular region, you get a
> storm of events saying that the same area is damaged over and over),
> because if you *do* try to use it, then Damage ends up sending O(n^2)
> redundant damage events when processing complex damage regions (where
> n is the number of distinct modified rectangles within the window, and
> can get very large when you are monitoring an app that is clever and
> tries to minimize the total number of pixels it draws on).

I've just read through the bug and discussion of this, and I had a
couple of comments.

It seems to me that there are a couple of simple techniques that you
could take to reduce problems in your application. (Maybe you've already
tried some of these)

First, instead of calling XSubtractDamage on each rectangle individually
in the region you've accumulated client-side, you could instead build an
XFixesRegion with *all* of the rectangles in the accumulated damage
region, and XSubtractDamage that. At that point, the only areas that
will be re-reported are those that are "in flight" ... that the server
has sent but you haven't yet processed.

(You can even ignore the "in flight" rectangles by examining event
serial numbers. Any damage events with serial numbers less than that of
your last XSubtractDamage() call can be ignored. See XNextRequest() for
how to get the serial number of a particular request. Still just
adding them to your region twice should be almost as cheap.)

Second, you could just offload the acculation of damage completely to
the server. When you decide that it's time to send new data over the

 - Call XSubtractRegion() with repair=None
 - Retrieve the resulting 'parts' region and use that to decide what
   region of the image to retrieve and send over the wire.

This is an extra round-trip to the X server, but its not going to matter
in the big scheme of things.

The usefulness of re-reporting the left-over damage is certainly not
obvious to me. I can make up ways of using the damage extension that
would rely on it, but they aren't the ways I would normally expect
people to do things. Without having full replay to the contents of
Keith's head when the spec was being written, we'll probably never know
for certain why its there.

I don't think it can just be struck out of the spec, however. Even if
nobody relies on it, the damage extension has been widely deployed and
used, and making incompatible changes to semantics would go against
reasonable maintenance policies.

Another level also doesn't make sense to me, since re-reporting of
left-over damage is really completely orthogonal from level.. it occurs
at all levels. If my above suggestions aren't enough to resolve the
problem, I think a fix would probably adding another option to the
Damage object for that.

That might be exposed as a DamageChangeAttributes along the lines
of RenderChangePicture or ChangeWindowAttributes. Or could simply be a
simple "setter" request.

- Owen

More information about the xorg mailing list