diff options
author | Fei Jiang <fei.jiang@intel.com> | 2011-12-18 23:29:11 +0800 |
---|---|---|
committer | Patrick Tjin <pattjin@google.com> | 2014-07-21 22:01:45 -0700 |
commit | 8acea2d0d04b7aff3fb59bb071cc7a69c47b9929 (patch) | |
tree | 4d28f1ad71ba09f502410940ffa88c5bb8101a3c | |
parent | 8ef3e48823dd4e458705a79dade6d1c0c1a00c72 (diff) | |
download | libwsbm-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.c | 130 | ||||
-rw-r--r-- | src/wsbm_manager.h | 5 | ||||
-rw-r--r-- | src/wsbm_ttmpool.c | 53 |
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; +} + |