summaryrefslogtreecommitdiffstats
path: root/gralloc_drm.c
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2011-07-29 20:43:12 +0900
committerChia-I Wu <olvaffe@gmail.com>2011-07-29 21:11:19 +0900
commit25e041367040b6faadebc38acd44e96b8e29a5ab (patch)
treecfd83cb658e60000e29b60cd87913078ee3262ec /gralloc_drm.c
parent2fc5da4da12c8fa36044acc58856b0e460e70621 (diff)
downloadexternal_drm_gralloc-25e041367040b6faadebc38acd44e96b8e29a5ab.zip
external_drm_gralloc-25e041367040b6faadebc38acd44e96b8e29a5ab.tar.gz
external_drm_gralloc-25e041367040b6faadebc38acd44e96b8e29a5ab.tar.bz2
map a bo only when it is locked for CPU access
To match the doc a little better.
Diffstat (limited to 'gralloc_drm.c')
-rw-r--r--gralloc_drm.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/gralloc_drm.c b/gralloc_drm.c
index e220ebe..2ec11ef 100644
--- a/gralloc_drm.c
+++ b/gralloc_drm.c
@@ -294,22 +294,57 @@ void gralloc_drm_bo_unregister(struct gralloc_drm_bo_t *bo)
}
/*
- * Map a bo for CPU access.
+ * Lock a bo. XXX thread-safety?
*/
-int gralloc_drm_bo_map(struct gralloc_drm_bo_t *bo,
- int x, int y, int w, int h,
- int enable_write, void **addr)
+int gralloc_drm_bo_lock(struct gralloc_drm_bo_t *bo,
+ int usage, int x, int y, int w, int h,
+ void **addr)
{
- return bo->drm->drv->map(bo->drm->drv, bo,
- x, y, w, h, enable_write, addr);
+ if ((bo->handle->usage & usage) != usage)
+ return -EINVAL;
+
+ /* allow multiple locks with compatible usages */
+ if (bo->lock_count && (bo->locked_for & usage) != usage)
+ return -EINVAL;
+
+ usage |= bo->locked_for;
+
+ if (usage & (GRALLOC_USAGE_SW_WRITE_MASK |
+ GRALLOC_USAGE_SW_READ_MASK)) {
+ /* the driver is supposed to wait for the bo */
+ int write = !!(usage & GRALLOC_USAGE_SW_WRITE_MASK);
+ int err = bo->drm->drv->map(bo->drm->drv, bo,
+ x, y, w, h, write, addr);
+ if (err)
+ return err;
+ }
+ else {
+ /* kernel handles the synchronization here */
+ }
+
+ bo->lock_count++;
+ bo->locked_for |= usage;
+
+ return 0;
}
/*
- * Unmap a bo.
+ * Unlock a bo.
*/
-void gralloc_drm_bo_unmap(struct gralloc_drm_bo_t *bo)
+void gralloc_drm_bo_unlock(struct gralloc_drm_bo_t *bo)
{
- bo->drm->drv->unmap(bo->drm->drv, bo);
+ int mapped = bo->locked_for &
+ (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_SW_READ_MASK);
+
+ if (!bo->lock_count)
+ return;
+
+ if (mapped)
+ bo->drm->drv->unmap(bo->drm->drv, bo);
+
+ bo->lock_count--;
+ if (!bo->lock_count)
+ bo->locked_for = 0;
}
/*