diff options
author | Rob Herring <[email protected]> | 2016-05-03 21:02:47 -0500 |
---|---|---|
committer | Emil Velikov <[email protected]> | 2016-05-23 12:07:46 +0100 |
commit | 8aeb6d768b4285f600d09f38d0b406adf46c251d (patch) | |
tree | c4ad438adb7e6862da2b8dbc77a3963a9188f073 /src/gbm/backends/dri | |
parent | 1f4869a2089c6172feff382e177d74ac68c241a7 (diff) |
gbm: Add map/unmap functions
This adds map and unmap functions to GBM utilizing the DRIimage extension
mapImage/unmapImage functions or existing internal mapping for dumb
buffers. Unlike prior attempts, this version provides a region to map and
usage flags for the mapping. The operation follows the same semantics as
the gallium transfer_map() function.
This was tested with GBM based gralloc on Android.
Signed-off-by: Rob Herring <[email protected]>
[Emil Velikov: drop no longer relevant hunk from commit message.]
Reviewed-by: Emil Velikov <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/gbm/backends/dri')
-rw-r--r-- | src/gbm/backends/dri/gbm_dri.c | 62 | ||||
-rw-r--r-- | src/gbm/backends/dri/gbm_driint.h | 3 |
2 files changed, 65 insertions, 0 deletions
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index 51d51dde3d0..c3626e39c07 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -32,6 +32,7 @@ #include <string.h> #include <errno.h> #include <limits.h> +#include <assert.h> #include <sys/types.h> #include <unistd.h> @@ -924,6 +925,60 @@ failed: return NULL; } +static void * +gbm_dri_bo_map(struct gbm_bo *_bo, + uint32_t x, uint32_t y, + uint32_t width, uint32_t height, + uint32_t flags, uint32_t *stride, void **map_data) +{ + struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm); + struct gbm_dri_bo *bo = gbm_dri_bo(_bo); + + /* If it's a dumb buffer, we already have a mapping */ + if (bo->map) { + *map_data = (char *)bo->map + (bo->base.base.stride * y) + (x * 4); + *stride = bo->base.base.stride; + return *map_data; + } + + if (!dri->image || dri->image->base.version < 12) { + errno = ENOSYS; + return NULL; + } + + mtx_lock(&dri->mutex); + if (!dri->context) + dri->context = dri->dri2->createNewContext(dri->screen, NULL, + NULL, NULL); + assert(dri->context); + mtx_unlock(&dri->mutex); + + /* GBM flags and DRI flags are the same, so just pass them on */ + return dri->image->mapImage(dri->context, bo->image, x, y, + width, height, flags, (int *)stride, + map_data); +} + +static void +gbm_dri_bo_unmap(struct gbm_bo *_bo, void *map_data) +{ + struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm); + struct gbm_dri_bo *bo = gbm_dri_bo(_bo); + + /* Check if it's a dumb buffer and check the pointer is in range */ + if (bo->map) { + assert(map_data >= bo->map); + assert(map_data < (bo->map + bo->size)); + return; + } + + if (!dri->context || !dri->image || dri->image->base.version < 12) + return; + + dri->image->unmapImage(dri->context, bo->image, map_data); +} + + static struct gbm_surface * gbm_dri_surface_create(struct gbm_device *gbm, uint32_t width, uint32_t height, @@ -958,6 +1013,9 @@ dri_destroy(struct gbm_device *gbm) struct gbm_dri_device *dri = gbm_dri_device(gbm); unsigned i; + if (dri->context) + dri->core->destroyContext(dri->context); + dri->core->destroyScreen(dri->screen); for (i = 0; dri->driver_configs[i]; i++) free((__DRIconfig *) dri->driver_configs[i]); @@ -981,6 +1039,8 @@ dri_device_create(int fd) dri->base.base.fd = fd; dri->base.base.bo_create = gbm_dri_bo_create; dri->base.base.bo_import = gbm_dri_bo_import; + dri->base.base.bo_map = gbm_dri_bo_map; + dri->base.base.bo_unmap = gbm_dri_bo_unmap; dri->base.base.is_format_supported = gbm_dri_is_format_supported; dri->base.base.bo_write = gbm_dri_bo_write; dri->base.base.bo_get_fd = gbm_dri_bo_get_fd; @@ -992,6 +1052,8 @@ dri_device_create(int fd) dri->base.type = GBM_DRM_DRIVER_TYPE_DRI; dri->base.base.name = "drm"; + mtx_init(&dri->mutex, mtx_plain); + force_sw = getenv("GBM_ALWAYS_SOFTWARE") != NULL; if (!force_sw) { ret = dri_screen_create(dri); diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h index b51cc4d90c2..46bb5c15619 100644 --- a/src/gbm/backends/dri/gbm_driint.h +++ b/src/gbm/backends/dri/gbm_driint.h @@ -30,6 +30,7 @@ #include <sys/mman.h> #include "gbmint.h" +#include "c11/threads.h" #include "common_drm.h" @@ -45,6 +46,8 @@ struct gbm_dri_device { void *driver; __DRIscreen *screen; + __DRIcontext *context; + mtx_t mutex; const __DRIcoreExtension *core; const __DRIdri2Extension *dri2; |