diff options
-rw-r--r-- | src/lib/efl_wl/dmabuf.c | 110 | ||||
-rw-r--r-- | src/lib/efl_wl/dmabuf.h | 3 | ||||
-rw-r--r-- | src/lib/efl_wl/efl_wl.c | 12 |
3 files changed, 108 insertions, 17 deletions
diff --git a/src/lib/efl_wl/dmabuf.c b/src/lib/efl_wl/dmabuf.c index a451179d53..273d141b05 100644 --- a/src/lib/efl_wl/dmabuf.c +++ b/src/lib/efl_wl/dmabuf.c | |||
@@ -43,6 +43,8 @@ | |||
43 | #include <Eina.h> | 43 | #include <Eina.h> |
44 | 44 | ||
45 | __attribute__ ((visibility("hidden"))) Eina_Bool comp_dmabuf_test(struct linux_dmabuf_buffer *dmabuf); | 45 | __attribute__ ((visibility("hidden"))) Eina_Bool comp_dmabuf_test(struct linux_dmabuf_buffer *dmabuf); |
46 | __attribute__ ((visibility("hidden"))) void comp_dmabuf_formats_query(void *c, int **formats, int *num_formats); | ||
47 | __attribute__ ((visibility("hidden"))) void comp_dmabuf_modifiers_query(void *c, int format, uint64_t **modifiers, int *num_modifiers); | ||
46 | 48 | ||
47 | static void | 49 | static void |
48 | linux_dmabuf_buffer_destroy(struct linux_dmabuf_buffer *buffer) | 50 | linux_dmabuf_buffer_destroy(struct linux_dmabuf_buffer *buffer) |
@@ -55,7 +57,6 @@ linux_dmabuf_buffer_destroy(struct linux_dmabuf_buffer *buffer) | |||
55 | } | 57 | } |
56 | 58 | ||
57 | buffer->attributes.n_planes = 0; | 59 | buffer->attributes.n_planes = 0; |
58 | |||
59 | free(buffer); | 60 | free(buffer); |
60 | } | 61 | } |
61 | 62 | ||
@@ -123,7 +124,7 @@ params_add(struct wl_client *client, | |||
123 | buffer->attributes.offset[plane_idx] = offset; | 124 | buffer->attributes.offset[plane_idx] = offset; |
124 | buffer->attributes.stride[plane_idx] = stride; | 125 | buffer->attributes.stride[plane_idx] = stride; |
125 | buffer->attributes.modifier[plane_idx] = ((uint64_t)modifier_hi << 32) | | 126 | buffer->attributes.modifier[plane_idx] = ((uint64_t)modifier_hi << 32) | |
126 | modifier_lo; | 127 | modifier_lo; |
127 | buffer->attributes.n_planes++; | 128 | buffer->attributes.n_planes++; |
128 | } | 129 | } |
129 | 130 | ||
@@ -154,12 +155,13 @@ destroy_linux_dmabuf_wl_buffer(struct wl_resource *resource) | |||
154 | } | 155 | } |
155 | 156 | ||
156 | static void | 157 | static void |
157 | params_create(struct wl_client *client, | 158 | params_create_common(struct wl_client *client, |
158 | struct wl_resource *params_resource, | 159 | struct wl_resource *params_resource, |
159 | int32_t width, | 160 | uint32_t buffer_id, |
160 | int32_t height, | 161 | int32_t width, |
161 | uint32_t format, | 162 | int32_t height, |
162 | uint32_t flags) | 163 | uint32_t format, |
164 | uint32_t flags) | ||
163 | { | 165 | { |
164 | struct linux_dmabuf_buffer *buffer; | 166 | struct linux_dmabuf_buffer *buffer; |
165 | int i; | 167 | int i; |
@@ -275,7 +277,7 @@ params_create(struct wl_client *client, | |||
275 | 277 | ||
276 | buffer->buffer_resource = wl_resource_create(client, | 278 | buffer->buffer_resource = wl_resource_create(client, |
277 | &wl_buffer_interface, | 279 | &wl_buffer_interface, |
278 | 1, 0); | 280 | 1, buffer_id); |
279 | if (!buffer->buffer_resource) { | 281 | if (!buffer->buffer_resource) { |
280 | wl_resource_post_no_memory(params_resource); | 282 | wl_resource_post_no_memory(params_resource); |
281 | goto err_buffer; | 283 | goto err_buffer; |
@@ -285,7 +287,10 @@ params_create(struct wl_client *client, | |||
285 | &linux_dmabuf_buffer_implementation, | 287 | &linux_dmabuf_buffer_implementation, |
286 | buffer, destroy_linux_dmabuf_wl_buffer); | 288 | buffer, destroy_linux_dmabuf_wl_buffer); |
287 | 289 | ||
288 | zwp_linux_buffer_params_v1_send_created(params_resource, | 290 | /* send 'created' event when the request is not for an immediate |
291 | * import, ie buffer_id is zero */ | ||
292 | if (buffer_id == 0) | ||
293 | zwp_linux_buffer_params_v1_send_created(params_resource, | ||
289 | buffer->buffer_resource); | 294 | buffer->buffer_resource); |
290 | 295 | ||
291 | return; | 296 | return; |
@@ -295,17 +300,54 @@ err_buffer: | |||
295 | buffer->user_data_destroy_func(buffer); | 300 | buffer->user_data_destroy_func(buffer); |
296 | 301 | ||
297 | err_failed: | 302 | err_failed: |
298 | zwp_linux_buffer_params_v1_send_failed(params_resource); | 303 | if (buffer_id == 0) |
304 | zwp_linux_buffer_params_v1_send_failed(params_resource); | ||
305 | else | ||
306 | /* since the behavior is left implementation defined by the | ||
307 | * protocol in case of create_immed failure due to an unknown cause, | ||
308 | * we choose to treat it as a fatal error and immediately kill the | ||
309 | * client instead of creating an invalid handle and waiting for it | ||
310 | * to be used. | ||
311 | */ | ||
312 | wl_resource_post_error(params_resource, | ||
313 | ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_INVALID_WL_BUFFER, | ||
314 | "importing the supplied dmabufs failed"); | ||
299 | 315 | ||
300 | err_out: | 316 | err_out: |
301 | linux_dmabuf_buffer_destroy(buffer); | 317 | linux_dmabuf_buffer_destroy(buffer); |
302 | } | 318 | } |
303 | 319 | ||
320 | static void | ||
321 | params_create(struct wl_client *client, | ||
322 | struct wl_resource *params_resource, | ||
323 | int32_t width, | ||
324 | int32_t height, | ||
325 | uint32_t format, | ||
326 | uint32_t flags) | ||
327 | { | ||
328 | params_create_common(client, params_resource, 0, width, height, format, | ||
329 | flags); | ||
330 | } | ||
331 | |||
332 | static void | ||
333 | params_create_immed(struct wl_client *client, | ||
334 | struct wl_resource *params_resource, | ||
335 | uint32_t buffer_id, | ||
336 | int32_t width, | ||
337 | int32_t height, | ||
338 | uint32_t format, | ||
339 | uint32_t flags) | ||
340 | { | ||
341 | params_create_common(client, params_resource, buffer_id, width, height, | ||
342 | format, flags); | ||
343 | } | ||
344 | |||
304 | static const struct zwp_linux_buffer_params_v1_interface | 345 | static const struct zwp_linux_buffer_params_v1_interface |
305 | zwp_linux_buffer_params_implementation = { | 346 | zwp_linux_buffer_params_implementation = { |
306 | params_destroy, | 347 | params_destroy, |
307 | params_add, | 348 | params_add, |
308 | params_create | 349 | params_create, |
350 | params_create_immed | ||
309 | }; | 351 | }; |
310 | 352 | ||
311 | static void | 353 | static void |
@@ -438,6 +480,11 @@ bind_linux_dmabuf(struct wl_client *client, | |||
438 | { | 480 | { |
439 | void *compositor = data; | 481 | void *compositor = data; |
440 | struct wl_resource *resource; | 482 | struct wl_resource *resource; |
483 | int *formats = NULL; | ||
484 | uint64_t *modifiers = NULL; | ||
485 | int num_formats, num_modifiers; | ||
486 | uint64_t modifier_invalid = DRM_FORMAT_MOD_INVALID; | ||
487 | int i, j; | ||
441 | 488 | ||
442 | resource = wl_resource_create(client, &zwp_linux_dmabuf_v1_interface, | 489 | resource = wl_resource_create(client, &zwp_linux_dmabuf_v1_interface, |
443 | version, id); | 490 | version, id); |
@@ -449,9 +496,38 @@ bind_linux_dmabuf(struct wl_client *client, | |||
449 | wl_resource_set_implementation(resource, &linux_dmabuf_implementation, | 496 | wl_resource_set_implementation(resource, &linux_dmabuf_implementation, |
450 | compositor, NULL); | 497 | compositor, NULL); |
451 | 498 | ||
452 | /* EGL_EXT_image_dma_buf_import does not provide a way to query the | 499 | if (version < ZWP_LINUX_DMABUF_V1_MODIFIER_SINCE_VERSION) |
453 | * supported pixel formats. */ | 500 | return; |
454 | /* XXX: send formats */ | 501 | /* |
502 | * Use EGL_EXT_image_dma_buf_import_modifiers to query and advertise | ||
503 | * format/modifier codes. | ||
504 | */ | ||
505 | comp_dmabuf_formats_query(compositor, &formats, | ||
506 | &num_formats); | ||
507 | |||
508 | for (i = 0; i < num_formats; i++) { | ||
509 | comp_dmabuf_modifiers_query(compositor, | ||
510 | formats[i], | ||
511 | &modifiers, | ||
512 | &num_modifiers); | ||
513 | |||
514 | /* send DRM_FORMAT_MOD_INVALID token when no modifiers are supported | ||
515 | * for this format */ | ||
516 | if (num_modifiers == 0) { | ||
517 | num_modifiers = 1; | ||
518 | modifiers = &modifier_invalid; | ||
519 | } | ||
520 | for (j = 0; j < num_modifiers; j++) { | ||
521 | uint32_t modifier_lo = modifiers[j] & 0xFFFFFFFF; | ||
522 | uint32_t modifier_hi = modifiers[j] >> 32; | ||
523 | zwp_linux_dmabuf_v1_send_modifier(resource, formats[i], | ||
524 | modifier_hi, | ||
525 | modifier_lo); | ||
526 | } | ||
527 | if (modifiers != &modifier_invalid) | ||
528 | free(modifiers); | ||
529 | } | ||
530 | free(formats); | ||
455 | } | 531 | } |
456 | 532 | ||
457 | /** Advertise linux_dmabuf support | 533 | /** Advertise linux_dmabuf support |
@@ -469,7 +545,7 @@ int | |||
469 | linux_dmabuf_setup(struct wl_display *display, void *comp) | 545 | linux_dmabuf_setup(struct wl_display *display, void *comp) |
470 | { | 546 | { |
471 | if (!wl_global_create(display, | 547 | if (!wl_global_create(display, |
472 | &zwp_linux_dmabuf_v1_interface, 1, | 548 | &zwp_linux_dmabuf_v1_interface, 3, |
473 | comp, bind_linux_dmabuf)) | 549 | comp, bind_linux_dmabuf)) |
474 | return -1; | 550 | return -1; |
475 | 551 | ||
@@ -487,7 +563,7 @@ linux_dmabuf_setup(struct wl_display *display, void *comp) | |||
487 | * In any case, the options are to either composite garbage or nothing, | 563 | * In any case, the options are to either composite garbage or nothing, |
488 | * or disconnect the client. This is a helper function for the latter. | 564 | * or disconnect the client. This is a helper function for the latter. |
489 | * | 565 | * |
490 | * The error is sent as a INVALID_OBJECT error on the client's wl_display. | 566 | * The error is sent as an INVALID_OBJECT error on the client's wl_display. |
491 | * | 567 | * |
492 | * \param buffer The linux_dmabuf_buffer that is unusable. | 568 | * \param buffer The linux_dmabuf_buffer that is unusable. |
493 | * \param msg A custom error message attached to the protocol error. | 569 | * \param msg A custom error message attached to the protocol error. |
diff --git a/src/lib/efl_wl/dmabuf.h b/src/lib/efl_wl/dmabuf.h index c1da1e3abf..72f42816a3 100644 --- a/src/lib/efl_wl/dmabuf.h +++ b/src/lib/efl_wl/dmabuf.h | |||
@@ -29,6 +29,9 @@ | |||
29 | #include <stdint.h> | 29 | #include <stdint.h> |
30 | 30 | ||
31 | #define MAX_DMABUF_PLANES 4 | 31 | #define MAX_DMABUF_PLANES 4 |
32 | #ifndef DRM_FORMAT_MOD_INVALID | ||
33 | #define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1) | ||
34 | #endif | ||
32 | 35 | ||
33 | struct linux_dmabuf_buffer; | 36 | struct linux_dmabuf_buffer; |
34 | typedef void (*dmabuf_user_data_destroy_func)( | 37 | typedef void (*dmabuf_user_data_destroy_func)( |
diff --git a/src/lib/efl_wl/efl_wl.c b/src/lib/efl_wl/efl_wl.c index 9a02d0a4e3..069e4ed0c2 100644 --- a/src/lib/efl_wl/efl_wl.c +++ b/src/lib/efl_wl/efl_wl.c | |||
@@ -5262,6 +5262,18 @@ comp_dmabuf_test(struct linux_dmabuf_buffer *dmabuf) | |||
5262 | return EINA_TRUE; | 5262 | return EINA_TRUE; |
5263 | } | 5263 | } |
5264 | 5264 | ||
5265 | void | ||
5266 | comp_dmabuf_formats_query(void *compositor EINA_UNUSED, int **formats EINA_UNUSED, int *num_formats) | ||
5267 | { | ||
5268 | *num_formats = 0; | ||
5269 | } | ||
5270 | |||
5271 | void | ||
5272 | comp_dmabuf_modifiers_query(void *compositor EINA_UNUSED, int format EINA_UNUSED, uint64_t **modifiers EINA_UNUSED, int *num_modifiers) | ||
5273 | { | ||
5274 | *num_modifiers = 0; | ||
5275 | } | ||
5276 | |||
5265 | Evas_Object * | 5277 | Evas_Object * |
5266 | efl_wl_add(Evas *e) | 5278 | efl_wl_add(Evas *e) |
5267 | { | 5279 | { |