forked from 12to11/12to11
Check in new files for explicit synchronization
* explicit_synchronization.c: * linux-explicit-synchronization-unstable-v1.xml: New files.
This commit is contained in:
parent
86216a1164
commit
28f1410e35
2 changed files with 746 additions and 0 deletions
490
explicit_synchronization.c
Normal file
490
explicit_synchronization.c
Normal file
|
@ -0,0 +1,490 @@
|
|||
/* Wayland compositor running on top of an X server.
|
||||
|
||||
Copyright (C) 2022 to various contributors.
|
||||
|
||||
This file is part of 12to11.
|
||||
|
||||
12to11 is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
12to11 is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with 12to11. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "compositor.h"
|
||||
|
||||
#include "linux-explicit-synchronization-unstable-v1.h"
|
||||
|
||||
struct _Synchronization
|
||||
{
|
||||
/* The surface destroy listener. */
|
||||
DestroyCallback *destroy_listener;
|
||||
|
||||
/* The surface. */
|
||||
Surface *surface;
|
||||
|
||||
/* The file descriptor of any pending acquire fence. */
|
||||
int acquire_fence;
|
||||
|
||||
/* Any associated release object. */
|
||||
SyncRelease *release;
|
||||
|
||||
/* The associated resource. */
|
||||
struct wl_resource *resource;
|
||||
};
|
||||
|
||||
struct _SyncRelease
|
||||
{
|
||||
/* The associated surface. */
|
||||
Surface *surface;
|
||||
|
||||
/* The associated synchronization. */
|
||||
Synchronization *synchronization;
|
||||
|
||||
/* The associated resource. */
|
||||
struct wl_resource *resource;
|
||||
};
|
||||
|
||||
/* The global zwp_linux_explicit_synchronization_v1 object. */
|
||||
static struct wl_global *explicit_sync_global;
|
||||
|
||||
static void
|
||||
HandleReleaseDestroy (struct wl_resource *resource)
|
||||
{
|
||||
SyncRelease *release;
|
||||
|
||||
release = wl_resource_get_user_data (resource);
|
||||
|
||||
/* If release is attached to a surface, remove it from the
|
||||
surface. */
|
||||
|
||||
if (release->surface)
|
||||
release->surface->release = NULL;
|
||||
|
||||
/* Do the same for the synchronization object. */
|
||||
|
||||
if (release->synchronization)
|
||||
release->synchronization->release = NULL;
|
||||
|
||||
/* Free the release object. */
|
||||
XLFree (release);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
DestroySynchronization (struct wl_client *client, struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
SetAcquireFence (struct wl_client *client, struct wl_resource *resource,
|
||||
int32_t fd)
|
||||
{
|
||||
Synchronization *synchronization;
|
||||
|
||||
synchronization = wl_resource_get_user_data (resource);
|
||||
|
||||
#define NoSurface ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_NO_SURFACE
|
||||
|
||||
/* If the surface was destroyed, raise such an error. */
|
||||
if (!synchronization->surface)
|
||||
{
|
||||
wl_resource_post_error (resource, NoSurface,
|
||||
"the surface associated with this"
|
||||
" resource was destroyed");
|
||||
goto error;
|
||||
}
|
||||
|
||||
#undef NoSurface
|
||||
|
||||
#define DuplicateFence \
|
||||
ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_DUPLICATE_FENCE
|
||||
|
||||
/* If a fence was already attached, raise that as an errore. */
|
||||
if (synchronization->acquire_fence != -1)
|
||||
{
|
||||
wl_resource_post_error (resource, DuplicateFence,
|
||||
"another fence has already been attached"
|
||||
" during this commit cycle");
|
||||
goto error;
|
||||
}
|
||||
|
||||
#undef DuplicateFence
|
||||
|
||||
/* Set the file descriptor and return. */
|
||||
synchronization->acquire_fence = fd;
|
||||
return;
|
||||
|
||||
error:
|
||||
close (fd);
|
||||
}
|
||||
|
||||
static void
|
||||
GetRelease (struct wl_client *client, struct wl_resource *resource,
|
||||
uint32_t id)
|
||||
{
|
||||
Synchronization *synchronization;
|
||||
SyncRelease *release;
|
||||
|
||||
/* The release lifecycle is somewhat like this:
|
||||
|
||||
First, it starts out as the `release' field of a Synchronization
|
||||
resource. When the synchronization is committed, it is moved to
|
||||
the release field of the surface, and it is detatched from both
|
||||
once release events are sent. */
|
||||
|
||||
synchronization = wl_resource_get_user_data (resource);
|
||||
|
||||
#define DuplicateRelease \
|
||||
ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_DUPLICATE_RELEASE
|
||||
|
||||
if (synchronization->release)
|
||||
{
|
||||
/* Uncommitted release already exists. Post an error. */
|
||||
wl_resource_post_error (resource, DuplicateRelease,
|
||||
"another release has already been acquired"
|
||||
" during this commit cycle");
|
||||
return;
|
||||
}
|
||||
|
||||
#undef DuplicateRelease
|
||||
|
||||
release = XLSafeMalloc (sizeof *release);
|
||||
|
||||
if (!release)
|
||||
{
|
||||
wl_resource_post_no_memory (resource);
|
||||
return;
|
||||
}
|
||||
|
||||
memset (release, 0, sizeof *release);
|
||||
release->resource
|
||||
= wl_resource_create (client,
|
||||
&zwp_linux_buffer_release_v1_interface,
|
||||
wl_resource_get_version (resource),
|
||||
id);
|
||||
|
||||
if (!release->resource)
|
||||
{
|
||||
wl_resource_post_no_memory (resource);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Attach the release. */
|
||||
release->synchronization = synchronization;
|
||||
synchronization->release = release;
|
||||
|
||||
/* Set the resource implementation. */
|
||||
wl_resource_set_implementation (release->resource,
|
||||
NULL, release,
|
||||
HandleReleaseDestroy);
|
||||
}
|
||||
|
||||
static void
|
||||
HandleSurfaceDestroy (void *data)
|
||||
{
|
||||
Synchronization *synchronization;
|
||||
|
||||
synchronization = data;
|
||||
|
||||
/* The surface was destroyed. Mark the object as invalid. */
|
||||
synchronization->surface = NULL;
|
||||
synchronization->destroy_listener = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
HandleSurfaceCommit (Synchronization *synchronization, Surface *surface)
|
||||
{
|
||||
#define NoBuffer ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_NO_BUFFER
|
||||
|
||||
if (synchronization->acquire_fence != -1)
|
||||
{
|
||||
if (!(surface->pending_state.pending & PendingBuffer
|
||||
&& surface->pending_state.buffer))
|
||||
{
|
||||
/* If no buffer was attached, report an error. */
|
||||
wl_resource_post_error (synchronization->resource,
|
||||
NoBuffer, "no buffer attached"
|
||||
" but acquire fence provided");
|
||||
close (synchronization->acquire_fence);
|
||||
synchronization->acquire_fence = -1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (surface->acquire_fence != -1)
|
||||
close (surface->acquire_fence);
|
||||
|
||||
surface->acquire_fence = synchronization->acquire_fence;
|
||||
synchronization->acquire_fence = -1;
|
||||
}
|
||||
|
||||
/* Move the release callback to the surface. Assume one does
|
||||
not already exist. */
|
||||
XLAssert (surface->release == NULL);
|
||||
|
||||
/* surface->release can still end up NULL if no release was
|
||||
attached. */
|
||||
surface->release = synchronization->release;
|
||||
|
||||
if (surface->release)
|
||||
{
|
||||
/* Clear these fields, to detach the release from the
|
||||
synchronization. */
|
||||
surface->release->synchronization = NULL;
|
||||
synchronization->release = NULL;
|
||||
|
||||
/* And set this field to attach the release to the
|
||||
surface. */
|
||||
surface->release->surface = surface;
|
||||
|
||||
if (surface->release
|
||||
&& !(surface->pending_state.pending & PendingBuffer
|
||||
&& surface->pending_state.buffer))
|
||||
wl_resource_post_error (synchronization->resource,
|
||||
NoBuffer, "no buffer attached"
|
||||
" but release provided");
|
||||
}
|
||||
#undef NoBuffer
|
||||
}
|
||||
|
||||
static void
|
||||
HandleSynchronizationDestroy (struct wl_resource *resource)
|
||||
{
|
||||
Synchronization *synchronization;
|
||||
|
||||
/* Free the synchronization as it has been destroyed. */
|
||||
synchronization = wl_resource_get_user_data (resource);
|
||||
|
||||
if (synchronization->destroy_listener)
|
||||
XLSurfaceCancelRunOnFree (synchronization->destroy_listener);
|
||||
|
||||
if (synchronization->surface)
|
||||
/* Also detach it from the surface. */
|
||||
synchronization->surface->synchronization = NULL;
|
||||
|
||||
/* Detach any attached release callback. */
|
||||
if (synchronization->release)
|
||||
wl_resource_destroy (synchronization->release->resource);
|
||||
|
||||
/* If a fence happens to still be attached, close it. */
|
||||
if (synchronization->acquire_fence != -1)
|
||||
close (synchronization->acquire_fence);
|
||||
|
||||
XLFree (synchronization);
|
||||
}
|
||||
|
||||
static struct zwp_linux_surface_synchronization_v1_interface synchronization_impl =
|
||||
{
|
||||
.destroy = DestroySynchronization,
|
||||
.set_acquire_fence = SetAcquireFence,
|
||||
.get_release = GetRelease,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void
|
||||
Destroy (struct wl_client *client, struct wl_resource *resource)
|
||||
{
|
||||
wl_resource_destroy (resource);
|
||||
}
|
||||
|
||||
static void
|
||||
GetSynchronization (struct wl_client *client, struct wl_resource *resource,
|
||||
uint32_t id, struct wl_resource *surface_resource)
|
||||
{
|
||||
Synchronization *synchronization;
|
||||
Surface *surface;
|
||||
|
||||
surface = wl_resource_get_user_data (surface_resource);
|
||||
|
||||
#define SynchronizationAlreadyExists \
|
||||
ZWP_LINUX_EXPLICIT_SYNCHRONIZATION_V1_ERROR_SYNCHRONIZATION_EXISTS
|
||||
|
||||
if (surface->synchronization)
|
||||
{
|
||||
/* Don't let clients create more synchronization objects if one
|
||||
already exists. */
|
||||
wl_resource_post_error (resource, SynchronizationAlreadyExists,
|
||||
"synchronization object already exists");
|
||||
return;
|
||||
}
|
||||
|
||||
#undef SynchronizationAlreadyExists
|
||||
|
||||
/* Allocate the synchronization object. */
|
||||
synchronization = XLSafeMalloc (sizeof *synchronization);
|
||||
|
||||
if (!synchronization)
|
||||
{
|
||||
wl_resource_post_no_memory (resource);
|
||||
return;
|
||||
}
|
||||
|
||||
memset (synchronization, 0, sizeof *synchronization);
|
||||
synchronization->resource
|
||||
= wl_resource_create (client,
|
||||
&zwp_linux_surface_synchronization_v1_interface,
|
||||
wl_resource_get_version (resource), id);
|
||||
|
||||
if (!synchronization->resource)
|
||||
{
|
||||
XLFree (synchronization);
|
||||
wl_resource_post_no_memory (resource);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now, attach the synchronization object to the surface. */
|
||||
surface->synchronization = synchronization;
|
||||
|
||||
/* And attach a destroy listener. */
|
||||
synchronization->destroy_listener
|
||||
= XLSurfaceRunOnFree (surface, HandleSurfaceDestroy,
|
||||
synchronization);
|
||||
|
||||
/* And attach the surface to the synchronization. */
|
||||
synchronization->surface = surface;
|
||||
|
||||
/* Set the implementation. */
|
||||
wl_resource_set_implementation (synchronization->resource,
|
||||
&synchronization_impl,
|
||||
synchronization,
|
||||
HandleSynchronizationDestroy);
|
||||
|
||||
/* Clear initial values. */
|
||||
synchronization->acquire_fence = -1;
|
||||
}
|
||||
|
||||
static struct zwp_linux_explicit_synchronization_v1_interface explicit_sync_impl =
|
||||
{
|
||||
.destroy = Destroy,
|
||||
.get_synchronization = GetSynchronization,
|
||||
};
|
||||
|
||||
static void
|
||||
HandleBind (struct wl_client *client, void *data, uint32_t version,
|
||||
uint32_t id)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource
|
||||
= wl_resource_create (client,
|
||||
&zwp_linux_explicit_synchronization_v1_interface,
|
||||
version, id);
|
||||
if (!resource)
|
||||
{
|
||||
wl_client_post_no_memory (client);
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_set_implementation (resource, &explicit_sync_impl,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
XLDestroyRelease (SyncRelease *release)
|
||||
{
|
||||
/* Destroying the resoruce will cause the release to be freed. */
|
||||
wl_resource_destroy (release->resource);
|
||||
}
|
||||
|
||||
void
|
||||
XLSyncRelease (SyncRelease *release)
|
||||
{
|
||||
Bool error;
|
||||
int fd;
|
||||
|
||||
/* Optimization ideas. Every time a buffer is attached with a
|
||||
release object, create new finish_fence for the buffer, that is
|
||||
signalled whenever the contents are drawn. Then, just use that
|
||||
fence here instead. */
|
||||
|
||||
error = False;
|
||||
fd = RenderGetFinishFence (&error);
|
||||
|
||||
if (error)
|
||||
#define InvalidFence ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_INVALID_FENCE
|
||||
wl_resource_post_error (release->resource, InvalidFence,
|
||||
"server failed to create finish fence");
|
||||
#undef InvalidFence
|
||||
else
|
||||
{
|
||||
/* Post a fenced release with the fence. */
|
||||
zwp_linux_buffer_release_v1_send_fenced_release (release->resource,
|
||||
fd);
|
||||
/* Close the file descriptor. */
|
||||
close (fd);
|
||||
}
|
||||
|
||||
/* Destroy the sync object. */
|
||||
wl_resource_destroy (release->resource);
|
||||
}
|
||||
|
||||
void
|
||||
XLSyncCommit (Synchronization *synchronization)
|
||||
{
|
||||
HandleSurfaceCommit (synchronization, synchronization->surface);
|
||||
}
|
||||
|
||||
void
|
||||
XLWaitFence (Surface *surface)
|
||||
{
|
||||
RenderFence fence;
|
||||
Bool error;
|
||||
|
||||
if (surface->acquire_fence == -1)
|
||||
return;
|
||||
|
||||
error = False;
|
||||
|
||||
/* This is expected to close the file descriptor. */
|
||||
fence = RenderImportFdFence (surface->acquire_fence, &error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
#define InvalidFence ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_INVALID_FENCE
|
||||
/* Importing the fence failed; signal an error to the
|
||||
server. */
|
||||
wl_resource_post_error (surface->resource,
|
||||
InvalidFence, "the specified sync"
|
||||
" fence could not be imported");
|
||||
#undef InvalidFence
|
||||
/* Try closing the file descriptor as well. */
|
||||
close (surface->acquire_fence);
|
||||
surface->acquire_fence = -1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
surface->acquire_fence = -1;
|
||||
|
||||
/* Wait for the fence to be triggered. */
|
||||
RenderWaitFence (fence);
|
||||
|
||||
/* Delete the fence. */
|
||||
RenderDeleteFence (fence);
|
||||
}
|
||||
|
||||
void
|
||||
XLInitExplicitSynchronization (void)
|
||||
{
|
||||
/* If the renderer does not support explicit synchronization,
|
||||
return. */
|
||||
if (!(renderer_flags & SupportsExplicitSync))
|
||||
return;
|
||||
|
||||
explicit_sync_global
|
||||
= wl_global_create (compositor.wl_display,
|
||||
&zwp_linux_explicit_synchronization_v1_interface,
|
||||
2, NULL, HandleBind);
|
||||
}
|
256
linux-explicit-synchronization-unstable-v1.xml
Normal file
256
linux-explicit-synchronization-unstable-v1.xml
Normal file
|
@ -0,0 +1,256 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="zwp_linux_explicit_synchronization_unstable_v1">
|
||||
|
||||
<copyright>
|
||||
Copyright 2016 The Chromium Authors.
|
||||
Copyright 2017 Intel Corporation
|
||||
Copyright 2018 Collabora, Ltd
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<interface name="zwp_linux_explicit_synchronization_v1" version="2">
|
||||
<description summary="protocol for providing explicit synchronization">
|
||||
This global is a factory interface, allowing clients to request
|
||||
explicit synchronization for buffers on a per-surface basis.
|
||||
|
||||
See zwp_linux_surface_synchronization_v1 for more information.
|
||||
|
||||
This interface is derived from Chromium's
|
||||
zcr_linux_explicit_synchronization_v1.
|
||||
|
||||
Warning! The protocol described in this file is experimental and
|
||||
backward incompatible changes may be made. Backward compatible changes
|
||||
may be added together with the corresponding interface version bump.
|
||||
Backward incompatible changes are done by bumping the version number in
|
||||
the protocol and interface names and resetting the interface version.
|
||||
Once the protocol is to be declared stable, the 'z' prefix and the
|
||||
version number in the protocol and interface names are removed and the
|
||||
interface version number is reset.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy explicit synchronization factory object">
|
||||
Destroy this explicit synchronization factory object. Other objects,
|
||||
including zwp_linux_surface_synchronization_v1 objects created by this
|
||||
factory, shall not be affected by this request.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="synchronization_exists" value="0"
|
||||
summary="the surface already has a synchronization object associated"/>
|
||||
</enum>
|
||||
|
||||
<request name="get_synchronization">
|
||||
<description summary="extend surface interface for explicit synchronization">
|
||||
Instantiate an interface extension for the given wl_surface to provide
|
||||
explicit synchronization.
|
||||
|
||||
If the given wl_surface already has an explicit synchronization object
|
||||
associated, the synchronization_exists protocol error is raised.
|
||||
|
||||
Graphics APIs, like EGL or Vulkan, that manage the buffer queue and
|
||||
commits of a wl_surface themselves, are likely to be using this
|
||||
extension internally. If a client is using such an API for a
|
||||
wl_surface, it should not directly use this extension on that surface,
|
||||
to avoid raising a synchronization_exists protocol error.
|
||||
</description>
|
||||
|
||||
<arg name="id" type="new_id"
|
||||
interface="zwp_linux_surface_synchronization_v1"
|
||||
summary="the new synchronization interface id"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="the surface"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwp_linux_surface_synchronization_v1" version="2">
|
||||
<description summary="per-surface explicit synchronization support">
|
||||
This object implements per-surface explicit synchronization.
|
||||
|
||||
Synchronization refers to co-ordination of pipelined operations performed
|
||||
on buffers. Most GPU clients will schedule an asynchronous operation to
|
||||
render to the buffer, then immediately send the buffer to the compositor
|
||||
to be attached to a surface.
|
||||
|
||||
In implicit synchronization, ensuring that the rendering operation is
|
||||
complete before the compositor displays the buffer is an implementation
|
||||
detail handled by either the kernel or userspace graphics driver.
|
||||
|
||||
By contrast, in explicit synchronization, dma_fence objects mark when the
|
||||
asynchronous operations are complete. When submitting a buffer, the
|
||||
client provides an acquire fence which will be waited on before the
|
||||
compositor accesses the buffer. The Wayland server, through a
|
||||
zwp_linux_buffer_release_v1 object, will inform the client with an event
|
||||
which may be accompanied by a release fence, when the compositor will no
|
||||
longer access the buffer contents due to the specific commit that
|
||||
requested the release event.
|
||||
|
||||
Each surface can be associated with only one object of this interface at
|
||||
any time.
|
||||
|
||||
In version 1 of this interface, explicit synchronization is only
|
||||
guaranteed to be supported for buffers created with any version of the
|
||||
wp_linux_dmabuf buffer factory. Version 2 additionally guarantees
|
||||
explicit synchronization support for opaque EGL buffers, which is a type
|
||||
of platform specific buffers described in the EGL_WL_bind_wayland_display
|
||||
extension. Compositors are free to support explicit synchronization for
|
||||
additional buffer types.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy synchronization object">
|
||||
Destroy this explicit synchronization object.
|
||||
|
||||
Any fence set by this object with set_acquire_fence since the last
|
||||
commit will be discarded by the server. Any fences set by this object
|
||||
before the last commit are not affected.
|
||||
|
||||
zwp_linux_buffer_release_v1 objects created by this object are not
|
||||
affected by this request.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="invalid_fence" value="0"
|
||||
summary="the fence specified by the client could not be imported"/>
|
||||
<entry name="duplicate_fence" value="1"
|
||||
summary="multiple fences added for a single surface commit"/>
|
||||
<entry name="duplicate_release" value="2"
|
||||
summary="multiple releases added for a single surface commit"/>
|
||||
<entry name="no_surface" value="3"
|
||||
summary="the associated wl_surface was destroyed"/>
|
||||
<entry name="unsupported_buffer" value="4"
|
||||
summary="the buffer does not support explicit synchronization"/>
|
||||
<entry name="no_buffer" value="5"
|
||||
summary="no buffer was attached"/>
|
||||
</enum>
|
||||
|
||||
<request name="set_acquire_fence">
|
||||
<description summary="set the acquire fence">
|
||||
Set the acquire fence that must be signaled before the compositor
|
||||
may sample from the buffer attached with wl_surface.attach. The fence
|
||||
is a dma_fence kernel object.
|
||||
|
||||
The acquire fence is double-buffered state, and will be applied on the
|
||||
next wl_surface.commit request for the associated surface. Thus, it
|
||||
applies only to the buffer that is attached to the surface at commit
|
||||
time.
|
||||
|
||||
If the provided fd is not a valid dma_fence fd, then an INVALID_FENCE
|
||||
error is raised.
|
||||
|
||||
If a fence has already been attached during the same commit cycle, a
|
||||
DUPLICATE_FENCE error is raised.
|
||||
|
||||
If the associated wl_surface was destroyed, a NO_SURFACE error is
|
||||
raised.
|
||||
|
||||
If at surface commit time the attached buffer does not support explicit
|
||||
synchronization, an UNSUPPORTED_BUFFER error is raised.
|
||||
|
||||
If at surface commit time there is no buffer attached, a NO_BUFFER
|
||||
error is raised.
|
||||
</description>
|
||||
<arg name="fd" type="fd" summary="acquire fence fd"/>
|
||||
</request>
|
||||
|
||||
<request name="get_release">
|
||||
<description summary="release fence for last-attached buffer">
|
||||
Create a listener for the release of the buffer attached by the
|
||||
client with wl_surface.attach. See zwp_linux_buffer_release_v1
|
||||
documentation for more information.
|
||||
|
||||
The release object is double-buffered state, and will be associated
|
||||
with the buffer that is attached to the surface at wl_surface.commit
|
||||
time.
|
||||
|
||||
If a zwp_linux_buffer_release_v1 object has already been requested for
|
||||
the surface in the same commit cycle, a DUPLICATE_RELEASE error is
|
||||
raised.
|
||||
|
||||
If the associated wl_surface was destroyed, a NO_SURFACE error
|
||||
is raised.
|
||||
|
||||
If at surface commit time there is no buffer attached, a NO_BUFFER
|
||||
error is raised.
|
||||
</description>
|
||||
<arg name="release" type="new_id" interface="zwp_linux_buffer_release_v1"
|
||||
summary="new zwp_linux_buffer_release_v1 object"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zwp_linux_buffer_release_v1" version="1">
|
||||
<description summary="buffer release explicit synchronization">
|
||||
This object is instantiated in response to a
|
||||
zwp_linux_surface_synchronization_v1.get_release request.
|
||||
|
||||
It provides an alternative to wl_buffer.release events, providing a
|
||||
unique release from a single wl_surface.commit request. The release event
|
||||
also supports explicit synchronization, providing a fence FD for the
|
||||
client to synchronize against.
|
||||
|
||||
Exactly one event, either a fenced_release or an immediate_release, will
|
||||
be emitted for the wl_surface.commit request. The compositor can choose
|
||||
release by release which event it uses.
|
||||
|
||||
This event does not replace wl_buffer.release events; servers are still
|
||||
required to send those events.
|
||||
|
||||
Once a buffer release object has delivered a 'fenced_release' or an
|
||||
'immediate_release' event it is automatically destroyed.
|
||||
</description>
|
||||
|
||||
<event name="fenced_release" type="destructor">
|
||||
<description summary="release buffer with fence">
|
||||
Sent when the compositor has finalised its usage of the associated
|
||||
buffer for the relevant commit, providing a dma_fence which will be
|
||||
signaled when all operations by the compositor on that buffer for that
|
||||
commit have finished.
|
||||
|
||||
Once the fence has signaled, and assuming the associated buffer is not
|
||||
pending release from other wl_surface.commit requests, no additional
|
||||
explicit or implicit synchronization is required to safely reuse or
|
||||
destroy the buffer.
|
||||
|
||||
This event destroys the zwp_linux_buffer_release_v1 object.
|
||||
</description>
|
||||
<arg name="fence" type="fd" summary="fence for last operation on buffer"/>
|
||||
</event>
|
||||
|
||||
<event name="immediate_release" type="destructor">
|
||||
<description summary="release buffer immediately">
|
||||
Sent when the compositor has finalised its usage of the associated
|
||||
buffer for the relevant commit, and either performed no operations
|
||||
using it, or has a guarantee that all its operations on that buffer for
|
||||
that commit have finished.
|
||||
|
||||
Once this event is received, and assuming the associated buffer is not
|
||||
pending release from other wl_surface.commit requests, no additional
|
||||
explicit or implicit synchronization is required to safely reuse or
|
||||
destroy the buffer.
|
||||
|
||||
This event destroys the zwp_linux_buffer_release_v1 object.
|
||||
</description>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
</protocol>
|
Loading…
Add table
Reference in a new issue