From 41aecd32dee1306351b411571284877c11768ac3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 5 May 2013 13:44:14 +0100 Subject: Add support for named bos * Add drm_dove_bo_create_from_name() * Add drm_dove_bo_flink() Signed-off-by: Russell King --- debian/changelog | 7 +++ dove_bufmgr.c | 170 +++++++++++++++++++++++++++++++++++++++---------------- dove_bufmgr.h | 7 +++ 3 files changed, 136 insertions(+), 48 deletions(-) diff --git a/debian/changelog b/debian/changelog index 70a37d8..5ec6932 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +libdrm-dove (1.0.1-1) unstable; urgency=low + + * Add drm_dove_bo_create_from_name() + * Add drm_dove_bo_flink() + + -- Russell King Tue, 23 Oct 2012 17:28:17 +0100 + libdrm-dove (1.0.0-1) unstable; urgency=low * Initial release. diff --git a/dove_bufmgr.c b/dove_bufmgr.c index 5737bf8..32e192a 100644 --- a/dove_bufmgr.c +++ b/dove_bufmgr.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -7,9 +8,22 @@ #include #include "dove_bufmgr.h" - #include "dove_ioctl.h" +#ifndef container_of +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) +#endif + +struct dove_bo { + struct drm_dove_bo bo; + uint32_t ref; + uint32_t name; /* Global name */ +}; + +#define to_dove_bo(_bo) container_of(_bo, struct dove_bo, bo) + #ifndef DRM_IOCTL_MODE_CREATE_DUMB /* create a dumb scanout buffer */ struct drm_mode_create_dumb { @@ -43,7 +57,7 @@ struct drm_mode_map_dumb { struct drm_dove_bo *drm_dove_bo_create_phys(int fd, uint32_t phys, size_t size) { - struct drm_dove_bo *bo; + struct dove_bo *bo; bo = calloc(1, sizeof *bo); if (bo) { @@ -59,18 +73,19 @@ struct drm_dove_bo *drm_dove_bo_create_phys(int fd, uint32_t phys, size_t size) free(bo); return NULL; } + bo->bo.ref = 1; + bo->bo.handle = arg.handle; + bo->bo.size = size; + bo->bo.phys = phys; + bo->bo.type = DRM_DOVE_BO_LINEAR; bo->ref = 1; - bo->handle = arg.handle; - bo->size = size; - bo->phys = phys; - bo->type = DRM_DOVE_BO_LINEAR; } - return bo; + return &bo->bo; } struct drm_dove_bo *drm_dove_bo_create(int fd, unsigned w, unsigned h, unsigned bpp) { - struct drm_dove_bo *bo; + struct dove_bo *bo; bo = calloc(1, sizeof *bo); if (bo) { @@ -87,21 +102,47 @@ struct drm_dove_bo *drm_dove_bo_create(int fd, unsigned w, unsigned h, unsigned free(bo); return NULL; } + + bo->bo.ref = 1; + bo->bo.handle = arg.handle; + bo->bo.size = arg.size; + bo->bo.pitch = arg.pitch; + bo->bo.type = DRM_DOVE_BO_SHMEM; bo->ref = 1; - bo->handle = arg.handle; - bo->size = arg.size; - bo->pitch = arg.pitch; - bo->type = DRM_DOVE_BO_SHMEM; } - return bo; + return &bo->bo; } +struct drm_dove_bo *drm_dove_bo_create_from_name(int fd, uint32_t name) +{ + struct dove_bo *bo; + bo = calloc(1, sizeof *bo); + if (bo) { + struct drm_gem_open arg; + int ret; + + memset(&arg, 0, sizeof(arg)); + arg.name = name; + ret = drmIoctl(fd, DRM_IOCTL_GEM_OPEN, &arg); + if (ret == -1) { + free(bo); + return NULL; + } + bo->bo.ref = 1; + bo->bo.handle = arg.handle; + bo->bo.size = arg.size; + bo->bo.type = DRM_DOVE_BO_LINEAR; /* assumed */ + bo->ref = 1; + bo->name = name; + } + return &bo->bo; +} struct drm_dove_bo *drm_dove_bo_dumb_create(int fd, unsigned w, unsigned h, unsigned bpp) { - struct drm_dove_bo *bo; + struct dove_bo *bo; bo = calloc(1, sizeof *bo); if (bo) { @@ -118,71 +159,103 @@ struct drm_dove_bo *drm_dove_bo_dumb_create(int fd, unsigned w, unsigned h, free(bo); return NULL; } + bo->bo.ref = 1; + bo->bo.handle = arg.handle; + bo->bo.size = arg.size; + bo->bo.pitch = arg.pitch; + bo->bo.type = DRM_DOVE_BO_DUMB; bo->ref = 1; - bo->handle = arg.handle; - bo->size = arg.size; - bo->pitch = arg.pitch; - bo->type = DRM_DOVE_BO_DUMB; } - return bo; + return &bo->bo; } -static void drm_dove_bo_dumb_destroy(int fd, struct drm_dove_bo *bo) +void drm_dove_bo_get(int fd, struct drm_dove_bo *dbo) { - struct drm_mode_destroy_dumb arg; - int ret; + struct dove_bo *bo = to_dove_bo(dbo); + bo->ref++; +} - if (bo->ptr) { - munmap(bo->ptr, bo->size); - bo->ptr = NULL; - } +void drm_dove_bo_put(int fd, struct drm_dove_bo *dbo) +{ + struct dove_bo *bo = to_dove_bo(dbo); - memset(&arg, 0, sizeof(arg)); - arg.handle = bo->handle; - ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg); - if (ret == 0) { - free(bo); + if (bo->ref-- == 1) { + int ret; + + if (bo->bo.ptr) { + munmap(bo->bo.ptr, bo->bo.size); + bo->bo.ptr = NULL; + } + + if (bo->bo.type == DRM_DOVE_BO_DUMB) { + struct drm_mode_destroy_dumb arg; + + memset(&arg, 0, sizeof(arg)); + arg.handle = bo->bo.handle; + ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg); + } else { + struct drm_gem_close close; + + memset(&close, 0, sizeof(close)); + close.handle = bo->bo.handle; + ret = ioctl(fd, DRM_IOCTL_GEM_CLOSE, &close); + } + + if (ret == 0) + free(bo); } } -void drm_dove_bo_get(int fd, struct drm_dove_bo *bo) +int drm_dove_bo_flink(int fd, struct drm_dove_bo *dbo, uint32_t *name) { - bo->ref++; -} + struct dove_bo *bo = to_dove_bo(dbo); -void drm_dove_bo_put(int fd, struct drm_dove_bo *bo) -{ - if (bo->ref-- == 1) - drm_dove_bo_dumb_destroy(fd, bo); + if (!bo->name) { + struct drm_gem_flink flink; + int ret; + + memset(&flink, 0, sizeof(flink)); + flink.handle = bo->bo.handle; + ret = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink); + if (ret) + return ret; + bo->name = flink.name; + } + *name = bo->name; + return 0; } -int drm_dove_bo_map(int fd, struct drm_dove_bo *bo) +int drm_dove_bo_map(int fd, struct drm_dove_bo *dbo) { + struct dove_bo *bo = to_dove_bo(dbo); void *map; int ret; - if (bo->type == DRM_DOVE_BO_DUMB) { + if (bo->bo.ptr) + return 0; + + if (bo->bo.type == DRM_DOVE_BO_DUMB) { struct drm_mode_map_dumb arg; memset(&arg, 0, sizeof(arg)); - arg.handle = bo->handle; + arg.handle = bo->bo.handle; ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg); if (ret) return ret; - map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, + map = mmap(0, bo->bo.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, arg.offset); if (map == MAP_FAILED) return -1; - } else if (bo->type == DRM_DOVE_BO_SHMEM) { + } else if (bo->bo.type == DRM_DOVE_BO_SHMEM) { struct drm_dove_gem_mmap arg; memset(&arg, 0, sizeof(arg)); - arg.handle = bo->handle; + arg.handle = bo->bo.handle; arg.offset = 0; - arg.size = bo->size; + arg.size = bo->bo.size; ret = drmIoctl(fd, DRM_IOCTL_DOVE_GEM_MMAP, &arg); if (ret) @@ -194,18 +267,19 @@ int drm_dove_bo_map(int fd, struct drm_dove_bo *bo) return -1; } - bo->ptr = map; + bo->bo.ptr = map; return 0; } -uint32_t drm_dove_bo_phys(int fd, struct drm_dove_bo *bo) +uint32_t drm_dove_bo_phys(int fd, struct drm_dove_bo *dbo) { + struct dove_bo *bo = to_dove_bo(dbo); struct drm_dove_gem_prop arg; int ret; memset(&arg, 0, sizeof(arg)); - arg.handle = bo->handle; + arg.handle = bo->bo.handle; ret = drmIoctl(fd, DRM_IOCTL_DOVE_GEM_PROP, &arg); diff --git a/dove_bufmgr.h b/dove_bufmgr.h index 701e128..88918f6 100644 --- a/dove_bufmgr.h +++ b/dove_bufmgr.h @@ -21,6 +21,13 @@ struct drm_dove_bo *drm_dove_bo_create(int fd, unsigned w, unsigned h, unsigned struct drm_dove_bo *drm_dove_bo_create_phys(int fd, uint32_t phys, size_t size); struct drm_dove_bo *drm_dove_bo_dumb_create(int fd, unsigned w, unsigned h, unsigned bpp); + +/* Create a BO from a global name */ +struct drm_dove_bo *drm_dove_bo_create_from_name(int fd, uint32_t name); + +/* Create a global name from a BO */ +int drm_dove_bo_flink(int fd, struct drm_dove_bo *bo, uint32_t *name); + int drm_dove_bo_map(int fd, struct drm_dove_bo *bo); uint32_t drm_dove_bo_phys(int fd, struct drm_dove_bo *bo); void drm_dove_bo_get(int fd, struct drm_dove_bo *bo); -- cgit