1From 5840de5c959343d8f367c4e191cb7221c2d77289 Mon Sep 17 00:00:00 2001 2From: Pekka Paalanen <pekka.paalanen@collabora.com> 3Date: Fri, 22 Jul 2022 11:30:04 +0300 4Subject: [PATCH 82/95] libweston: add weston_renderer::resize_output() 5 6Previously renderers were not told when the output (framebuffer they 7need to draw) size changed. Renderers just pulled that information out 8from weston_output::current_mode when they happened to need it. This 9makes some things awkward, like resizing the shadow or intermediate 10buffers. In fact, Pixman-renderer does not even support resizing its 11shadow buffer, nor does GL-renderer. DRM-backend has to destroy and 12re-create the renderer output state anyway, but rdp, x11 and wayland 13backends would be natural users of resizing API. 14 15This commit adds an API for resizing with empty implementations. Actual 16implementations will be added in following patches for each renderer 17while moving parts of resizing code from backends into the renderers. 18No-op renderer needs no implementation. 19 20Only wayland-backend has actual resizing code already, and that is made 21to call the new API. Unfortunately, Pixman and GL renderers differ: one 22does not blit them while the other does. In order to assert the 23functionality of each renderer to keep the API consistent, 24wayland-backend needs to lie to pixman-renderer. That's not new, it 25already does so in wayland_output_get_shm_buffer() where the 'pm_image' 26addresses only the interior area instead of the whole buffer. 27 28Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com> 29(cherry picked from commit 8636422309462226436bc52f35e53e422bfd7e67) 30Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 31--- 32 libweston/backend-wayland/wayland.c | 14 ++++++++++++- 33 libweston/compositor.c | 27 ++++++++++++++++++++++++ 34 libweston/libweston-internal.h | 32 +++++++++++++++++++++++++++++ 35 libweston/noop-renderer.c | 10 +++++++++ 36 libweston/pixman-renderer.c | 20 ++++++++++++++++++ 37 libweston/renderer-gl/gl-renderer.c | 10 +++++++++ 38 6 files changed, 112 insertions(+), 1 deletion(-) 39 40diff --git a/libweston/backend-wayland/wayland.c b/libweston/backend-wayland/wayland.c 41index bb5648d..7f27264 100644 42--- a/libweston/backend-wayland/wayland.c 43+++ b/libweston/backend-wayland/wayland.c 44@@ -886,6 +886,7 @@ wayland_output_resize_surface(struct wayland_output *output) 45 if (output->gl.egl_window) { 46 wl_egl_window_resize(output->gl.egl_window, 47 fb_size.width, fb_size.height, 0, 0); 48+ weston_renderer_resize_output(&output->base, &fb_size, &area); 49 50 /* These will need to be re-created due to the resize */ 51 gl_renderer->output_set_border(&output->base, 52@@ -908,8 +909,19 @@ wayland_output_resize_surface(struct wayland_output *output) 53 0, 0, 0, NULL); 54 cairo_surface_destroy(output->gl.border.bottom); 55 output->gl.border.bottom = NULL; 56- } 57+ } else 58 #endif 59+ { 60+ /* 61+ * Pixman-renderer never knows about decorations, we blit them 62+ * ourselves. 63+ */ 64+ struct weston_size pm_size = { 65+ .width = area.width, 66+ .height = area.height 67+ }; 68+ weston_renderer_resize_output(&output->base, &pm_size, NULL); 69+ } 70 71 wayland_output_destroy_shm_buffers(output); 72 } 73diff --git a/libweston/compositor.c b/libweston/compositor.c 74index d51a0bd..cd5c48d 100644 75--- a/libweston/compositor.c 76+++ b/libweston/compositor.c 77@@ -9273,3 +9273,30 @@ weston_output_disable_planes_decr(struct weston_output *output) 78 weston_schedule_surface_protection_update(output->compositor); 79 80 } 81+ 82+/** Tell the renderer that the target framebuffer size has changed 83+ * 84+ * \param output The output that was resized. 85+ * \param fb_size The framebuffer size, including output decorations. 86+ * \param area The composited area inside the framebuffer, excluding 87+ * decorations. This can also be NULL, which means the whole fb_size is 88+ * the composited area. 89+ */ 90+WL_EXPORT void 91+weston_renderer_resize_output(struct weston_output *output, 92+ const struct weston_size *fb_size, 93+ const struct weston_geometry *area) 94+{ 95+ struct weston_renderer *r = output->compositor->renderer; 96+ struct weston_geometry def = { 97+ .x = 0, 98+ .y = 0, 99+ .width = fb_size->width, 100+ .height = fb_size->height 101+ }; 102+ 103+ if (!r->resize_output(output, fb_size, area ?: &def)) { 104+ weston_log("Error: Resizing output '%s' failed.\n", 105+ output->name); 106+ } 107+} 108diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h 109index 39d9e85..bcfb153 100644 110--- a/libweston/libweston-internal.h 111+++ b/libweston/libweston-internal.h 112@@ -41,6 +41,7 @@ 113 */ 114 115 #include <libweston/libweston.h> 116+#include <assert.h> 117 #include "color.h" 118 119 /* compositor <-> renderer interface */ 120@@ -52,6 +53,15 @@ struct weston_renderer { 121 uint32_t width, uint32_t height); 122 void (*repaint_output)(struct weston_output *output, 123 pixman_region32_t *output_damage); 124+ 125+ /** See weston_renderer_resize_output() 126+ * 127+ * \return True for success, false for leaving the output in a mess. 128+ */ 129+ bool (*resize_output)(struct weston_output *output, 130+ const struct weston_size *fb_size, 131+ const struct weston_geometry *area); 132+ 133 void (*flush_damage)(struct weston_surface *surface, 134 struct weston_buffer *buffer); 135 void (*attach)(struct weston_surface *es, struct weston_buffer *buffer); 136@@ -74,6 +84,28 @@ struct weston_renderer { 137 struct weston_buffer *buffer); 138 }; 139 140+void 141+weston_renderer_resize_output(struct weston_output *output, 142+ const struct weston_size *fb_size, 143+ const struct weston_geometry *area); 144+ 145+static inline void 146+check_compositing_area(const struct weston_size *fb_size, 147+ const struct weston_geometry *area) 148+{ 149+ assert(fb_size); 150+ assert(fb_size->width > 0); 151+ assert(fb_size->height > 0); 152+ 153+ assert(area); 154+ assert(area->x >= 0); 155+ assert(area->width > 0); 156+ assert(area->x <= fb_size->width - area->width); 157+ assert(area->y >= 0); 158+ assert(area->height > 0); 159+ assert(area->y <= fb_size->height - area->height); 160+} 161+ 162 /* weston_buffer */ 163 164 void 165diff --git a/libweston/noop-renderer.c b/libweston/noop-renderer.c 166index f99a313..35f180e 100644 167--- a/libweston/noop-renderer.c 168+++ b/libweston/noop-renderer.c 169@@ -51,6 +51,15 @@ noop_renderer_repaint_output(struct weston_output *output, 170 { 171 } 172 173+static bool 174+noop_renderer_resize_output(struct weston_output *output, 175+ const struct weston_size *fb_size, 176+ const struct weston_geometry *area) 177+{ 178+ check_compositing_area(fb_size, area); 179+ return true; 180+} 181+ 182 static void 183 noop_renderer_flush_damage(struct weston_surface *surface, 184 struct weston_buffer *buffer) 185@@ -124,6 +133,7 @@ noop_renderer_init(struct weston_compositor *ec) 186 187 renderer->base.read_pixels = noop_renderer_read_pixels; 188 renderer->base.repaint_output = noop_renderer_repaint_output; 189+ renderer->base.resize_output = noop_renderer_resize_output; 190 renderer->base.flush_damage = noop_renderer_flush_damage; 191 renderer->base.attach = noop_renderer_attach; 192 renderer->base.destroy = noop_renderer_destroy; 193diff --git a/libweston/pixman-renderer.c b/libweston/pixman-renderer.c 194index 4e9e704..7678587 100644 195--- a/libweston/pixman-renderer.c 196+++ b/libweston/pixman-renderer.c 197@@ -1191,6 +1191,25 @@ pixman_renderer_surface_copy_content(struct weston_surface *surface, 198 return 0; 199 } 200 201+static bool 202+pixman_renderer_resize_output(struct weston_output *output, 203+ const struct weston_size *fb_size, 204+ const struct weston_geometry *area) 205+{ 206+ check_compositing_area(fb_size, area); 207+ 208+ /* 209+ * Pixman-renderer does not implement output decorations blitting, 210+ * wayland-backend does it on its own. 211+ */ 212+ assert(area->x == 0); 213+ assert(area->y == 0); 214+ assert(fb_size->width == area->width); 215+ assert(fb_size->height == area->height); 216+ 217+ return true; 218+} 219+ 220 static void 221 debug_binding(struct weston_keyboard *keyboard, const struct timespec *time, 222 uint32_t key, void *data) 223@@ -1371,6 +1390,7 @@ pixman_renderer_init(struct weston_compositor *ec) 224 renderer->debug_color = NULL; 225 renderer->base.read_pixels = pixman_renderer_read_pixels; 226 renderer->base.repaint_output = pixman_renderer_repaint_output; 227+ renderer->base.resize_output = pixman_renderer_resize_output; 228 renderer->base.flush_damage = pixman_renderer_flush_damage; 229 renderer->base.attach = pixman_renderer_attach; 230 renderer->base.destroy = pixman_renderer_destroy; 231diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c 232index 9b63c24..28fc4ae 100644 233--- a/libweston/renderer-gl/gl-renderer.c 234+++ b/libweston/renderer-gl/gl-renderer.c 235@@ -3427,6 +3427,15 @@ gl_renderer_output_set_border(struct weston_output *output, 236 go->border_status |= 1 << side; 237 } 238 239+static bool 240+gl_renderer_resize_output(struct weston_output *output, 241+ const struct weston_size *fb_size, 242+ const struct weston_geometry *area) 243+{ 244+ check_compositing_area(fb_size, area); 245+ return true; 246+} 247+ 248 static int 249 gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface); 250 251@@ -3780,6 +3789,7 @@ gl_renderer_display_create(struct weston_compositor *ec, 252 253 gr->base.read_pixels = gl_renderer_read_pixels; 254 gr->base.repaint_output = gl_renderer_repaint_output; 255+ gr->base.resize_output = gl_renderer_resize_output; 256 gr->base.flush_damage = gl_renderer_flush_damage; 257 gr->base.attach = gl_renderer_attach; 258 gr->base.destroy = gl_renderer_destroy; 259-- 2602.20.1 261 262