diff options
author | Sun, Jian <jianx.sun@intel.com> | 2013-08-15 11:33:24 +0800 |
---|---|---|
committer | cactus <cactus@intel.com> | 2013-09-24 22:52:43 -0700 |
commit | fa92afb1e8276eefc983bd8e209a1e1b098d5b95 (patch) | |
tree | 3eac0e0636c426142bc708b63ff980c7e35ad155 /ips | |
parent | 4fddd8df606f33efc106924c02f3afc47724cacd (diff) | |
download | hwcomposer-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.cpp | 535 | ||||
-rw-r--r-- | ips/common/RotationBufferProvider.h | 102 | ||||
-rw-r--r-- | ips/common/WsbmWrapper.c | 2 | ||||
-rw-r--r-- | ips/tangier/TngOverlayPlane.cpp | 74 | ||||
-rw-r--r-- | ips/tangier/TngOverlayPlane.h | 5 |
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 |