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