diff options
-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); |