Commit 3384f69e authored by Derek Foreman's avatar Derek Foreman

protocol: Add wl_surface.damage_buffer

wl_surface.damage uses surface local co-ordinates.

Buffer scale and buffer transforms came along, and EGL surfaces
have no understanding of them.

Theoretically, clients pass damage rectangles - in Y-inverted surface
co-ordinates) to EGLSwapBuffersWithDamage, and the EGL implementation
passed them on to wayland.  However, for this to work the EGL
implementation must be able to flip those rectangles into the space
the compositor is expecting, but it's unable to do so because it
doesn't know the height of the transformed buffer.

So, currently, EGLSwapBuffersWithDamage is unusable and EGLSwapBuffers
has to pass (0,0) - (INT32_MAX, INT32_MAX) damage to function.

wl_surface.damage_buffer allows damage to be registered on a surface
in buffer co-ordinates, avoiding this problem.

Credit where it's due, these ideas are not entirely my own:
Over a year ago the idea of changing damage co-ordinates to buffer
co-ordinates was suggested (by Jason Ekstrand), and it was at least
partially rejected and abandoned.  At the time it was also suggested
(by Pekka Paalanen) that adding a new wl_surface.damage_buffer request
was another option.

This will eventually resolve:
by making the problem irrelevant.
Reviewed-by: Pekka Paalanen's avatarPekka Paalanen <>
Reviewed-by: Jason Ekstrand's avatarJason Ekstrand <>
Signed-off-by: default avatarDerek Foreman <>
Reviewed-by: Jonas Ådahl's avatarJonas Ådahl <>
parent 389c84e2
......@@ -176,7 +176,7 @@
<interface name="wl_compositor" version="3">
<interface name="wl_compositor" version="4">
<description summary="the compositor singleton">
A compositor. This object is a singleton global. The
compositor is in charge of combining the contents of multiple
......@@ -986,7 +986,7 @@
<interface name="wl_surface" version="3">
<interface name="wl_surface" version="4">
<description summary="an onscreen surface">
A surface is a rectangular area that is displayed on the screen.
It has a location, size and pixel contents.
......@@ -1109,6 +1109,10 @@
wl_surface.commit assigns pending damage as the current damage,
and clears pending damage. The server will clear the current
damage as it repaints the surface.
Alternatively, damage can be posted with wl_surface.damage_buffer
which uses buffer co-ordinates instead of surface co-ordinates,
and is probably the preferred and intuitive way of doing this.
<arg name="x" type="int"/>
......@@ -1325,6 +1329,48 @@
<arg name="scale" type="int"/>
<!-- Version 4 additions -->
<request name="damage_buffer" since="4">
<description summary="mark part of the surface damaged using buffer co-ordinates">
This request is used to describe the regions where the pending
buffer is different from the current surface contents, and where
the surface therefore needs to be repainted. The compositor
ignores the parts of the damage that fall outside of the surface.
Damage is double-buffered state, see wl_surface.commit.
The damage rectangle is specified in buffer coordinates.
The initial value for pending damage is empty: no damage.
wl_surface.damage_buffer adds pending damage: the new pending
damage is the union of old pending damage and the given rectangle.
wl_surface.commit assigns pending damage as the current damage,
and clears pending damage. The server will clear the current
damage as it repaints the surface.
This request differs from wl_surface.damage in only one way - it
takes damage in buffer co-ordinates instead of surface local
co-ordinates. While this generally is more intuitive than surface
co-ordinates, it is especially desirable when using wp_viewport
or when a drawing library (like EGL) is unaware of buffer scale
and buffer transform.
Note: Because buffer transformation changes and damage requests may
be interleaved in the protocol stream, It is impossible to determine
the actual mapping between surface and buffer damage until
wl_surface.commit time. Therefore, compositors wishing to take both
kinds of damage into account will have to accumulate damage from the
two requests separately and only transform from one to the other
after receiving the wl_surface.commit.
<arg name="x" type="int"/>
<arg name="y" type="int"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<interface name="wl_seat" version="5">
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment