hwc: enable dual display on hwc 1.1
Enable dual display on HWC 1.1; video uses overlay.
Bug: 7124159
Change-Id: I8333e46cfc74072f6259fba2b82368f0dd52b6df
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/libhwcomposer/hwc_uimirror.cpp b/libhwcomposer/hwc_uimirror.cpp
index 1b81421..62b7efd 100644
--- a/libhwcomposer/hwc_uimirror.cpp
+++ b/libhwcomposer/hwc_uimirror.cpp
@@ -26,30 +26,6 @@
namespace qhwc {
-
-// Function to get the orientation of UI on primary.
-// When external display is connected, the primary UI is
-// fixed to landscape by the phone window manager.
-// Return the landscape orientation based on w and hw of primary
-int getDeviceOrientation() {
- int orientation = 0;
- //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 =
- ovutils::FrameBufferInfo::getInstance()->getHeight();
- if(fbWidth >= fbHeight) {
- // landscape panel
- orientation = overlay::utils::OVERLAY_TRANSFORM_0;
- } else {
- // portrait panel
- orientation = overlay::utils::OVERLAY_TRANSFORM_ROT_90;
- }
- return orientation;
-}
-
//Static Members
ovutils::eOverlayState UIMirrorOverlay::sState = ovutils::OV_CLOSED;
bool UIMirrorOverlay::sIsUiMirroringOn = false;
@@ -61,83 +37,75 @@
//Prepare the overlay for the UI mirroring
bool UIMirrorOverlay::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) {
- sState = ovutils::OV_CLOSED;
- sIsUiMirroringOn = false;
+ reset();
if(!ctx->mMDP.hasOverlay) {
ALOGD_IF(HWC_UI_MIRROR, "%s, this hw doesnt support mirroring",
__FUNCTION__);
return false;
}
- // If external display is active
- if(isExternalActive(ctx)) {
- sState = ovutils::OV_UI_MIRROR;
- configure(ctx, fblayer);
+
+ sState = ovutils::OV_UI_MIRROR;
+ ovutils::eOverlayState newState = ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->getState();
+ if(newState == ovutils::OV_UI_VIDEO_TV) {
+ sState = newState;
}
+
+ configure(ctx, fblayer);
return sIsUiMirroringOn;
}
// Configure
bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_layer_1_t *layer)
{
- if (LIKELY(ctx->mOverlay)) {
- overlay::Overlay& ov = *(ctx->mOverlay);
+ if (LIKELY(ctx->mOverlay[HWC_DISPLAY_EXTERNAL])) {
+ overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]);
// Set overlay state
ov.setState(sState);
- framebuffer_device_t *fbDev = ctx->mFbDev;
- if(fbDev) {
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
- // Determine the RGB pipe for UI depending on the state
- ovutils::eDest dest = ovutils::OV_PIPE_ALL;
- if (sState == ovutils::OV_2D_TRUE_UI_MIRROR) {
- // True UI mirroring state: external RGB pipe is OV_PIPE2
- dest = ovutils::OV_PIPE2;
- } else if (sState == ovutils::OV_UI_MIRROR) {
- // UI-only mirroring state: external RGB pipe is OV_PIPE0
- dest = ovutils::OV_PIPE0;
- }
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
+ // Determine the RGB pipe for UI depending on the state
+ ovutils::eDest dest = ovutils::OV_PIPE0;
- ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
- if(ctx->mSecureMode) {
- ovutils::setMdpFlags(mdpFlags,
- ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
- }
+ ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
+ if(ctx->mSecureMode) {
+ ovutils::setMdpFlags(mdpFlags,
+ ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
+ }
- ovutils::PipeArgs parg(mdpFlags,
- info,
- ovutils::ZORDER_0,
- ovutils::IS_FG_OFF,
- ovutils::ROT_FLAG_ENABLED);
- ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
- ov.setSource(pargs, dest);
+ ovutils::PipeArgs parg(mdpFlags,
+ info,
+ ovutils::ZORDER_0,
+ ovutils::IS_FG_OFF,
+ 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,
+ 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);
- ov.setCrop(dcrop, dest);
+ ov.setCrop(dcrop, dest);
- //Get the current orientation on primary panel
- int transform = getDeviceOrientation();
- ovutils::eTransform orient =
- static_cast<ovutils::eTransform>(transform);
- ov.setTransform(orient, dest);
+ int transform = layer->transform;
+ ovutils::eTransform orient =
+ static_cast<ovutils::eTransform>(transform);
+ ov.setTransform(orient, dest);
- hwc_rect_t displayFrame = layer->displayFrame;
- ovutils::Dim dpos(displayFrame.left,
+ hwc_rect_t displayFrame = layer->displayFrame;
+ ovutils::Dim dpos(displayFrame.left,
displayFrame.top,
displayFrame.right - displayFrame.left,
displayFrame.bottom - displayFrame.top);
- ov.setPosition(dpos, dest);
+ ov.setPosition(dpos, dest);
- if (!ov.commit(dest)) {
- ALOGE("%s: commit fails", __FUNCTION__);
- return false;
- }
- sIsUiMirroringOn = true;
+ if (!ov.commit(dest)) {
+ ALOGE("%s: commit fails", __FUNCTION__);
+ sIsUiMirroringOn = false;
+ return false;
}
+ sIsUiMirroringOn = true;
}
return sIsUiMirroringOn;
}
@@ -148,36 +116,20 @@
return true;
}
bool ret = true;
- overlay::Overlay& ov = *(ctx->mOverlay);
+ overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]);
ovutils::eOverlayState state = ov.getState();
- ovutils::eDest dest = ovutils::OV_PIPE_ALL;
- framebuffer_device_t *fbDev = ctx->mFbDev;
- if(fbDev) {
- private_module_t* m = reinterpret_cast<private_module_t*>(
- fbDev->common.module);
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- switch (state) {
- case ovutils::OV_UI_MIRROR:
- //TODO why is this primary fd
- if (!ov.queueBuffer(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd,
- hnd->offset, //div by line_length like in PAN?
- ovutils::OV_PIPE0)) {
- ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
- ret = false;
- }
- break;
- case ovutils::OV_2D_TRUE_UI_MIRROR:
- if (!ov.queueBuffer(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd,
- hnd->offset,
- ovutils::OV_PIPE2)) {
- ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
- ret = false;
- }
- break;
-
+ ovutils::eDest dest = ovutils::OV_PIPE0;
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ switch (state) {
+ case ovutils::OV_UI_MIRROR:
+ case ovutils::OV_UI_VIDEO_TV:
+ if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
+ ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
+ ret = false;
+ }
+ break;
default:
break;
- }
}
return ret;
}