diff options
author | Tapani Pälli <tapani.palli@intel.com> | 2012-08-01 16:06:00 +0300 |
---|---|---|
committer | Daniel Leung <daniel.leung@intel.com> | 2012-10-12 08:20:45 -0700 |
commit | a86ecd9036df3862f7289378609509e50ef38cb3 (patch) | |
tree | d517ead1e2764990299357a86efb8a44d1248a6e | |
parent | 12971f83cab2f56198bb16f00fbbbabfe84226ca (diff) | |
download | external_drm_gralloc-a86ecd9036df3862f7289378609509e50ef38cb3.zip external_drm_gralloc-a86ecd9036df3862f7289378609509e50ef38cb3.tar.gz external_drm_gralloc-a86ecd9036df3862f7289378609509e50ef38cb3.tar.bz2 |
gralloc: add refcount to gralloc_drm_bo_t
This is an basic enabler for gralloc to let buffers live while they are still
in use by gralloc (for example during scanout), otherwise Android may choose
to destroy them while they are still needed. This facility will get used with
upcoming plane support and direct rendering support.
Change-Id: I2f0bc595846a68e8d2feb5138b022d16f207e2b5
Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
-rw-r--r-- | gralloc.c | 6 | ||||
-rw-r--r-- | gralloc_drm.c | 21 | ||||
-rw-r--r-- | gralloc_drm.h | 2 | ||||
-rw-r--r-- | gralloc_drm_kms.c | 4 | ||||
-rw-r--r-- | gralloc_drm_priv.h | 2 |
5 files changed, 26 insertions, 9 deletions
@@ -174,9 +174,7 @@ static int drm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle) if (!bo) return -EINVAL; - if (gralloc_drm_bo_need_fb(bo)) - gralloc_drm_bo_rm_fb(bo); - gralloc_drm_bo_destroy(bo); + gralloc_drm_bo_decref(bo); return 0; } @@ -201,7 +199,7 @@ static int drm_mod_alloc_gpu0(alloc_device_t *dev, err = gralloc_drm_bo_add_fb(bo); if (err) { ALOGE("failed to add fb"); - gralloc_drm_bo_destroy(bo); + gralloc_drm_bo_decref(bo); return err; } } diff --git a/gralloc_drm.c b/gralloc_drm.c index ca069f1..63b5217 100644 --- a/gralloc_drm.c +++ b/gralloc_drm.c @@ -236,7 +236,7 @@ int gralloc_drm_handle_unregister(buffer_handle_t handle) return -EINVAL; if (bo->imported) - gralloc_drm_bo_destroy(bo); + gralloc_drm_bo_decref(bo); return 0; } @@ -288,6 +288,8 @@ struct gralloc_drm_bo_t *gralloc_drm_bo_create(struct gralloc_drm_t *drm, bo->drm = drm; bo->imported = 0; bo->handle = handle; + bo->fb_id = 0; + bo->refcount = 1; handle->data_owner = gralloc_drm_get_pid(); handle->data = (int) bo; @@ -298,11 +300,17 @@ struct gralloc_drm_bo_t *gralloc_drm_bo_create(struct gralloc_drm_t *drm, /* * Destroy a bo. */ -void gralloc_drm_bo_destroy(struct gralloc_drm_bo_t *bo) +static void gralloc_drm_bo_destroy(struct gralloc_drm_bo_t *bo) { struct gralloc_drm_handle_t *handle = bo->handle; int imported = bo->imported; + /* gralloc still has a reference */ + if (bo->refcount) + return; + + gralloc_drm_bo_rm_fb(bo); + bo->drm->drv->free(bo->drm->drv, bo); if (imported) { handle->data_owner = 0; @@ -314,6 +322,15 @@ void gralloc_drm_bo_destroy(struct gralloc_drm_bo_t *bo) } /* + * Decrease refcount, if no refs anymore then destroy. + */ +void gralloc_drm_bo_decref(struct gralloc_drm_bo_t *bo) +{ + if (!--bo->refcount) + gralloc_drm_bo_destroy(bo); +} + +/* * Return the bo of a registered handle. */ struct gralloc_drm_bo_t *gralloc_drm_bo_from_handle(buffer_handle_t handle) diff --git a/gralloc_drm.h b/gralloc_drm.h index 85e3675..cf2d71c 100644 --- a/gralloc_drm.h +++ b/gralloc_drm.h @@ -113,7 +113,7 @@ int gralloc_drm_handle_register(buffer_handle_t handle, struct gralloc_drm_t *dr int gralloc_drm_handle_unregister(buffer_handle_t handle); struct gralloc_drm_bo_t *gralloc_drm_bo_create(struct gralloc_drm_t *drm, int width, int height, int format, int usage); -void gralloc_drm_bo_destroy(struct gralloc_drm_bo_t *bo); +void gralloc_drm_bo_decref(struct gralloc_drm_bo_t *bo); struct gralloc_drm_bo_t *gralloc_drm_bo_from_handle(buffer_handle_t handle); buffer_handle_t gralloc_drm_bo_get_handle(struct gralloc_drm_bo_t *bo, int *stride); diff --git a/gralloc_drm_kms.c b/gralloc_drm_kms.c index 12bc065..4664ecb 100644 --- a/gralloc_drm_kms.c +++ b/gralloc_drm_kms.c @@ -384,7 +384,7 @@ static void drm_kms_init_features(struct gralloc_drm_t *drm) drm->fb_format, GRALLOC_USAGE_HW_FB); if (front && gralloc_drm_bo_add_fb(front)) { - gralloc_drm_bo_destroy(front); + gralloc_drm_bo_decref(front); front = NULL; } @@ -605,7 +605,7 @@ void gralloc_drm_fini_kms(struct gralloc_drm_t *drm) &drm->current_front : &drm->next_front; if (*bo) - gralloc_drm_bo_destroy(*bo); + gralloc_drm_bo_decref(*bo); *bo = NULL; } break; diff --git a/gralloc_drm_priv.h b/gralloc_drm_priv.h index 1da3e4a..33f688d 100644 --- a/gralloc_drm_priv.h +++ b/gralloc_drm_priv.h @@ -110,6 +110,8 @@ struct gralloc_drm_bo_t { int lock_count; int locked_for; + + unsigned int refcount; }; struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_pipe(int fd, const char *name); |