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