diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp index 5b20ba4..a0ae331 100644 --- a/libhwcomposer/hwc_video.cpp +++ b/libhwcomposer/hwc_video.cpp @@ -39,11 +39,15 @@ bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_layer_list_t *list) { ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__); return false; } + if(sYuvLayerIndex == -1) { + return false; + } chooseState(ctx); //if the state chosen above is CLOSED, skip this block. if(sState != ovutils::OV_CLOSED) { if(configure(ctx, &list->hwLayers[sYuvLayerIndex])) { markFlags(&list->hwLayers[sYuvLayerIndex]); + sIsModeOn = true; } } @@ -65,8 +69,7 @@ void VideoOverlay::chooseState(hwc_context_t *ctx) { if(sYuvCount == 1) { //Skip on primary, display on ext. if(sIsLayerSkip && ctx->mExtDisplay->getExternalDisplay()) { - //TODO - //VIDEO_ON_TV_ONLY + newState = ovutils::OV_2D_VIDEO_ON_TV; } else if(sIsLayerSkip) { //skip on primary, no ext newState = ovutils::OV_CLOSED; } else if(ctx->mExtDisplay->getExternalDisplay()) { @@ -88,110 +91,169 @@ void VideoOverlay::markFlags(hwc_layer_t *layer) { layer->compositionType = HWC_OVERLAY; layer->hints |= HWC_HINT_CLEAR_FB; break; - //TODO - //case ovutils::OV_2D_VIDEO_ON_TV: - //just break, dont update flags. + case ovutils::OV_2D_VIDEO_ON_TV: + break; //dont update flags. default: break; } } -bool VideoOverlay::configure(hwc_context_t *ctx, hwc_layer_t *layer) -{ - if (LIKELY(ctx->mOverlay)) { +/* Helpers */ +bool configPrimVid(hwc_context_t *ctx, hwc_layer_t *layer) { + overlay::Overlay& ov = *(ctx->mOverlay); + private_handle_t *hnd = (private_handle_t *)layer->handle; + ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); - overlay::Overlay& ov = *(ctx->mOverlay); - // Set overlay state - ov.setState(sState); + ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; + if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { + ovutils::setMdpFlags(mdpFlags, + ovutils::OV_MDP_SECURE_OVERLAY_SESSION); + } - private_handle_t *hnd = (private_handle_t *)layer->handle; - ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); + ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF; + if (ctx->numHwLayers == 1) { + isFgFlag = ovutils::IS_FG_SET; + } - //TODO change this based on state. - ovutils::eDest dest = ovutils::OV_PIPE_ALL; + ovutils::PipeArgs parg(mdpFlags, + info, + ovutils::ZORDER_0, + isFgFlag, + ovutils::ROT_FLAG_DISABLED); + ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg }; + ov.setSource(pargs, ovutils::OV_PIPE0); - ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; - if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { - ovutils::setMdpFlags(mdpFlags, - ovutils::OV_MDP_SECURE_OVERLAY_SESSION); - } + hwc_rect_t sourceCrop = layer->sourceCrop; + // x,y,w,h + ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top, + sourceCrop.right - sourceCrop.left, + sourceCrop.bottom - sourceCrop.top); - ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF; - if (ctx->numHwLayers == 1) { - isFgFlag = ovutils::IS_FG_SET; - } + ovutils::Dim dpos; + hwc_rect_t displayFrame = layer->displayFrame; + dpos.x = displayFrame.left; + dpos.y = displayFrame.top; + dpos.w = (displayFrame.right - displayFrame.left); + dpos.h = (displayFrame.bottom - displayFrame.top); - ovutils::PipeArgs parg(mdpFlags, - info, - ovutils::ZORDER_0, - isFgFlag, - ovutils::ROT_FLAG_DISABLED); - ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg }; - ov.setSource(pargs, dest); - - hwc_rect_t sourceCrop = layer->sourceCrop; - // x,y,w,h - ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top, - sourceCrop.right - sourceCrop.left, - sourceCrop.bottom - sourceCrop.top); - //Only for External - ov.setCrop(dcrop, ovutils::OV_PIPE1); - - // FIXME: Use source orientation for TV when source is portrait - //Only for External - ov.setTransform(0, dest); - - ovutils::Dim dpos; - hwc_rect_t displayFrame = layer->displayFrame; - dpos.x = displayFrame.left; - dpos.y = displayFrame.top; - dpos.w = (displayFrame.right - displayFrame.left); - dpos.h = (displayFrame.bottom - displayFrame.top); - - //Only for External - ov.setPosition(dpos, ovutils::OV_PIPE1); - - //Calculate the rect for primary based on whether the supplied position - //is within or outside bounds. - const int fbWidth = + //Calculate the rect for primary based on whether the supplied position + //is within or outside bounds. + const int fbWidth = ovutils::FrameBufferInfo::getInstance()->getWidth(); - const int fbHeight = + const int fbHeight = ovutils::FrameBufferInfo::getInstance()->getHeight(); - if( displayFrame.left < 0 || + if( displayFrame.left < 0 || displayFrame.top < 0 || displayFrame.right > fbWidth || displayFrame.bottom > fbHeight) { - calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight); + calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight); - //Update calculated width and height - dcrop.w = sourceCrop.right - sourceCrop.left; - dcrop.h = sourceCrop.bottom - sourceCrop.top; + //Update calculated width and height + dcrop.w = sourceCrop.right - sourceCrop.left; + dcrop.h = sourceCrop.bottom - sourceCrop.top; - dpos.w = displayFrame.right - displayFrame.left; - dpos.h = displayFrame.bottom - displayFrame.top; - } - - //Only for Primary - ov.setCrop(dcrop, ovutils::OV_PIPE0); - - int transform = layer->transform & FINAL_TRANSFORM_MASK; - ovutils::eTransform orient = - static_cast(transform); - ov.setTransform(orient, ovutils::OV_PIPE0); - - ov.setPosition(dpos, ovutils::OV_PIPE0); - - //Both prim and external - if (!ov.commit(dest)) { - ALOGE("%s: commit fails", __FUNCTION__); - return false; - } - - sIsModeOn = true; + dpos.w = displayFrame.right - displayFrame.left; + dpos.h = displayFrame.bottom - displayFrame.top; } - return sIsModeOn; + + //Only for Primary + ov.setCrop(dcrop, ovutils::OV_PIPE0); + + int transform = layer->transform & FINAL_TRANSFORM_MASK; + ovutils::eTransform orient = + static_cast(transform); + ov.setTransform(orient, ovutils::OV_PIPE0); + + ov.setPosition(dpos, ovutils::OV_PIPE0); + + if (!ov.commit(ovutils::OV_PIPE0)) { + ALOGE("%s: commit fails", __FUNCTION__); + return false; + } + return true; +} + +bool configExtVid(hwc_context_t *ctx, hwc_layer_t *layer) { + overlay::Overlay& ov = *(ctx->mOverlay); + private_handle_t *hnd = (private_handle_t *)layer->handle; + ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size); + + ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE; + if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) { + ovutils::setMdpFlags(mdpFlags, + ovutils::OV_MDP_SECURE_OVERLAY_SESSION); + } + + ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF; + if (ctx->numHwLayers == 1) { + isFgFlag = ovutils::IS_FG_SET; + } + + ovutils::PipeArgs parg(mdpFlags, + info, + ovutils::ZORDER_0, + isFgFlag, + ovutils::ROT_FLAG_DISABLED); + ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg }; + ov.setSource(pargs, ovutils::OV_PIPE1); + + hwc_rect_t sourceCrop = layer->sourceCrop; + // x,y,w,h + ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top, + sourceCrop.right - sourceCrop.left, + sourceCrop.bottom - sourceCrop.top); + //Only for External + ov.setCrop(dcrop, ovutils::OV_PIPE1); + + // FIXME: Use source orientation for TV when source is portrait + //Only for External + ov.setTransform(0, ovutils::OV_PIPE1); + + ovutils::Dim dpos; + hwc_rect_t displayFrame = layer->displayFrame; + dpos.x = displayFrame.left; + dpos.y = displayFrame.top; + dpos.w = (displayFrame.right - displayFrame.left); + dpos.h = (displayFrame.bottom - displayFrame.top); + + //Only for External + ov.setPosition(dpos, ovutils::OV_PIPE1); + + if (!ov.commit(ovutils::OV_PIPE1)) { + ALOGE("%s: commit fails", __FUNCTION__); + return false; + } + return true; +} + +bool VideoOverlay::configure(hwc_context_t *ctx, hwc_layer_t *yuvLayer) +{ + bool ret = true; + if (LIKELY(ctx->mOverlay)) { + overlay::Overlay& ov = *(ctx->mOverlay); + // Set overlay state + ov.setState(sState); + switch(sState) { + case ovutils::OV_2D_VIDEO_ON_PANEL: + ret &= configPrimVid(ctx, yuvLayer); + break; + case ovutils::OV_2D_VIDEO_ON_PANEL_TV: + ret &= configExtVid(ctx, yuvLayer); + ret &= configPrimVid(ctx, yuvLayer); + break; + case ovutils::OV_2D_VIDEO_ON_TV: + ret &= configExtVid(ctx, yuvLayer); + break; + default: + return false; + } + } else { + //Ov null + return false; + } + return ret; } bool VideoOverlay::draw(hwc_context_t *ctx, hwc_layer_list_t *list) @@ -211,37 +273,47 @@ bool VideoOverlay::draw(hwc_context_t *ctx, hwc_layer_list_t *list) switch (state) { case ovutils::OV_2D_VIDEO_ON_PANEL_TV: - case ovutils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: // Play external if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) { ALOGE("%s: queueBuffer failed for external", __FUNCTION__); ret = false; } - // Play primary if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) { ALOGE("%s: queueBuffer failed for primary", __FUNCTION__); ret = false; } - // Wait for external vsync to be done if (!ov.waitForVsync(ovutils::OV_PIPE1)) { ALOGE("%s: waitForVsync failed for external", __FUNCTION__); ret = false; } break; - default: - // In most cases, displaying only to one (primary or external) - // so use OV_PIPE_ALL since overlay will ignore NullPipes - if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE_ALL)) { - ALOGE("%s: queueBuffer failed", __FUNCTION__); + case ovutils::OV_2D_VIDEO_ON_PANEL: + // Play primary + if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) { + ALOGE("%s: queueBuffer failed for primary", __FUNCTION__); ret = false; } break; + case ovutils::OV_2D_VIDEO_ON_TV: + // Play external + if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) { + ALOGE("%s: queueBuffer failed for external", __FUNCTION__); + ret = false; + } + // Wait for external vsync to be done + if (!ov.waitForVsync(ovutils::OV_PIPE1)) { + ALOGE("%s: waitForVsync failed for external", __FUNCTION__); + ret = false; + } + default: + ALOGE("%s Unused state %s", __FUNCTION__, + ovutils::getStateString(state)); + break; } return ret; } - }; //namespace qhwc diff --git a/liboverlay/Android.mk b/liboverlay/Android.mk index 67bb85f..bb83111 100644 --- a/liboverlay/Android.mk +++ b/liboverlay/Android.mk @@ -13,7 +13,6 @@ LOCAL_SRC_FILES := \ overlayCtrl.cpp \ overlayUtils.cpp \ overlayMdp.cpp \ - overlayRotator.cpp \ - overlayTransitions.cpp + overlayRotator.cpp include $(BUILD_SHARED_LIBRARY) diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp index a05a307..4dea6ef 100644 --- a/liboverlay/overlay.cpp +++ b/liboverlay/overlay.cpp @@ -54,6 +54,7 @@ bool Overlay::commit(utils::eDest dest) switch (st) { case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL_TV: + case utils::OV_2D_VIDEO_ON_TV: case utils::OV_3D_VIDEO_ON_2D_PANEL: case utils::OV_3D_VIDEO_ON_3D_PANEL: case utils::OV_3D_VIDEO_ON_3D_TV: @@ -63,6 +64,7 @@ bool Overlay::commit(utils::eDest dest) case utils::OV_BYPASS_1_LAYER: case utils::OV_BYPASS_2_LAYER: case utils::OV_BYPASS_3_LAYER: + case utils::OV_DUAL_DISP: if(!mOv->commit(dest)) { ALOGE("Overlay %s failed", __FUNCTION__); return false; @@ -85,6 +87,7 @@ bool Overlay::queueBuffer(int fd, uint32_t offset, switch (st) { case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL_TV: + case utils::OV_2D_VIDEO_ON_TV: case utils::OV_3D_VIDEO_ON_2D_PANEL: case utils::OV_3D_VIDEO_ON_3D_PANEL: case utils::OV_3D_VIDEO_ON_3D_TV: @@ -94,6 +97,7 @@ bool Overlay::queueBuffer(int fd, uint32_t offset, case utils::OV_BYPASS_1_LAYER: case utils::OV_BYPASS_2_LAYER: case utils::OV_BYPASS_3_LAYER: + case utils::OV_DUAL_DISP: if(!mOv->queueBuffer(fd, offset, dest)) { ALOGE("Overlay %s failed", __FUNCTION__); return false; @@ -115,6 +119,7 @@ bool Overlay::waitForVsync(utils::eDest dest) switch (st) { case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL_TV: + case utils::OV_2D_VIDEO_ON_TV: case utils::OV_3D_VIDEO_ON_2D_PANEL: case utils::OV_3D_VIDEO_ON_3D_PANEL: case utils::OV_3D_VIDEO_ON_3D_TV: @@ -124,6 +129,7 @@ bool Overlay::waitForVsync(utils::eDest dest) case utils::OV_BYPASS_1_LAYER: case utils::OV_BYPASS_2_LAYER: case utils::OV_BYPASS_3_LAYER: + case utils::OV_DUAL_DISP: if(!mOv->waitForVsync(dest)) { ALOGE("Overlay %s failed", __FUNCTION__); return false; @@ -146,6 +152,7 @@ bool Overlay::setCrop(const utils::Dim& d, switch (st) { case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL_TV: + case utils::OV_2D_VIDEO_ON_TV: case utils::OV_3D_VIDEO_ON_2D_PANEL: case utils::OV_3D_VIDEO_ON_3D_PANEL: case utils::OV_3D_VIDEO_ON_3D_TV: @@ -155,6 +162,7 @@ bool Overlay::setCrop(const utils::Dim& d, case utils::OV_BYPASS_1_LAYER: case utils::OV_BYPASS_2_LAYER: case utils::OV_BYPASS_3_LAYER: + case utils::OV_DUAL_DISP: if(!mOv->setCrop(d, dest)) { ALOGE("Overlay %s failed", __FUNCTION__); return false; @@ -176,6 +184,7 @@ bool Overlay::setPosition(const utils::Dim& d, switch (st) { case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL_TV: + case utils::OV_2D_VIDEO_ON_TV: case utils::OV_3D_VIDEO_ON_2D_PANEL: case utils::OV_3D_VIDEO_ON_3D_PANEL: case utils::OV_3D_VIDEO_ON_3D_TV: @@ -185,6 +194,7 @@ bool Overlay::setPosition(const utils::Dim& d, case utils::OV_BYPASS_1_LAYER: case utils::OV_BYPASS_2_LAYER: case utils::OV_BYPASS_3_LAYER: + case utils::OV_DUAL_DISP: if(!mOv->setPosition(d, dest)) { ALOGE("Overlay %s failed", __FUNCTION__); return false; @@ -207,6 +217,7 @@ bool Overlay::setTransform(const int orient, switch (st) { case utils::OV_2D_VIDEO_ON_PANEL: case utils::OV_2D_VIDEO_ON_PANEL_TV: + case utils::OV_2D_VIDEO_ON_TV: case utils::OV_3D_VIDEO_ON_2D_PANEL: case utils::OV_3D_VIDEO_ON_3D_PANEL: case utils::OV_3D_VIDEO_ON_3D_TV: @@ -216,6 +227,7 @@ bool Overlay::setTransform(const int orient, case utils::OV_BYPASS_1_LAYER: case utils::OV_BYPASS_2_LAYER: case utils::OV_BYPASS_3_LAYER: + case utils::OV_DUAL_DISP: if(!mOv->setTransform(transform, dest)) { ALOGE("Overlay %s failed", __FUNCTION__); return false; @@ -247,11 +259,13 @@ bool Overlay::setSource(const utils::PipeArgs args[utils::MAX_PIPES], case utils::OV_BYPASS_1_LAYER: case utils::OV_BYPASS_2_LAYER: case utils::OV_BYPASS_3_LAYER: + case utils::OV_DUAL_DISP: break; case utils::OV_3D_VIDEO_ON_3D_PANEL: case utils::OV_3D_VIDEO_ON_3D_TV: //TODO set zorder for channel 1 as 1 in 3D pipe case utils::OV_2D_VIDEO_ON_PANEL_TV: + case utils::OV_2D_VIDEO_ON_TV: case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: break; case utils::OV_2D_TRUE_UI_MIRROR: diff --git a/liboverlay/overlayState.h b/liboverlay/overlayState.h index ea6860f..518eafa 100644 --- a/liboverlay/overlayState.h +++ b/liboverlay/overlayState.h @@ -46,17 +46,15 @@ namespace overlay { class OverlayState : utils::NoCopy { public: - /**/ + /*ctor*/ explicit OverlayState(); - /**/ + /*dtor*/ ~OverlayState(); /* return current state */ utils::eOverlayState state() const; - /* Overlay Event */ - /* Hard reset to a new state. If the state is the same * as the current one, it would be a no-op */ OverlayImplBase* reset(utils::eOverlayState s); @@ -68,54 +66,31 @@ public: OverlayImplBase* handleEvent(utils::eOverlayState s, OverlayImplBase* ov); - /* Transitions from XXX to XXX */ - OverlayImplBase* handle_closed(utils::eOverlayState s); - OverlayImplBase* handle_2D_2DPanel(utils::eOverlayState s, - OverlayImplBase* ov); - OverlayImplBase* handle_2D_2DTV(utils::eOverlayState s, - OverlayImplBase* ov); - OverlayImplBase* handle_3D_2DPanel(utils::eOverlayState s, - OverlayImplBase* ov); - OverlayImplBase* handle_3D_3DPanel(utils::eOverlayState s, - OverlayImplBase* ov); - OverlayImplBase* handle_3D_3DTV(utils::eOverlayState s, - OverlayImplBase* ov); - OverlayImplBase* handle_3D_2DTV(utils::eOverlayState s, - OverlayImplBase* ov); - OverlayImplBase* handle_UI_Mirror(utils::eOverlayState s, - OverlayImplBase* ov); - OverlayImplBase* handle_2D_trueUI_Mirror(utils::eOverlayState s, - OverlayImplBase* ov); - OverlayImplBase* handle_bypass(utils::eOverlayState s, - OverlayImplBase* ov); - - /* Transition from any state to 2D video on 2D panel */ - OverlayImplBase* handle_xxx_to_2D_2DPanel(OverlayImplBase* ov); - - /* Transition from any state to 2D video on 2D panel and 2D TV */ - OverlayImplBase* handle_xxx_to_2D_2DTV(OverlayImplBase* ov); - - /* Transition from any state to 3D video on 2D panel */ - OverlayImplBase* handle_xxx_to_3D_2DPanel(OverlayImplBase* ov); - - /* Transition from any state to 3D video on 2D panel and 2D TV */ - OverlayImplBase* handle_xxx_to_3D_2DTV(OverlayImplBase* ov); - - /* Transition from any state to 2D video true UI mirroring (2D video + UI) */ - OverlayImplBase* handle_xxx_to_2D_trueUI_Mirror(OverlayImplBase* ov); - - /* Transitions from any state to 1 layer composition bypass */ - OverlayImplBase* handle_xxx_to_bypass1(OverlayImplBase* ov); - - /* Transitions from any state to 2 layers composition bypass */ - OverlayImplBase* handle_xxx_to_bypass2(OverlayImplBase* ov); - - /* Transitions from any state to 3 layers composition bypass */ - OverlayImplBase* handle_xxx_to_bypass3(OverlayImplBase* ov); - /* Dump */ void dump() const; + private: + + /* Transitions from a state to a state. Default behavior is to move from an + * old state to CLOSED and from CLOSED to a new state. Any impl wishing to + * copy pipes should specialize this call */ + template + OverlayImplBase* handle_from_to(OverlayImplBase* ov); + + /* Just a convenient intermediate function to bring down the number of + * combinations arising from multiple states */ + template + OverlayImplBase* handle_from(utils::eOverlayState toState, + OverlayImplBase* ov); + + /* Substitues for partially specialized templated handle functions since the + * standard doesn't allow partial specialization of functions */ + template + OverlayImplBase* handle_xxx_to_CLOSED(OverlayImplBase* ov); + + template + OverlayImplBase* handle_CLOSED_to_xxx(OverlayImplBase* ov); + /* States here */ utils::eOverlayState mState; }; @@ -133,7 +108,7 @@ template struct StateTraits {}; template <> struct StateTraits { - typedef overlay::GenericPipe pipe0; + typedef overlay::GenericPipe pipe0; //prim video typedef overlay::NullPipe pipe1; // place holder typedef overlay::NullPipe pipe2; // place holder @@ -141,20 +116,33 @@ template <> struct StateTraits typedef NullRotator rot1; typedef NullRotator rot2; - typedef overlay::OverlayImpl ovimpl; + typedef overlay::OverlayImpl ovimpl; }; template <> struct StateTraits { - typedef overlay::GenericPipe pipe0; - typedef overlay::VideoExtPipe pipe1; - typedef overlay::NullPipe pipe2; // place holder + typedef overlay::GenericPipe pipe0; //prim video + typedef overlay::VideoExtPipe pipe1; //ext video + typedef overlay::GenericPipe pipe2; //ext subtitle typedef Rotator rot0; typedef Rotator rot1; typedef NullRotator rot2; - typedef overlay::OverlayImpl ovimpl; + typedef overlay::OverlayImpl ovimpl; +}; + +template <> struct StateTraits +{ + typedef overlay::NullPipe pipe0; //nothing on primary with mdp + typedef overlay::VideoExtPipe pipe1; //ext video + typedef overlay::GenericPipe pipe2; //ext subtitle + + typedef NullRotator rot0; + typedef Rotator rot1; + typedef NullRotator rot2; + + typedef overlay::OverlayImpl ovimpl; }; template <> struct StateTraits @@ -219,7 +207,7 @@ template <> struct StateTraits typedef NullRotator rot1; typedef NullRotator rot2; - typedef overlay::OverlayImpl ovimpl; + typedef overlay::OverlayImpl ovimpl; }; template <> struct StateTraits @@ -245,7 +233,7 @@ template <> struct StateTraits typedef NullRotator rot1; typedef NullRotator rot2; - typedef overlay::OverlayImpl ovimpl; + typedef overlay::OverlayImpl ovimpl; }; template <> struct StateTraits @@ -258,7 +246,7 @@ template <> struct StateTraits typedef NullRotator rot1; typedef NullRotator rot2; - typedef overlay::OverlayImpl ovimpl; + typedef overlay::OverlayImpl ovimpl; }; template <> struct StateTraits @@ -274,47 +262,197 @@ template <> struct StateTraits typedef overlay::OverlayImpl ovimpl; }; +template <> struct StateTraits +{ + typedef overlay::GenericPipe pipe0; + typedef overlay::GenericPipe pipe1; + typedef overlay::NullPipe pipe2; + + typedef NullRotator rot0; + typedef NullRotator rot1; + typedef NullRotator rot2; + + typedef overlay::OverlayImpl ovimpl; +}; + //------------------------Inlines -------------------------------- -inline OverlayState::OverlayState() : mState(utils::OV_CLOSED) -{} +inline OverlayState::OverlayState() : mState(utils::OV_CLOSED){} inline OverlayState::~OverlayState() {} - -inline utils::eOverlayState OverlayState::state() const -{ - return mState; -} - -inline OverlayImplBase* OverlayState::reset(utils::eOverlayState s) -{ +inline utils::eOverlayState OverlayState::state() const { return mState; } +inline OverlayImplBase* OverlayState::reset(utils::eOverlayState s) { return handleEvent(s, 0); } - -inline void OverlayState::dump() const -{ +inline void OverlayState::dump() const { ALOGE("== Dump state %d start/end ==", mState); } -template -inline OverlayImplBase* handle_closed_to_xxx() +inline OverlayImplBase* OverlayState::handleEvent(utils::eOverlayState toState, + OverlayImplBase* ov) { - OverlayImplBase* ov = new typename StateTraits::ovimpl; - RotatorBase* rot0 = new typename StateTraits::rot0; - RotatorBase* rot1 = new typename StateTraits::rot1; - RotatorBase* rot2 = new typename StateTraits::rot2; + OverlayImplBase* newov = ov; // at least, we return the same + if (mState != toState) { + ALOGD_IF(DEBUG_OVERLAY, "%s: state changed %s-->%s", + __FUNCTION__, getStateString(mState), getStateString(toState)); + } else { + ALOGD_IF(DEBUG_OVERLAY, "%s: no state change, state=%s", + __FUNCTION__, getStateString(toState)); + return newov; + } + + switch(mState) + { + case utils::OV_CLOSED: + newov = handle_from(toState, ov); + break; + case utils::OV_2D_VIDEO_ON_PANEL: + newov = handle_from(toState, ov); + break; + case utils::OV_2D_VIDEO_ON_PANEL_TV: + newov = handle_from(toState, ov); + break; + case utils::OV_2D_VIDEO_ON_TV: + newov = handle_from(toState, ov); + break; + case utils::OV_3D_VIDEO_ON_2D_PANEL: + newov = handle_from(toState, ov); + break; + case utils::OV_3D_VIDEO_ON_3D_PANEL: + newov = handle_from(toState, ov); + break; + case utils::OV_3D_VIDEO_ON_3D_TV: + newov = handle_from(toState, ov); + break; + case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: + newov = handle_from(toState, + ov); + break; + case utils::OV_UI_MIRROR: + newov = handle_from(toState, ov); + break; + case utils::OV_2D_TRUE_UI_MIRROR: + newov = handle_from(toState, ov); + break; + case utils::OV_BYPASS_1_LAYER: + newov = handle_from(toState, ov); + break; + case utils::OV_BYPASS_2_LAYER: + newov = handle_from(toState, ov); + break; + case utils::OV_BYPASS_3_LAYER: + newov = handle_from(toState, ov); + break; + case utils::OV_DUAL_DISP: + newov = handle_from(toState, ov); + break; + default: + OVASSERT(1 == 0, "%s: unknown state = %d", __FUNCTION__, mState); + + } + return newov; +} + +template +inline OverlayImplBase* OverlayState::handle_from(utils::eOverlayState toState, + OverlayImplBase* ov) { + + switch(toState) + { + case utils::OV_CLOSED: + ov = handle_xxx_to_CLOSED(ov); + break; + case utils::OV_2D_VIDEO_ON_PANEL: + ov = handle_from_to(ov); + break; + case utils::OV_2D_VIDEO_ON_PANEL_TV: + ov = handle_from_to(ov); + break; + case utils::OV_2D_VIDEO_ON_TV: + ov = handle_from_to(ov); + break; + case utils::OV_3D_VIDEO_ON_2D_PANEL: + ov = handle_from_to(ov); + break; + case utils::OV_3D_VIDEO_ON_3D_PANEL: + ov = handle_from_to(ov); + break; + case utils::OV_3D_VIDEO_ON_3D_TV: + ov = handle_from_to(ov); + break; + case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: + ov = handle_from_to(ov); + break; + case utils::OV_UI_MIRROR: + ov = handle_from_to(ov); + break; + case utils::OV_2D_TRUE_UI_MIRROR: + ov = handle_from_to(ov); + break; + case utils::OV_BYPASS_1_LAYER: + ov = handle_from_to(ov); + break; + case utils::OV_BYPASS_2_LAYER: + ov = handle_from_to(ov); + break; + case utils::OV_BYPASS_3_LAYER: + ov = handle_from_to(ov); + break; + case utils::OV_DUAL_DISP: + ov = handle_from_to(ov); + break; + default: + OVASSERT(1 == 0, "%s: unknown state = %d", __FUNCTION__, toState); + } + mState = toState; + return ov; +} + + +/* Transition default from any to any. Does in two steps. + * Moves from OLD to CLOSED and then from CLOSED to NEW + */ +template +inline OverlayImplBase* OverlayState::handle_from_to(OverlayImplBase* ov) { + handle_xxx_to_CLOSED(ov); + return handle_CLOSED_to_xxx(ov); +} + +//---------------Specializations------------- + + +/* Transition from CLOSED to ANY */ +template +inline OverlayImplBase* OverlayState::handle_CLOSED_to_xxx( + OverlayImplBase* /*ignored*/) { + //If going from CLOSED to CLOSED, nothing to do. + if(TO_STATE == utils::OV_CLOSED) return NULL; + ALOGD("FROM_STATE = %s TO_STATE = %s", + utils::getStateString(utils::OV_CLOSED), + utils::getStateString(TO_STATE)); + OverlayImplBase* ov = new typename StateTraits::ovimpl; + RotatorBase* rot0 = new typename StateTraits::rot0; + RotatorBase* rot1 = new typename StateTraits::rot1; + RotatorBase* rot2 = new typename StateTraits::rot2; if(!ov->init(rot0, rot1, rot2)) { - ALOGE("Overlay failed to init in state %d", STATE); + ALOGE("Overlay failed to init in state %d", TO_STATE); return 0; } return ov; } -inline OverlayImplBase* handle_xxx_to_closed(OverlayImplBase* ov) +/* Transition from ANY to CLOSED */ +template +inline OverlayImplBase* OverlayState::handle_xxx_to_CLOSED(OverlayImplBase* ov) { + //If going from CLOSED to CLOSED, nothing to do. + if(FROM_STATE == utils::OV_CLOSED) return NULL; + ALOGD("FROM_STATE = %s TO_STATE = %s", + utils::getStateString(FROM_STATE), + utils::getStateString(utils::OV_CLOSED)); OVASSERT(ov, "%s: ov is null", __FUNCTION__); - if(!ov->close()) { ALOGE("%s: Failed to ov close", __FUNCTION__); } @@ -323,580 +461,125 @@ inline OverlayImplBase* handle_xxx_to_closed(OverlayImplBase* ov) return 0; } -/* Hard transitions from any state to any state will close and then init */ -template -inline OverlayImplBase* handle_xxx_to_xxx(OverlayImplBase* ov) -{ +/* Transition from 2D_VIDEO_ON_PANEL to 2D_VIDEO_ON_PANEL_TV */ +template<> +inline OverlayImplBase* OverlayState::handle_from_to< + utils::OV_2D_VIDEO_ON_PANEL, + utils::OV_2D_VIDEO_ON_PANEL_TV>( + OverlayImplBase* ov) { OVASSERT(ov, "%s: ov is null", __FUNCTION__); + ALOGD("FROM_STATE = %s TO_STATE = %s", + utils::getStateString(utils::OV_2D_VIDEO_ON_PANEL), + utils::getStateString(utils::OV_2D_VIDEO_ON_PANEL_TV)); + // Create new ovimpl based on new state + typedef StateTraits NewState; + OverlayImplBase* newov = new NewState::ovimpl; - handle_xxx_to_closed(ov); - return handle_closed_to_xxx(); -} - -inline OverlayImplBase* OverlayState::handleEvent(utils::eOverlayState newState, - OverlayImplBase* ov) -{ - OverlayImplBase* newov = ov; // at least, we return the same - if (mState != newState) { - ALOGE_IF(DEBUG_OVERLAY, "%s: state changed %s-->%s", - __FUNCTION__, getStateString(mState), getStateString(newState)); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: no state change, state=%s", - __FUNCTION__, getStateString(newState)); - return newov; - } - - switch(mState) - { - case utils::OV_CLOSED: - newov = handle_closed(newState); - break; - case utils::OV_2D_VIDEO_ON_PANEL: - newov = handle_2D_2DPanel(newState, ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - newov = handle_2D_2DTV(newState, ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - newov = handle_3D_2DPanel(newState, ov); - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - newov = handle_3D_3DPanel(newState, ov); - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - newov = handle_3D_3DTV(newState, ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - newov = handle_3D_2DTV(newState, ov); - break; - case utils::OV_UI_MIRROR: - newov = handle_UI_Mirror(newState, ov); - break; - case utils::OV_2D_TRUE_UI_MIRROR: - newov = handle_2D_trueUI_Mirror(newState, ov); - break; - case utils::OV_BYPASS_1_LAYER: - case utils::OV_BYPASS_2_LAYER: - case utils::OV_BYPASS_3_LAYER: - newov = handle_bypass(newState, ov); - break; - default: - ALOGE("%s: unknown state=%d", __FUNCTION__, mState); - } - - // FIXME, how to communicate bad transition? - // Should we have bool returned from transition func? - // This is also a very good interview question. - + //copy pipe0/rot0 (primary video) + newov->copyOvPipe(ov, utils::OV_PIPE0); + //close old pipe1, create new pipe1 + ov->closePipe(utils::OV_PIPE1); + RotatorBase* rot1 = new NewState::rot1; + newov->initPipe(rot1, utils::OV_PIPE1); + //close old pipe2, create new pipe2 + ov->closePipe(utils::OV_PIPE2); + RotatorBase* rot2 = new NewState::rot2; + newov->initPipe(rot2, utils::OV_PIPE2); + // All pipes are copied or deleted so no more need for previous ovimpl + delete ov; + ov = 0; return newov; } -// Transitions from closed to XXX -inline OverlayImplBase* OverlayState::handle_closed(utils::eOverlayState s) -{ - OverlayImplBase* ov = 0; - switch(s) - { - case utils::OV_CLOSED: - // no state change - break; - case utils::OV_2D_VIDEO_ON_PANEL: - ov = handle_closed_to_xxx(); - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - ov = handle_closed_to_xxx(); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - ov = handle_closed_to_xxx(); - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - ov = handle_closed_to_xxx(); - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - ov = handle_closed_to_xxx(); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - ov = handle_closed_to_xxx(); - break; - case utils::OV_UI_MIRROR: - ov = handle_closed_to_xxx(); - break; - case utils::OV_2D_TRUE_UI_MIRROR: - ov = handle_closed_to_xxx(); - break; - case utils::OV_BYPASS_1_LAYER: - ov = handle_closed_to_xxx(); - break; - case utils::OV_BYPASS_2_LAYER: - ov = handle_closed_to_xxx(); - break; - case utils::OV_BYPASS_3_LAYER: - ov = handle_closed_to_xxx(); - break; - default: - ALOGE("%s: unknown state=%d", __FUNCTION__, s); - } - mState = s; - return ov; -} +/* Transition from 2D_VIDEO_ON_PANEL_TV to 2D_VIDEO_ON_PANEL */ +template<> +inline OverlayImplBase* OverlayState::handle_from_to< + utils::OV_2D_VIDEO_ON_PANEL_TV, + utils::OV_2D_VIDEO_ON_PANEL>( + OverlayImplBase* ov) { + OVASSERT(ov, "%s: ov is null", __FUNCTION__); + ALOGD("FROM_STATE = %s TO_STATE = %s", + utils::getStateString(utils::OV_2D_VIDEO_ON_PANEL_TV), + utils::getStateString(utils::OV_2D_VIDEO_ON_PANEL)); -// Transitions from 2D video on 2D panel to XXX -inline OverlayImplBase* OverlayState::handle_2D_2DPanel( - utils::eOverlayState s, - OverlayImplBase* ov) -{ - OverlayImplBase* newov = ov; - switch(s) - { - case utils::OV_CLOSED: - newov = handle_xxx_to_closed(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL: - // no state change - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - newov = handle_xxx_to_2D_2DTV(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_TRUE_UI_MIRROR: - newov = handle_xxx_to_2D_trueUI_Mirror(ov); - break; - case utils::OV_BYPASS_1_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_2_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_3_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - default: - ALOGE("%s: unknown state=%d", __FUNCTION__, s); - } - mState = s; + // Create new ovimpl based on new state + typedef StateTraits NewState; + OverlayImplBase* newov = new NewState::ovimpl; + + //copy pipe0/rot0 (primary video) + newov->copyOvPipe(ov, utils::OV_PIPE0); + //close old pipe1, create new pipe1 + ov->closePipe(utils::OV_PIPE1); + RotatorBase* rot1 = new NewState::rot1; + newov->initPipe(rot1, utils::OV_PIPE1); + //close old pipe2, create new pipe2 + ov->closePipe(utils::OV_PIPE2); + RotatorBase* rot2 = new NewState::rot2; + newov->initPipe(rot2, utils::OV_PIPE2); + // All pipes are copied or deleted so no more need for previous ovimpl + delete ov; + ov = 0; return newov; } -// Transitions from 2D video on 2D panel and 2D TV to XXX -inline OverlayImplBase* OverlayState::handle_2D_2DTV( - utils::eOverlayState s, - OverlayImplBase* ov) -{ - OverlayImplBase* newov = ov; - switch(s) - { - case utils::OV_CLOSED: - newov = handle_xxx_to_closed(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL: - newov = handle_xxx_to_2D_2DPanel(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - // no state change - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_TRUE_UI_MIRROR: - newov = handle_xxx_to_2D_trueUI_Mirror(ov); - break; - case utils::OV_BYPASS_1_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_2_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_3_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - default: - ALOGE("%s: unknown state=%d", __FUNCTION__, s); - } - mState = s; +/* Transition from 2D_VIDEO_ON_PANEL_TV to 2D_VIDEO_ON_TV */ +template<> +inline OverlayImplBase* OverlayState::handle_from_to< + utils::OV_2D_VIDEO_ON_PANEL_TV, + utils::OV_2D_VIDEO_ON_TV>( + OverlayImplBase* ov) { + OVASSERT(ov, "%s: ov is null", __FUNCTION__); + ALOGD("FROM_STATE = %s TO_STATE = %s", + utils::getStateString(utils::OV_2D_VIDEO_ON_PANEL_TV), + utils::getStateString(utils::OV_2D_VIDEO_ON_TV)); + + // Create new ovimpl based on new state + typedef StateTraits NewState; + OverlayImplBase* newov = new NewState::ovimpl; + + //close old pipe0, create new pipe0 + ov->closePipe(utils::OV_PIPE0); + RotatorBase* rot0 = new NewState::rot0; + newov->initPipe(rot0, utils::OV_PIPE0); + //copy pipe1/rot1 (ext video) + newov->copyOvPipe(ov, utils::OV_PIPE1); + //copy pipe2/rot2 (ext cc) + newov->copyOvPipe(ov, utils::OV_PIPE2); + // All pipes are copied or deleted so no more need for previous ovimpl + delete ov; + ov = 0; return newov; } -// Transitions from 3D video on 2D panel to XXX -inline OverlayImplBase* OverlayState::handle_3D_2DPanel( - utils::eOverlayState s, - OverlayImplBase* ov) -{ - OverlayImplBase* newov = ov; - switch(s) - { - case utils::OV_CLOSED: - newov = handle_xxx_to_closed(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - // no state change - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - newov = handle_xxx_to_3D_2DTV(ov); - break; - case utils::OV_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_TRUE_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_1_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_2_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_3_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - default: - ALOGE("%s: unknown state=%d", __FUNCTION__, s); - } - mState = s; +/* Transition from 2D_VIDEO_ON_TV to 2D_VIDEO_ON_PANEL_TV */ +template<> +inline OverlayImplBase* OverlayState::handle_from_to< + utils::OV_2D_VIDEO_ON_TV, + utils::OV_2D_VIDEO_ON_PANEL_TV>( + OverlayImplBase* ov) { + OVASSERT(ov, "%s: ov is null", __FUNCTION__); + ALOGD("FROM_STATE = %s TO_STATE = %s", + utils::getStateString(utils::OV_2D_VIDEO_ON_TV), + utils::getStateString(utils::OV_2D_VIDEO_ON_PANEL_TV)); + + // Create new ovimpl based on new state + typedef StateTraits NewState; + OverlayImplBase* newov = new NewState::ovimpl; + + //close old pipe0, create new pipe0 + ov->closePipe(utils::OV_PIPE0); + RotatorBase* rot0 = new NewState::rot0; + newov->initPipe(rot0, utils::OV_PIPE0); + //copy pipe1/rot1 (ext video) + newov->copyOvPipe(ov, utils::OV_PIPE1); + //copy pipe2/rot2 (ext cc) + newov->copyOvPipe(ov, utils::OV_PIPE2); + // All pipes are copied or deleted so no more need for previous ovimpl + delete ov; + ov = 0; return newov; } -// Transitions from 3D video on 3D panel to XXX -inline OverlayImplBase* OverlayState::handle_3D_3DPanel( - utils::eOverlayState s, - OverlayImplBase* ov) -{ - OverlayImplBase* newov = ov; - switch(s) - { - case utils::OV_CLOSED: - newov = handle_xxx_to_closed(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - // no state change - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_TRUE_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_1_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_2_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_3_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - default: - ALOGE("%s: unknown state=%d", __FUNCTION__, s); - } - mState = s; - return newov; -} - -// Transitions from 3D video on 3D TV to XXX -inline OverlayImplBase* OverlayState::handle_3D_3DTV( - utils::eOverlayState s, - OverlayImplBase* ov) -{ - OverlayImplBase* newov = ov; - switch(s) - { - case utils::OV_CLOSED: - newov = handle_xxx_to_closed(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - // no state change - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_TRUE_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_1_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_2_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_3_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - default: - ALOGE("%s: unknown state=%d", __FUNCTION__, s); - } - mState = s; - return newov; -} - -// Transitions from 3D video on 2D panel and 2D TV to XXX -inline OverlayImplBase* OverlayState::handle_3D_2DTV( - utils::eOverlayState s, - OverlayImplBase* ov) -{ - OverlayImplBase* newov = ov; - switch(s) - { - case utils::OV_CLOSED: - newov = handle_xxx_to_closed(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - newov = handle_xxx_to_3D_2DPanel(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - // no state change - break; - case utils::OV_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_TRUE_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_1_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_2_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_3_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - default: - ALOGE("%s: unknown state=%d", __FUNCTION__, s); - } - mState = s; - return newov; -} - -// Transitions from UI mirroring to XXX -inline OverlayImplBase* OverlayState::handle_UI_Mirror(utils::eOverlayState s, - OverlayImplBase* ov) -{ - OverlayImplBase* newov = ov; - switch(s) - { - case utils::OV_CLOSED: - newov = handle_xxx_to_closed(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_UI_MIRROR: - // no state change - break; - case utils::OV_2D_TRUE_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_1_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_2_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_3_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - default: - ALOGE("%s: unknown state=%d", __FUNCTION__, s); - } - mState = s; - return newov; -} - -// Transitions from 2D video true UI mirroring (2D video + UI) to XXX -inline OverlayImplBase* OverlayState::handle_2D_trueUI_Mirror(utils::eOverlayState s, - OverlayImplBase* ov) -{ - OverlayImplBase* newov = ov; - switch(s) - { - case utils::OV_CLOSED: - newov = handle_xxx_to_closed(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL: - newov = handle_xxx_to_2D_2DPanel(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - newov = handle_xxx_to_2D_2DTV(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_TRUE_UI_MIRROR: - // no state change - break; - case utils::OV_BYPASS_1_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_2_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_3_LAYER: - newov = handle_xxx_to_xxx(ov); - break; - default: - ALOGE("%s: unknown state=%d", __FUNCTION__, s); - } - mState = s; - return newov; -} - -// Transitions from composition bypass to XXX -inline OverlayImplBase* OverlayState::handle_bypass(utils::eOverlayState s, - OverlayImplBase* ov) -{ - OverlayImplBase* newov = ov; - switch(s) - { - case utils::OV_CLOSED: - newov = handle_xxx_to_closed(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_VIDEO_ON_PANEL_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_PANEL: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_3D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_2D_TRUE_UI_MIRROR: - newov = handle_xxx_to_xxx(ov); - break; - case utils::OV_BYPASS_1_LAYER: - newov = handle_xxx_to_bypass1(ov); - break; - case utils::OV_BYPASS_2_LAYER: - newov = handle_xxx_to_bypass2(ov); - break; - case utils::OV_BYPASS_3_LAYER: - newov = handle_xxx_to_bypass3(ov); - break; - default: - ALOGE("%s: unknown state=%d", __FUNCTION__, s); - } - mState = s; - return newov; -} - - } // overlay #endif // OVERLAY_STATE_H diff --git a/liboverlay/overlayTransitions.cpp b/liboverlay/overlayTransitions.cpp deleted file mode 100644 index 8096ad5..0000000 --- a/liboverlay/overlayTransitions.cpp +++ /dev/null @@ -1,504 +0,0 @@ -/* -* Copyright (c) 2012, Code Aurora Forum. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following -* disclaimer in the documentation and/or other materials provided -* with the distribution. -* * Neither the name of Code Aurora Forum, Inc. nor the names of its -* contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "overlayState.h" - -namespace overlay { - -/* - * Transition from any state to 2D video on 2D panel - */ -OverlayImplBase* OverlayState::handle_xxx_to_2D_2DPanel( - OverlayImplBase* ov) -{ - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGE("%s", __FUNCTION__); - - // Create new ovimpl based on new state - typedef StateTraits NewState; - OverlayImplBase* newov = new NewState::ovimpl(); - - //=========================================================== - // For each pipe: - // - If pipe matches, copy from previous into new ovimpl - // - Otherwise init for new and delete from previous ovimpl - //=========================================================== - - // pipe0/rot0 (GenericPipe) - if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_GENERIC) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (GenericPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE0); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (GenericPipe)", __FUNCTION__); - ov->closePipe(utils::OV_PIPE0); - RotatorBase* rot0 = new NewState::rot0; - newov->initPipe(rot0, utils::OV_PIPE0); - } - - // pipe1/rot1 (NullPipe) - if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_NULL) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (NullPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE1); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (NullPipe)", __FUNCTION__); - ov->closePipe(utils::OV_PIPE1); - RotatorBase* rot1 = new NewState::rot1; - newov->initPipe(rot1, utils::OV_PIPE1); - } - - // pipe2/rot2 (NullPipe) - if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_NULL) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE2); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (NullPipe)", __FUNCTION__); - ov->closePipe(utils::OV_PIPE2); - RotatorBase* rot2 = new NewState::rot2; - newov->initPipe(rot2, utils::OV_PIPE2); - } - - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - - return newov; -} - -/* - * Transition from any state to 2D video on 2D panel and 2D TV - */ -OverlayImplBase* OverlayState::handle_xxx_to_2D_2DTV( - OverlayImplBase* ov) -{ - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGE("%s", __FUNCTION__); - - // Create new ovimpl based on new state - typedef StateTraits NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //=========================================================== - // For each pipe: - // - If pipe matches, copy from previous into new ovimpl - // - Otherwise init for new and delete from previous ovimpl - //=========================================================== - - // pipe0/rot0 (GenericPipe) - if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_GENERIC) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (GenericPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE0); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (GenericPipe)", __FUNCTION__); - RotatorBase* rot0 = new NewState::rot0; - ov->closePipe(utils::OV_PIPE0); - newov->initPipe(rot0, utils::OV_PIPE0); - } - - // pipe1/rot1 (VideoExtPipe) - if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_VIDEO_EXT) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (VideoExtPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE1); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (VideoExtPipe)", __FUNCTION__); - RotatorBase* rot1 = new NewState::rot1; - ov->closePipe(utils::OV_PIPE1); - newov->initPipe(rot1, utils::OV_PIPE1); - } - - // pipe2/rot2 (NullPipe) - if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_NULL) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE2); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (NullPipe)", __FUNCTION__); - RotatorBase* rot2 = new NewState::rot2; - ov->closePipe(utils::OV_PIPE2); - newov->initPipe(rot2, utils::OV_PIPE2); - } - - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - - return newov; -} - -/* - * Transition from any state to 3D video on 2D panel - */ -OverlayImplBase* OverlayState::handle_xxx_to_3D_2DPanel( - OverlayImplBase* ov) -{ - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGE("%s", __FUNCTION__); - - // Create new ovimpl based on new state - typedef StateTraits NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //================================================================= - // For each pipe: - // - If pipe matches, copy from previous into new ovimpl. - // (which also makes previous pipe ref 0, so nobody can use) - // - Otherwise init pipe for new ovimpl and delete from previous - //================================================================= - - // pipe0/rot0 (M3DPrimaryPipe) - if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_M3D_PRIMARY) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (M3DPrimaryPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE0); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (M3DPrimaryPipe)", __FUNCTION__); - RotatorBase* rot0 = new NewState::rot0; - ov->closePipe(utils::OV_PIPE0); - newov->initPipe(rot0, utils::OV_PIPE0); - } - - // pipe1/rot1 (NullPipe) - if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_NULL) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (NullPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE1); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (NullPipe)", __FUNCTION__); - RotatorBase* rot1 = new NewState::rot1; - ov->closePipe(utils::OV_PIPE1); - newov->initPipe(rot1, utils::OV_PIPE1); - } - - // pipe2/rot2 (NullPipe) - if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_NULL) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE2); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (NullPipe)", __FUNCTION__); - RotatorBase* rot2 = new NewState::rot2; - ov->closePipe(utils::OV_PIPE2); - newov->initPipe(rot2, utils::OV_PIPE2); - } - - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - - return newov; -} - -/* - * Transition from any state to 3D video on 2D panel and 2D TV - */ -OverlayImplBase* OverlayState::handle_xxx_to_3D_2DTV( - OverlayImplBase* ov) -{ - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGE("%s", __FUNCTION__); - - // Create new ovimpl based on new state - typedef StateTraits NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //=========================================================== - // For each pipe: - // - If pipe matches, copy from previous into new ovimpl - // - Otherwise init for new and delete from previous ovimpl - //=========================================================== - - // pipe0/rot0 (M3DPrimaryPipe) - if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_M3D_PRIMARY) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (M3DPrimaryPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE0); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (M3DPrimaryPipe)", __FUNCTION__); - RotatorBase* rot0 = new NewState::rot0; - ov->closePipe(utils::OV_PIPE0); - newov->initPipe(rot0, utils::OV_PIPE0); - } - - // pipe1/rot1 (M3DExtPipe) - if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_M3D_EXTERNAL) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (M3DExtPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE1); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (M3DExtPipe)", __FUNCTION__); - RotatorBase* rot1 = new NewState::rot1; - ov->closePipe(utils::OV_PIPE1); - newov->initPipe(rot1, utils::OV_PIPE1); - } - - // pipe2/rot2 (NullPipe) - if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_NULL) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE2); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (NullPipe)", __FUNCTION__); - RotatorBase* rot2 = new NewState::rot2; - ov->closePipe(utils::OV_PIPE2); - newov->initPipe(rot2, utils::OV_PIPE2); - } - - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - - return newov; -} - -/* - * Transition from any state to 2D true UI mirroring (2D video + UI) - */ -OverlayImplBase* OverlayState::handle_xxx_to_2D_trueUI_Mirror( - OverlayImplBase* ov) -{ - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGE("%s", __FUNCTION__); - - // Create new ovimpl based on new state - typedef StateTraits NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //=========================================================== - // For each pipe: - // - If pipe matches, copy from previous into new ovimpl - // - Otherwise init for new and delete from previous ovimpl - //=========================================================== - - // pipe0/rot0 (GenericPipe) - if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_GENERIC) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (GenericPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE0); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (GenericPipe)", __FUNCTION__); - RotatorBase* rot0 = new NewState::rot0; - ov->closePipe(utils::OV_PIPE0); - newov->initPipe(rot0, utils::OV_PIPE0); - } - - // pipe1/rot1 (VideoExtPipe) - if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_VIDEO_EXT) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (VideoExtPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE1); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (VideoExtPipe)", __FUNCTION__); - RotatorBase* rot1 = new NewState::rot1; - ov->closePipe(utils::OV_PIPE1); - newov->initPipe(rot1, utils::OV_PIPE1); - } - - // pipe2/rot2 (UIMirrorPipe) - if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_UI_MIRROR) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (UIMirrorPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE2); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (UIMirrorPipe)", __FUNCTION__); - RotatorBase* rot2 = new NewState::rot2; - ov->closePipe(utils::OV_PIPE2); - newov->initPipe(rot2, utils::OV_PIPE2); - } - - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - - return newov; -} - -/* - * Transitions from any state to 1 layer composition bypass - */ -OverlayImplBase* OverlayState::handle_xxx_to_bypass1(OverlayImplBase* ov) -{ - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGE("%s", __FUNCTION__); - - // Create new ovimpl based on new state - typedef StateTraits NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //=========================================================== - // For each pipe: - // - If pipe matches, copy from previous into new ovimpl - // - Otherwise init for new and delete from previous ovimpl - //=========================================================== - - // pipe0/rot0 (BypassPipe) - if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_BYPASS) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (BypassPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE0); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (BypassPipe)", __FUNCTION__); - RotatorBase* rot0 = new NewState::rot0; - ov->closePipe(utils::OV_PIPE0); - newov->initPipe(rot0, utils::OV_PIPE0); - } - - // pipe1/rot1 (NullPipe) - if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_NULL) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (NullPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE1); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (NullPipe)", __FUNCTION__); - RotatorBase* rot1 = new NewState::rot1; - ov->closePipe(utils::OV_PIPE1); - newov->initPipe(rot1, utils::OV_PIPE1); - } - - // pipe2/rot2 (NullPipe) - if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_NULL) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE2); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (NullPipe)", __FUNCTION__); - RotatorBase* rot2 = new NewState::rot2; - ov->closePipe(utils::OV_PIPE2); - newov->initPipe(rot2, utils::OV_PIPE2); - } - - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - - return newov; -} - -/* - * Transitions from any state to 2 layers composition bypass - */ -OverlayImplBase* OverlayState::handle_xxx_to_bypass2(OverlayImplBase* ov) -{ - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGE("%s", __FUNCTION__); - - // Create new ovimpl based on new state - typedef StateTraits NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //=========================================================== - // For each pipe: - // - If pipe matches, copy from previous into new ovimpl - // - Otherwise init for new and delete from previous ovimpl - //=========================================================== - - // pipe0/rot0 (BypassPipe) - if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_BYPASS) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (BypassPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE0); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (BypassPipe)", __FUNCTION__); - RotatorBase* rot0 = new NewState::rot0; - ov->closePipe(utils::OV_PIPE0); - newov->initPipe(rot0, utils::OV_PIPE0); - } - - // pipe1/rot1 (BypassPipe) - if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_BYPASS) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (BypassPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE1); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (BypassPipe)", __FUNCTION__); - RotatorBase* rot1 = new NewState::rot1; - ov->closePipe(utils::OV_PIPE1); - newov->initPipe(rot1, utils::OV_PIPE1); - } - - // pipe2/rot2 (NullPipe) - if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_NULL) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (NullPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE2); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (NullPipe)", __FUNCTION__); - RotatorBase* rot2 = new NewState::rot2; - ov->closePipe(utils::OV_PIPE2); - newov->initPipe(rot2, utils::OV_PIPE2); - } - - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - - return newov; -} - -/* - * Transitions from any state to 3 layers composition bypass - */ -OverlayImplBase* OverlayState::handle_xxx_to_bypass3(OverlayImplBase* ov) -{ - OVASSERT(ov, "%s: ov is null", __FUNCTION__); - ALOGE("%s", __FUNCTION__); - - // Create new ovimpl based on new state - typedef StateTraits NewState; - OverlayImplBase* newov = new NewState::ovimpl; - - //=========================================================== - // For each pipe: - // - If pipe matches, copy from previous into new ovimpl - // - Otherwise init for new and delete from previous ovimpl - //=========================================================== - - // pipe0/rot0 (BypassPipe) - if (ov->getOvPipeType(utils::OV_PIPE0) == utils::OV_PIPE_TYPE_BYPASS) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe0 (BypassPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE0); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe0 (BypassPipe)", __FUNCTION__); - RotatorBase* rot0 = new NewState::rot0; - ov->closePipe(utils::OV_PIPE0); - newov->initPipe(rot0, utils::OV_PIPE0); - } - - // pipe1/rot1 (BypassPipe) - if (ov->getOvPipeType(utils::OV_PIPE1) == utils::OV_PIPE_TYPE_BYPASS) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe1 (BypassPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE1); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe1 (BypassPipe)", __FUNCTION__); - RotatorBase* rot1 = new NewState::rot1; - ov->closePipe(utils::OV_PIPE1); - newov->initPipe(rot1, utils::OV_PIPE1); - } - - // pipe2/rot2 (BypassPipe) - if (ov->getOvPipeType(utils::OV_PIPE2) == utils::OV_PIPE_TYPE_BYPASS) { - ALOGE_IF(DEBUG_OVERLAY, "%s: Copy pipe2 (BypassPipe)", __FUNCTION__); - newov->copyOvPipe(ov, utils::OV_PIPE2); - } else { - ALOGE_IF(DEBUG_OVERLAY, "%s: init pipe2 (BypassPipe)", __FUNCTION__); - RotatorBase* rot2 = new NewState::rot2; - ov->closePipe(utils::OV_PIPE2); - newov->initPipe(rot2, utils::OV_PIPE2); - } - - // All pipes are copied or deleted so no more need for previous ovimpl - delete ov; - ov = 0; - - return newov; -} - -} // overlay diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h index f82fb88..f070bd1 100644 --- a/liboverlay/overlayUtils.h +++ b/liboverlay/overlayUtils.h @@ -370,6 +370,7 @@ enum eOverlayState{ /* 2D Video */ OV_2D_VIDEO_ON_PANEL, OV_2D_VIDEO_ON_PANEL_TV, + OV_2D_VIDEO_ON_TV, /* 3D Video on one display (panel or TV) */ OV_3D_VIDEO_ON_2D_PANEL, @@ -382,12 +383,14 @@ enum eOverlayState{ /* UI Mirroring */ OV_UI_MIRROR, OV_2D_TRUE_UI_MIRROR, - OV_M3D_TRUE_UI_MIRROR, // Not yet supported /* Composition Bypass */ OV_BYPASS_1_LAYER, OV_BYPASS_2_LAYER, OV_BYPASS_3_LAYER, + + /* External only for dual-disp */ + OV_DUAL_DISP, }; inline void setMdpFlags(eMdpFlags& f, eMdpFlags v) { @@ -606,6 +609,8 @@ inline const char* getStateString(eOverlayState state){ return "OV_2D_VIDEO_ON_PANEL"; case OV_2D_VIDEO_ON_PANEL_TV: return "OV_2D_VIDEO_ON_PANEL_TV"; + case OV_2D_VIDEO_ON_TV: + return "OV_2D_VIDEO_ON_TV"; case OV_3D_VIDEO_ON_2D_PANEL: return "OV_3D_VIDEO_ON_2D_PANEL"; case OV_3D_VIDEO_ON_3D_PANEL: @@ -624,6 +629,8 @@ inline const char* getStateString(eOverlayState state){ return "OV_BYPASS_2_LAYER"; case OV_BYPASS_3_LAYER: return "OV_BYPASS_3_LAYER"; + case OV_DUAL_DISP: + return "OV_DUAL_DISP"; default: return "UNKNOWN_STATE"; }