diff options
author | Robert Crabtree <robert.crabtree@intel.com> | 2013-05-07 14:27:47 -0700 |
---|---|---|
committer | buildbot <buildbot@intel.com> | 2013-05-23 22:07:56 -0700 |
commit | 2e984efc749e64542fce507c9d6f23202344c37a (patch) | |
tree | 2e999cf1f2228f303e09c85639143efc2c581194 | |
parent | 114561fb66d0464f48d373487c29a81859ce33a7 (diff) | |
download | hwcomposer-2e984efc749e64542fce507c9d6f23202344c37a.tar.gz |
widi: Enable extended mode video for Merrifield
BZ: 90154
Patch utilizes HWC 1.2 APIs to enable extended mode. This patch
uses the extended mode implemenation on CTP as a reference.
Change-Id: Iaba9208c7ea7f9677360244a6e7fd522307c4e25
Signed-off-by: Robert Crabtree <robert.crabtree@intel.com>
Reviewed-on: http://android.intel.com:8080/106703
Reviewed-by: cactus <cactus@intel.com>
Reviewed-by: Qiu, Junhai <junhai.qiu@intel.com>
Reviewed-by: Singhi, Ashish <ashish.singhi@intel.com>
Tested-by: Post, DavidX J <davidx.j.post@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
-rw-r--r-- | common/devices/VirtualDevice.cpp | 187 | ||||
-rw-r--r-- | include/IVideoPayloadManager.h | 64 | ||||
-rw-r--r-- | include/VirtualDevice.h | 18 | ||||
-rw-r--r-- | ips/common/VideoPayloadManager.cpp | 101 | ||||
-rw-r--r-- | ips/common/VideoPayloadManager.h | 54 | ||||
-rw-r--r-- | platforms/merrifield/Android.mk | 1 | ||||
-rw-r--r-- | platforms/merrifield/PlatfVirtualDevice.cpp | 7 | ||||
-rw-r--r-- | platforms/merrifield/PlatfVirtualDevice.h | 3 |
8 files changed, 421 insertions, 14 deletions
diff --git a/common/devices/VirtualDevice.cpp b/common/devices/VirtualDevice.cpp index 1acae1f..6ec3e96 100644 --- a/common/devices/VirtualDevice.cpp +++ b/common/devices/VirtualDevice.cpp @@ -26,10 +26,11 @@ * */ #include <HwcTrace.h> -#include <Drm.h> #include <Hwcomposer.h> #include <DisplayPlaneManager.h> +#include <DisplayQuery.h> #include <VirtualDevice.h> +#include <IVideoPayloadManager.h> #include <binder/IServiceManager.h> #include <binder/ProcessState.h> @@ -37,6 +38,19 @@ namespace android { namespace intel { +VirtualDevice::CachedBuffer::CachedBuffer(BufferManager *mgr, buffer_handle_t handle) + : manager(mgr), + buffer(mgr->get((uint32_t) handle)), + mapper(mgr->map(*buffer)) +{ +} + +VirtualDevice::CachedBuffer::~CachedBuffer() +{ + manager->unmap(*mapper); + manager->put(*buffer); +} + VirtualDevice::VirtualDevice(Hwcomposer& hwc, DisplayPlaneManager& dpm) : mInitialized(false), mHwc(hwc), @@ -51,6 +65,19 @@ VirtualDevice::~VirtualDevice() deinitialize(); } +sp<VirtualDevice::CachedBuffer> VirtualDevice::getDisplayBuffer(buffer_handle_t handle) +{ + ssize_t index = mDisplayBufferCache.indexOfKey(handle); + sp<CachedBuffer> cachedBuffer; + if (index == NAME_NOT_FOUND) { + cachedBuffer = new CachedBuffer(mHwc.getBufferManager(), handle); + mDisplayBufferCache.add(handle, cachedBuffer); + } else { + cachedBuffer = mDisplayBufferCache[index]; + } + return cachedBuffer; +} + status_t VirtualDevice::start(sp<IFrameTypeChangeListener> typeChangeListener, bool disableExtVideoMode) { ITRACE(); @@ -84,6 +111,17 @@ status_t VirtualDevice::stop(bool isConnected) status_t VirtualDevice::notifyBufferReturned(int khandle) { CTRACE(); + Mutex::Autolock _l(mHeldBuffersLock); + ssize_t index = mHeldBuffers.indexOfKey(khandle); + if (index == NAME_NOT_FOUND) { + ETRACE("Couldn't find returned khandle %x", khandle); + } else { + sp<CachedBuffer> cachedBuffer = mHeldBuffers.valueAt(index); + if (!mPayloadManager->setRenderStatus(cachedBuffer->mapper, false)) { + ETRACE("Failed to set render status"); + } + mHeldBuffers.removeItemsAt(index, 1); + } return NO_ERROR; } @@ -110,18 +148,83 @@ bool VirtualDevice::prepare(hwc_display_contents_1_t *display) mCurrentConfig = mNextConfig; mNextConfig.forceNotify = false; } + + buffer_handle_t videoFrame = NULL; + hwc_layer_1_t* videoLayer = NULL; + + if (mCurrentConfig.extendedModeEnabled) { + for (size_t i = 0; i < display->numHwLayers-1; i++) { + hwc_layer_1_t& layer = display->hwLayers[i]; + + DisplayAnalyzer *analyzer = mHwc.getDisplayAnalyzer(); + if (analyzer->isVideoLayer(layer)) { + videoFrame = layer.handle; + videoLayer = &layer; + break; + } + } + } + bool extActive = false; if (mCurrentConfig.typeChangeListener != NULL) { FrameInfo frameInfo; - if (!extActive) - { + if (videoFrame != NULL) { + sp<CachedBuffer> cachedBuffer; + if ((cachedBuffer = getDisplayBuffer(videoFrame)) == NULL) { + ETRACE("Failed to map display buffer"); + } else { + memset(&frameInfo, 0, sizeof(frameInfo)); + + IVideoPayloadManager::MetaData metadata; + if (mPayloadManager->getMetaData(cachedBuffer->mapper, &metadata)) { + + frameInfo.frameType = HWC_FRAMETYPE_VIDEO; + frameInfo.bufferFormat = metadata.format; + + hwc_layer_1_t& layer = *videoLayer; + if ((metadata.transform & HAL_TRANSFORM_ROT_90) == 0) { + frameInfo.contentWidth = layer.sourceCrop.right - layer.sourceCrop.left; + frameInfo.contentHeight = layer.sourceCrop.bottom - layer.sourceCrop.top; + } else { + frameInfo.contentWidth = layer.sourceCrop.bottom - layer.sourceCrop.top; + frameInfo.contentHeight = layer.sourceCrop.right - layer.sourceCrop.left; + } + + frameInfo.bufferWidth = metadata.width; + frameInfo.bufferHeight = metadata.height; + frameInfo.lumaUStride = metadata.lumaStride; + frameInfo.chromaUStride = metadata.chromaUStride; + frameInfo.chromaVStride = metadata.chromaVStride; + + // TODO: Need to get framerate from HWC when available (for now indicate default with zero) + frameInfo.contentFrameRateN = 0; + frameInfo.contentFrameRateD = 1; + + if (frameInfo.bufferFormat != 0 && + frameInfo.bufferWidth >= frameInfo.contentWidth && + frameInfo.bufferHeight >= frameInfo.contentHeight && + frameInfo.contentWidth > 0 && frameInfo.contentHeight > 0 && + frameInfo.lumaUStride > 0 && + frameInfo.chromaUStride > 0 && frameInfo.chromaVStride > 0) { + extActive = true; + } else { + ITRACE("Payload cleared or inconsistent info, aborting extended mode"); + } + } else { + ETRACE("Failed to get metadata"); + } + } + } + + if (!extActive) { memset(&frameInfo, 0, sizeof(frameInfo)); frameInfo.frameType = HWC_FRAMETYPE_NOTHING; } - if (mCurrentConfig.forceNotify != 0) { + + if (mCurrentConfig.forceNotify || memcmp(&frameInfo, &mLastFrameInfo, sizeof(frameInfo)) != 0) { // something changed, notify type change listener - //mCurrentConfig.typeChangeListener->frameTypeChanged(frameInfo); + mCurrentConfig.typeChangeListener->frameTypeChanged(frameInfo); mCurrentConfig.typeChangeListener->bufferInfoChanged(frameInfo); mExtLastTimestamp = 0; @@ -129,8 +232,8 @@ bool VirtualDevice::prepare(hwc_display_contents_1_t *display) if (frameInfo.frameType == HWC_FRAMETYPE_NOTHING) { ITRACE("Clone mode"); - } - else { + mDisplayBufferCache.clear(); + } else { ITRACE("Extended mode: %dx%d in %dx%d @ %d fps", frameInfo.contentWidth, frameInfo.contentHeight, frameInfo.bufferWidth, frameInfo.bufferHeight, @@ -138,7 +241,50 @@ bool VirtualDevice::prepare(hwc_display_contents_1_t *display) } mLastFrameInfo = frameInfo; } - } + } + + if (extActive) { + // tell surfaceflinger to not render the layers if we're + // in extended video mode + for (size_t i = 0; i < display->numHwLayers-1; i++) { + hwc_layer_1_t& layer = display->hwLayers[i]; + if (layer.compositionType != HWC_BACKGROUND) { + layer.compositionType = HWC_OVERLAY; + layer.flags |= HWC_HINT_DISABLE_ANIMATION; + } + } + + if (mCurrentConfig.frameListener != NULL) { + sp<CachedBuffer> cachedBuffer = getDisplayBuffer(videoFrame); + if (cachedBuffer == NULL) { + ETRACE("Failed to map display buffer"); + return true; + } + + IVideoPayloadManager::MetaData metadata; + if (mPayloadManager->getMetaData(cachedBuffer->mapper, &metadata)) { + + if (metadata.timestamp == mExtLastTimestamp && metadata.kHandle == mExtLastKhandle) + return true; + + mExtLastTimestamp = metadata.timestamp; + mExtLastKhandle = metadata.kHandle; + + status_t status = mCurrentConfig.frameListener->onFrameReady( + metadata.kHandle, HWC_HANDLE_TYPE_KBUF, systemTime(), metadata.timestamp); + if (status == OK) { + if (!mPayloadManager->setRenderStatus(cachedBuffer->mapper, true)) { + ETRACE("Failed to set render status"); + } + Mutex::Autolock _l(mHeldBuffersLock); + mHeldBuffers.add(metadata.kHandle, cachedBuffer); + } + } else { + ETRACE("Failed to get metadata"); + } + } + } + return true; } @@ -234,16 +380,25 @@ bool VirtualDevice::initialize() mCurrentConfig = mNextConfig; memset(&mLastFrameInfo, 0, sizeof(mLastFrameInfo)); - mInitialized = true; + + mPayloadManager = createVideoPayloadManager(); + if (!mPayloadManager) { + ETRACE("Failed to create payload manager"); + return false; + } + // Publish frame server service with service manager status_t ret = defaultServiceManager()->addService(String16("hwc.widi"), this); - if (ret != NO_ERROR) { + if (ret == NO_ERROR) { + ProcessState::self()->startThreadPool(); + mInitialized = true; + } else { ETRACE("Could not register hwc.widi with service manager, error = %d", ret); - mInitialized = false; - return false; + delete mPayloadManager; + mPayloadManager = NULL; } - ProcessState::self()->startThreadPool(); - return true; + + return mInitialized; } bool VirtualDevice::isConnected() const @@ -268,6 +423,10 @@ void VirtualDevice::dump(Dump& d) void VirtualDevice::deinitialize() { mInitialized = false; + if (mPayloadManager) { + delete mPayloadManager; + mPayloadManager = NULL; + } } } // namespace intel diff --git a/include/IVideoPayloadManager.h b/include/IVideoPayloadManager.h new file mode 100644 index 0000000..1a543dc --- /dev/null +++ b/include/IVideoPayloadManager.h @@ -0,0 +1,64 @@ +/* + * Copyright © 2013 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: + * Robert Crabtree <robert.crabtree@intel.com> + * + */ +#ifndef IVIDEO_PAYLOAD_MANAGER_H +#define IVIDEO_PAYLOAD_MANAGER_H + +#include <hardware/hwcomposer.h> + +namespace android { +namespace intel { + +class BufferMapper; + +class IVideoPayloadManager { +public: + IVideoPayloadManager() {} + virtual ~IVideoPayloadManager() {} + +public: + struct MetaData { + uint32_t kHandle; + uint32_t transform; + uint32_t width; + uint32_t height; + uint32_t format; + uint16_t lumaStride; + uint16_t chromaUStride; + uint16_t chromaVStride; + int64_t timestamp; + }; + +public: + virtual bool getMetaData(BufferMapper *mapper, MetaData *metadata) = 0; + virtual bool setRenderStatus(BufferMapper *mapper, bool renderStatus) = 0; +}; + +} // namespace intel +} // namespace android + +#endif /* IVIDEO_PAYLOAD_MANAGER_H */ diff --git a/include/VirtualDevice.h b/include/VirtualDevice.h index f0a39c6..7d83db8 100644 --- a/include/VirtualDevice.h +++ b/include/VirtualDevice.h @@ -37,9 +37,17 @@ namespace intel { class Hwcomposer; class DisplayPlaneManager; +class IVideoPayloadManager; class VirtualDevice : public IDisplayDevice, public BnFrameServer { protected: + struct CachedBuffer : public android::RefBase { + CachedBuffer(BufferManager *mgr, buffer_handle_t handle); + ~CachedBuffer(); + BufferManager *manager; + DataBuffer *buffer; + BufferMapper *mapper; + }; struct Configuration { sp<IFrameTypeChangeListener> typeChangeListener; sp<IFrameListener> frameListener; @@ -56,6 +64,14 @@ protected: Mutex mListenerLock; FrameInfo mLastFrameInfo; + + android::KeyedVector<buffer_handle_t, android::sp<CachedBuffer> > mDisplayBufferCache; + android::Mutex mHeldBuffersLock; + android::KeyedVector<uint32_t, android::sp<CachedBuffer> > mHeldBuffers; + +private: + android::sp<CachedBuffer> getDisplayBuffer(buffer_handle_t handle); + public: VirtualDevice(Hwcomposer& hwc, DisplayPlaneManager& dpm); virtual ~VirtualDevice(); @@ -87,11 +103,13 @@ public: virtual android::status_t setResolution(const FrameProcessingPolicy& policy, android::sp<IFrameListener> listener); protected: virtual void deinitialize(); + virtual IVideoPayloadManager* createVideoPayloadManager() = 0; protected: bool mInitialized; Hwcomposer& mHwc; DisplayPlaneManager& mDisplayPlaneManager; + IVideoPayloadManager *mPayloadManager; }; } diff --git a/ips/common/VideoPayloadManager.cpp b/ips/common/VideoPayloadManager.cpp new file mode 100644 index 0000000..e54efff --- /dev/null +++ b/ips/common/VideoPayloadManager.cpp @@ -0,0 +1,101 @@ +/* + * Copyright © 2013 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: + * Robert Crabtree <robert.crabtree@intel.com> + * + */ + +#include <HwcTrace.h> +#include <BufferMapper.h> +#include <common/GrallocSubBuffer.h> +#include <common/VideoPayloadManager.h> +#include <common/VideoPayloadBuffer.h> + +namespace android { +namespace intel { + +VideoPayloadManager::VideoPayloadManager() + : IVideoPayloadManager() +{ +} + +VideoPayloadManager::~VideoPayloadManager() +{ +} + +bool VideoPayloadManager::getMetaData(BufferMapper *mapper, MetaData *metadata) +{ + if (!mapper || !metadata) { + ETRACE("Null input params"); + return false; + } + + VideoPayloadBuffer *p = (VideoPayloadBuffer*) mapper->getCpuAddress(SUB_BUFFER1); + if (!p) { + ETRACE("Got null payload from display buffer"); + return false; + } + + metadata->format = p->format; + metadata->transform = p->metadata_transform; + metadata->timestamp = p->timestamp; + + if (p->metadata_transform == 0) { + metadata->width = p->width; + metadata->height = p->height; + metadata->lumaStride = p->luma_stride; + metadata->chromaUStride = p->chroma_u_stride; + metadata->chromaVStride = p->chroma_v_stride; + metadata->kHandle = p->khandle; + } else { + metadata->width = p->rotated_width; + metadata->height = p->rotated_height; + metadata->lumaStride = p->rotate_luma_stride; + metadata->chromaUStride = p->rotate_chroma_u_stride; + metadata->chromaVStride = p->rotate_chroma_v_stride; + metadata->kHandle = p->rotated_buffer_handle; + } + + return true; +} + +bool VideoPayloadManager::setRenderStatus(BufferMapper *mapper, bool renderStatus) +{ + if (!mapper) { + ETRACE("Null mapper param"); + return false; + } + + VideoPayloadBuffer* p = (VideoPayloadBuffer*) mapper->getCpuAddress(SUB_BUFFER1); + if (!p) { + ETRACE("Got null payload from display buffer"); + return false; + } + + p->renderStatus = renderStatus ? 1 : 0; + return true; +} + +} // namespace intel +} // namespace android diff --git a/ips/common/VideoPayloadManager.h b/ips/common/VideoPayloadManager.h new file mode 100644 index 0000000..a13d6b9 --- /dev/null +++ b/ips/common/VideoPayloadManager.h @@ -0,0 +1,54 @@ +/* + * Copyright © 2013 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: + * Robert Crabtree <robert.crabtree@intel.com> + * + */ +#ifndef VIDEO_PAYLOAD_MANAGER_H +#define VIDEO_PAYLOAD_MANAGER_H + +#include <IVideoPayloadManager.h> + +namespace android { +namespace intel { + +class BufferMapper; + +class VideoPayloadManager : public IVideoPayloadManager { + +public: + VideoPayloadManager(); + virtual ~VideoPayloadManager(); + + // IVideoPayloadManager +public: + virtual bool getMetaData(BufferMapper *mapper, MetaData *metadata); + virtual bool setRenderStatus(BufferMapper *mapper, bool renderStatus); + +}; // class VideoPayloadManager + +} // namespace intel +} // namespace android + +#endif /* VIDEO_PAYLOAD_MANAGER_H */ diff --git a/platforms/merrifield/Android.mk b/platforms/merrifield/Android.mk index c4b03fb..831e478 100644 --- a/platforms/merrifield/Android.mk +++ b/platforms/merrifield/Android.mk @@ -58,6 +58,7 @@ LOCAL_SRC_FILES += \ ../../ips/common/GrallocBufferMapperBase.cpp \ ../../ips/common/TTMBufferMapper.cpp \ ../../ips/common/DrmConfig.cpp \ + ../../ips/common/VideoPayloadManager.cpp \ ../../ips/common/Wsbm.cpp \ ../../ips/common/WsbmWrapper.c diff --git a/platforms/merrifield/PlatfVirtualDevice.cpp b/platforms/merrifield/PlatfVirtualDevice.cpp index 989eba9..a6ac4cb 100644 --- a/platforms/merrifield/PlatfVirtualDevice.cpp +++ b/platforms/merrifield/PlatfVirtualDevice.cpp @@ -29,6 +29,7 @@ #include <Hwcomposer.h> #include <DisplayPlaneManager.h> #include <PlatfVirtualDevice.h> +#include <common/VideoPayloadManager.h> namespace android { namespace intel { @@ -45,6 +46,12 @@ PlatfVirtualDevice::~PlatfVirtualDevice() CTRACE(); } +IVideoPayloadManager* PlatfVirtualDevice::createVideoPayloadManager() +{ + return new VideoPayloadManager(); +} + + } // namespace intel } // namespace android diff --git a/platforms/merrifield/PlatfVirtualDevice.h b/platforms/merrifield/PlatfVirtualDevice.h index 88b2334..e891906 100644 --- a/platforms/merrifield/PlatfVirtualDevice.h +++ b/platforms/merrifield/PlatfVirtualDevice.h @@ -34,11 +34,14 @@ namespace android { namespace intel { +class IVideoPayloadManager; + class PlatfVirtualDevice : public VirtualDevice { public: PlatfVirtualDevice(Hwcomposer& hwc, DisplayPlaneManager& dpm); ~PlatfVirtualDevice(); + virtual IVideoPayloadManager* createVideoPayloadManager(); }; } |