[PATCH wayland 1/4] protocol: double-buffered state for wl_surface

David Herrmann dh.herrmann at googlemail.com
Thu Oct 11 04:00:40 PDT 2012


Hi Pekka

On Wed, Oct 10, 2012 at 11:47 AM, Pekka Paalanen <ppaalanen at gmail.com> wrote:
> This change breaks the protocol.
>
> The current protocol is racy in that updates to surface content and
> surface state (e.g. damage, input and opaque regions) are not guaranteed
> to happen at the same time. Due to protocol buffering and handling
> practices, the issues are very hard to trigger.
>
> Committing damage to a surface at arbitrary times makes it hard to
> track when the wl_buffer is being read by the server, and when it is
> safe to overwrite (the case of wl_shm with a single buffer reused
> constantly).
>
> This protocol change introduces the concept of double-buffered state.
> Such state is accumulated and cached in the server, unused, until the
> final commit request. The surface will receive its new content and apply
> its new state atomically.
>
> A wl_surface.commit request is added to the protocol. This is thought to
> be more clear, than having wl_surface.attach committing implicitly, and
> then having another request to commit without attaching, as would be
> required for a GL app that wants to change e.g. input region without
> redrawing.
>
> When these changes are implemented, clients do not have to worry about
> ordering damage vs. input region vs. attach vs. ... anymore. Clients set
> the state in any order they want, and kick it all in with a commit.
>
> The interactions between wl_surface.attach, (wl_surface.commit,)
> wl_buffer.release, and wl_buffer.destroy have been undocumented. Only
> careful inspection of the compositor code has told when a wl_buffer is
> free for re-use, especially for wl_shm and wrt. wl_surface.damage.
> Try to clarify how it all should work, and what happens if the wl_buffer
> gets destroyed.
>
> An additional minor fix: allow NULL argument to
> wl_surface.set_opaque_region. The wording in the documentation already
> implied that a nil region is allowed.
>
> Signed-off-by: Pekka Paalanen <ppaalanen at gmail.com>
> ---
>  protocol/wayland.xml |  121 ++++++++++++++++++++++++++++++++++++++++---------
>  1 files changed, 98 insertions(+), 23 deletions(-)
>
> diff --git a/protocol/wayland.xml b/protocol/wayland.xml
> index efd71dd..c45a404 100644
> --- a/protocol/wayland.xml
> +++ b/protocol/wayland.xml
> @@ -630,9 +630,37 @@
>
>      <request name="attach">
>        <description summary="set the surface contents">
> -       Copy the contents of a buffer into this surface. The x and y
> -       arguments specify the location of the new buffers upper left
> -       corner, relative to the old buffers upper left corner.
> +       Set the contents of a buffer into this surface. The x and y
> +       arguments specify the location of the new pending buffer's upper
> +       left corner, relative to the current buffer's upper left corner. In
> +       other words, the x and y, and the width and height of the wl_buffer
> +       together define in which directions the surface's size changes.
> +
> +       Surface contents are double-buffered state, see wl_surface.commit.
> +
> +       The initial surface contents are void; there is no content.
> +       wl_surface.attach assigns the given wl_buffer as the pending wl_buffer.
> +       wl_surface.commit applies the pending wl_buffer as the new
> +       surface contents, and the size of the surface becomes the size of
> +       the wl_buffer. The wl_buffer is also kept as pending, until
> +       changed by wl_surface.attach or the wl_buffer is destroyed.
> +
> +       Committing a pending wl_buffer allows the compositor to read the
> +       pixels in the wl_buffer. The compositor may access the pixels at any
> +       time after the wl_surface.commit request. When the compositor will
> +       not access the pixels anymore, it will send the wl_buffer.release
> +       event. Only after receiving wl_buffer.release, the client may re-use
> +       the wl_buffer.
> +
> +       Destroying the wl_buffer after wl_buffer.release does not change the
> +       surface contents, even if the wl_buffer is still pending for the
> +       next commit. In such case, the next commit does not change the
> +       surface contents. However, if the client destroys the wl_buffer
> +       before receiving wl_buffer.release, the surface contents become
> +       undefined immediately.
> +
> +       Only if wl_surface.attach is sent with a nil wl_buffer, the
> +       following wl_surface.commit will remove the surface content.

If I do multiple wl_surface.attach()s on different buffers and after
that a wl_surface.commit(), do I get wl_buffer.release() events for
the buffers that I attached first and aren't affected by the commit?
I guess not but I just wanted to go sure.

Regards
David


More information about the wayland-devel mailing list