1*4882a593SmuzhiyunFrom 108ff56cf2a650bb9650a701e22c7bc69e770cde 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 25/93] 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 | 427 ++++++++++++++++++++++++++++-------- 14*4882a593Smuzhiyun 2 files changed, 338 insertions(+), 99 deletions(-) 15*4882a593Smuzhiyun 16*4882a593Smuzhiyundiff --git a/libweston/meson.build b/libweston/meson.build 17*4882a593Smuzhiyunindex 313a84f..6a845cc 100644 18*4882a593Smuzhiyun--- a/libweston/meson.build 19*4882a593Smuzhiyun+++ b/libweston/meson.build 20*4882a593Smuzhiyun@@ -73,12 +73,10 @@ srcs_libweston = [ 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun subdir('desktop') 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 29d2b60..5ab4b55 100644 39*4882a593Smuzhiyun--- a/libweston/pixman-renderer.c 40*4882a593Smuzhiyun+++ b/libweston/pixman-renderer.c 41*4882a593Smuzhiyun@@ -47,6 +47,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 pixman_image_t *shadow_image; 60*4882a593Smuzhiyun pixman_image_t *hw_buffer; 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@@ -672,6 +707,91 @@ pixman_renderer_surface_set_color(struct weston_surface *es, 98*4882a593Smuzhiyun ps->image = pixman_image_create_solid_fill(&color); 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+ attributes->modifier[i] != DRM_FORMAT_MOD_LINEAR) 133*4882a593Smuzhiyun+ return false; 134*4882a593Smuzhiyun+ } 135*4882a593Smuzhiyun+ 136*4882a593Smuzhiyun+ /* reject all flags we do not recognize or handle */ 137*4882a593Smuzhiyun+ if (attributes->flags & ~ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT) 138*4882a593Smuzhiyun+ return false; 139*4882a593Smuzhiyun+ 140*4882a593Smuzhiyun+ if (attributes->n_planes < 0) 141*4882a593Smuzhiyun+ return false; 142*4882a593Smuzhiyun+ 143*4882a593Smuzhiyun+ if (attributes->n_planes == 1) 144*4882a593Smuzhiyun+ goto out; 145*4882a593Smuzhiyun+ 146*4882a593Smuzhiyun+ vstride0 = (attributes->offset[1] - attributes->offset[0]) / 147*4882a593Smuzhiyun+ attributes->stride[0]; 148*4882a593Smuzhiyun+ 149*4882a593Smuzhiyun+ for (i = 1; i < attributes->n_planes; i++) { 150*4882a593Smuzhiyun+ size_t size = attributes->offset[i] - attributes->offset[i - 1]; 151*4882a593Smuzhiyun+ size_t vstride = size / attributes->stride[i - 1]; 152*4882a593Smuzhiyun+ 153*4882a593Smuzhiyun+ /* not contig */ 154*4882a593Smuzhiyun+ if (size <= 0 || vstride <= 0 || 155*4882a593Smuzhiyun+ attributes->offset[i - 1] + size > total_size) 156*4882a593Smuzhiyun+ return false; 157*4882a593Smuzhiyun+ 158*4882a593Smuzhiyun+ /* stride unmatched */ 159*4882a593Smuzhiyun+ if ((vstride != vstride0 && vstride != vstride0 / 2) || 160*4882a593Smuzhiyun+ (attributes->stride[i] != attributes->stride[0] && 161*4882a593Smuzhiyun+ attributes->stride[i] != attributes->stride[0] / 2)) 162*4882a593Smuzhiyun+ return false; 163*4882a593Smuzhiyun+ } 164*4882a593Smuzhiyun+ 165*4882a593Smuzhiyun+out: 166*4882a593Smuzhiyun+ /* Handle contig dma buffer */ 167*4882a593Smuzhiyun+ 168*4882a593Smuzhiyun+ ptr = mmap(NULL, total_size, PROT_READ, 169*4882a593Smuzhiyun+ MAP_SHARED, attributes->fd[0], 0); 170*4882a593Smuzhiyun+ if (!ptr) 171*4882a593Smuzhiyun+ return false; 172*4882a593Smuzhiyun+ 173*4882a593Smuzhiyun+ data = zalloc(sizeof *data); 174*4882a593Smuzhiyun+ if (!data) { 175*4882a593Smuzhiyun+ munmap(ptr, total_size); 176*4882a593Smuzhiyun+ return false; 177*4882a593Smuzhiyun+ } 178*4882a593Smuzhiyun+ 179*4882a593Smuzhiyun+ data->size = total_size; 180*4882a593Smuzhiyun+ data->ptr = ptr; 181*4882a593Smuzhiyun+ linux_dmabuf_buffer_set_user_data(dmabuf, data, 182*4882a593Smuzhiyun+ pixman_renderer_destroy_dmabuf); 183*4882a593Smuzhiyun+ return true; 184*4882a593Smuzhiyun+} 185*4882a593Smuzhiyun+ 186*4882a593Smuzhiyun static void 187*4882a593Smuzhiyun pixman_renderer_attach_dmabuf(struct weston_surface *es, 188*4882a593Smuzhiyun struct weston_buffer *buffer, 189*4882a593Smuzhiyun@@ -683,14 +803,12 @@ pixman_renderer_attach_dmabuf(struct weston_surface *es, 190*4882a593Smuzhiyun pixman_format_code_t pixman_format; 191*4882a593Smuzhiyun size_t vstride; 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun+ if (!pixman_renderer_prepare_dmabuf(dmabuf)) 194*4882a593Smuzhiyun+ goto err; 195*4882a593Smuzhiyun+ 196*4882a593Smuzhiyun data = linux_dmabuf_buffer_get_user_data(dmabuf); 197*4882a593Smuzhiyun- if (!data || !data->ptr) { 198*4882a593Smuzhiyun- weston_buffer_reference(&ps->buffer_ref, NULL, 199*4882a593Smuzhiyun- BUFFER_WILL_NOT_BE_ACCESSED); 200*4882a593Smuzhiyun- weston_buffer_release_reference(&ps->buffer_release_ref, 201*4882a593Smuzhiyun- NULL); 202*4882a593Smuzhiyun- return; 203*4882a593Smuzhiyun- } 204*4882a593Smuzhiyun+ if (!data || !data->ptr) 205*4882a593Smuzhiyun+ goto err; 206*4882a593Smuzhiyun 207*4882a593Smuzhiyun buffer->width = attributes->width; 208*4882a593Smuzhiyun buffer->height = attributes->height; 209*4882a593Smuzhiyun@@ -755,11 +873,7 @@ pixman_renderer_attach_dmabuf(struct weston_surface *es, 210*4882a593Smuzhiyun #endif 211*4882a593Smuzhiyun default: 212*4882a593Smuzhiyun weston_log("Unsupported dmabuf format\n"); 213*4882a593Smuzhiyun- weston_buffer_reference(&ps->buffer_ref, NULL, 214*4882a593Smuzhiyun- BUFFER_WILL_NOT_BE_ACCESSED); 215*4882a593Smuzhiyun- weston_buffer_release_reference(&ps->buffer_release_ref, 216*4882a593Smuzhiyun- NULL); 217*4882a593Smuzhiyun- return; 218*4882a593Smuzhiyun+ goto err; 219*4882a593Smuzhiyun break; 220*4882a593Smuzhiyun } 221*4882a593Smuzhiyun 222*4882a593Smuzhiyun@@ -772,6 +886,11 @@ pixman_renderer_attach_dmabuf(struct weston_surface *es, 223*4882a593Smuzhiyun buffer_state_handle_buffer_destroy; 224*4882a593Smuzhiyun wl_signal_add(&buffer->destroy_signal, 225*4882a593Smuzhiyun &ps->buffer_destroy_listener); 226*4882a593Smuzhiyun+ return; 227*4882a593Smuzhiyun+err: 228*4882a593Smuzhiyun+ weston_buffer_reference(&ps->buffer_ref, NULL, 229*4882a593Smuzhiyun+ BUFFER_WILL_NOT_BE_ACCESSED); 230*4882a593Smuzhiyun+ weston_buffer_release_reference(&ps->buffer_release_ref, NULL); 231*4882a593Smuzhiyun } 232*4882a593Smuzhiyun 233*4882a593Smuzhiyun static void 234*4882a593Smuzhiyun@@ -779,7 +898,6 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) 235*4882a593Smuzhiyun { 236*4882a593Smuzhiyun struct pixman_surface_state *ps = get_surface_state(es); 237*4882a593Smuzhiyun struct wl_shm_buffer *shm_buffer; 238*4882a593Smuzhiyun- struct linux_dmabuf_buffer *dmabuf; 239*4882a593Smuzhiyun const struct pixel_format_info *pixel_info; 240*4882a593Smuzhiyun 241*4882a593Smuzhiyun weston_buffer_reference(&ps->buffer_ref, buffer, 242*4882a593Smuzhiyun@@ -813,17 +931,40 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) 243*4882a593Smuzhiyun return; 244*4882a593Smuzhiyun } 245*4882a593Smuzhiyun 246*4882a593Smuzhiyun- if (buffer->type != WESTON_BUFFER_SHM) { 247*4882a593Smuzhiyun- if ((dmabuf = linux_dmabuf_buffer_get(buffer->resource))) { 248*4882a593Smuzhiyun- pixman_renderer_attach_dmabuf(es, buffer, dmabuf); 249*4882a593Smuzhiyun- } else { 250*4882a593Smuzhiyun- weston_log("unhandled buffer type!\n"); 251*4882a593Smuzhiyun- weston_buffer_reference(&ps->buffer_ref, NULL, 252*4882a593Smuzhiyun- BUFFER_WILL_NOT_BE_ACCESSED); 253*4882a593Smuzhiyun- weston_buffer_release_reference(&ps->buffer_release_ref, 254*4882a593Smuzhiyun- NULL); 255*4882a593Smuzhiyun- } 256*4882a593Smuzhiyun+ if (buffer->type == WESTON_BUFFER_DMABUF) { 257*4882a593Smuzhiyun+ struct linux_dmabuf_buffer *dmabuf = 258*4882a593Smuzhiyun+ linux_dmabuf_buffer_get(buffer->resource); 259*4882a593Smuzhiyun+ pixman_renderer_attach_dmabuf(es, buffer, dmabuf); 260*4882a593Smuzhiyun+ return; 261*4882a593Smuzhiyun+ } 262*4882a593Smuzhiyun+ 263*4882a593Smuzhiyun+#ifdef ENABLE_EGL 264*4882a593Smuzhiyun+ if (buffer->type == WESTON_BUFFER_RENDERER_OPAQUE) { 265*4882a593Smuzhiyun+ struct egl_buffer_info *info; 266*4882a593Smuzhiyun+ struct linux_dmabuf_buffer dmabuf = { 0 }; 267*4882a593Smuzhiyun+ struct dmabuf_attributes *attributes = &dmabuf.attributes; 268*4882a593Smuzhiyun+ 269*4882a593Smuzhiyun+ info = wl_resource_get_user_data(buffer->resource); 270*4882a593Smuzhiyun 271*4882a593Smuzhiyun+ attributes->format = buffer->pixel_format->format; 272*4882a593Smuzhiyun+ attributes->width = buffer->width; 273*4882a593Smuzhiyun+ attributes->height = buffer->height; 274*4882a593Smuzhiyun+ 275*4882a593Smuzhiyun+ attributes->n_planes = 1; 276*4882a593Smuzhiyun+ attributes->fd[0] = info->dma_fd; 277*4882a593Smuzhiyun+ attributes->stride[0] = info->stride; 278*4882a593Smuzhiyun+ 279*4882a593Smuzhiyun+ pixman_renderer_attach_dmabuf(es, buffer, &dmabuf); 280*4882a593Smuzhiyun+ return; 281*4882a593Smuzhiyun+ } 282*4882a593Smuzhiyun+#endif 283*4882a593Smuzhiyun+ 284*4882a593Smuzhiyun+ if (buffer->type != WESTON_BUFFER_SHM) { 285*4882a593Smuzhiyun+ weston_log("unhandled buffer type!\n"); 286*4882a593Smuzhiyun+ weston_buffer_reference(&ps->buffer_ref, NULL, 287*4882a593Smuzhiyun+ BUFFER_WILL_NOT_BE_ACCESSED); 288*4882a593Smuzhiyun+ weston_buffer_release_reference(&ps->buffer_release_ref, 289*4882a593Smuzhiyun+ NULL); 290*4882a593Smuzhiyun return; 291*4882a593Smuzhiyun } 292*4882a593Smuzhiyun 293*4882a593Smuzhiyun@@ -852,6 +993,70 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) 294*4882a593Smuzhiyun &ps->buffer_destroy_listener); 295*4882a593Smuzhiyun } 296*4882a593Smuzhiyun 297*4882a593Smuzhiyun+#ifdef ENABLE_EGL 298*4882a593Smuzhiyun+static bool 299*4882a593Smuzhiyun+pixman_renderer_fill_buffer_info(struct weston_compositor *ec, 300*4882a593Smuzhiyun+ struct weston_buffer *buffer) 301*4882a593Smuzhiyun+{ 302*4882a593Smuzhiyun+ struct pixman_renderer *pr = get_renderer(ec); 303*4882a593Smuzhiyun+ struct egl_buffer_info *info; 304*4882a593Smuzhiyun+ struct stat s; 305*4882a593Smuzhiyun+ EGLint format; 306*4882a593Smuzhiyun+ uint32_t fourcc; 307*4882a593Smuzhiyun+ EGLint y_inverted; 308*4882a593Smuzhiyun+ bool ret = true; 309*4882a593Smuzhiyun+ 310*4882a593Smuzhiyun+ if (!pr->egl_inited) 311*4882a593Smuzhiyun+ return false; 312*4882a593Smuzhiyun+ 313*4882a593Smuzhiyun+ info = wl_resource_get_user_data(buffer->resource); 314*4882a593Smuzhiyun+ if (!info) 315*4882a593Smuzhiyun+ return false; 316*4882a593Smuzhiyun+ 317*4882a593Smuzhiyun+ buffer->legacy_buffer = (struct wl_buffer *)buffer->resource; 318*4882a593Smuzhiyun+ ret &= pr->query_buffer(pr->egl_display, buffer->legacy_buffer, 319*4882a593Smuzhiyun+ EGL_WIDTH, &buffer->width); 320*4882a593Smuzhiyun+ ret &= pr->query_buffer(pr->egl_display, buffer->legacy_buffer, 321*4882a593Smuzhiyun+ EGL_HEIGHT, &buffer->height); 322*4882a593Smuzhiyun+ ret &= pr->query_buffer(pr->egl_display, buffer->legacy_buffer, 323*4882a593Smuzhiyun+ EGL_TEXTURE_FORMAT, &format); 324*4882a593Smuzhiyun+ if (!ret) { 325*4882a593Smuzhiyun+ weston_log("eglQueryWaylandBufferWL failed\n"); 326*4882a593Smuzhiyun+ return false; 327*4882a593Smuzhiyun+ } 328*4882a593Smuzhiyun+ 329*4882a593Smuzhiyun+ if (fstat(info->dma_fd, &s) < 0 || 330*4882a593Smuzhiyun+ info->width != buffer->width || info->height != buffer->height) 331*4882a593Smuzhiyun+ return false; 332*4882a593Smuzhiyun+ 333*4882a593Smuzhiyun+ switch (format) { 334*4882a593Smuzhiyun+ case EGL_TEXTURE_RGB: 335*4882a593Smuzhiyun+ fourcc = DRM_FORMAT_XRGB8888; 336*4882a593Smuzhiyun+ break; 337*4882a593Smuzhiyun+ case EGL_TEXTURE_RGBA: 338*4882a593Smuzhiyun+ fourcc = DRM_FORMAT_ARGB8888; 339*4882a593Smuzhiyun+ break; 340*4882a593Smuzhiyun+ default: 341*4882a593Smuzhiyun+ return false; 342*4882a593Smuzhiyun+ } 343*4882a593Smuzhiyun+ 344*4882a593Smuzhiyun+ buffer->pixel_format = pixel_format_get_info(fourcc); 345*4882a593Smuzhiyun+ assert(buffer->pixel_format); 346*4882a593Smuzhiyun+ buffer->format_modifier = DRM_FORMAT_MOD_INVALID; 347*4882a593Smuzhiyun+ 348*4882a593Smuzhiyun+ /* Assume scanout co-ordinate space i.e. (0,0) is top-left 349*4882a593Smuzhiyun+ * if the query fails */ 350*4882a593Smuzhiyun+ ret = pr->query_buffer(pr->egl_display, buffer->legacy_buffer, 351*4882a593Smuzhiyun+ EGL_WAYLAND_Y_INVERTED_WL, &y_inverted); 352*4882a593Smuzhiyun+ if (!ret || y_inverted) 353*4882a593Smuzhiyun+ buffer->buffer_origin = ORIGIN_TOP_LEFT; 354*4882a593Smuzhiyun+ else 355*4882a593Smuzhiyun+ buffer->buffer_origin = ORIGIN_BOTTOM_LEFT; 356*4882a593Smuzhiyun+ 357*4882a593Smuzhiyun+ return true; 358*4882a593Smuzhiyun+} 359*4882a593Smuzhiyun+#endif 360*4882a593Smuzhiyun+ 361*4882a593Smuzhiyun static void 362*4882a593Smuzhiyun pixman_renderer_surface_state_destroy(struct pixman_surface_state *ps) 363*4882a593Smuzhiyun { 364*4882a593Smuzhiyun@@ -931,6 +1136,21 @@ pixman_renderer_destroy(struct weston_compositor *ec) 365*4882a593Smuzhiyun { 366*4882a593Smuzhiyun struct pixman_renderer *pr = get_renderer(ec); 367*4882a593Smuzhiyun 368*4882a593Smuzhiyun+#ifdef ENABLE_EGL 369*4882a593Smuzhiyun+ if (pr->egl_inited) { 370*4882a593Smuzhiyun+ if (pr->unbind_display) 371*4882a593Smuzhiyun+ pr->unbind_display(pr->egl_display, ec->wl_display); 372*4882a593Smuzhiyun+ 373*4882a593Smuzhiyun+ eglTerminate(pr->egl_display); 374*4882a593Smuzhiyun+ eglReleaseThread(); 375*4882a593Smuzhiyun+ 376*4882a593Smuzhiyun+ if (pr->gbm) 377*4882a593Smuzhiyun+ gbm_device_destroy(pr->gbm); 378*4882a593Smuzhiyun+ 379*4882a593Smuzhiyun+ close(pr->drm_fd); 380*4882a593Smuzhiyun+ } 381*4882a593Smuzhiyun+#endif 382*4882a593Smuzhiyun+ 383*4882a593Smuzhiyun wl_signal_emit(&pr->destroy_signal, pr); 384*4882a593Smuzhiyun weston_binding_destroy(pr->debug_binding); 385*4882a593Smuzhiyun 386*4882a593Smuzhiyun@@ -994,80 +1214,11 @@ debug_binding(struct weston_keyboard *keyboard, const struct timespec *time, 387*4882a593Smuzhiyun } 388*4882a593Smuzhiyun } 389*4882a593Smuzhiyun 390*4882a593Smuzhiyun-static void 391*4882a593Smuzhiyun-pixman_renderer_destroy_dmabuf(struct linux_dmabuf_buffer *dmabuf) 392*4882a593Smuzhiyun-{ 393*4882a593Smuzhiyun- struct dmabuf_data *data = dmabuf->user_data; 394*4882a593Smuzhiyun- linux_dmabuf_buffer_set_user_data(dmabuf, NULL, NULL); 395*4882a593Smuzhiyun- 396*4882a593Smuzhiyun- if (data) { 397*4882a593Smuzhiyun- if (data->ptr) 398*4882a593Smuzhiyun- munmap(data->ptr, data->size); 399*4882a593Smuzhiyun- 400*4882a593Smuzhiyun- free(data); 401*4882a593Smuzhiyun- } 402*4882a593Smuzhiyun-} 403*4882a593Smuzhiyun- 404*4882a593Smuzhiyun static bool 405*4882a593Smuzhiyun pixman_renderer_import_dmabuf(struct weston_compositor *ec, 406*4882a593Smuzhiyun struct linux_dmabuf_buffer *dmabuf) 407*4882a593Smuzhiyun { 408*4882a593Smuzhiyun- struct dmabuf_attributes *attributes = &dmabuf->attributes; 409*4882a593Smuzhiyun- struct dmabuf_data *data; 410*4882a593Smuzhiyun- size_t total_size, vstride0; 411*4882a593Smuzhiyun- int i; 412*4882a593Smuzhiyun- 413*4882a593Smuzhiyun- for (i = 0; i < attributes->n_planes; i++) { 414*4882a593Smuzhiyun- if (attributes->modifier[i] != DRM_FORMAT_MOD_INVALID && 415*4882a593Smuzhiyun- attributes->modifier[i] != DRM_FORMAT_MOD_LINEAR) 416*4882a593Smuzhiyun- return false; 417*4882a593Smuzhiyun- } 418*4882a593Smuzhiyun- 419*4882a593Smuzhiyun- /* reject all flags we do not recognize or handle */ 420*4882a593Smuzhiyun- if (attributes->flags & ~ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT) 421*4882a593Smuzhiyun- return false; 422*4882a593Smuzhiyun- 423*4882a593Smuzhiyun- if (attributes->n_planes < 0) 424*4882a593Smuzhiyun- return false; 425*4882a593Smuzhiyun- 426*4882a593Smuzhiyun- if (attributes->n_planes == 1) 427*4882a593Smuzhiyun- goto out; 428*4882a593Smuzhiyun- 429*4882a593Smuzhiyun- total_size = lseek(attributes->fd[0], 0, SEEK_END); 430*4882a593Smuzhiyun- vstride0 = (attributes->offset[1] - attributes->offset[0]) / 431*4882a593Smuzhiyun- attributes->stride[0]; 432*4882a593Smuzhiyun- 433*4882a593Smuzhiyun- for (i = 1; i < attributes->n_planes; i++) { 434*4882a593Smuzhiyun- size_t size = attributes->offset[i] - attributes->offset[i - 1]; 435*4882a593Smuzhiyun- size_t vstride = size / attributes->stride[i - 1]; 436*4882a593Smuzhiyun- 437*4882a593Smuzhiyun- /* not contig */ 438*4882a593Smuzhiyun- if (size <= 0 || vstride <= 0 || 439*4882a593Smuzhiyun- attributes->offset[i - 1] + size > total_size) 440*4882a593Smuzhiyun- return false; 441*4882a593Smuzhiyun- 442*4882a593Smuzhiyun- /* stride unmatched */ 443*4882a593Smuzhiyun- if ((vstride != vstride0 && vstride != vstride0 / 2) || 444*4882a593Smuzhiyun- (attributes->stride[i] != attributes->stride[0] && 445*4882a593Smuzhiyun- attributes->stride[i] != attributes->stride[0] / 2)) 446*4882a593Smuzhiyun- return false; 447*4882a593Smuzhiyun- } 448*4882a593Smuzhiyun- 449*4882a593Smuzhiyun-out: 450*4882a593Smuzhiyun- /* Handle contig dma buffer */ 451*4882a593Smuzhiyun- 452*4882a593Smuzhiyun- data = zalloc(sizeof *data); 453*4882a593Smuzhiyun- if (!data) 454*4882a593Smuzhiyun- return false; 455*4882a593Smuzhiyun- 456*4882a593Smuzhiyun- linux_dmabuf_buffer_set_user_data(dmabuf, data, 457*4882a593Smuzhiyun- pixman_renderer_destroy_dmabuf); 458*4882a593Smuzhiyun- 459*4882a593Smuzhiyun- data->size = lseek(attributes->fd[0], 0, SEEK_END); 460*4882a593Smuzhiyun- 461*4882a593Smuzhiyun- data->ptr = mmap(NULL, data->size, PROT_READ, 462*4882a593Smuzhiyun- MAP_SHARED, attributes->fd[0], 0); 463*4882a593Smuzhiyun- return data->ptr != MAP_FAILED; 464*4882a593Smuzhiyun+ return pixman_renderer_prepare_dmabuf(dmabuf); 465*4882a593Smuzhiyun } 466*4882a593Smuzhiyun 467*4882a593Smuzhiyun static const struct weston_drm_format_array * 468*4882a593Smuzhiyun@@ -1123,6 +1274,89 @@ out: 469*4882a593Smuzhiyun return ret; 470*4882a593Smuzhiyun } 471*4882a593Smuzhiyun 472*4882a593Smuzhiyun+#ifdef ENABLE_EGL 473*4882a593Smuzhiyun+static bool 474*4882a593Smuzhiyun+pixman_renderer_init_egl(struct pixman_renderer *pr, 475*4882a593Smuzhiyun+ struct weston_compositor *ec) 476*4882a593Smuzhiyun+{ 477*4882a593Smuzhiyun+ PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display; 478*4882a593Smuzhiyun+ const char *extensions; 479*4882a593Smuzhiyun+ 480*4882a593Smuzhiyun+ get_platform_display = 481*4882a593Smuzhiyun+ (void *) eglGetProcAddress("eglGetPlatformDisplayEXT"); 482*4882a593Smuzhiyun+ pr->query_buffer = 483*4882a593Smuzhiyun+ (void *) eglGetProcAddress("eglQueryWaylandBufferWL"); 484*4882a593Smuzhiyun+ pr->bind_display = 485*4882a593Smuzhiyun+ (void *) eglGetProcAddress("eglBindWaylandDisplayWL"); 486*4882a593Smuzhiyun+ pr->unbind_display = 487*4882a593Smuzhiyun+ (void *) eglGetProcAddress("eglUnbindWaylandDisplayWL"); 488*4882a593Smuzhiyun+ 489*4882a593Smuzhiyun+ if (!get_platform_display || !pr->query_buffer || 490*4882a593Smuzhiyun+ !pr->bind_display || !pr->unbind_display) { 491*4882a593Smuzhiyun+ weston_log("Failed to get egl proc\n"); 492*4882a593Smuzhiyun+ return false; 493*4882a593Smuzhiyun+ } 494*4882a593Smuzhiyun+ 495*4882a593Smuzhiyun+ pr->drm_fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC); 496*4882a593Smuzhiyun+ if (pr->drm_fd < 0) { 497*4882a593Smuzhiyun+ weston_log("Failed to open drm dev\n"); 498*4882a593Smuzhiyun+ return false; 499*4882a593Smuzhiyun+ } 500*4882a593Smuzhiyun+ 501*4882a593Smuzhiyun+ pr->gbm = gbm_create_device(pr->drm_fd); 502*4882a593Smuzhiyun+ if (!pr->gbm) { 503*4882a593Smuzhiyun+ weston_log("Failed to create gbm device\n"); 504*4882a593Smuzhiyun+ goto err_close_fd; 505*4882a593Smuzhiyun+ } 506*4882a593Smuzhiyun+ 507*4882a593Smuzhiyun+ pr->egl_display = get_platform_display(EGL_PLATFORM_GBM_KHR, 508*4882a593Smuzhiyun+ (void*) pr->gbm, NULL); 509*4882a593Smuzhiyun+ if (pr->egl_display == EGL_NO_DISPLAY) { 510*4882a593Smuzhiyun+ weston_log("Failed to create egl display\n"); 511*4882a593Smuzhiyun+ goto err_destroy_gbm; 512*4882a593Smuzhiyun+ } 513*4882a593Smuzhiyun+ 514*4882a593Smuzhiyun+ if (!eglInitialize(pr->egl_display, NULL, NULL)) { 515*4882a593Smuzhiyun+ weston_log("Failed to initialize egl\n"); 516*4882a593Smuzhiyun+ goto err_terminate_display; 517*4882a593Smuzhiyun+ } 518*4882a593Smuzhiyun+ 519*4882a593Smuzhiyun+ extensions = 520*4882a593Smuzhiyun+ (const char *) eglQueryString(pr->egl_display, EGL_EXTENSIONS); 521*4882a593Smuzhiyun+ if (!extensions) { 522*4882a593Smuzhiyun+ weston_log("Retrieving EGL extension string failed.\n"); 523*4882a593Smuzhiyun+ goto err_terminate_display; 524*4882a593Smuzhiyun+ } 525*4882a593Smuzhiyun+ 526*4882a593Smuzhiyun+ if (!weston_check_egl_extension(extensions, 527*4882a593Smuzhiyun+ "EGL_WL_bind_wayland_display")) { 528*4882a593Smuzhiyun+ weston_log("Wayland extension not supported.\n"); 529*4882a593Smuzhiyun+ goto err_terminate_display; 530*4882a593Smuzhiyun+ } 531*4882a593Smuzhiyun+ 532*4882a593Smuzhiyun+ if (!eglBindAPI(EGL_OPENGL_ES_API)) { 533*4882a593Smuzhiyun+ weston_log("Failed to bind api\n"); 534*4882a593Smuzhiyun+ goto err_terminate_display; 535*4882a593Smuzhiyun+ } 536*4882a593Smuzhiyun+ 537*4882a593Smuzhiyun+ if (!pr->bind_display(pr->egl_display, ec->wl_display)) 538*4882a593Smuzhiyun+ goto err_terminate_display; 539*4882a593Smuzhiyun+ 540*4882a593Smuzhiyun+ pr->egl_inited = true; 541*4882a593Smuzhiyun+ return true; 542*4882a593Smuzhiyun+ 543*4882a593Smuzhiyun+err_terminate_display: 544*4882a593Smuzhiyun+ eglTerminate(pr->egl_display); 545*4882a593Smuzhiyun+err_destroy_gbm: 546*4882a593Smuzhiyun+ gbm_device_destroy(pr->gbm); 547*4882a593Smuzhiyun+ pr->gbm = NULL; 548*4882a593Smuzhiyun+err_close_fd: 549*4882a593Smuzhiyun+ close(pr->drm_fd); 550*4882a593Smuzhiyun+ pr->drm_fd = -1; 551*4882a593Smuzhiyun+ return false; 552*4882a593Smuzhiyun+} 553*4882a593Smuzhiyun+#endif 554*4882a593Smuzhiyun+ 555*4882a593Smuzhiyun WL_EXPORT int 556*4882a593Smuzhiyun pixman_renderer_init(struct weston_compositor *ec) 557*4882a593Smuzhiyun { 558*4882a593Smuzhiyun@@ -1144,6 +1378,9 @@ pixman_renderer_init(struct weston_compositor *ec) 559*4882a593Smuzhiyun renderer->base.destroy = pixman_renderer_destroy; 560*4882a593Smuzhiyun renderer->base.surface_copy_content = 561*4882a593Smuzhiyun pixman_renderer_surface_copy_content; 562*4882a593Smuzhiyun+#ifdef ENABLE_EGL 563*4882a593Smuzhiyun+ renderer->base.fill_buffer_info = pixman_renderer_fill_buffer_info; 564*4882a593Smuzhiyun+#endif 565*4882a593Smuzhiyun ec->renderer = &renderer->base; 566*4882a593Smuzhiyun ec->capabilities |= WESTON_CAP_ROTATION_ANY; 567*4882a593Smuzhiyun ec->capabilities |= WESTON_CAP_VIEW_CLIP_MASK; 568*4882a593Smuzhiyun@@ -1184,6 +1421,10 @@ pixman_renderer_init(struct weston_compositor *ec) 569*4882a593Smuzhiyun renderer->base.get_supported_formats = 570*4882a593Smuzhiyun pixman_renderer_get_supported_formats; 571*4882a593Smuzhiyun 572*4882a593Smuzhiyun+#ifdef ENABLE_EGL 573*4882a593Smuzhiyun+ pixman_renderer_init_egl(renderer, ec); 574*4882a593Smuzhiyun+#endif 575*4882a593Smuzhiyun+ 576*4882a593Smuzhiyun return 0; 577*4882a593Smuzhiyun } 578*4882a593Smuzhiyun 579*4882a593Smuzhiyun-- 580*4882a593Smuzhiyun2.20.1 581*4882a593Smuzhiyun 582