1*4882a593SmuzhiyunFrom 0f3dea67852b76216bfe1f8ea59274513000a1a9 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com>
3*4882a593SmuzhiyunDate: Fri, 3 Jul 2020 14:53:52 +0800
4*4882a593SmuzhiyunSubject: [PATCH 22/79] HACK: pixman-renderer: Support mali egl client and egl
5*4882a593Smuzhiyun buffer attaching
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunThe mali clients requires mali_buffer_sharing extension, and it needs
8*4882a593Smuzhiyunlots of hacks to attach a wl_buffer created in that way.
9*4882a593Smuzhiyun
10*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
11*4882a593Smuzhiyun---
12*4882a593Smuzhiyun libweston/meson.build       |  10 +-
13*4882a593Smuzhiyun libweston/pixman-renderer.c | 365 ++++++++++++++++++++++++++++--------
14*4882a593Smuzhiyun 2 files changed, 290 insertions(+), 85 deletions(-)
15*4882a593Smuzhiyun
16*4882a593Smuzhiyundiff --git a/libweston/meson.build b/libweston/meson.build
17*4882a593Smuzhiyunindex 257d695..a73e932 100644
18*4882a593Smuzhiyun--- a/libweston/meson.build
19*4882a593Smuzhiyun+++ b/libweston/meson.build
20*4882a593Smuzhiyun@@ -70,12 +70,10 @@ srcs_libweston = [
21*4882a593Smuzhiyun 	weston_direct_display_server_protocol_h,
22*4882a593Smuzhiyun ]
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun-if get_option('renderer-gl')
25*4882a593Smuzhiyun-	dep_egl = dependency('egl', required: false)
26*4882a593Smuzhiyun-	if not dep_egl.found()
27*4882a593Smuzhiyun-		error('libweston + gl-renderer requires egl which was not found. Or, you can use \'-Drenderer-gl=false\'.')
28*4882a593Smuzhiyun-	endif
29*4882a593Smuzhiyun-	deps_libweston += dep_egl
30*4882a593Smuzhiyun+dep_egl = dependency('egl', required: false)
31*4882a593Smuzhiyun+dep_gbm = dependency('gbm', required: false)
32*4882a593Smuzhiyun+if dep_egl.found() and dep_gbm.found()
33*4882a593Smuzhiyun+	deps_libweston += [ dep_egl, dep_gbm ]
34*4882a593Smuzhiyun endif
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun lib_weston = shared_library(
37*4882a593Smuzhiyundiff --git a/libweston/pixman-renderer.c b/libweston/pixman-renderer.c
38*4882a593Smuzhiyunindex d5c5422..ece4d91 100644
39*4882a593Smuzhiyun--- a/libweston/pixman-renderer.c
40*4882a593Smuzhiyun+++ b/libweston/pixman-renderer.c
41*4882a593Smuzhiyun@@ -46,6 +46,19 @@
42*4882a593Smuzhiyun #include "linux-dmabuf.h"
43*4882a593Smuzhiyun #include "linux-dmabuf-unstable-v1-server-protocol.h"
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun+#ifdef ENABLE_EGL
46*4882a593Smuzhiyun+#include <fcntl.h>
47*4882a593Smuzhiyun+#include <sys/stat.h>
48*4882a593Smuzhiyun+
49*4882a593Smuzhiyun+#include <gbm.h>
50*4882a593Smuzhiyun+#include <EGL/egl.h>
51*4882a593Smuzhiyun+#include <EGL/eglext.h>
52*4882a593Smuzhiyun+#include <GLES2/gl2.h>
53*4882a593Smuzhiyun+#include <GLES2/gl2ext.h>
54*4882a593Smuzhiyun+#include "shared/platform.h"
55*4882a593Smuzhiyun+#include "shared/weston-egl-ext.h"  /* for PFN* stuff */
56*4882a593Smuzhiyun+#endif
57*4882a593Smuzhiyun+
58*4882a593Smuzhiyun struct pixman_output_state {
59*4882a593Smuzhiyun 	void *shadow_buffer;
60*4882a593Smuzhiyun 	pixman_image_t *shadow_image;
61*4882a593Smuzhiyun@@ -75,6 +88,18 @@ struct pixman_renderer {
62*4882a593Smuzhiyun 	struct wl_signal destroy_signal;
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun 	struct weston_drm_format_array supported_formats;
65*4882a593Smuzhiyun+
66*4882a593Smuzhiyun+#ifdef ENABLE_EGL
67*4882a593Smuzhiyun+	PFNEGLBINDWAYLANDDISPLAYWL bind_display;
68*4882a593Smuzhiyun+	PFNEGLUNBINDWAYLANDDISPLAYWL unbind_display;
69*4882a593Smuzhiyun+	PFNEGLQUERYWAYLANDBUFFERWL query_buffer;
70*4882a593Smuzhiyun+	EGLDisplay egl_display;
71*4882a593Smuzhiyun+
72*4882a593Smuzhiyun+	int drm_fd;
73*4882a593Smuzhiyun+	struct gbm_device *gbm;
74*4882a593Smuzhiyun+
75*4882a593Smuzhiyun+	bool egl_inited;
76*4882a593Smuzhiyun+#endif
77*4882a593Smuzhiyun };
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun struct dmabuf_data {
80*4882a593Smuzhiyun@@ -82,6 +107,16 @@ struct dmabuf_data {
81*4882a593Smuzhiyun 	size_t size;
82*4882a593Smuzhiyun };
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun+#ifdef ENABLE_EGL
85*4882a593Smuzhiyun+/* HACK: For mali_buffer_sharing */
86*4882a593Smuzhiyun+struct egl_buffer_info {
87*4882a593Smuzhiyun+	int dma_fd;
88*4882a593Smuzhiyun+	int width;
89*4882a593Smuzhiyun+	int height;
90*4882a593Smuzhiyun+	unsigned int stride;
91*4882a593Smuzhiyun+};
92*4882a593Smuzhiyun+#endif
93*4882a593Smuzhiyun+
94*4882a593Smuzhiyun static inline struct pixman_output_state *
95*4882a593Smuzhiyun get_output_state(struct weston_output *output)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun@@ -636,6 +671,90 @@ buffer_state_handle_buffer_destroy(struct wl_listener *listener, void *data)
98*4882a593Smuzhiyun 	ps->buffer_destroy_listener.notify = NULL;
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun+static void
102*4882a593Smuzhiyun+pixman_renderer_destroy_dmabuf(struct linux_dmabuf_buffer *dmabuf)
103*4882a593Smuzhiyun+{
104*4882a593Smuzhiyun+	struct dmabuf_data *data = dmabuf->user_data;
105*4882a593Smuzhiyun+	linux_dmabuf_buffer_set_user_data(dmabuf, NULL, NULL);
106*4882a593Smuzhiyun+
107*4882a593Smuzhiyun+	if (data) {
108*4882a593Smuzhiyun+		if (data->ptr)
109*4882a593Smuzhiyun+			munmap(data->ptr, data->size);
110*4882a593Smuzhiyun+
111*4882a593Smuzhiyun+		free(data);
112*4882a593Smuzhiyun+	}
113*4882a593Smuzhiyun+}
114*4882a593Smuzhiyun+
115*4882a593Smuzhiyun+static bool
116*4882a593Smuzhiyun+pixman_renderer_prepare_dmabuf(struct linux_dmabuf_buffer *dmabuf)
117*4882a593Smuzhiyun+{
118*4882a593Smuzhiyun+	struct dmabuf_attributes *attributes = &dmabuf->attributes;
119*4882a593Smuzhiyun+	struct dmabuf_data *data;
120*4882a593Smuzhiyun+	size_t total_size, vstride0;
121*4882a593Smuzhiyun+	void *ptr;
122*4882a593Smuzhiyun+	int i;
123*4882a593Smuzhiyun+
124*4882a593Smuzhiyun+	data = linux_dmabuf_buffer_get_user_data(dmabuf);
125*4882a593Smuzhiyun+	if (data)
126*4882a593Smuzhiyun+		return true;
127*4882a593Smuzhiyun+
128*4882a593Smuzhiyun+	total_size = lseek(attributes->fd[0], 0, SEEK_END);
129*4882a593Smuzhiyun+
130*4882a593Smuzhiyun+	for (i = 0; i < attributes->n_planes; i++) {
131*4882a593Smuzhiyun+		if (attributes->modifier[i] != DRM_FORMAT_MOD_INVALID)
132*4882a593Smuzhiyun+			return false;
133*4882a593Smuzhiyun+	}
134*4882a593Smuzhiyun+
135*4882a593Smuzhiyun+	/* reject all flags we do not recognize or handle */
136*4882a593Smuzhiyun+	if (attributes->flags & ~ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT)
137*4882a593Smuzhiyun+		return false;
138*4882a593Smuzhiyun+
139*4882a593Smuzhiyun+	if (attributes->n_planes < 0)
140*4882a593Smuzhiyun+		return false;
141*4882a593Smuzhiyun+
142*4882a593Smuzhiyun+	if (attributes->n_planes == 1)
143*4882a593Smuzhiyun+		goto out;
144*4882a593Smuzhiyun+
145*4882a593Smuzhiyun+	vstride0 = (attributes->offset[1] - attributes->offset[0]) /
146*4882a593Smuzhiyun+		attributes->stride[0];
147*4882a593Smuzhiyun+
148*4882a593Smuzhiyun+	for (i = 1; i < attributes->n_planes; i++) {
149*4882a593Smuzhiyun+		size_t size = attributes->offset[i] - attributes->offset[i - 1];
150*4882a593Smuzhiyun+		size_t vstride = size / attributes->stride[i - 1];
151*4882a593Smuzhiyun+
152*4882a593Smuzhiyun+		/* not contig */
153*4882a593Smuzhiyun+		if (size <= 0 || vstride <= 0 ||
154*4882a593Smuzhiyun+		    attributes->offset[i - 1] + size > total_size)
155*4882a593Smuzhiyun+			return false;
156*4882a593Smuzhiyun+
157*4882a593Smuzhiyun+		/* stride unmatched */
158*4882a593Smuzhiyun+		if ((vstride != vstride0 && vstride != vstride0 / 2) ||
159*4882a593Smuzhiyun+		    (attributes->stride[i] != attributes->stride[0] &&
160*4882a593Smuzhiyun+		     attributes->stride[i] != attributes->stride[0] / 2))
161*4882a593Smuzhiyun+			return false;
162*4882a593Smuzhiyun+	}
163*4882a593Smuzhiyun+
164*4882a593Smuzhiyun+out:
165*4882a593Smuzhiyun+	/* Handle contig dma buffer */
166*4882a593Smuzhiyun+
167*4882a593Smuzhiyun+	ptr = mmap(NULL, total_size, PROT_READ,
168*4882a593Smuzhiyun+		   MAP_SHARED, attributes->fd[0], 0);
169*4882a593Smuzhiyun+	if (!ptr)
170*4882a593Smuzhiyun+		return false;
171*4882a593Smuzhiyun+
172*4882a593Smuzhiyun+	data = zalloc(sizeof *data);
173*4882a593Smuzhiyun+	if (!data) {
174*4882a593Smuzhiyun+		munmap(ptr, total_size);
175*4882a593Smuzhiyun+		return false;
176*4882a593Smuzhiyun+	}
177*4882a593Smuzhiyun+
178*4882a593Smuzhiyun+	data->size = total_size;
179*4882a593Smuzhiyun+	data->ptr = ptr;
180*4882a593Smuzhiyun+	linux_dmabuf_buffer_set_user_data(dmabuf, data,
181*4882a593Smuzhiyun+					  pixman_renderer_destroy_dmabuf);
182*4882a593Smuzhiyun+	return true;
183*4882a593Smuzhiyun+}
184*4882a593Smuzhiyun+
185*4882a593Smuzhiyun static void
186*4882a593Smuzhiyun pixman_renderer_attach_dmabuf(struct weston_surface *es,
187*4882a593Smuzhiyun 			      struct weston_buffer *buffer,
188*4882a593Smuzhiyun@@ -647,13 +766,12 @@ pixman_renderer_attach_dmabuf(struct weston_surface *es,
189*4882a593Smuzhiyun 	pixman_format_code_t pixman_format;
190*4882a593Smuzhiyun 	size_t vstride;
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun+	if (!pixman_renderer_prepare_dmabuf(dmabuf))
193*4882a593Smuzhiyun+		goto err;
194*4882a593Smuzhiyun+
195*4882a593Smuzhiyun 	data = linux_dmabuf_buffer_get_user_data(dmabuf);
196*4882a593Smuzhiyun-	if (!data || !data->ptr) {
197*4882a593Smuzhiyun-		weston_buffer_reference(&ps->buffer_ref, NULL);
198*4882a593Smuzhiyun-		weston_buffer_release_reference(&ps->buffer_release_ref,
199*4882a593Smuzhiyun-						NULL);
200*4882a593Smuzhiyun-		return;
201*4882a593Smuzhiyun-	}
202*4882a593Smuzhiyun+	if (!data || !data->ptr)
203*4882a593Smuzhiyun+		goto err;
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun 	buffer->width = attributes->width;
206*4882a593Smuzhiyun 	buffer->height = attributes->height;
207*4882a593Smuzhiyun@@ -694,10 +812,7 @@ pixman_renderer_attach_dmabuf(struct weston_surface *es,
208*4882a593Smuzhiyun #endif
209*4882a593Smuzhiyun 	default:
210*4882a593Smuzhiyun 		weston_log("Unsupported dmabuf format\n");
211*4882a593Smuzhiyun-		weston_buffer_reference(&ps->buffer_ref, NULL);
212*4882a593Smuzhiyun-		weston_buffer_release_reference(&ps->buffer_release_ref,
213*4882a593Smuzhiyun-						NULL);
214*4882a593Smuzhiyun-		return;
215*4882a593Smuzhiyun+		goto err;
216*4882a593Smuzhiyun 	break;
217*4882a593Smuzhiyun 	}
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun@@ -710,16 +825,25 @@ pixman_renderer_attach_dmabuf(struct weston_surface *es,
220*4882a593Smuzhiyun 		buffer_state_handle_buffer_destroy;
221*4882a593Smuzhiyun 	wl_signal_add(&buffer->destroy_signal,
222*4882a593Smuzhiyun 		      &ps->buffer_destroy_listener);
223*4882a593Smuzhiyun+	return;
224*4882a593Smuzhiyun+err:
225*4882a593Smuzhiyun+	weston_buffer_reference(&ps->buffer_ref, NULL);
226*4882a593Smuzhiyun+	weston_buffer_release_reference(&ps->buffer_release_ref, NULL);
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun static void
230*4882a593Smuzhiyun pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
231*4882a593Smuzhiyun {
232*4882a593Smuzhiyun+	struct pixman_renderer *pr = get_renderer(es->compositor);
233*4882a593Smuzhiyun 	struct pixman_surface_state *ps = get_surface_state(es);
234*4882a593Smuzhiyun 	struct wl_shm_buffer *shm_buffer;
235*4882a593Smuzhiyun 	struct linux_dmabuf_buffer *dmabuf;
236*4882a593Smuzhiyun 	const struct pixel_format_info *pixel_info;
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun+#ifdef ENABLE_EGL
239*4882a593Smuzhiyun+	EGLint format;
240*4882a593Smuzhiyun+#endif
241*4882a593Smuzhiyun+
242*4882a593Smuzhiyun 	weston_buffer_reference(&ps->buffer_ref, buffer);
243*4882a593Smuzhiyun 	weston_buffer_release_reference(&ps->buffer_release_ref,
244*4882a593Smuzhiyun 					es->buffer_release_ref.buffer_release);
245*4882a593Smuzhiyun@@ -742,7 +866,56 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
246*4882a593Smuzhiyun 	if (! shm_buffer) {
247*4882a593Smuzhiyun 		if ((dmabuf = linux_dmabuf_buffer_get(buffer->resource))) {
248*4882a593Smuzhiyun 			pixman_renderer_attach_dmabuf(es, buffer, dmabuf);
249*4882a593Smuzhiyun+#ifdef ENABLE_EGL
250*4882a593Smuzhiyun+		} else if (pr->egl_inited &&
251*4882a593Smuzhiyun+			   pr->query_buffer(pr->egl_display,
252*4882a593Smuzhiyun+					    (void *)buffer->resource,
253*4882a593Smuzhiyun+					    EGL_TEXTURE_FORMAT, &format)){
254*4882a593Smuzhiyun+			struct egl_buffer_info *info;
255*4882a593Smuzhiyun+			struct linux_dmabuf_buffer dmabuf = { 0 };
256*4882a593Smuzhiyun+			struct dmabuf_attributes *attributes =
257*4882a593Smuzhiyun+				&dmabuf.attributes;
258*4882a593Smuzhiyun+			struct stat s;
259*4882a593Smuzhiyun+			int width, height;
260*4882a593Smuzhiyun+
261*4882a593Smuzhiyun+			pr->query_buffer(pr->egl_display,
262*4882a593Smuzhiyun+					 (void *)buffer->resource,
263*4882a593Smuzhiyun+					 EGL_WIDTH, &width);
264*4882a593Smuzhiyun+			pr->query_buffer(pr->egl_display,
265*4882a593Smuzhiyun+					 (void *)buffer->resource,
266*4882a593Smuzhiyun+					 EGL_HEIGHT, &height);
267*4882a593Smuzhiyun+
268*4882a593Smuzhiyun+			info = wl_resource_get_user_data(buffer->resource);
269*4882a593Smuzhiyun+			if (!info)
270*4882a593Smuzhiyun+				goto err;
271*4882a593Smuzhiyun+
272*4882a593Smuzhiyun+			if (fstat(info->dma_fd, &s) < 0 ||
273*4882a593Smuzhiyun+			    info->width != width || info->height != height)
274*4882a593Smuzhiyun+				goto err;
275*4882a593Smuzhiyun+
276*4882a593Smuzhiyun+			switch (format) {
277*4882a593Smuzhiyun+			case EGL_TEXTURE_RGB:
278*4882a593Smuzhiyun+				attributes->format = DRM_FORMAT_RGB888;
279*4882a593Smuzhiyun+				break;
280*4882a593Smuzhiyun+			case EGL_TEXTURE_RGBA:
281*4882a593Smuzhiyun+				attributes->format = DRM_FORMAT_ARGB8888;
282*4882a593Smuzhiyun+				break;
283*4882a593Smuzhiyun+			default:
284*4882a593Smuzhiyun+				goto err;
285*4882a593Smuzhiyun+			}
286*4882a593Smuzhiyun+
287*4882a593Smuzhiyun+			attributes->n_planes = 1;
288*4882a593Smuzhiyun+			attributes->fd[0] = info->dma_fd;
289*4882a593Smuzhiyun+			attributes->width = info->width;
290*4882a593Smuzhiyun+			attributes->height = info->height;
291*4882a593Smuzhiyun+			attributes->stride[0] = info->stride;
292*4882a593Smuzhiyun+
293*4882a593Smuzhiyun+			pixman_renderer_attach_dmabuf(es, buffer, &dmabuf);
294*4882a593Smuzhiyun+		} else {
295*4882a593Smuzhiyun+err:
296*4882a593Smuzhiyun+#else
297*4882a593Smuzhiyun 		} else {
298*4882a593Smuzhiyun+#endif
299*4882a593Smuzhiyun 			weston_log("unhandled buffer type!\n");
300*4882a593Smuzhiyun 			weston_buffer_reference(&ps->buffer_ref, NULL);
301*4882a593Smuzhiyun 			weston_buffer_release_reference(&ps->buffer_release_ref,
302*4882a593Smuzhiyun@@ -880,6 +1053,21 @@ pixman_renderer_destroy(struct weston_compositor *ec)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	struct pixman_renderer *pr = get_renderer(ec);
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun+#ifdef ENABLE_EGL
307*4882a593Smuzhiyun+	if (pr->egl_inited) {
308*4882a593Smuzhiyun+		if (pr->unbind_display)
309*4882a593Smuzhiyun+			pr->unbind_display(pr->egl_display, ec->wl_display);
310*4882a593Smuzhiyun+
311*4882a593Smuzhiyun+		eglTerminate(pr->egl_display);
312*4882a593Smuzhiyun+		eglReleaseThread();
313*4882a593Smuzhiyun+
314*4882a593Smuzhiyun+		if (pr->gbm)
315*4882a593Smuzhiyun+			gbm_device_destroy(pr->gbm);
316*4882a593Smuzhiyun+
317*4882a593Smuzhiyun+		close(pr->drm_fd);
318*4882a593Smuzhiyun+	}
319*4882a593Smuzhiyun+#endif
320*4882a593Smuzhiyun+
321*4882a593Smuzhiyun 	wl_signal_emit(&pr->destroy_signal, pr);
322*4882a593Smuzhiyun 	weston_binding_destroy(pr->debug_binding);
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun@@ -958,79 +1146,11 @@ debug_binding(struct weston_keyboard *keyboard, const struct timespec *time,
325*4882a593Smuzhiyun 	}
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun-static void
329*4882a593Smuzhiyun-pixman_renderer_destroy_dmabuf(struct linux_dmabuf_buffer *dmabuf)
330*4882a593Smuzhiyun-{
331*4882a593Smuzhiyun-	struct dmabuf_data *data = dmabuf->user_data;
332*4882a593Smuzhiyun-	linux_dmabuf_buffer_set_user_data(dmabuf, NULL, NULL);
333*4882a593Smuzhiyun-
334*4882a593Smuzhiyun-	if (data) {
335*4882a593Smuzhiyun-		if (data->ptr)
336*4882a593Smuzhiyun-			munmap(data->ptr, data->size);
337*4882a593Smuzhiyun-
338*4882a593Smuzhiyun-		free(data);
339*4882a593Smuzhiyun-	}
340*4882a593Smuzhiyun-}
341*4882a593Smuzhiyun-
342*4882a593Smuzhiyun static bool
343*4882a593Smuzhiyun pixman_renderer_import_dmabuf(struct weston_compositor *ec,
344*4882a593Smuzhiyun 			      struct linux_dmabuf_buffer *dmabuf)
345*4882a593Smuzhiyun {
346*4882a593Smuzhiyun-	struct dmabuf_attributes *attributes = &dmabuf->attributes;
347*4882a593Smuzhiyun-	struct dmabuf_data *data;
348*4882a593Smuzhiyun-	size_t total_size, vstride0;
349*4882a593Smuzhiyun-	int i;
350*4882a593Smuzhiyun-
351*4882a593Smuzhiyun-	for (i = 0; i < attributes->n_planes; i++) {
352*4882a593Smuzhiyun-		if (attributes->modifier[i] != DRM_FORMAT_MOD_INVALID)
353*4882a593Smuzhiyun-			return false;
354*4882a593Smuzhiyun-	}
355*4882a593Smuzhiyun-
356*4882a593Smuzhiyun-	/* reject all flags we do not recognize or handle */
357*4882a593Smuzhiyun-	if (attributes->flags & ~ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT)
358*4882a593Smuzhiyun-		return false;
359*4882a593Smuzhiyun-
360*4882a593Smuzhiyun-	if (attributes->n_planes < 0)
361*4882a593Smuzhiyun-		return false;
362*4882a593Smuzhiyun-
363*4882a593Smuzhiyun-	if (attributes->n_planes == 1)
364*4882a593Smuzhiyun-		goto out;
365*4882a593Smuzhiyun-
366*4882a593Smuzhiyun-	total_size = lseek(attributes->fd[0], 0, SEEK_END);
367*4882a593Smuzhiyun-	vstride0 = (attributes->offset[1] - attributes->offset[0]) /
368*4882a593Smuzhiyun-		attributes->stride[0];
369*4882a593Smuzhiyun-
370*4882a593Smuzhiyun-	for (i = 1; i < attributes->n_planes; i++) {
371*4882a593Smuzhiyun-		size_t size = attributes->offset[i] - attributes->offset[i - 1];
372*4882a593Smuzhiyun-		size_t vstride = size / attributes->stride[i - 1];
373*4882a593Smuzhiyun-
374*4882a593Smuzhiyun-		/* not contig */
375*4882a593Smuzhiyun-		if (size <= 0 || vstride <= 0 ||
376*4882a593Smuzhiyun-		    attributes->offset[i - 1] + size > total_size)
377*4882a593Smuzhiyun-			return false;
378*4882a593Smuzhiyun-
379*4882a593Smuzhiyun-		/* stride unmatched */
380*4882a593Smuzhiyun-		if ((vstride != vstride0 && vstride != vstride0 / 2) ||
381*4882a593Smuzhiyun-		    (attributes->stride[i] != attributes->stride[0] &&
382*4882a593Smuzhiyun-		     attributes->stride[i] != attributes->stride[0] / 2))
383*4882a593Smuzhiyun-			return false;
384*4882a593Smuzhiyun-	}
385*4882a593Smuzhiyun-
386*4882a593Smuzhiyun-out:
387*4882a593Smuzhiyun-	/* Handle contig dma buffer */
388*4882a593Smuzhiyun-
389*4882a593Smuzhiyun-	data = zalloc(sizeof *data);
390*4882a593Smuzhiyun-	if (!data)
391*4882a593Smuzhiyun-		return false;
392*4882a593Smuzhiyun-
393*4882a593Smuzhiyun-	linux_dmabuf_buffer_set_user_data(dmabuf, data,
394*4882a593Smuzhiyun-					  pixman_renderer_destroy_dmabuf);
395*4882a593Smuzhiyun-
396*4882a593Smuzhiyun-	data->size = lseek(attributes->fd[0], 0, SEEK_END);
397*4882a593Smuzhiyun-
398*4882a593Smuzhiyun-	data->ptr = mmap(NULL, data->size, PROT_READ,
399*4882a593Smuzhiyun-			 MAP_SHARED, attributes->fd[0], 0);
400*4882a593Smuzhiyun-	return data->ptr != MAP_FAILED;
401*4882a593Smuzhiyun+	return pixman_renderer_prepare_dmabuf(dmabuf);
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun static const struct weston_drm_format_array *
405*4882a593Smuzhiyun@@ -1086,6 +1206,89 @@ out:
406*4882a593Smuzhiyun 	return ret;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun+#ifdef ENABLE_EGL
410*4882a593Smuzhiyun+static bool
411*4882a593Smuzhiyun+pixman_renderer_init_egl(struct pixman_renderer *pr,
412*4882a593Smuzhiyun+			 struct weston_compositor *ec)
413*4882a593Smuzhiyun+{
414*4882a593Smuzhiyun+	PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display;
415*4882a593Smuzhiyun+	const char *extensions;
416*4882a593Smuzhiyun+
417*4882a593Smuzhiyun+	get_platform_display =
418*4882a593Smuzhiyun+		(void *) eglGetProcAddress("eglGetPlatformDisplayEXT");
419*4882a593Smuzhiyun+	pr->query_buffer =
420*4882a593Smuzhiyun+		(void *) eglGetProcAddress("eglQueryWaylandBufferWL");
421*4882a593Smuzhiyun+	pr->bind_display =
422*4882a593Smuzhiyun+		(void *) eglGetProcAddress("eglBindWaylandDisplayWL");
423*4882a593Smuzhiyun+	pr->unbind_display =
424*4882a593Smuzhiyun+		(void *) eglGetProcAddress("eglUnbindWaylandDisplayWL");
425*4882a593Smuzhiyun+
426*4882a593Smuzhiyun+	if (!get_platform_display || !pr->query_buffer ||
427*4882a593Smuzhiyun+	    !pr->bind_display || !pr->unbind_display) {
428*4882a593Smuzhiyun+		weston_log("Failed to get egl proc\n");
429*4882a593Smuzhiyun+		return false;
430*4882a593Smuzhiyun+	}
431*4882a593Smuzhiyun+
432*4882a593Smuzhiyun+	pr->drm_fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
433*4882a593Smuzhiyun+	if (pr->drm_fd < 0) {
434*4882a593Smuzhiyun+		weston_log("Failed to open drm dev\n");
435*4882a593Smuzhiyun+		return false;
436*4882a593Smuzhiyun+	}
437*4882a593Smuzhiyun+
438*4882a593Smuzhiyun+	pr->gbm = gbm_create_device(pr->drm_fd);
439*4882a593Smuzhiyun+	if (!pr->gbm) {
440*4882a593Smuzhiyun+		weston_log("Failed to create gbm device\n");
441*4882a593Smuzhiyun+		goto err_close_fd;
442*4882a593Smuzhiyun+	}
443*4882a593Smuzhiyun+
444*4882a593Smuzhiyun+	pr->egl_display = get_platform_display(EGL_PLATFORM_GBM_KHR,
445*4882a593Smuzhiyun+					       (void*) pr->gbm, NULL);
446*4882a593Smuzhiyun+	if (pr->egl_display == EGL_NO_DISPLAY) {
447*4882a593Smuzhiyun+		weston_log("Failed to create egl display\n");
448*4882a593Smuzhiyun+		goto err_destroy_gbm;
449*4882a593Smuzhiyun+	}
450*4882a593Smuzhiyun+
451*4882a593Smuzhiyun+	if (!eglInitialize(pr->egl_display, NULL, NULL)) {
452*4882a593Smuzhiyun+		weston_log("Failed to initialize egl\n");
453*4882a593Smuzhiyun+		goto err_terminate_display;
454*4882a593Smuzhiyun+	}
455*4882a593Smuzhiyun+
456*4882a593Smuzhiyun+	extensions =
457*4882a593Smuzhiyun+		(const char *) eglQueryString(pr->egl_display, EGL_EXTENSIONS);
458*4882a593Smuzhiyun+	if (!extensions) {
459*4882a593Smuzhiyun+		weston_log("Retrieving EGL extension string failed.\n");
460*4882a593Smuzhiyun+		goto err_terminate_display;
461*4882a593Smuzhiyun+	}
462*4882a593Smuzhiyun+
463*4882a593Smuzhiyun+	if (!weston_check_egl_extension(extensions,
464*4882a593Smuzhiyun+					"EGL_WL_bind_wayland_display")) {
465*4882a593Smuzhiyun+		weston_log("Wayland extension not supported.\n");
466*4882a593Smuzhiyun+		goto err_terminate_display;
467*4882a593Smuzhiyun+	}
468*4882a593Smuzhiyun+
469*4882a593Smuzhiyun+	if (!eglBindAPI(EGL_OPENGL_ES_API)) {
470*4882a593Smuzhiyun+		weston_log("Failed to bind api\n");
471*4882a593Smuzhiyun+		goto err_terminate_display;
472*4882a593Smuzhiyun+	}
473*4882a593Smuzhiyun+
474*4882a593Smuzhiyun+	if (!pr->bind_display(pr->egl_display, ec->wl_display))
475*4882a593Smuzhiyun+		goto err_terminate_display;
476*4882a593Smuzhiyun+
477*4882a593Smuzhiyun+	pr->egl_inited = true;
478*4882a593Smuzhiyun+	return true;
479*4882a593Smuzhiyun+
480*4882a593Smuzhiyun+err_terminate_display:
481*4882a593Smuzhiyun+	eglTerminate(pr->egl_display);
482*4882a593Smuzhiyun+err_destroy_gbm:
483*4882a593Smuzhiyun+	gbm_device_destroy(pr->gbm);
484*4882a593Smuzhiyun+	pr->gbm = NULL;
485*4882a593Smuzhiyun+err_close_fd:
486*4882a593Smuzhiyun+	close(pr->drm_fd);
487*4882a593Smuzhiyun+	pr->drm_fd = -1;
488*4882a593Smuzhiyun+	return false;
489*4882a593Smuzhiyun+}
490*4882a593Smuzhiyun+#endif
491*4882a593Smuzhiyun+
492*4882a593Smuzhiyun WL_EXPORT int
493*4882a593Smuzhiyun pixman_renderer_init(struct weston_compositor *ec)
494*4882a593Smuzhiyun {
495*4882a593Smuzhiyun@@ -1150,6 +1353,10 @@ pixman_renderer_init(struct weston_compositor *ec)
496*4882a593Smuzhiyun 	renderer->base.get_supported_formats =
497*4882a593Smuzhiyun 		pixman_renderer_get_supported_formats;
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun+#ifdef ENABLE_EGL
500*4882a593Smuzhiyun+	pixman_renderer_init_egl(renderer, ec);
501*4882a593Smuzhiyun+#endif
502*4882a593Smuzhiyun+
503*4882a593Smuzhiyun 	return 0;
504*4882a593Smuzhiyun }
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun--
507*4882a593Smuzhiyun2.20.1
508*4882a593Smuzhiyun
509