summaryrefslogtreecommitdiff
path: root/ips
diff options
context:
space:
mode:
authorSun, Jian <jianx.sun@intel.com>2013-08-15 11:33:24 +0800
committercactus <cactus@intel.com>2013-09-24 22:52:43 -0700
commitfa92afb1e8276eefc983bd8e209a1e1b098d5b95 (patch)
tree3eac0e0636c426142bc708b63ff980c7e35ad155 /ips
parent4fddd8df606f33efc106924c02f3afc47724cacd (diff)
downloadhwcomposer-fa92afb1e8276eefc983bd8e209a1e1b098d5b95.tar.gz
HWC: enable VED two-pass rotation for merrifield platform
BZ: 130994 Enable VED two-pass rotaion for DRM playback in merrifield ,if rotaion buffer was not generated by decoder pipeline,generate rotation here Change-Id: I4c07782c60d1094ded06335ceddfc38607caa8bf Signed-off-by: Sun, Jian <jianx.sun@intel.com> Signed-off-by: Li Zeng <li.zeng@intel.com> Reviewed-on: http://android.intel.com:8080/125686 Reviewed-by: Qiu, Junhai <junhai.qiu@intel.com> Reviewed-by: Wang, Yi A <yi.a.wang@intel.com> Tested-by: Ding, Haitao <haitao.ding@intel.com> Reviewed-by: cactus <cactus@intel.com> Tested-by: cactus <cactus@intel.com>
Diffstat (limited to 'ips')
-rw-r--r--ips/common/RotationBufferProvider.cpp535
-rw-r--r--ips/common/RotationBufferProvider.h102
-rw-r--r--ips/common/WsbmWrapper.c2
-rw-r--r--ips/tangier/TngOverlayPlane.cpp74
-rw-r--r--ips/tangier/TngOverlayPlane.h5
5 files changed, 716 insertions, 2 deletions
diff --git a/ips/common/RotationBufferProvider.cpp b/ips/common/RotationBufferProvider.cpp
new file mode 100644
index 0000000..a2ccb66
--- /dev/null
+++ b/ips/common/RotationBufferProvider.cpp
@@ -0,0 +1,535 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Li Zeng <li.zeng@intel.com>
+ * Jian Sun <jianx.sun@intel.com>
+ */
+
+#include <HwcTrace.h>
+#include <common/RotationBufferProvider.h>
+
+namespace android {
+namespace intel {
+
+#define CHECK_VA_STATUS_RETURN(FUNC) \
+if (vaStatus != VA_STATUS_SUCCESS) {\
+ ETRACE(FUNC" failed. vaStatus = %#x", vaStatus);\
+ return false;\
+}
+
+#define CHECK_VA_STATUS_BREAK(FUNC) \
+if (vaStatus != VA_STATUS_SUCCESS) {\
+ ETRACE(FUNC" failed. vaStatus = %#x", vaStatus);\
+ break;\
+}
+
+// With this display value, VA will hook VED driver insead of VSP driver for buffer rotation
+#define DISPLAYVALUE 0x56454450
+
+RotationBufferProvider::RotationBufferProvider(Wsbm* wsbm)
+ : mWsbm(wsbm),
+ mVaInitialized(false),
+ mVaDpy(0),
+ mVaCfg(0),
+ mVaCtx(0),
+ mVaBufFilter(0),
+ mSourceSurface(0),
+ mDisplay(DISPLAYVALUE),
+ mWidth(0),
+ mHeight(0),
+ mTransform(0),
+ mRotatedWidth(0),
+ mRotatedHeight(0),
+ mRotatedStride(0),
+ mTargetIndex(0)
+{
+ for (int i = 0; i < MAX_SURFACE_NUM; i++) {
+ mKhandles[i] = 0;
+ mRotatedSurfaces[i] = 0;
+ mDrmBuf[i] = NULL;
+ }
+}
+
+RotationBufferProvider::~RotationBufferProvider()
+{
+}
+
+uint32_t RotationBufferProvider::getMilliseconds()
+{
+ struct timeval ptimeval;
+ gettimeofday(&ptimeval, NULL);
+ return (uint32_t)((ptimeval.tv_sec * 1000) + (ptimeval.tv_usec / 1000));
+}
+
+bool RotationBufferProvider::initialize()
+{
+ if (NULL == mWsbm)
+ return false;
+ return true;
+}
+
+void RotationBufferProvider::deinitialize()
+{
+ stopVA();
+}
+
+int RotationBufferProvider::transFromHalToVa(int transform)
+{
+ if (transform == HAL_TRANSFORM_ROT_90)
+ return VA_ROTATION_90;
+ if (transform == HAL_TRANSFORM_ROT_180)
+ return VA_ROTATION_180;
+ if (transform == HAL_TRANSFORM_ROT_270)
+ return VA_ROTATION_270;
+ return 0;
+}
+
+int RotationBufferProvider::getStride(bool isTarget, int width)
+{
+ int stride = 0;
+ if (width <= 512)
+ stride = 512;
+ else if (width <= 1024)
+ stride = 1024;
+ else if (width <= 1280) {
+ stride = 1280;
+ if (isTarget)
+ stride = 2048;
+ } else if (width <= 2048)
+ stride = 2048;
+ else if (width <= 4096)
+ stride = 4096;
+ else
+ stride = (width + 0x3f) & ~0x3f;
+ return stride;
+}
+
+uint32_t RotationBufferProvider::createWsbmBuffer(int width, int height, void **buf)
+{
+ int size = width * height * 3 / 2; // YUV420 NV12 format
+ int allignment = 16 * 2048; // tiling row stride aligned
+ bool ret = mWsbm->allocateTTMBuffer(size, allignment, buf);
+
+ if (ret == false) {
+ ETRACE("failed to allocate TTM buffer");
+ return 0;
+ }
+
+ return mWsbm->getKBufHandle(*buf);
+}
+
+bool RotationBufferProvider::createVaSurface(VideoPayloadBuffer *payload, int transform, bool isTarget)
+{
+ VAStatus vaStatus;
+ VASurfaceAttributeTPI attribTpi;
+ VASurfaceAttributeTPI *vaSurfaceAttrib = &attribTpi;
+ int stride;
+ unsigned int buffers;
+ VASurfaceID *surface;
+ int width = 0, height = 0, bufferHeight = 0;
+
+ if (isTarget) {
+ if (transFromHalToVa(transform) == VA_ROTATION_180) {
+ width = payload->width;
+ height = payload->height;
+ } else {
+ width = payload->height;
+ height = payload->width;
+ }
+ mRotatedWidth = width;
+ mRotatedHeight = height;
+ } else {
+ width = payload->width;
+ height = payload->height;
+ }
+
+ bufferHeight = (height + 0x1f) & ~0x1f;
+ stride = getStride(isTarget, width);
+ if (!stride) {
+ ETRACE("invalid stride value");
+ return false;
+ }
+
+ vaSurfaceAttrib->count = 1;
+ vaSurfaceAttrib->width = width;
+ vaSurfaceAttrib->height = height;
+ vaSurfaceAttrib->pixel_format = payload->format;
+ vaSurfaceAttrib->type = VAExternalMemoryKernelDRMBufffer;
+ vaSurfaceAttrib->tiling = payload->tiling;
+ vaSurfaceAttrib->size = (stride * bufferHeight * 3) / 2;
+ vaSurfaceAttrib->luma_offset = 0;
+ vaSurfaceAttrib->chroma_v_offset = stride * bufferHeight;
+ vaSurfaceAttrib->luma_stride = vaSurfaceAttrib->chroma_u_stride
+ = vaSurfaceAttrib->chroma_v_stride
+ = stride;
+ vaSurfaceAttrib->chroma_u_offset = vaSurfaceAttrib->chroma_v_offset;
+ vaSurfaceAttrib->buffers = &buffers;
+
+ if (isTarget) {
+ int khandle = createWsbmBuffer(stride, bufferHeight, &mDrmBuf[mTargetIndex]);
+ if (khandle == 0) {
+ ETRACE("failed to create buffer by wsbm");
+ return false;
+ }
+
+ mKhandles[mTargetIndex] = khandle;
+ vaSurfaceAttrib->buffers[0] = khandle;
+ mRotatedStride = stride;
+ surface = &mRotatedSurfaces[mTargetIndex];
+ } else {
+ vaSurfaceAttrib->buffers[0] = payload->khandle;
+ surface = &mSourceSurface;
+ }
+
+ vaStatus = vaCreateSurfacesWithAttribute(mVaDpy,
+ width,
+ height,
+ VA_RT_FORMAT_YUV420,
+ 1,
+ surface,
+ vaSurfaceAttrib);
+ CHECK_VA_STATUS_RETURN("vaCreateSurfacesWithAttribute");
+
+ return true;
+}
+
+bool RotationBufferProvider::startVA(VideoPayloadBuffer *payload, int transform)
+{
+ bool ret = true;
+ VAStatus vaStatus;
+ VAEntrypoint *entryPoint;
+ VAConfigAttrib attribDummy;
+ int numEntryPoints;
+ bool supportVideoProcessing = false;
+ int majorVer = 0, minorVer = 0;
+
+ // VA will hold a copy of the param pointer, so local varialbe doesn't work
+ mVaDpy = vaGetDisplay(&mDisplay);
+ if (NULL == mVaDpy) {
+ ETRACE("failed to get VADisplay");
+ return false;
+ }
+
+ vaStatus = vaInitialize(mVaDpy, &majorVer, &minorVer);
+ CHECK_VA_STATUS_RETURN("vaInitialize");
+
+ numEntryPoints = vaMaxNumEntrypoints(mVaDpy);
+
+ if (numEntryPoints <= 0) {
+ ETRACE("numEntryPoints value is invalid");
+ return false;
+ }
+
+ entryPoint = (VAEntrypoint*)malloc(sizeof(VAEntrypoint) * numEntryPoints);
+ if (NULL == entryPoint) {
+ ETRACE("failed to malloc memory for entryPoint");
+ return false;
+ }
+
+ vaStatus = vaQueryConfigEntrypoints(mVaDpy,
+ VAProfileNone,
+ entryPoint,
+ &numEntryPoints);
+ CHECK_VA_STATUS_RETURN("vaQueryConfigEntrypoints");
+
+ for (int i = 0; i < numEntryPoints; i++)
+ if (entryPoint[i] == VAEntrypointVideoProc)
+ supportVideoProcessing = true;
+
+ free(entryPoint);
+ entryPoint = NULL;
+
+ if (!supportVideoProcessing) {
+ ETRACE("VAEntrypointVideoProc is not supported");
+ return false;
+ }
+
+ vaStatus = vaCreateConfig(mVaDpy,
+ VAProfileNone,
+ VAEntrypointVideoProc,
+ &attribDummy,
+ 0,
+ &mVaCfg);
+ CHECK_VA_STATUS_RETURN("vaCreateConfig");
+
+ // create first target surface
+ ret = createVaSurface(payload, transform, true);
+ if (ret == false) {
+ ETRACE("failed to create target surface with attribute");
+ return false;
+ }
+
+ vaStatus = vaCreateContext(mVaDpy,
+ mVaCfg,
+ payload->width,
+ payload->height,
+ 0,
+ &mRotatedSurfaces[0],
+ 1,
+ &mVaCtx);
+ CHECK_VA_STATUS_RETURN("vaCreateContext");
+
+ VAProcFilterType filters[VAProcFilterCount];
+ unsigned int numFilters = VAProcFilterCount;
+ vaStatus = vaQueryVideoProcFilters(mVaDpy, mVaCtx, filters, &numFilters);
+ CHECK_VA_STATUS_RETURN("vaQueryVideoProcFilters");
+
+ bool supportVideoProcFilter = false;
+ for (unsigned int j = 0; j < numFilters; j++)
+ if (filters[j] == VAProcFilterNone)
+ supportVideoProcFilter = true;
+
+ if (!supportVideoProcFilter) {
+ ETRACE("VAProcFilterNone is not supported");
+ return false;
+ }
+
+ VAProcFilterParameterBuffer filter;
+ filter.type = VAProcFilterNone;
+ filter.value = 0;
+
+ vaStatus = vaCreateBuffer(mVaDpy,
+ mVaCtx,
+ VAProcFilterParameterBufferType,
+ sizeof(filter),
+ 1,
+ &filter,
+ &mVaBufFilter);
+ CHECK_VA_STATUS_RETURN("vaCreateBuffer");
+
+ VAProcPipelineCaps pipelineCaps;
+ unsigned int numCaps = 1;
+ vaStatus = vaQueryVideoProcPipelineCaps(mVaDpy,
+ mVaCtx,
+ &mVaBufFilter,
+ numCaps,
+ &pipelineCaps);
+ CHECK_VA_STATUS_RETURN("vaQueryVideoProcPipelineCaps");
+
+ if (!(pipelineCaps.rotation_flags & (1 << transFromHalToVa(transform)))) {
+ ETRACE("VA_ROTATION_xxx: 0x%08x is not supported by the filter",
+ transFromHalToVa(transform));
+ return false;
+ }
+
+ mVaInitialized = true;
+
+ return true;
+}
+
+bool RotationBufferProvider::setupRotationBuffer(VideoPayloadBuffer *payload, int transform)
+{
+#ifdef DEBUG_ROTATION_PERFROMANCE
+ uint32_t setup_Begin = getMilliseconds();
+#endif
+ VAStatus vaStatus;
+ int stride;
+ bool ret = false;
+
+ if (payload->format != VA_FOURCC_NV12 || payload->width == 0 || payload->height == 0) {
+ ETRACE("payload data is not correct");
+ return ret;
+ }
+
+ do {
+ if (isContextChanged(payload->width, payload->height, transform)) {
+ ITRACE("Rotation config changes, will re-start VA");
+
+ if (mVaInitialized)
+ stopVA(); // need to re-initialize VA for new rotation config
+
+ mTransform = transform;
+ mWidth = payload->width;
+ mHeight = payload->height;
+ }
+
+ if (!mVaInitialized) {
+ ret = startVA(payload, transform);
+ if (ret == false) {
+ vaStatus = VA_STATUS_ERROR_OPERATION_FAILED;
+ break;
+ }
+ }
+
+ // start to create next target surface
+ if (!mRotatedSurfaces[mTargetIndex]) {
+ ret = createVaSurface(payload, transform, true);
+ if (ret == false) {
+ ETRACE("failed to create target surface with attribute");
+ vaStatus = VA_STATUS_ERROR_OPERATION_FAILED;
+ break;
+ }
+ }
+
+ // create source surface
+ ret = createVaSurface(payload, transform, false);
+ if (ret == false) {
+ ETRACE("failed to create source surface with attribute");
+ vaStatus = VA_STATUS_ERROR_OPERATION_FAILED;
+ break;
+ }
+
+#ifdef DEBUG_ROTATION_PERFROMANCE
+ uint32_t beginPicture = getMilliseconds();
+#endif
+ vaStatus = vaBeginPicture(mVaDpy, mVaCtx, mRotatedSurfaces[mTargetIndex]);
+ CHECK_VA_STATUS_BREAK("vaBeginPicture");
+
+ VABufferID pipelineBuf;
+ void *p;
+ VAProcPipelineParameterBuffer *pipelineParam;
+ vaStatus = vaCreateBuffer(mVaDpy,
+ mVaCtx,
+ VAProcPipelineParameterBufferType,
+ sizeof(*pipelineParam),
+ 1,
+ NULL,
+ &pipelineBuf);
+ CHECK_VA_STATUS_BREAK("vaCreateBuffer");
+
+ vaStatus = vaMapBuffer(mVaDpy, pipelineBuf, &p);
+ CHECK_VA_STATUS_BREAK("vaMapBuffer");
+
+ pipelineParam = (VAProcPipelineParameterBuffer*)p;
+ pipelineParam->surface = mSourceSurface;
+ pipelineParam->rotation_state = transFromHalToVa(transform);
+ pipelineParam->filters = &mVaBufFilter;
+ pipelineParam->num_filters = 1;
+ vaStatus = vaUnmapBuffer(mVaDpy, pipelineBuf);
+ CHECK_VA_STATUS_BREAK("vaUnmapBuffer");
+
+ vaStatus = vaRenderPicture(mVaDpy, mVaCtx, &pipelineBuf, 1);
+ CHECK_VA_STATUS_BREAK("vaRenderPicture");
+
+ vaStatus = vaEndPicture(mVaDpy, mVaCtx);
+ CHECK_VA_STATUS_BREAK("vaEndPicture");
+
+ vaStatus = vaSyncSurface(mVaDpy, mRotatedSurfaces[mTargetIndex]);
+ CHECK_VA_STATUS_BREAK("vaSyncSurface");
+
+#ifdef DEBUG_ROTATION_PERFROMANCE
+ ITRACE("time spent %dms from vaBeginPicture to vaSyncSurface",
+ getMilliseconds() - beginPicture);
+#endif
+
+ // Populate payload fields so that overlayPlane can flip the buffer
+ payload->rotated_width = mRotatedStride;
+ payload->rotated_height = mRotatedHeight;
+ payload->rotated_buffer_handle = mKhandles[mTargetIndex];
+
+ mTargetIndex++;
+ if (mTargetIndex >= MAX_SURFACE_NUM)
+ mTargetIndex = 0;
+
+ } while(0);
+
+#ifdef DEBUG_ROTATION_PERFROMANCE
+ ITRACE("time spent %dms for setupRotationBuffer",
+ getMilliseconds() - setup_Begin);
+#endif
+
+ if (mSourceSurface > 0) {
+ vaStatus = vaDestroySurfaces(mVaDpy, &mSourceSurface, 1);
+ if (vaStatus != VA_STATUS_SUCCESS)
+ WTRACE("vaDestroySurfaces failed, vaStatus = %d", vaStatus);
+ mSourceSurface = 0;
+ }
+
+ if (vaStatus != VA_STATUS_SUCCESS) {
+ stopVA();
+ return false; // To not block in HWC, just abort instead of re-try
+ }
+
+ return true;
+}
+
+void RotationBufferProvider::freeVaSurfaces()
+{
+ bool ret;
+ VAStatus vaStatus;
+
+ for (int i = 0; i < MAX_SURFACE_NUM; i++) {
+ if (NULL != mDrmBuf[i]) {
+ ret = mWsbm->destroyTTMBuffer(mDrmBuf[i]);
+ if (!ret)
+ WTRACE("failed to free TTMBuffer");
+ mDrmBuf[i] = NULL;
+ }
+ }
+
+ // remove wsbm buffer ref from VA
+ for (int j = 0; j < MAX_SURFACE_NUM; j++) {
+ if (0 != mRotatedSurfaces[j]) {
+ vaStatus = vaDestroySurfaces(mVaDpy, &mRotatedSurfaces[j], 1);
+ if (vaStatus != VA_STATUS_SUCCESS)
+ WTRACE("vaDestroySurfaces failed, vaStatus = %d", vaStatus);
+ }
+ mRotatedSurfaces[j] = 0;
+ }
+}
+
+void RotationBufferProvider::stopVA()
+{
+ freeVaSurfaces();
+
+ if (0 != mVaBufFilter)
+ vaDestroyBuffer(mVaDpy, mVaBufFilter);
+ if (0 != mVaCfg)
+ vaDestroyConfig(mVaDpy,mVaCfg);
+ if (0 != mVaCtx)
+ vaDestroyContext(mVaDpy, mVaCtx);
+ if (0 != mVaDpy)
+ vaTerminate(mVaDpy);
+
+ mVaInitialized = false;
+
+ // reset VA variable
+ mVaDpy = 0;
+ mVaCfg = 0;
+ mVaCtx = 0;
+ mVaBufFilter = 0;
+ mSourceSurface = 0;
+
+ mWidth = 0;
+ mHeight = 0;
+ mRotatedWidth = 0;
+ mRotatedHeight = 0;
+ mRotatedStride = 0;
+ mTargetIndex = 0;
+}
+
+bool RotationBufferProvider::isContextChanged(int width, int height, int transform)
+{
+ // check rotation config
+ if (height == mHeight &&
+ width == mWidth &&
+ transform == mTransform) {
+ return false;
+ }
+
+ return true;
+}
+
+} // name space intel
+} // name space android
diff --git a/ips/common/RotationBufferProvider.h b/ips/common/RotationBufferProvider.h
new file mode 100644
index 0000000..39da5e8
--- /dev/null
+++ b/ips/common/RotationBufferProvider.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Li Zeng <li.zeng@intel.com>
+ * Jian Sun <jianx.sun@intel.com>
+ */
+
+#ifndef __ROTATIONO_BUFFER_PROVIDER_H__
+#define __ROTATIONO_BUFFER_PROVIDER_H__
+
+#include <va/va.h>
+#include <sys/time.h>
+#include <va/va_tpi.h>
+#include <va/va_vpp.h>
+#include <common/Wsbm.h>
+#include <utils/Timers.h>
+#include <va/va_android.h>
+#include <common/VideoPayloadBuffer.h>
+
+namespace android {
+namespace intel {
+
+#define Display unsigned int
+typedef void* VADisplay;
+typedef int VAStatus;
+
+class RotationBufferProvider {
+
+public:
+ RotationBufferProvider(Wsbm* wsbm);
+ ~RotationBufferProvider();
+
+ bool initialize();
+ void deinitialize();
+ bool setupRotationBuffer(VideoPayloadBuffer *payload, int transform);
+
+private:
+ bool startVA(VideoPayloadBuffer *payload, int transform);
+ void stopVA();
+ bool isContextChanged(int width, int height, int transform);
+ int transFromHalToVa(int transform);
+ uint32_t createWsbmBuffer(int width, int height, void **buf);
+ int getStride(bool isTarget, int width);
+ bool createVaSurface(VideoPayloadBuffer *payload, int transform, bool isTarget);
+ void freeVaSurfaces();
+ inline uint32_t getMilliseconds();
+
+private:
+ enum {
+ MAX_SURFACE_NUM = 4
+ };
+
+ Wsbm* mWsbm;
+
+ bool mVaInitialized;
+ VADisplay mVaDpy;
+ VAConfigID mVaCfg;
+ VAContextID mVaCtx;
+ VABufferID mVaBufFilter;
+ VASurfaceID mSourceSurface;
+ Display mDisplay;
+
+ // rotation config variables
+ int mWidth;
+ int mHeight;
+ int mTransform;
+
+ int mRotatedWidth;
+ int mRotatedHeight;
+ int mRotatedStride;
+
+ int mTargetIndex;
+ int mKhandles[MAX_SURFACE_NUM];
+ VASurfaceID mRotatedSurfaces[MAX_SURFACE_NUM];
+ void *mDrmBuf[MAX_SURFACE_NUM];
+};
+
+} // name space intel
+} // name space android
+
+#endif
diff --git a/ips/common/WsbmWrapper.c b/ips/common/WsbmWrapper.c
index c79f4ca..5966535 100644
--- a/ips/common/WsbmWrapper.c
+++ b/ips/common/WsbmWrapper.c
@@ -187,7 +187,7 @@ int psbWsbmAllocateTTMBuffer(uint32_t size, uint32_t align, void ** buf)
return ret;
}
- wsbmBOReference(wsbmBuf);
+ /* wsbmBOReference(wsbmBuf); */ /* no need to add reference */
*buf = wsbmBuf;
diff --git a/ips/tangier/TngOverlayPlane.cpp b/ips/tangier/TngOverlayPlane.cpp
index 0e674ea..e3cf7d7 100644
--- a/ips/tangier/TngOverlayPlane.cpp
+++ b/ips/tangier/TngOverlayPlane.cpp
@@ -36,7 +36,8 @@ namespace android {
namespace intel {
TngOverlayPlane::TngOverlayPlane(int index, int disp)
- : OverlayPlaneBase(index, disp)
+ : OverlayPlaneBase(index, disp),
+ mRotationBufProvider(NULL)
{
CTRACE();
@@ -91,6 +92,77 @@ bool TngOverlayPlane::setDataBuffer(BufferMapper& mapper)
return true;
}
+bool TngOverlayPlane::initialize(uint32_t bufferCount)
+{
+ if (!OverlayPlaneBase::initialize(bufferCount)) {
+ ETRACE("failed to initialize OverlayPlaneBase");
+ return false;
+ }
+
+ // setup rotation buffer
+ if (!mRotationBufProvider) {
+ mRotationBufProvider = new RotationBufferProvider(mWsbm);
+ if (mRotationBufProvider == NULL)
+ return false;
+ if (!mRotationBufProvider->initialize()) {
+ ETRACE("failed to initialize RotationBufferProvider");
+ return false;
+ }
+ }
+ return true;
+}
+
+void TngOverlayPlane::deinitialize()
+{
+ DEINIT_AND_DELETE_OBJ(mRotationBufProvider);
+ OverlayPlaneBase::deinitialize();
+}
+
+bool TngOverlayPlane::rotatedBufferReady(BufferMapper& mapper)
+{
+ struct VideoPayloadBuffer *payload;
+ uint32_t format;
+ // only NV12_VED has rotated buffer
+ format = mapper.getFormat();
+ if (format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar &&
+ format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled)
+ return false;
+
+ payload = (struct VideoPayloadBuffer *)mapper.getCpuAddress(SUB_BUFFER1);
+ // check payload
+ if (!payload) {
+ ETRACE("no payload found");
+ return false;
+ }
+
+ if (payload->force_output_method == FORCE_OUTPUT_GPU)
+ return false;
+
+ if (payload->client_transform != mTransform) {
+ if (payload->surface_protected) {
+ payload->hwc_timestamp = systemTime();
+ payload->layer_transform = mTransform;
+ }
+
+ if (payload->force_output_method == FORCE_OUTPUT_OVERLAY ||
+ payload->surface_protected) {
+ bool ret;
+ ret = mRotationBufProvider->setupRotationBuffer(payload, mTransform);
+ if (ret == false) {
+ ETRACE("failed to setup rotation buffer");
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ WTRACE("client is not ready");
+ return false;
+ }
+ }
+
+ return true;
+}
+
bool TngOverlayPlane::flush(uint32_t flags)
{
RETURN_FALSE_IF_NOT_INIT();
diff --git a/ips/tangier/TngOverlayPlane.h b/ips/tangier/TngOverlayPlane.h
index 28fd483..7c7e62c 100644
--- a/ips/tangier/TngOverlayPlane.h
+++ b/ips/tangier/TngOverlayPlane.h
@@ -34,6 +34,7 @@
#include <BufferMapper.h>
#include <common/Wsbm.h>
#include <common/OverlayPlaneBase.h>
+#include <common/RotationBufferProvider.h>
#include <displayclass_interface.h>
@@ -49,12 +50,16 @@ public:
virtual bool flip(void *ctx);
virtual void* getContext() const;
+ virtual bool initialize(uint32_t bufferCount);
+ virtual void deinitialize();
+ virtual bool rotatedBufferReady(BufferMapper& mapper);
protected:
virtual bool setDataBuffer(BufferMapper& mapper);
virtual bool flush(uint32_t flags);
protected:
struct intel_dc_plane_ctx mContext;
+ RotationBufferProvider *mRotationBufProvider;
};
} // namespace intel