summaryrefslogtreecommitdiff
path: root/src/lib/ecore_wl2/ecore_wl2_buffer.c
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2017-11-21 16:29:55 -0600
committerDerek Foreman <derekf@osg.samsung.com>2017-11-21 16:31:23 -0600
commitcf605549c5773d6b90c3e664799845186ef0e603 (patch)
treebdd9270384142da9e59ac3c01357862797788703 /src/lib/ecore_wl2/ecore_wl2_buffer.c
parent78664198bd3509a8eb36cb26f2b9655d4d89d840 (diff)
ecore_wl2: Add dmabuf allocations for vc4
This should theoretically be better for software rendering on rpi3 since it allows the compositor to use our sw rendered buffers as a texture.
Diffstat (limited to 'src/lib/ecore_wl2/ecore_wl2_buffer.c')
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_buffer.c138
1 files changed, 137 insertions, 1 deletions
diff --git a/src/lib/ecore_wl2/ecore_wl2_buffer.c b/src/lib/ecore_wl2/ecore_wl2_buffer.c
index 8c4b0ff39e..a8e5bec5cb 100644
--- a/src/lib/ecore_wl2/ecore_wl2_buffer.c
+++ b/src/lib/ecore_wl2/ecore_wl2_buffer.c
@@ -11,10 +11,11 @@
11#include <drm_fourcc.h> 11#include <drm_fourcc.h>
12#include <intel_bufmgr.h> 12#include <intel_bufmgr.h>
13#include <i915_drm.h> 13#include <i915_drm.h>
14 14#include <vc4_drm.h>
15#include <exynos_drm.h> 15#include <exynos_drm.h>
16#include <exynos_drmif.h> 16#include <exynos_drmif.h>
17#include <sys/mman.h> 17#include <sys/mman.h>
18#include <sys/ioctl.h>
18 19
19#include "linux-dmabuf-unstable-v1-client-protocol.h" 20#include "linux-dmabuf-unstable-v1-client-protocol.h"
20 21
@@ -397,6 +398,140 @@ _wl_shm_buffer_manager_setup(int fd EINA_UNUSED)
397 return EINA_TRUE; 398 return EINA_TRUE;
398} 399}
399 400
401struct internal_vc4_bo
402{
403 __u32 handle;
404 int size;
405 int fd;
406};
407
408static int
409align(int v, int a)
410{
411 return (v + a - 1) & ~((uint64_t)a - 1);
412}
413
414static Buffer_Handle *
415_vc4_alloc(Buffer_Manager *self EINA_UNUSED, const char *name EINA_UNUSED, int w, int h, unsigned long *stride, int32_t *fd)
416{
417 struct drm_vc4_create_bo bo;
418 struct internal_vc4_bo *obo;
419 struct drm_gem_close cl;
420 size_t size;
421 int ret;
422
423 obo = malloc(sizeof(struct internal_vc4_bo));
424 if (!obo) return NULL;
425
426 *stride = align(w * 4, 16);
427 size = *stride * h;
428 memset(&bo, 0, sizeof(bo));
429 bo.size = size;
430 ret = ioctl(drm_fd, DRM_IOCTL_VC4_CREATE_BO, &bo);
431 if (ret) return NULL;
432 obo->handle = bo.handle;
433 obo->size = size;
434 /* First try to allocate an mmapable buffer with O_RDWR,
435 * if that fails retry unmappable - if the compositor is
436 * using GL it won't need to mmap the buffer and this can
437 * work - otherwise it'll reject this buffer and we'll
438 * have to fall back to shm rendering.
439 */
440 if (sym_drmPrimeHandleToFD(drm_fd, bo.handle,
441 DRM_CLOEXEC | O_RDWR, fd) != 0)
442 if (sym_drmPrimeHandleToFD(drm_fd, bo.handle,
443 DRM_CLOEXEC, fd) != 0) goto err;
444
445 obo->fd = *fd;
446 return (Buffer_Handle *)obo;
447
448err:
449 memset(&cl, 0, sizeof(cl));
450 cl.handle = bo.handle;
451 ioctl(drm_fd, DRM_IOCTL_GEM_CLOSE, &cl);
452 return NULL;
453}
454
455static void *
456_vc4_map(Ecore_Wl2_Buffer *buf)
457{
458 struct drm_vc4_mmap_bo map;
459 struct internal_vc4_bo *bo;
460 void *ptr;
461 int ret;
462
463 bo = (struct internal_vc4_bo *)buf->bh;
464
465 memset(&map, 0, sizeof(map));
466 map.handle = bo->handle;
467 ret = ioctl(drm_fd, DRM_IOCTL_VC4_MMAP_BO, &map);
468 if (ret) return NULL;
469
470 ptr = mmap(NULL, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, drm_fd,
471 map.offset);
472 if (ptr == MAP_FAILED) return NULL;
473
474 return ptr;
475}
476
477static void
478_vc4_unmap(Ecore_Wl2_Buffer *buf)
479{
480 struct internal_vc4_bo *bo;
481
482 bo = (struct internal_vc4_bo *)buf->bh;
483 munmap(buf->mapping, bo->size);
484}
485
486static void
487_vc4_discard(Ecore_Wl2_Buffer *buf)
488{
489 struct drm_gem_close cl;
490 struct internal_vc4_bo *bo;
491
492 bo = (struct internal_vc4_bo *)buf->bh;
493
494 memset(&cl, 0, sizeof(cl));
495 cl.handle = bo->handle;
496 ioctl(drm_fd, DRM_IOCTL_GEM_CLOSE, &cl);
497}
498
499static Eina_Bool
500_vc4_buffer_manager_setup(int fd)
501{
502 struct drm_gem_close cl;
503 struct drm_vc4_create_bo bo;
504 Eina_Bool fail = EINA_FALSE;
505 void *drm_lib;
506
507 memset(&bo, 0, sizeof(bo));
508 bo.size = 32;
509 if (ioctl(fd, DRM_IOCTL_VC4_CREATE_BO, &bo)) return EINA_FALSE;
510
511 memset(&cl, 0, sizeof(cl));
512 cl.handle = bo.handle;
513 ioctl(fd, DRM_IOCTL_GEM_CLOSE, &cl);
514
515 drm_lib = dlopen("libdrm.so", RTLD_LAZY | RTLD_GLOBAL);
516 if (!drm_lib) return EINA_FALSE;
517
518 SYM(drm_lib, drmPrimeHandleToFD);
519
520 if (fail) goto err;
521
522 buffer_manager->alloc = _vc4_alloc;
523 buffer_manager->to_buffer = _evas_dmabuf_wl_buffer_from_dmabuf;
524 buffer_manager->map = _vc4_map;
525 buffer_manager->unmap = _vc4_unmap;
526 buffer_manager->discard = _vc4_discard;
527 buffer_manager->manager_destroy = NULL;
528 buffer_manager->dl_handle = drm_lib;
529 return EINA_TRUE;
530err:
531 dlclose(drm_lib);
532 return EINA_FALSE;
533}
534
400EAPI Eina_Bool 535EAPI Eina_Bool
401ecore_wl2_buffer_init(Ecore_Wl2_Display *ewd, Ecore_Wl2_Buffer_Type types) 536ecore_wl2_buffer_init(Ecore_Wl2_Display *ewd, Ecore_Wl2_Buffer_Type types)
402{ 537{
@@ -421,6 +556,7 @@ ecore_wl2_buffer_init(Ecore_Wl2_Display *ewd, Ecore_Wl2_Buffer_Type types)
421 556
422 success = _intel_buffer_manager_setup(fd); 557 success = _intel_buffer_manager_setup(fd);
423 if (!success) success = _exynos_buffer_manager_setup(fd); 558 if (!success) success = _exynos_buffer_manager_setup(fd);
559 if (!success) success = _vc4_buffer_manager_setup(fd);
424 } 560 }
425 if (!success) success = shm && _wl_shm_buffer_manager_setup(0); 561 if (!success) success = shm && _wl_shm_buffer_manager_setup(0);
426 if (!success) goto err_bm; 562 if (!success) goto err_bm;