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