clients: Paint desktop-shell color background with single-pixel-buffer

So the buffer has the WESTON_BUFFER_SOLID type, which will make
additional optimizations easier going forward.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
This commit is contained in:
Robert Mader 2025-09-08 13:32:42 +02:00 committed by Daniel Stone
parent 2497377af4
commit 6cc8f48cd8
4 changed files with 169 additions and 72 deletions

View file

@ -53,6 +53,7 @@
#include "window.h" #include "window.h"
#include "single-pixel-buffer-v1-client-protocol.h"
#include "tablet-unstable-v2-client-protocol.h" #include "tablet-unstable-v2-client-protocol.h"
#include "weston-desktop-shell-client-protocol.h" #include "weston-desktop-shell-client-protocol.h"
@ -782,10 +783,54 @@ enum {
BACKGROUND_CENTERED BACKGROUND_CENTERED
}; };
static void
buffer_release(void *data, struct wl_buffer *buffer)
{
wl_buffer_destroy(buffer);
}
static const struct wl_buffer_listener buffer_listener = {
buffer_release
};
static void static void
background_draw(struct widget *widget, void *data) background_draw(struct widget *widget, void *data)
{ {
struct background *background = data; struct background *background = data;
if (!background->image && background->color) {
struct display *display = window_get_display(background->window);
struct wp_single_pixel_buffer_manager_v1 *sp_manager;
struct wl_surface *wl_surface;
struct wl_buffer *wl_buffer;
uint32_t r8, g8, b8;
uint32_t r32, g32, b32;
sp_manager = display_get_single_pixel_buffer_manager(display);
assert(sp_manager);
wl_surface = widget_get_wl_surface(background->widget);
assert(wl_surface);
r8 = (background->color >> 16) & 0xff;
g8 = (background->color >> 8) & 0xff;
b8 = (background->color >> 0) & 0xff;
r32 = r8 << 24 | r8 << 16 | r8 << 8 | r8;
g32 = g8 << 24 | g8 << 16 | g8 << 8 | g8;
b32 = b8 << 24 | b8 << 16 | b8 << 8 | b8;
wl_buffer =
wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer(sp_manager,
r32,
g32,
b32,
0xffffffff);
assert(wl_buffer);
wl_surface_attach(wl_surface, wl_buffer, 0, 0);
wl_buffer_add_listener(wl_buffer, &buffer_listener, NULL);
widget_surface_flush(widget);
} else {
cairo_surface_t *surface, *image; cairo_surface_t *surface, *image;
cairo_pattern_t *pattern; cairo_pattern_t *pattern;
cairo_matrix_t matrix; cairo_matrix_t matrix;
@ -870,6 +915,7 @@ background_draw(struct widget *widget, void *data)
cairo_destroy(cr); cairo_destroy(cr);
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
}
background->painted = 1; background->painted = 1;
check_desktop_ready(background->window); check_desktop_ready(background->window);
@ -897,6 +943,7 @@ background_configure(void *data,
} }
if (!background->image && background->color) { if (!background->image && background->color) {
widget_set_use_cairo(background->widget, 0);
widget_set_viewport_destination(background->widget, width, height); widget_set_viewport_destination(background->widget, width, height);
width = 1; width = 1;
height = 1; height = 1;

View file

@ -14,6 +14,8 @@ srcs_toytoolkit = [
relative_pointer_unstable_v1_protocol_c, relative_pointer_unstable_v1_protocol_c,
pointer_constraints_unstable_v1_client_protocol_h, pointer_constraints_unstable_v1_client_protocol_h,
pointer_constraints_unstable_v1_protocol_c, pointer_constraints_unstable_v1_protocol_c,
single_pixel_buffer_v1_client_protocol_h,
single_pixel_buffer_v1_protocol_c,
tablet_unstable_v2_client_protocol_h, tablet_unstable_v2_client_protocol_h,
tablet_unstable_v2_protocol_c, tablet_unstable_v2_protocol_c,
ivi_application_client_protocol_h, ivi_application_client_protocol_h,

View file

@ -55,6 +55,7 @@
#include <libweston/zalloc.h> #include <libweston/zalloc.h>
#include "xdg-shell-client-protocol.h" #include "xdg-shell-client-protocol.h"
#include "color-management-v1-client-protocol.h" #include "color-management-v1-client-protocol.h"
#include "single-pixel-buffer-v1-client-protocol.h"
#include "text-cursor-position-client-protocol.h" #include "text-cursor-position-client-protocol.h"
#include "pointer-constraints-unstable-v1-client-protocol.h" #include "pointer-constraints-unstable-v1-client-protocol.h"
#include "relative-pointer-unstable-v1-client-protocol.h" #include "relative-pointer-unstable-v1-client-protocol.h"
@ -93,6 +94,7 @@ struct display {
struct zwp_tablet_manager_v2 *tablet_manager; struct zwp_tablet_manager_v2 *tablet_manager;
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager; struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
struct zwp_pointer_constraints_v1 *pointer_constraints; struct zwp_pointer_constraints_v1 *pointer_constraints;
struct wp_single_pixel_buffer_manager_v1 *single_pixel_buffer_manager;
uint32_t serial; uint32_t serial;
uint32_t color_manager_features; uint32_t color_manager_features;
@ -1447,6 +1449,35 @@ surface_flush(struct surface *surface)
surface->cairo_surface = NULL; surface->cairo_surface = NULL;
} }
void
widget_surface_flush(struct widget *widget)
{
struct surface *surface = widget->surface;
if (surface->opaque_region) {
wl_surface_set_opaque_region(surface->surface,
surface->opaque_region);
wl_region_destroy(surface->opaque_region);
surface->opaque_region = NULL;
}
if (surface->input_region) {
wl_surface_set_input_region(surface->surface,
surface->input_region);
wl_region_destroy(surface->input_region);
surface->input_region = NULL;
}
if (surface->viewport) {
wp_viewport_set_destination(surface->viewport,
widget->viewport_dest_width,
widget->viewport_dest_height);
}
wl_surface_damage(surface->surface, 0, 0, INT32_MAX, INT32_MAX);
wl_surface_commit(surface->surface);
}
int int
window_has_focus(struct window *window) window_has_focus(struct window *window)
{ {
@ -6807,6 +6838,11 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id,
&wp_color_manager_v1_interface, 1); &wp_color_manager_v1_interface, 1);
wp_color_manager_v1_add_listener(d->color_manager, wp_color_manager_v1_add_listener(d->color_manager,
&cm_listener, d); &cm_listener, d);
} else if (strcmp(interface, wp_single_pixel_buffer_manager_v1_interface.name) == 0) {
d->single_pixel_buffer_manager =
wl_registry_bind(registry, id,
&wp_single_pixel_buffer_manager_v1_interface,
1);
} }
if (d->global_handler) if (d->global_handler)
@ -7095,6 +7131,12 @@ display_get_compositor(struct display *display)
return display->compositor; return display->compositor;
} }
struct wp_single_pixel_buffer_manager_v1 *
display_get_single_pixel_buffer_manager(struct display *display)
{
return display->single_pixel_buffer_manager;
}
uint32_t uint32_t
display_get_serial(struct display *display) display_get_serial(struct display *display)
{ {

View file

@ -76,6 +76,9 @@ display_has_subcompositor(struct display *display);
struct wl_compositor * struct wl_compositor *
display_get_compositor(struct display *display); display_get_compositor(struct display *display);
struct wp_single_pixel_buffer_manager_v1 *
display_get_single_pixel_buffer_manager(struct display *display);
struct output * struct output *
display_get_output(struct display *display); display_get_output(struct display *display);
@ -610,6 +613,9 @@ widget_cairo_create(struct widget *widget);
struct wl_surface * struct wl_surface *
widget_get_wl_surface(struct widget *widget); widget_get_wl_surface(struct widget *widget);
void
widget_surface_flush(struct widget *widget);
uint32_t uint32_t
widget_get_last_time(struct widget *widget); widget_get_last_time(struct widget *widget);