Introduce support for the zwp_linux_explicit_synchronization_unstable_v1 protocol with an implementation of the zwp_linux_explicit_synchronization_v1 interface. Explicit synchronization provides a more versatile notification mechanism for buffer readiness and availability, and can be used to improve efficiency by integrating with related functionality in display and graphics APIs. In addition, the per-commit nature of the release events provided by this protocol potentially offers a solution to a deficiency of the wl_buffer.release event (see https://gitlab.freedesktop.org/wayland/wayland/issues/46). Support for this protocol depends on the capabilities of the backend, so we don't register it by default but provide a function which each backend will need to call. In this commit only the headless backend when using the noop renderer supports this to enable testing. Note that the zwp_surface_synchronization_v1 interface, which contains the core functionality of the protocol, is not implemented in this commit. Support for it will be added in future commits. Changes in v7: - Added some information in the commit message about the benefits of the explicit sync protocol. Changes in v6: - Fall back to advertising minor version 1 of the explicit sync protocol, although we support minor version 2 features, until the new wayland-protocols version is released. Changes in v5: - Meson support. - Advertise minor version 2 of the explicit sync protocol. Changes in v4: - Enable explicit sync support in the headless backend for all renderers. Changes in v3: - Use wl_resource_get_version() instead of hardcoding version 1. - Use updated protocol interface names. - Use correct format specifier for resource id. - Change test name to 'linux-explicit-synchronization.weston' (s/_/-/g). Changes in v2: - Move implementation to separate file so protocol can be registered on demand by backends. - Register protocol in headless+noop backend for testing purposes. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>dev
							parent
							
								
									a37920e77c
								
							
						
					
					
						commit
						27d7c395c7
					
				@ -0,0 +1,164 @@ | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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. | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "config.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <inttypes.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "compositor.h" | 
				
			||||||
 | 
					#include "linux-explicit-synchronization.h" | 
				
			||||||
 | 
					#include "linux-explicit-synchronization-unstable-v1-server-protocol.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void | 
				
			||||||
 | 
					destroy_linux_surface_synchronization(struct wl_resource *resource) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						struct weston_surface *surface = | 
				
			||||||
 | 
							wl_resource_get_user_data(resource); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (surface) | 
				
			||||||
 | 
							surface->synchronization_resource = NULL; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void | 
				
			||||||
 | 
					linux_surface_synchronization_destroy(struct wl_client *client, | 
				
			||||||
 | 
									      struct wl_resource *resource) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						wl_resource_destroy(resource); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void | 
				
			||||||
 | 
					linux_surface_synchronization_set_acquire_fence(struct wl_client *client, | 
				
			||||||
 | 
											struct wl_resource *resource, | 
				
			||||||
 | 
											int32_t fd) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						wl_client_post_no_memory(client); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void | 
				
			||||||
 | 
					linux_surface_synchronization_get_release(struct wl_client *client, | 
				
			||||||
 | 
										  struct wl_resource *resource, | 
				
			||||||
 | 
										  uint32_t id) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						wl_client_post_no_memory(client); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct zwp_linux_surface_synchronization_v1_interface | 
				
			||||||
 | 
					linux_surface_synchronization_implementation = { | 
				
			||||||
 | 
						linux_surface_synchronization_destroy, | 
				
			||||||
 | 
						linux_surface_synchronization_set_acquire_fence, | 
				
			||||||
 | 
						linux_surface_synchronization_get_release, | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void | 
				
			||||||
 | 
					linux_explicit_synchronization_destroy(struct wl_client *client, | 
				
			||||||
 | 
									       struct wl_resource *resource) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						wl_resource_destroy(resource); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void | 
				
			||||||
 | 
					linux_explicit_synchronization_get_synchronization(struct wl_client *client, | 
				
			||||||
 | 
											   struct wl_resource *resource, | 
				
			||||||
 | 
											   uint32_t id, | 
				
			||||||
 | 
											   struct wl_resource *surface_resource) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						struct weston_surface *surface = | 
				
			||||||
 | 
							wl_resource_get_user_data(surface_resource); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (surface->synchronization_resource) { | 
				
			||||||
 | 
							wl_resource_post_error( | 
				
			||||||
 | 
								resource, | 
				
			||||||
 | 
								ZWP_LINUX_EXPLICIT_SYNCHRONIZATION_V1_ERROR_SYNCHRONIZATION_EXISTS, | 
				
			||||||
 | 
								"wl_surface@%"PRIu32" already has a synchronization object", | 
				
			||||||
 | 
								wl_resource_get_id(surface_resource)); | 
				
			||||||
 | 
							return; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						surface->synchronization_resource = | 
				
			||||||
 | 
							wl_resource_create(client, | 
				
			||||||
 | 
									   &zwp_linux_surface_synchronization_v1_interface, | 
				
			||||||
 | 
									   wl_resource_get_version(resource), id); | 
				
			||||||
 | 
						if (!surface->synchronization_resource) { | 
				
			||||||
 | 
							wl_client_post_no_memory(client); | 
				
			||||||
 | 
							return; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_resource_set_implementation(surface->synchronization_resource, | 
				
			||||||
 | 
									       &linux_surface_synchronization_implementation, | 
				
			||||||
 | 
									       surface, | 
				
			||||||
 | 
									       destroy_linux_surface_synchronization); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct zwp_linux_explicit_synchronization_v1_interface | 
				
			||||||
 | 
					linux_explicit_synchronization_implementation = { | 
				
			||||||
 | 
						linux_explicit_synchronization_destroy, | 
				
			||||||
 | 
						linux_explicit_synchronization_get_synchronization | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void | 
				
			||||||
 | 
					bind_linux_explicit_synchronization(struct wl_client *client, | 
				
			||||||
 | 
									    void *data, uint32_t version, | 
				
			||||||
 | 
									    uint32_t id) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						struct weston_compositor *compositor = data; | 
				
			||||||
 | 
						struct wl_resource *resource; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						resource = wl_resource_create(client, | 
				
			||||||
 | 
								&zwp_linux_explicit_synchronization_v1_interface, | 
				
			||||||
 | 
								version, id); | 
				
			||||||
 | 
						if (resource == NULL) { | 
				
			||||||
 | 
							wl_client_post_no_memory(client); | 
				
			||||||
 | 
							return; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_resource_set_implementation(resource, | 
				
			||||||
 | 
						       &linux_explicit_synchronization_implementation, | 
				
			||||||
 | 
						       compositor, NULL); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Advertise linux_explicit_synchronization support
 | 
				
			||||||
 | 
					 * | 
				
			||||||
 | 
					 * Calling this initializes the zwp_linux_explicit_synchronization_v1 | 
				
			||||||
 | 
					 * protocol support, so that the interface will be advertised to clients. | 
				
			||||||
 | 
					 * Essentially it creates a global. Do not call this function multiple times | 
				
			||||||
 | 
					 * in the compositor's lifetime. There is no way to deinit explicitly, globals | 
				
			||||||
 | 
					 * will be reaped when the wl_display gets destroyed. | 
				
			||||||
 | 
					 * | 
				
			||||||
 | 
					 * \param compositor The compositor to init for. | 
				
			||||||
 | 
					 * \return Zero on success, -1 on failure. | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					WL_EXPORT int | 
				
			||||||
 | 
					linux_explicit_synchronization_setup(struct weston_compositor *compositor) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						/* TODO: Update to minor version 2 when the next version of
 | 
				
			||||||
 | 
						 * wayland-protocols that contains it is released. */ | 
				
			||||||
 | 
						if (!wl_global_create(compositor->wl_display, | 
				
			||||||
 | 
								      &zwp_linux_explicit_synchronization_v1_interface, | 
				
			||||||
 | 
								      1, compositor, | 
				
			||||||
 | 
								      bind_linux_explicit_synchronization)) | 
				
			||||||
 | 
							return -1; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,34 @@ | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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. | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef WESTON_LINUX_EXPLICIT_SYNCHRONIZATION_H | 
				
			||||||
 | 
					#define WESTON_LINUX_EXPLICIT_SYNCHRONIZATION_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct weston_compositor; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int | 
				
			||||||
 | 
					linux_explicit_synchronization_setup(struct weston_compositor *compositor); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* WESTON_LINUX_EXPLICIT_SYNCHRONIZATION */ | 
				
			||||||
@ -0,0 +1,96 @@ | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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. | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "config.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "linux-explicit-synchronization-unstable-v1-client-protocol.h" | 
				
			||||||
 | 
					#include "weston-test-client-helper.h" | 
				
			||||||
 | 
					#include "wayland-server-protocol.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct zwp_linux_explicit_synchronization_v1 * | 
				
			||||||
 | 
					get_linux_explicit_synchronization(struct client *client) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						struct global *g; | 
				
			||||||
 | 
						struct global *global_sync = NULL; | 
				
			||||||
 | 
						struct zwp_linux_explicit_synchronization_v1 *sync = NULL; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wl_list_for_each(g, &client->global_list, link) { | 
				
			||||||
 | 
							if (strcmp(g->interface, | 
				
			||||||
 | 
								   zwp_linux_explicit_synchronization_v1_interface.name)) | 
				
			||||||
 | 
								continue; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (global_sync) | 
				
			||||||
 | 
								assert(!"Multiple linux explicit sync objects"); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							global_sync = g; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert(global_sync); | 
				
			||||||
 | 
						assert(global_sync->version == 1); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sync = wl_registry_bind( | 
				
			||||||
 | 
								client->wl_registry, global_sync->name, | 
				
			||||||
 | 
								&zwp_linux_explicit_synchronization_v1_interface, 1); | 
				
			||||||
 | 
						assert(sync); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sync; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct client * | 
				
			||||||
 | 
					create_test_client(void) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						struct client *cl = create_client_and_test_surface(0, 0, 100, 100); | 
				
			||||||
 | 
						assert(cl); | 
				
			||||||
 | 
						return cl; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST(second_surface_synchronization_on_surface_raises_error) | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
						struct client *client = create_test_client(); | 
				
			||||||
 | 
						struct zwp_linux_explicit_synchronization_v1 *sync = | 
				
			||||||
 | 
							get_linux_explicit_synchronization(client); | 
				
			||||||
 | 
						struct zwp_linux_surface_synchronization_v1 *surface_sync1; | 
				
			||||||
 | 
						struct zwp_linux_surface_synchronization_v1 *surface_sync2; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						surface_sync1 = | 
				
			||||||
 | 
							zwp_linux_explicit_synchronization_v1_get_synchronization( | 
				
			||||||
 | 
								sync, client->surface->wl_surface); | 
				
			||||||
 | 
						client_roundtrip(client); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Second surface_synchronization creation should fail */ | 
				
			||||||
 | 
						surface_sync2 = | 
				
			||||||
 | 
							zwp_linux_explicit_synchronization_v1_get_synchronization( | 
				
			||||||
 | 
								sync, client->surface->wl_surface); | 
				
			||||||
 | 
						expect_protocol_error( | 
				
			||||||
 | 
							client, | 
				
			||||||
 | 
							&zwp_linux_explicit_synchronization_v1_interface, | 
				
			||||||
 | 
							ZWP_LINUX_EXPLICIT_SYNCHRONIZATION_V1_ERROR_SYNCHRONIZATION_EXISTS); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						zwp_linux_surface_synchronization_v1_destroy(surface_sync2); | 
				
			||||||
 | 
						zwp_linux_surface_synchronization_v1_destroy(surface_sync1); | 
				
			||||||
 | 
						zwp_linux_explicit_synchronization_v1_destroy(sync); | 
				
			||||||
 | 
					} | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue