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