xref: /OK3568_Linux_fs/buildroot/package/weston/0021-pixman-renderer-Support-linux-dmabuf.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593SmuzhiyunFrom a2b9d85182c9089e27ecf02c4f3fecd7a8006bce Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com>
3*4882a593SmuzhiyunDate: Fri, 3 Jul 2020 14:43:49 +0800
4*4882a593SmuzhiyunSubject: [PATCH 21/95] pixman-renderer: Support linux dmabuf
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunNOTE: Only support contig dmabuf.
7*4882a593Smuzhiyun
8*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
9*4882a593Smuzhiyun---
10*4882a593Smuzhiyun libweston/pixman-renderer.c | 287 +++++++++++++++++++++++++++++++++++-
11*4882a593Smuzhiyun 1 file changed, 281 insertions(+), 6 deletions(-)
12*4882a593Smuzhiyun
13*4882a593Smuzhiyundiff --git a/libweston/pixman-renderer.c b/libweston/pixman-renderer.c
14*4882a593Smuzhiyunindex 62c2cb1..07b7888 100644
15*4882a593Smuzhiyun--- a/libweston/pixman-renderer.c
16*4882a593Smuzhiyun+++ b/libweston/pixman-renderer.c
17*4882a593Smuzhiyun@@ -37,9 +37,16 @@
18*4882a593Smuzhiyun #include "pixel-formats.h"
19*4882a593Smuzhiyun #include "shared/helpers.h"
20*4882a593Smuzhiyun #include "shared/signal.h"
21*4882a593Smuzhiyun+#include "shared/weston-drm-fourcc.h"
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun+#include <string.h>
24*4882a593Smuzhiyun+#include <unistd.h>
25*4882a593Smuzhiyun+#include <sys/mman.h>
26*4882a593Smuzhiyun #include <linux/input.h>
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun+#include "linux-dmabuf.h"
29*4882a593Smuzhiyun+#include "linux-dmabuf-unstable-v1-server-protocol.h"
30*4882a593Smuzhiyun+
31*4882a593Smuzhiyun struct pixman_output_state {
32*4882a593Smuzhiyun 	pixman_image_t *shadow_image;
33*4882a593Smuzhiyun 	pixman_image_t *hw_buffer;
34*4882a593Smuzhiyun@@ -66,6 +73,13 @@ struct pixman_renderer {
35*4882a593Smuzhiyun 	struct weston_binding *debug_binding;
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun 	struct wl_signal destroy_signal;
38*4882a593Smuzhiyun+
39*4882a593Smuzhiyun+	struct weston_drm_format_array supported_formats;
40*4882a593Smuzhiyun+};
41*4882a593Smuzhiyun+
42*4882a593Smuzhiyun+struct dmabuf_data {
43*4882a593Smuzhiyun+	void *ptr;
44*4882a593Smuzhiyun+	size_t size;
45*4882a593Smuzhiyun };
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun static inline struct pixman_output_state *
48*4882a593Smuzhiyun@@ -350,7 +364,8 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
49*4882a593Smuzhiyun 	else
50*4882a593Smuzhiyun 		filter = PIXMAN_FILTER_NEAREST;
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun-	if (ps->buffer_ref.buffer)
53*4882a593Smuzhiyun+	if (ps->buffer_ref.buffer &&
54*4882a593Smuzhiyun+	    ps->buffer_ref.buffer->type == WESTON_BUFFER_SHM)
55*4882a593Smuzhiyun 		wl_shm_buffer_begin_access(ps->buffer_ref.buffer->shm_buffer);
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun 	if (ev->alpha < 1.0) {
58*4882a593Smuzhiyun@@ -370,7 +385,8 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
59*4882a593Smuzhiyun 	if (mask_image)
60*4882a593Smuzhiyun 		pixman_image_unref(mask_image);
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun-	if (ps->buffer_ref.buffer)
63*4882a593Smuzhiyun+	if (ps->buffer_ref.buffer &&
64*4882a593Smuzhiyun+	    ps->buffer_ref.buffer->type == WESTON_BUFFER_SHM)
65*4882a593Smuzhiyun 		wl_shm_buffer_end_access(ps->buffer_ref.buffer->shm_buffer);
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun 	if (pr->repaint_debug)
68*4882a593Smuzhiyun@@ -653,11 +669,114 @@ pixman_renderer_surface_set_color(struct weston_surface *es,
69*4882a593Smuzhiyun 	ps->image = pixman_image_create_solid_fill(&color);
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun+static void
73*4882a593Smuzhiyun+pixman_renderer_attach_dmabuf(struct weston_surface *es,
74*4882a593Smuzhiyun+			      struct weston_buffer *buffer,
75*4882a593Smuzhiyun+			      struct linux_dmabuf_buffer *dmabuf)
76*4882a593Smuzhiyun+{
77*4882a593Smuzhiyun+	struct pixman_surface_state *ps = get_surface_state(es);
78*4882a593Smuzhiyun+	struct dmabuf_attributes *attributes = &dmabuf->attributes;
79*4882a593Smuzhiyun+	struct dmabuf_data *data;
80*4882a593Smuzhiyun+	pixman_format_code_t pixman_format;
81*4882a593Smuzhiyun+	size_t vstride;
82*4882a593Smuzhiyun+
83*4882a593Smuzhiyun+	data = linux_dmabuf_buffer_get_user_data(dmabuf);
84*4882a593Smuzhiyun+	if (!data || !data->ptr) {
85*4882a593Smuzhiyun+		weston_buffer_reference(&ps->buffer_ref, NULL,
86*4882a593Smuzhiyun+					BUFFER_WILL_NOT_BE_ACCESSED);
87*4882a593Smuzhiyun+		weston_buffer_release_reference(&ps->buffer_release_ref,
88*4882a593Smuzhiyun+						NULL);
89*4882a593Smuzhiyun+		return;
90*4882a593Smuzhiyun+	}
91*4882a593Smuzhiyun+
92*4882a593Smuzhiyun+	buffer->width = attributes->width;
93*4882a593Smuzhiyun+	buffer->height = attributes->height;
94*4882a593Smuzhiyun+
95*4882a593Smuzhiyun+	if (attributes->n_planes == 1)
96*4882a593Smuzhiyun+		vstride = attributes->height;
97*4882a593Smuzhiyun+	else
98*4882a593Smuzhiyun+		vstride = (attributes->offset[1] - attributes->offset[0]) /
99*4882a593Smuzhiyun+			attributes->stride[0];
100*4882a593Smuzhiyun+
101*4882a593Smuzhiyun+	switch (attributes->format) {
102*4882a593Smuzhiyun+	case DRM_FORMAT_RGBA8888:
103*4882a593Smuzhiyun+		pixman_format = PIXMAN_r8g8b8a8;
104*4882a593Smuzhiyun+		break;
105*4882a593Smuzhiyun+	case DRM_FORMAT_RGBX8888:
106*4882a593Smuzhiyun+		pixman_format = PIXMAN_r8g8b8x8;
107*4882a593Smuzhiyun+		break;
108*4882a593Smuzhiyun+	case DRM_FORMAT_BGRA8888:
109*4882a593Smuzhiyun+		pixman_format = PIXMAN_b8g8r8a8;
110*4882a593Smuzhiyun+		break;
111*4882a593Smuzhiyun+	case DRM_FORMAT_BGRX8888:
112*4882a593Smuzhiyun+		pixman_format = PIXMAN_b8g8r8x8;
113*4882a593Smuzhiyun+		break;
114*4882a593Smuzhiyun+	case DRM_FORMAT_ABGR8888:
115*4882a593Smuzhiyun+		pixman_format = PIXMAN_a8b8g8r8;
116*4882a593Smuzhiyun+		break;
117*4882a593Smuzhiyun+	case DRM_FORMAT_XBGR8888:
118*4882a593Smuzhiyun+		pixman_format = PIXMAN_x8b8g8r8;
119*4882a593Smuzhiyun+		break;
120*4882a593Smuzhiyun+	case DRM_FORMAT_BGR888:
121*4882a593Smuzhiyun+		pixman_format = PIXMAN_b8g8r8;
122*4882a593Smuzhiyun+		break;
123*4882a593Smuzhiyun+	case DRM_FORMAT_ARGB8888:
124*4882a593Smuzhiyun+		pixman_format = PIXMAN_a8r8g8b8;
125*4882a593Smuzhiyun+		break;
126*4882a593Smuzhiyun+	case DRM_FORMAT_XRGB8888:
127*4882a593Smuzhiyun+		pixman_format = PIXMAN_x8r8g8b8;
128*4882a593Smuzhiyun+		break;
129*4882a593Smuzhiyun+	case DRM_FORMAT_RGB888:
130*4882a593Smuzhiyun+		pixman_format = PIXMAN_r8g8b8;
131*4882a593Smuzhiyun+		break;
132*4882a593Smuzhiyun+	case DRM_FORMAT_YUYV:
133*4882a593Smuzhiyun+		pixman_format = PIXMAN_yuy2;
134*4882a593Smuzhiyun+		break;
135*4882a593Smuzhiyun+	case DRM_FORMAT_YVU420:
136*4882a593Smuzhiyun+		pixman_format = PIXMAN_yv12;
137*4882a593Smuzhiyun+		break;
138*4882a593Smuzhiyun+#ifdef HAVE_PIXMAN_I420
139*4882a593Smuzhiyun+	case DRM_FORMAT_YUV420:
140*4882a593Smuzhiyun+		pixman_format = PIXMAN_i420;
141*4882a593Smuzhiyun+		break;
142*4882a593Smuzhiyun+#endif
143*4882a593Smuzhiyun+#ifdef HAVE_PIXMAN_NV12
144*4882a593Smuzhiyun+	case DRM_FORMAT_NV12:
145*4882a593Smuzhiyun+		pixman_format = PIXMAN_nv12;
146*4882a593Smuzhiyun+		break;
147*4882a593Smuzhiyun+#endif
148*4882a593Smuzhiyun+#ifdef HAVE_PIXMAN_NV16
149*4882a593Smuzhiyun+	case DRM_FORMAT_NV16:
150*4882a593Smuzhiyun+		pixman_format = PIXMAN_nv16;
151*4882a593Smuzhiyun+		break;
152*4882a593Smuzhiyun+#endif
153*4882a593Smuzhiyun+	default:
154*4882a593Smuzhiyun+		weston_log("Unsupported dmabuf format\n");
155*4882a593Smuzhiyun+		weston_buffer_reference(&ps->buffer_ref, NULL,
156*4882a593Smuzhiyun+					BUFFER_WILL_NOT_BE_ACCESSED);
157*4882a593Smuzhiyun+		weston_buffer_release_reference(&ps->buffer_release_ref,
158*4882a593Smuzhiyun+						NULL);
159*4882a593Smuzhiyun+		return;
160*4882a593Smuzhiyun+	break;
161*4882a593Smuzhiyun+	}
162*4882a593Smuzhiyun+
163*4882a593Smuzhiyun+	ps->image = pixman_image_create_bits(pixman_format,
164*4882a593Smuzhiyun+					     buffer->width, vstride,
165*4882a593Smuzhiyun+					     data->ptr + attributes->offset[0],
166*4882a593Smuzhiyun+					     attributes->stride[0]);
167*4882a593Smuzhiyun+
168*4882a593Smuzhiyun+	ps->buffer_destroy_listener.notify =
169*4882a593Smuzhiyun+		buffer_state_handle_buffer_destroy;
170*4882a593Smuzhiyun+	wl_signal_add(&buffer->destroy_signal,
171*4882a593Smuzhiyun+		      &ps->buffer_destroy_listener);
172*4882a593Smuzhiyun+}
173*4882a593Smuzhiyun+
174*4882a593Smuzhiyun static void
175*4882a593Smuzhiyun pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	struct pixman_surface_state *ps = get_surface_state(es);
178*4882a593Smuzhiyun 	struct wl_shm_buffer *shm_buffer;
179*4882a593Smuzhiyun+	struct linux_dmabuf_buffer *dmabuf;
180*4882a593Smuzhiyun 	const struct pixel_format_info *pixel_info;
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun 	weston_buffer_reference(&ps->buffer_ref, buffer,
183*4882a593Smuzhiyun@@ -692,10 +811,16 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
184*4882a593Smuzhiyun 	}
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun 	if (buffer->type != WESTON_BUFFER_SHM) {
187*4882a593Smuzhiyun-		weston_log("Pixman renderer supports only SHM buffers\n");
188*4882a593Smuzhiyun-		weston_buffer_reference(&ps->buffer_ref, NULL,
189*4882a593Smuzhiyun-					BUFFER_WILL_NOT_BE_ACCESSED);
190*4882a593Smuzhiyun-		weston_buffer_release_reference(&ps->buffer_release_ref, NULL);
191*4882a593Smuzhiyun+		if ((dmabuf = linux_dmabuf_buffer_get(buffer->resource))) {
192*4882a593Smuzhiyun+			pixman_renderer_attach_dmabuf(es, buffer, dmabuf);
193*4882a593Smuzhiyun+		} else {
194*4882a593Smuzhiyun+			weston_log("unhandled buffer type!\n");
195*4882a593Smuzhiyun+			weston_buffer_reference(&ps->buffer_ref, NULL,
196*4882a593Smuzhiyun+						BUFFER_WILL_NOT_BE_ACCESSED);
197*4882a593Smuzhiyun+			weston_buffer_release_reference(&ps->buffer_release_ref,
198*4882a593Smuzhiyun+							NULL);
199*4882a593Smuzhiyun+		}
200*4882a593Smuzhiyun+
201*4882a593Smuzhiyun 		return;
202*4882a593Smuzhiyun 	}
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun@@ -792,6 +917,9 @@ pixman_renderer_create_surface(struct weston_surface *surface)
205*4882a593Smuzhiyun 	wl_signal_add(&pr->destroy_signal,
206*4882a593Smuzhiyun 		      &ps->renderer_destroy_listener);
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun+	if (surface->buffer_ref.buffer)
209*4882a593Smuzhiyun+		pixman_renderer_attach(surface, surface->buffer_ref.buffer);
210*4882a593Smuzhiyun+
211*4882a593Smuzhiyun 	return 0;
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun@@ -802,6 +930,9 @@ pixman_renderer_destroy(struct weston_compositor *ec)
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun 	wl_signal_emit(&pr->destroy_signal, pr);
217*4882a593Smuzhiyun 	weston_binding_destroy(pr->debug_binding);
218*4882a593Smuzhiyun+
219*4882a593Smuzhiyun+	weston_drm_format_array_fini(&pr->supported_formats);
220*4882a593Smuzhiyun+
221*4882a593Smuzhiyun 	free(pr);
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun 	ec->renderer = NULL;
224*4882a593Smuzhiyun@@ -860,12 +991,142 @@ debug_binding(struct weston_keyboard *keyboard, const struct timespec *time,
225*4882a593Smuzhiyun 	}
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun+static void
229*4882a593Smuzhiyun+pixman_renderer_destroy_dmabuf(struct linux_dmabuf_buffer *dmabuf)
230*4882a593Smuzhiyun+{
231*4882a593Smuzhiyun+	struct dmabuf_data *data = dmabuf->user_data;
232*4882a593Smuzhiyun+	linux_dmabuf_buffer_set_user_data(dmabuf, NULL, NULL);
233*4882a593Smuzhiyun+
234*4882a593Smuzhiyun+	if (data) {
235*4882a593Smuzhiyun+		if (data->ptr)
236*4882a593Smuzhiyun+			munmap(data->ptr, data->size);
237*4882a593Smuzhiyun+
238*4882a593Smuzhiyun+		free(data);
239*4882a593Smuzhiyun+	}
240*4882a593Smuzhiyun+}
241*4882a593Smuzhiyun+
242*4882a593Smuzhiyun+static bool
243*4882a593Smuzhiyun+pixman_renderer_import_dmabuf(struct weston_compositor *ec,
244*4882a593Smuzhiyun+			      struct linux_dmabuf_buffer *dmabuf)
245*4882a593Smuzhiyun+{
246*4882a593Smuzhiyun+	struct dmabuf_attributes *attributes = &dmabuf->attributes;
247*4882a593Smuzhiyun+	struct dmabuf_data *data;
248*4882a593Smuzhiyun+	size_t total_size, vstride0;
249*4882a593Smuzhiyun+	int i;
250*4882a593Smuzhiyun+
251*4882a593Smuzhiyun+	for (i = 0; i < attributes->n_planes; i++) {
252*4882a593Smuzhiyun+		if (attributes->modifier[i] != DRM_FORMAT_MOD_INVALID &&
253*4882a593Smuzhiyun+		    attributes->modifier[i] != DRM_FORMAT_MOD_LINEAR)
254*4882a593Smuzhiyun+			return false;
255*4882a593Smuzhiyun+	}
256*4882a593Smuzhiyun+
257*4882a593Smuzhiyun+	/* reject all flags we do not recognize or handle */
258*4882a593Smuzhiyun+	if (attributes->flags & ~ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT)
259*4882a593Smuzhiyun+		return false;
260*4882a593Smuzhiyun+
261*4882a593Smuzhiyun+	if (attributes->n_planes < 0)
262*4882a593Smuzhiyun+		return false;
263*4882a593Smuzhiyun+
264*4882a593Smuzhiyun+	if (attributes->n_planes == 1)
265*4882a593Smuzhiyun+		goto out;
266*4882a593Smuzhiyun+
267*4882a593Smuzhiyun+	total_size = lseek(attributes->fd[0], 0, SEEK_END);
268*4882a593Smuzhiyun+	vstride0 = (attributes->offset[1] - attributes->offset[0]) /
269*4882a593Smuzhiyun+		attributes->stride[0];
270*4882a593Smuzhiyun+
271*4882a593Smuzhiyun+	for (i = 1; i < attributes->n_planes; i++) {
272*4882a593Smuzhiyun+		size_t size = attributes->offset[i] - attributes->offset[i - 1];
273*4882a593Smuzhiyun+		size_t vstride = size / attributes->stride[i - 1];
274*4882a593Smuzhiyun+
275*4882a593Smuzhiyun+		/* not contig */
276*4882a593Smuzhiyun+		if (size <= 0 || vstride <= 0 ||
277*4882a593Smuzhiyun+		    attributes->offset[i - 1] + size > total_size)
278*4882a593Smuzhiyun+			return false;
279*4882a593Smuzhiyun+
280*4882a593Smuzhiyun+		/* stride unmatched */
281*4882a593Smuzhiyun+		if ((vstride != vstride0 && vstride != vstride0 / 2) ||
282*4882a593Smuzhiyun+		    (attributes->stride[i] != attributes->stride[0] &&
283*4882a593Smuzhiyun+		     attributes->stride[i] != attributes->stride[0] / 2))
284*4882a593Smuzhiyun+			return false;
285*4882a593Smuzhiyun+	}
286*4882a593Smuzhiyun+
287*4882a593Smuzhiyun+out:
288*4882a593Smuzhiyun+	/* Handle contig dma buffer */
289*4882a593Smuzhiyun+
290*4882a593Smuzhiyun+	data = zalloc(sizeof *data);
291*4882a593Smuzhiyun+	if (!data)
292*4882a593Smuzhiyun+		return false;
293*4882a593Smuzhiyun+
294*4882a593Smuzhiyun+	linux_dmabuf_buffer_set_user_data(dmabuf, data,
295*4882a593Smuzhiyun+					  pixman_renderer_destroy_dmabuf);
296*4882a593Smuzhiyun+
297*4882a593Smuzhiyun+	data->size = lseek(attributes->fd[0], 0, SEEK_END);
298*4882a593Smuzhiyun+
299*4882a593Smuzhiyun+	data->ptr = mmap(NULL, data->size, PROT_READ,
300*4882a593Smuzhiyun+			 MAP_SHARED, attributes->fd[0], 0);
301*4882a593Smuzhiyun+	return data->ptr != MAP_FAILED;
302*4882a593Smuzhiyun+}
303*4882a593Smuzhiyun+
304*4882a593Smuzhiyun+static const struct weston_drm_format_array *
305*4882a593Smuzhiyun+pixman_renderer_get_supported_formats(struct weston_compositor *ec)
306*4882a593Smuzhiyun+{
307*4882a593Smuzhiyun+	struct pixman_renderer *pr = get_renderer(ec);
308*4882a593Smuzhiyun+
309*4882a593Smuzhiyun+	return &pr->supported_formats;
310*4882a593Smuzhiyun+}
311*4882a593Smuzhiyun+
312*4882a593Smuzhiyun+static int
313*4882a593Smuzhiyun+populate_supported_formats(struct weston_compositor *ec,
314*4882a593Smuzhiyun+			   struct weston_drm_format_array *supported_formats)
315*4882a593Smuzhiyun+{
316*4882a593Smuzhiyun+	struct weston_drm_format *fmt;
317*4882a593Smuzhiyun+	int i, ret = 0;
318*4882a593Smuzhiyun+
319*4882a593Smuzhiyun+	/* TODO: support more formats */
320*4882a593Smuzhiyun+	static const int formats[] = {
321*4882a593Smuzhiyun+		DRM_FORMAT_ARGB8888,
322*4882a593Smuzhiyun+		DRM_FORMAT_XRGB8888,
323*4882a593Smuzhiyun+		DRM_FORMAT_RGBA8888,
324*4882a593Smuzhiyun+		DRM_FORMAT_RGBX8888,
325*4882a593Smuzhiyun+		DRM_FORMAT_ABGR8888,
326*4882a593Smuzhiyun+		DRM_FORMAT_XBGR8888,
327*4882a593Smuzhiyun+		DRM_FORMAT_BGRA8888,
328*4882a593Smuzhiyun+		DRM_FORMAT_BGRX8888,
329*4882a593Smuzhiyun+		DRM_FORMAT_YUYV,
330*4882a593Smuzhiyun+		DRM_FORMAT_YVU420,
331*4882a593Smuzhiyun+		DRM_FORMAT_YUV420,
332*4882a593Smuzhiyun+		DRM_FORMAT_NV12,
333*4882a593Smuzhiyun+		DRM_FORMAT_NV16,
334*4882a593Smuzhiyun+	};
335*4882a593Smuzhiyun+
336*4882a593Smuzhiyun+	int num_formats = ARRAY_LENGTH(formats);
337*4882a593Smuzhiyun+
338*4882a593Smuzhiyun+	for (i = 0; i < num_formats; i++) {
339*4882a593Smuzhiyun+		fmt = weston_drm_format_array_add_format(supported_formats,
340*4882a593Smuzhiyun+							 formats[i]);
341*4882a593Smuzhiyun+		if (!fmt) {
342*4882a593Smuzhiyun+			ret = -1;
343*4882a593Smuzhiyun+			goto out;
344*4882a593Smuzhiyun+		}
345*4882a593Smuzhiyun+
346*4882a593Smuzhiyun+		/* Always add DRM_FORMAT_MOD_INVALID, as EGL implementations
347*4882a593Smuzhiyun+		 * support implicit modifiers. */
348*4882a593Smuzhiyun+		ret = weston_drm_format_add_modifier(fmt, DRM_FORMAT_MOD_INVALID);
349*4882a593Smuzhiyun+		if (ret < 0)
350*4882a593Smuzhiyun+			goto out;
351*4882a593Smuzhiyun+	}
352*4882a593Smuzhiyun+
353*4882a593Smuzhiyun+out:
354*4882a593Smuzhiyun+	return ret;
355*4882a593Smuzhiyun+}
356*4882a593Smuzhiyun+
357*4882a593Smuzhiyun WL_EXPORT int
358*4882a593Smuzhiyun pixman_renderer_init(struct weston_compositor *ec)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun 	struct pixman_renderer *renderer;
361*4882a593Smuzhiyun 	const struct pixel_format_info *pixel_info, *info_argb8888, *info_xrgb8888;
362*4882a593Smuzhiyun 	unsigned int i, num_formats;
363*4882a593Smuzhiyun+	int ret;
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun 	renderer = zalloc(sizeof *renderer);
366*4882a593Smuzhiyun 	if (renderer == NULL)
367*4882a593Smuzhiyun@@ -884,6 +1145,15 @@ pixman_renderer_init(struct weston_compositor *ec)
368*4882a593Smuzhiyun 	ec->capabilities |= WESTON_CAP_ROTATION_ANY;
369*4882a593Smuzhiyun 	ec->capabilities |= WESTON_CAP_VIEW_CLIP_MASK;
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun+	weston_drm_format_array_init(&renderer->supported_formats);
372*4882a593Smuzhiyun+
373*4882a593Smuzhiyun+	ret = populate_supported_formats(ec, &renderer->supported_formats);
374*4882a593Smuzhiyun+	if (ret < 0) {
375*4882a593Smuzhiyun+		weston_drm_format_array_fini(&renderer->supported_formats);
376*4882a593Smuzhiyun+		free(renderer);
377*4882a593Smuzhiyun+		return -1;
378*4882a593Smuzhiyun+	}
379*4882a593Smuzhiyun+
380*4882a593Smuzhiyun 	renderer->debug_binding =
381*4882a593Smuzhiyun 		weston_compositor_add_debug_binding(ec, KEY_R,
382*4882a593Smuzhiyun 						    debug_binding, ec);
383*4882a593Smuzhiyun@@ -906,6 +1176,11 @@ pixman_renderer_init(struct weston_compositor *ec)
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun 	wl_signal_init(&renderer->destroy_signal);
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun+	renderer->base.import_dmabuf = pixman_renderer_import_dmabuf;
388*4882a593Smuzhiyun+
389*4882a593Smuzhiyun+	renderer->base.get_supported_formats =
390*4882a593Smuzhiyun+		pixman_renderer_get_supported_formats;
391*4882a593Smuzhiyun+
392*4882a593Smuzhiyun 	return 0;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun--
396*4882a593Smuzhiyun2.20.1
397*4882a593Smuzhiyun
398