summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gralloc.c6
-rw-r--r--gralloc_drm.c21
-rw-r--r--gralloc_drm.h2
-rw-r--r--gralloc_drm_kms.c4
-rw-r--r--gralloc_drm_priv.h2
5 files changed, 26 insertions, 9 deletions
diff --git a/gralloc.c b/gralloc.c
index 6d55307..e54aca6 100644
--- a/gralloc.c
+++ b/gralloc.c
@@ -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);