aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFei Jiang <fei.jiang@intel.com>2011-12-18 23:29:11 +0800
committerPatrick Tjin <pattjin@google.com>2014-07-21 22:01:45 -0700
commit8acea2d0d04b7aff3fb59bb071cc7a69c47b9929 (patch)
tree4d28f1ad71ba09f502410940ffa88c5bb8101a3c
parent8ef3e48823dd4e458705a79dade6d1c0c1a00c72 (diff)
downloadlibwsbm-8acea2d0d04b7aff3fb59bb071cc7a69c47b9929.tar.gz
libwsbm: enable ICS graphic buffer decoding and rendering.
BZ: 18370 This patch enabled to use external buffer for video decoding, will wrap a gralloc buffer to TTM buffer. Add function wsbmBODataUB and ttm_pool_ub_create to support wrap a GraphicBuffer to a TTM buffer. Change-Id: I73a3050142ccaa45e9ebe7feb771a6a3843f6172 Reviewed-on: http://android.intel.com:8080/27889 Reviewed-by: Yuan, Shengquan <shengquan.yuan@intel.com> Reviewed-by: Ding, Haitao <haitao.ding@intel.com> Tested-by: Ding, Haitao <haitao.ding@intel.com> Reviewed-by: buildbot <buildbot@intel.com> Tested-by: buildbot <buildbot@intel.com>
-rw-r--r--src/wsbm_manager.c130
-rw-r--r--src/wsbm_manager.h5
-rw-r--r--src/wsbm_ttmpool.c53
3 files changed, 188 insertions, 0 deletions
diff --git a/src/wsbm_manager.c b/src/wsbm_manager.c
index 1c347c7..a86b894 100644
--- a/src/wsbm_manager.c
+++ b/src/wsbm_manager.c
@@ -610,6 +610,136 @@ wsbmBOData(struct _WsbmBufferObject *buf,
return retval;
}
+int
+wsbmBODataUB(struct _WsbmBufferObject *buf,
+ unsigned size, const void *data, struct _WsbmBufferPool *newPool,
+ uint32_t placement, const unsigned long *user_ptr)
+{
+ int newBuffer;
+ int retval = 0;
+ struct _WsbmBufStorage *storage;
+ int synced = 0;
+ uint32_t placement_diff;
+ struct _WsbmBufferPool *curPool;
+ extern struct _WsbmBufStorage *
+ ttm_pool_ub_create(struct _WsbmBufferPool *pool,
+ unsigned long size, uint32_t placement, unsigned alignment,
+ const unsigned long *user_ptr);
+
+ if (buf->bufferType == WSBM_BUFFER_SIMPLE)
+ return -EINVAL;
+
+ storage = buf->storage;
+
+ if (newPool == NULL)
+ newPool = buf->pool;
+
+ if (newPool == NULL)
+ return -EINVAL;
+
+ newBuffer = (!storage || storage->pool != newPool ||
+ storage->pool->size(storage) < size ||
+ storage->pool->size(storage) >
+ size + WSBM_BODATA_SIZE_ACCEPT);
+
+ if (!placement)
+ placement = buf->placement;
+
+ if (newBuffer) {
+ if (buf->bufferType == WSBM_BUFFER_REF)
+ return -EINVAL;
+
+ wsbmBufStorageUnref(&buf->storage);
+
+ if (size == 0) {
+ buf->pool = newPool;
+ buf->placement = placement;
+ retval = 0;
+ goto out;
+ }
+
+ buf->storage =
+ ttm_pool_ub_create(newPool, size, placement, buf->alignment, user_ptr);
+ if (!buf->storage) {
+ retval = -ENOMEM;
+ goto out;
+ }
+
+ buf->placement = placement;
+ buf->pool = newPool;
+ } else if (wsbmAtomicRead(&storage->onList) ||
+ 0 != storage->pool->syncforcpu(storage, WSBM_SYNCCPU_WRITE |
+ WSBM_SYNCCPU_DONT_BLOCK)) {
+ /*
+ * Buffer is busy. need to create a new one.
+ * Actually such case will not be encountered for current ICS implementation
+ * TODO: maybe need refine the following code when such usage case is required
+ */
+
+ struct _WsbmBufStorage *tmp_storage;
+
+ curPool = storage->pool;
+
+ tmp_storage =
+ ttm_pool_ub_create(curPool, size, placement, buf->alignment, user_ptr);
+
+ if (tmp_storage) {
+ wsbmBufStorageUnref(&buf->storage);
+ buf->storage = tmp_storage;
+ buf->placement = placement;
+ } else {
+ retval = curPool->syncforcpu(storage, WSBM_SYNCCPU_WRITE);
+ if (retval)
+ goto out;
+ synced = 1;
+ }
+ } else {
+ synced = 1;
+ }
+
+ placement_diff = placement ^ buf->placement;
+
+ /*
+ * We might need to change buffer placement.
+ */
+
+ storage = buf->storage;
+ curPool = storage->pool;
+
+ if (placement_diff) {
+ assert(curPool->setStatus != NULL);
+ curPool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
+ retval = curPool->setStatus(storage,
+ placement_diff & placement,
+ placement_diff & ~placement);
+ if (retval)
+ goto out;
+
+ buf->placement = placement;
+ }
+
+ if (!synced) {
+ retval = curPool->syncforcpu(buf->storage, WSBM_SYNCCPU_WRITE);
+ if (retval)
+ goto out;
+ synced = 1;
+ }
+
+ storage = buf->storage;
+ curPool = storage->pool;
+
+ if (data) {
+ memcpy(user_ptr, data, size);
+ }
+
+ out:
+
+ if (synced)
+ curPool->releasefromcpu(storage, WSBM_SYNCCPU_WRITE);
+
+ return retval;
+}
+
static struct _WsbmBufStorage *
wsbmStorageClone(struct _WsbmBufferObject *buf)
{
diff --git a/src/wsbm_manager.h b/src/wsbm_manager.h
index ee0636f..aa2eb5f 100644
--- a/src/wsbm_manager.h
+++ b/src/wsbm_manager.h
@@ -92,6 +92,11 @@ extern void wsbmBOUnreference(struct _WsbmBufferObject **p_buf);
extern int wsbmBOData(struct _WsbmBufferObject *r_buf,
unsigned size, const void *data,
struct _WsbmBufferPool *pool, uint32_t placement);
+
+extern int wsbmBODataUB(struct _WsbmBufferObject *buf,
+ unsigned size, const void *data, struct _WsbmBufferPool *newPool,
+ uint32_t placement, const unsigned long *user_ptr);
+
extern int wsbmBOSetStatus(struct _WsbmBufferObject *buf,
uint32_t setPlacement, uint32_t clrPlacement);
extern int wsbmBOSubData(struct _WsbmBufferObject *buf,
diff --git a/src/wsbm_ttmpool.c b/src/wsbm_ttmpool.c
index 5847a2f..9df90fb 100644
--- a/src/wsbm_ttmpool.c
+++ b/src/wsbm_ttmpool.c
@@ -520,3 +520,56 @@ wsbmTTMPoolInit(int fd, unsigned int devOffset)
pool->setStatus = &pool_setStatus;
return pool;
}
+
+struct _WsbmBufStorage *
+ttm_pool_ub_create(struct _WsbmBufferPool *pool, unsigned long size, uint32_t placement, unsigned alignment, const unsigned long *user_ptr)
+{
+ struct _TTMBuffer *dBuf = (struct _TTMBuffer *)
+ calloc(1, sizeof(*dBuf));
+ struct _TTMPool *ttmPool = containerOf(pool, struct _TTMPool, pool);
+ int ret;
+ unsigned pageSize = ttmPool->pageSize;
+ union ttm_pl_create_ub_arg arg;
+
+ if (!dBuf)
+ return NULL;
+
+ if ((alignment > pageSize) && (alignment % pageSize))
+ goto out_err0;
+
+ ret = wsbmBufStorageInit(&dBuf->buf, pool);
+ if (ret)
+ goto out_err0;
+
+ ret = WSBM_COND_INIT(&dBuf->event);
+ if (ret)
+ goto out_err1;
+
+ arg.req.size = size;
+ arg.req.placement = placement;
+ arg.req.page_alignment = alignment / pageSize;
+ arg.req.user_address = user_ptr;
+
+ DRMRESTARTCOMMANDWRITEREAD(pool->fd, ttmPool->devOffset + TTM_PL_CREATE_UB,
+ arg, ret);
+ if (ret)
+ goto out_err2;
+
+ dBuf->requestedSize = size;
+ dBuf->kBuf.gpuOffset = arg.rep.gpu_offset;
+ dBuf->mapHandle = arg.rep.map_handle;
+ dBuf->realSize = arg.rep.bo_size;
+ dBuf->kBuf.placement = arg.rep.placement;
+ dBuf->kBuf.handle = arg.rep.handle;
+
+ return &dBuf->buf;
+
+ out_err2:
+ WSBM_COND_FREE(&dBuf->event);
+ out_err1:
+ wsbmBufStorageTakedown(&dBuf->buf);
+ out_err0:
+ free(dBuf);
+ return NULL;
+}
+