[RFC] damage handling rewrite

Pekka Paalanen ppaalanen at gmail.com
Fri Feb 3 07:43:52 PST 2012

Hi Kristian, Jesse,

while I was thinking on how to implement my fix to the wandering
surface problem, I noticed a flaw in the surface transformation
handling. weston_surface_configure() takes care to call
weston_surface_damage_below(), but weston_surface_update_transform()
does not. Therefore, I should see some old rendering messing my output.

I tried removing the explicit damage calls from the rotation
manipulation, but still did not see any misrendering. So I started
looking more closely to the damage handling.

Turned out surface damage is never cleared. Effectively we repaint the
whole display every time.

I tried to find a place to clear the surface damage, but it was just
impossible. weston_output_repaint() is called asynchronously
per-output, so I could not find a synchronisation point where I could
clear the surface damage. While repainting an output, the surface
damage cannot be cleared or even *modified at all*, because we may need
the damage again on repainting another output. I'm also thinking of
overlapping outputs, otherwise we might get away with subtracting the
output region from surface damage.

The existing code was already modifying the per-surface damage. (But
maybe did no harm?)

Taking a shot to fix things, I practically removed damage regions from
surfaces, and added the equivalents to outputs. When a surface is
damaged, the damage is applied to all outputs. Now I can track
per-output damage and clear it as needed. This fixed the repaint whole
display every time -issue.

Then I added the opaque surfaces optimisation back, and started reusing
the weston_surface::damage member, but this time it is valid only
during a single weston_output_repaint() call. It seems to work fine.

Looks like I got all my immediate issues solved by this, and IMHO the
resulting code is a little less complex. I am worried, though, that
this approach might make efficient integration of Jesse's sprite
support difficult if not impossible.

I pushed my WIP changes to a branch:

The following changes since commit 0452abc8203e2c037f074c059b9952b9410ccbdd:

  compositor: Don't just update uniforms when we change shaders (2012-01-31 15:38:43 -0500)

are available in the git repository at:
  git://git.collabora.co.uk/git/user/pq/wayland-demos.git repaint-wip

Pekka Paalanen (5):
      configure: add libpng to client libs
      compositor: fix and simplify shader uniform handling
      compositor: rewrite damage accumulation
      compositor: bring back opaque optimisation
      damage debug

 configure.ac     |    2 +-
 src/compositor.c |  178 ++++++++++++++++++++++++-----------------------------
 src/compositor.h |   12 ++--
 src/shell.c      |    2 +-
 4 files changed, 89 insertions(+), 105 deletions(-)

The libpng thing is just a build fix, and the shader uniform is a
simplification I would like to propose, but the meat of the damage
handling are the three last commits.

There is still clean-up to do, we can get rid of a couple of functions,
etc. if this approach works.

I'd like to hear your comments on this change and if you have other
suggestions on resolving the damage clearing problem.

If the new approach is impossible for sprites, could we perhaps combine
both the old and the new approach, tracking damage in both surfaces and
outputs, if that would let everything work?


More information about the wayland-devel mailing list