diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dd018f83..65ae360b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,7 +43,7 @@ variables: FDO_UPSTREAM_REPO: wayland/weston FDO_REPO_SUFFIX: "$BUILD_OS/$BUILD_ARCH" - FDO_DISTRIBUTION_TAG: '2022-06-28.00-graphviz' + FDO_DISTRIBUTION_TAG: '2022-07-13.00-wayland-protocols-1.26' include: diff --git a/.gitlab-ci/build-deps.sh b/.gitlab-ci/build-deps.sh index 1f85fb8f..3c8f36fc 100755 --- a/.gitlab-ci/build-deps.sh +++ b/.gitlab-ci/build-deps.sh @@ -107,7 +107,7 @@ rm -rf wayland # Keep this version in sync with our dependency in meson.build. If you wish to # raise a MR against custom protocol, please change this reference to clone # your relevant tree, and make sure you bump $FDO_DISTRIBUTION_TAG. -git clone --branch 1.24 --depth=1 https://gitlab.freedesktop.org/wayland/wayland-protocols +git clone --branch 1.26 --depth=1 https://gitlab.freedesktop.org/wayland/wayland-protocols cd wayland-protocols git show -s HEAD meson build diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index 6e5ebbca..79ac8954 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -1318,6 +1318,10 @@ struct weston_compositor { bool warned_about_unmapped_surface_or_view; }; +struct solid_buffer_values { + float r, g, b, a; +}; + struct weston_buffer { struct wl_resource *resource; struct wl_signal destroy_signal; @@ -1334,9 +1338,7 @@ struct weston_buffer { struct wl_shm_buffer *shm_buffer; void *dmabuf; void *legacy_buffer; - struct { - float r, g, b, a; - } solid; + struct solid_buffer_values solid; }; int32_t width, height; diff --git a/libweston/compositor.c b/libweston/compositor.c index deb91b1c..9d7bffdf 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -65,6 +65,7 @@ #include "xdg-output-unstable-v1-server-protocol.h" #include "linux-explicit-synchronization-unstable-v1-server-protocol.h" #include "linux-explicit-synchronization.h" +#include "single-pixel-buffer-v1-server-protocol.h" #include "shared/fd-util.h" #include "shared/helpers.h" #include "shared/os-compatibility.h" @@ -2414,6 +2415,9 @@ destroy_surface(struct wl_resource *resource) weston_surface_unref(surface); } +static struct solid_buffer_values * +single_pixel_buffer_get(struct wl_resource *resource); + static void weston_buffer_destroy_handler(struct wl_listener *listener, void *data) { @@ -2438,6 +2442,7 @@ weston_buffer_from_resource(struct weston_compositor *ec, struct wl_shm_buffer *shm; struct linux_dmabuf_buffer *dmabuf; struct wl_listener *listener; + struct solid_buffer_values *solid; listener = wl_resource_get_destroy_listener(resource, weston_buffer_destroy_handler); @@ -2485,6 +2490,19 @@ weston_buffer_from_resource(struct weston_compositor *ec, buffer->buffer_origin = ORIGIN_BOTTOM_LEFT; else buffer->buffer_origin = ORIGIN_TOP_LEFT; + } else if ((solid = single_pixel_buffer_get(buffer->resource))) { + buffer->type = WESTON_BUFFER_SOLID; + buffer->solid = *solid; + buffer->width = 1; + buffer->height = 1; + if (buffer->solid.a == 1.0) { + buffer->pixel_format = + pixel_format_get_info(DRM_FORMAT_XRGB8888); + } else { + buffer->pixel_format = + pixel_format_get_info(DRM_FORMAT_ARGB8888); + } + buffer->format_modifier = DRM_FORMAT_MOD_LINEAR; } else { /* Only taken for legacy EGL buffers */ if (!ec->renderer->fill_buffer_info || @@ -2701,6 +2719,97 @@ weston_buffer_destroy_solid(struct weston_buffer_reference *buffer_ref) free(buffer_ref); } +static void +single_pixel_buffer_destroy(struct wl_resource *resource) +{ + struct solid_buffer_values *solid = + wl_resource_get_user_data(resource); + free(solid); +} + +static void +single_pixel_buffer_handle_buffer_destroy(struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static const struct wl_buffer_interface single_pixel_buffer_implementation = { + single_pixel_buffer_handle_buffer_destroy, +}; + +static struct solid_buffer_values * +single_pixel_buffer_get(struct wl_resource *resource) +{ + if (!resource) + return NULL; + + if (!wl_resource_instance_of(resource, &wl_buffer_interface, + &single_pixel_buffer_implementation)) + return NULL; + + return wl_resource_get_user_data(resource); +} + +static void +single_pixel_buffer_manager_destroy(struct wl_client *client, + struct wl_resource *resource) +{ + wl_resource_destroy(resource); +} + +static void +single_pixel_buffer_create(struct wl_client *client, struct wl_resource *resource, + uint32_t id, uint32_t r, uint32_t g, uint32_t b, uint32_t a) +{ + struct solid_buffer_values *solid = zalloc(sizeof(*solid)); + struct wl_resource *buffer; + + if (!solid) { + wl_client_post_no_memory(client); + return; + } + + solid->r = r / (double) 0xffffffff; + solid->g = g / (double) 0xffffffff; + solid->b = b / (double) 0xffffffff; + solid->a = a / (double) 0xffffffff; + + buffer = wl_resource_create(client, &wl_buffer_interface, 1, id); + if (!buffer) { + wl_client_post_no_memory(client); + free(solid); + return; + } + wl_resource_set_implementation(buffer, + &single_pixel_buffer_implementation, + solid, single_pixel_buffer_destroy); +} + +static const struct wp_single_pixel_buffer_manager_v1_interface +single_pixel_buffer_manager_implementation = { + single_pixel_buffer_manager_destroy, + single_pixel_buffer_create, +}; + +static void +bind_single_pixel_buffer(struct wl_client *client, void *data, uint32_t version, + uint32_t id) +{ + struct wl_resource *resource; + + resource = wl_resource_create(client, + &wp_single_pixel_buffer_manager_v1_interface, 1, + id); + if (!resource) { + wl_client_post_no_memory(client); + return; + } + wl_resource_set_implementation(resource, + &single_pixel_buffer_manager_implementation, + NULL, NULL); +} + static void weston_surface_attach(struct weston_surface *surface, struct weston_buffer *buffer) @@ -8232,6 +8341,11 @@ weston_compositor_create(struct wl_display *display, ec, bind_presentation)) goto fail; + if (!wl_global_create(ec->wl_display, + &wp_single_pixel_buffer_manager_v1_interface, 1, + NULL, bind_single_pixel_buffer)) + goto fail; + if (weston_input_init(ec) != 0) goto fail; diff --git a/libweston/meson.build b/libweston/meson.build index 82f81466..313a84f6 100644 --- a/libweston/meson.build +++ b/libweston/meson.build @@ -51,6 +51,8 @@ srcs_libweston = [ relative_pointer_unstable_v1_server_protocol_h, weston_screenshooter_protocol_c, weston_screenshooter_server_protocol_h, + single_pixel_buffer_v1_protocol_c, + single_pixel_buffer_v1_server_protocol_h, text_cursor_position_protocol_c, text_cursor_position_server_protocol_h, text_input_unstable_v1_protocol_c, diff --git a/protocol/meson.build b/protocol/meson.build index 973388fd..ba52089b 100644 --- a/protocol/meson.build +++ b/protocol/meson.build @@ -1,7 +1,7 @@ dep_scanner = dependency('wayland-scanner', native: true) prog_scanner = find_program(dep_scanner.get_pkgconfig_variable('wayland_scanner')) -dep_wp = dependency('wayland-protocols', version: '>= 1.24', +dep_wp = dependency('wayland-protocols', version: '>= 1.26', fallback: ['wayland-protocols', 'wayland_protocols']) dir_wp_base = dep_wp.get_variable(pkgconfig: 'pkgdatadir', internal: 'pkgdatadir') @@ -25,6 +25,7 @@ generated_protocols = [ [ 'presentation-time', 'stable' ], [ 'pointer-constraints', 'unstable', 'v1' ], [ 'relative-pointer', 'unstable', 'v1' ], + [ 'single-pixel-buffer', 'staging', 'v1' ], [ 'tablet', 'unstable', 'v2' ], [ 'text-cursor-position', 'internal' ], [ 'text-input', 'unstable', 'v1' ], @@ -52,6 +53,9 @@ foreach proto: generated_protocols elif proto[1] == 'unstable' base_file = '@0@-unstable-@1@'.format(proto_name, proto[2]) xml_path = '@0@/unstable/@1@/@2@.xml'.format(dir_wp_base, proto_name, base_file) + elif proto[1] == 'staging' + base_file = '@0@-@1@'.format(proto_name, proto[2]) + xml_path = '@0@/staging/@1@/@2@.xml'.format(dir_wp_base, proto_name, base_file) endif foreach output_type: [ 'client-header', 'server-header', 'private-code' ] diff --git a/tests/meson.build b/tests/meson.build index 50722f95..cc35934d 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -205,6 +205,14 @@ tests = [ xdg_shell_protocol_c, ], }, + { + 'name': 'single-pixel-buffer', + 'sources': [ + 'single-pixel-buffer-test.c', + single_pixel_buffer_v1_client_protocol_h, + single_pixel_buffer_v1_protocol_c, + ] + }, { 'name': 'string', }, { 'name': 'subsurface', }, { 'name': 'subsurface-shot', }, diff --git a/tests/reference/single-pixel-buffer-00.png b/tests/reference/single-pixel-buffer-00.png new file mode 100644 index 00000000..2fa7f594 Binary files /dev/null and b/tests/reference/single-pixel-buffer-00.png differ diff --git a/tests/single-pixel-buffer-test.c b/tests/single-pixel-buffer-test.c new file mode 100644 index 00000000..ba013232 --- /dev/null +++ b/tests/single-pixel-buffer-test.c @@ -0,0 +1,111 @@ +/* + * Copyright © 2020 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 +#include +#include +#include +#include + +#include "weston-test-client-helper.h" +#include "weston-test-fixture-compositor.h" +#include "single-pixel-buffer-v1-client-protocol.h" +#include "shared/os-compatibility.h" +#include "shared/xalloc.h" + +struct setup_args { + struct fixture_metadata meta; + enum renderer_type renderer; +}; + +static const struct setup_args my_setup_args[] = { + { + .renderer = RENDERER_PIXMAN, + .meta.name = "pixman" + }, + { + .renderer = RENDERER_GL, + .meta.name = "GL" + }, +}; + +static enum test_result_code +fixture_setup(struct weston_test_harness *harness, const struct setup_args *arg) +{ + struct compositor_setup setup; + + compositor_setup_defaults(&setup); + setup.renderer = arg->renderer; + setup.width = 320; + setup.height = 240; + setup.shell = SHELL_TEST_DESKTOP; + setup.logging_scopes = "log,test-harness-plugin"; + + return weston_test_harness_execute_as_client(harness, &setup); +} +DECLARE_FIXTURE_SETUP_WITH_ARG(fixture_setup, my_setup_args, meta); + +TEST(solid_buffer_argb_u32) +{ + struct client *client; + struct wp_single_pixel_buffer_manager_v1 *mgr; + struct wp_viewport *viewport; + struct wl_buffer *buffer; + int done; + bool match; + + client = create_client(); + client->surface = create_test_surface(client); + viewport = client_create_viewport(client); + wp_viewport_set_destination(viewport, 128, 128); + + mgr = bind_to_singleton_global(client, + &wp_single_pixel_buffer_manager_v1_interface, + 1); + buffer = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer(mgr, + 0xcfffffff, /* r */ + 0x8fffffff, /* g */ + 0x4fffffff, /* b */ + 0xffffffff /* a */); + assert(buffer); + + weston_test_move_surface(client->test->weston_test, + client->surface->wl_surface, + 64, 64); + wl_surface_attach(client->surface->wl_surface, buffer, 0, 0); + wl_surface_damage_buffer(client->surface->wl_surface, 0, 0, 1, 1); + frame_callback_set(client->surface->wl_surface, &done); + wl_surface_commit(client->surface->wl_surface); + frame_callback_wait(client, &done); + + match = verify_screen_content(client, "single-pixel-buffer", 0, NULL, 0); + assert(match); + + wl_buffer_destroy(buffer); + wp_viewport_destroy(viewport); + client_destroy(client); +}