summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTapani Pälli <tapani.palli@intel.com>2012-08-01 16:06:00 +0300
committerDaniel Leung <daniel.leung@intel.com>2012-10-12 08:20:45 -0700
commita86ecd9036df3862f7289378609509e50ef38cb3 (patch)
treed517ead1e2764990299357a86efb8a44d1248a6e
parent12971f83cab2f56198bb16f00fbbbabfe84226ca (diff)
downloadexternal_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.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);