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_video.cpp b/libhwcomposer/hwc_video.cpp
index 2e4342a..7bbfaf9 100644
--- a/libhwcomposer/hwc_video.cpp
+++ b/libhwcomposer/hwc_video.cpp
@@ -25,19 +25,22 @@
#define FINAL_TRANSFORM_MASK 0x000F
//Static Members
-ovutils::eOverlayState VideoOverlay::sState = ovutils::OV_CLOSED;
-bool VideoOverlay::sIsModeOn = false;
+ovutils::eOverlayState VideoOverlay::sState[] = {ovutils::OV_CLOSED};
+bool VideoOverlay::sIsModeOn[] = {false};
//Cache stats, figure out the state, config overlay
bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
int dpy) {
+
int yuvIndex = ctx->listStats[dpy].yuvIndex;
+ sIsModeOn[dpy] = false;
if(!ctx->mMDP.hasOverlay) {
ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__);
return false;
}
- if(yuvIndex == -1) {
+
+ if(yuvIndex == -1 || ctx->listStats[dpy].yuvCount != 1) {
return false;
}
@@ -55,16 +58,16 @@
chooseState(ctx, dpy, yuvLayer);
if(configure(ctx, dpy, yuvLayer)) {
markFlags(yuvLayer);
- sIsModeOn = true;
+ sIsModeOn[dpy] = true;
}
- return sIsModeOn;
+ return sIsModeOn[dpy];
}
void VideoOverlay::chooseState(hwc_context_t *ctx, int dpy,
hwc_layer_1_t *yuvLayer) {
ALOGD_IF(VIDEO_DEBUG, "%s: old state = %s", __FUNCTION__,
- ovutils::getStateString(sState));
+ ovutils::getStateString(sState[dpy]));
private_handle_t *hnd = NULL;
if(yuvLayer) {
@@ -74,38 +77,27 @@
switch(dpy) {
case HWC_DISPLAY_PRIMARY:
if(ctx->listStats[dpy].yuvCount == 1) {
- newState = isExternalActive(ctx) ?
- ovutils::OV_2D_VIDEO_ON_PANEL_TV : ovutils::OV_2D_VIDEO_ON_PANEL;
+ newState = ovutils::OV_2D_VIDEO_ON_PANEL;
if(isSkipLayer(yuvLayer) && !isSecureBuffer(hnd)) {
- newState = isExternalActive(ctx) ?
- ovutils::OV_2D_VIDEO_ON_TV : ovutils::OV_CLOSED;
+ newState = ovutils::OV_CLOSED;
}
}
break;
case HWC_DISPLAY_EXTERNAL:
- //TODO needs overlay state change for UI also
- newState = sState; //Previously set by HWC_DISPLAY_PRIMARY
- /*if(ctx->listStats[dpy].yuvCount == 1 && isExternalActive(ctx)) {
+ newState = ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->getState(); //If we are here, external is active
+ if(ctx->listStats[dpy].yuvCount == 1) {
if(!isSkipLayer(yuvLayer) || isSecureBuffer(hnd)) {
- switch(sState) { //set by primary chooseState
- case ovutils::OV_2D_VIDEO_ON_PANEL:
- //upgrade
- sState = ovutils::OV_2D_VIDEO_PANEL_TV;
- break;
- case ovutils::OV_CLOSED:
- sState = ovutils::OV_2D_VIDEO_ON_TV;
- break;
- }
+ newState = ovutils::OV_UI_VIDEO_TV;
}
- }*/
+ }
break;
default:
break;
}
- sState = newState;
+ sState[dpy] = newState;
ALOGD_IF(VIDEO_DEBUG, "%s: new chosen state = %s", __FUNCTION__,
- ovutils::getStateString(sState));
+ ovutils::getStateString(sState[dpy]));
}
void VideoOverlay::markFlags(hwc_layer_1_t *yuvLayer) {
@@ -117,7 +109,7 @@
/* Helpers */
bool configPrimVid(hwc_context_t *ctx, hwc_layer_1_t *layer) {
- overlay::Overlay& ov = *(ctx->mOverlay);
+ overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_PRIMARY]);
private_handle_t *hnd = (private_handle_t *)layer->handle;
ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
@@ -184,7 +176,7 @@
}
bool configExtVid(hwc_context_t *ctx, hwc_layer_1_t *layer) {
- overlay::Overlay& ov = *(ctx->mOverlay);
+ overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]);
private_handle_t *hnd = (private_handle_t *)layer->handle;
ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
@@ -201,10 +193,9 @@
ovutils::PipeArgs parg(mdpFlags,
info,
- ovutils::ZORDER_0,
+ ovutils::ZORDER_1,
isFgFlag,
- ovutils::ROT_FLAG_ENABLED); //TODO remove this hack when sync for
- //ext is done
+ ovutils::ROT_FLAG_DISABLED);
ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
ov.setSource(pargs, ovutils::OV_PIPE1);
@@ -216,9 +207,10 @@
//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);
+ int transform = layer->transform;
+ ovutils::eTransform orient =
+ static_cast<ovutils::eTransform>(transform);
+ ov.setTransform(orient, ovutils::OV_PIPE1);
ovutils::Dim dpos;
hwc_rect_t displayFrame = layer->displayFrame;
@@ -240,31 +232,23 @@
bool VideoOverlay::configure(hwc_context_t *ctx, int dpy,
hwc_layer_1_t *yuvLayer) {
bool ret = true;
- overlay::Overlay& ov = *(ctx->mOverlay);
+ overlay::Overlay& ov = *(ctx->mOverlay[dpy]);
switch(dpy) {
case HWC_DISPLAY_PRIMARY:
// Set overlay state
- ov.setState(sState);
- switch(sState) {
+ ov.setState(sState[dpy]);
+ switch(sState[dpy]) {
case ovutils::OV_2D_VIDEO_ON_PANEL:
ret &= configPrimVid(ctx, yuvLayer);
break;
- case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
- ret &= configPrimVid(ctx, yuvLayer);
- ret &= configExtVid(ctx, yuvLayer);
- break;
- case ovutils::OV_2D_VIDEO_ON_TV:
- ret &= configExtVid(ctx, yuvLayer);
- break;
default:
return false;
}
break;
case HWC_DISPLAY_EXTERNAL:
- ov.setState(sState);
- switch(sState) {
- case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
- case ovutils::OV_2D_VIDEO_ON_TV:
+ ov.setState(sState[dpy]);
+ switch(sState[dpy]) {
+ case ovutils::OV_UI_VIDEO_TV:
ret = configExtVid(ctx, yuvLayer);
break;
default:
@@ -278,8 +262,12 @@
bool VideoOverlay::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
int dpy)
{
+ if(!sIsModeOn[dpy]) {
+ return true;
+ }
+
int yuvIndex = ctx->listStats[dpy].yuvIndex;
- if(!sIsModeOn || yuvIndex == -1) {
+ if(yuvIndex == -1) {
return true;
}
@@ -287,7 +275,7 @@
list->hwLayers[yuvIndex].handle;
bool ret = true;
- overlay::Overlay& ov = *(ctx->mOverlay);
+ overlay::Overlay& ov = *(ctx->mOverlay[dpy]);
ovutils::eOverlayState state = ov.getState();
switch(dpy) {
@@ -300,24 +288,6 @@
ret = false;
}
break;
- case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
- if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) {
- ALOGE("%s: queueBuffer failed for primary", __FUNCTION__);
- ret = false;
- }
- // Play external
- if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) {
- ALOGE("%s: queueBuffer failed for external", __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;
- }
- break;
default:
ret = false;
break;
@@ -325,8 +295,7 @@
break;
case HWC_DISPLAY_EXTERNAL:
switch(state) {
- case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
- case ovutils::OV_2D_VIDEO_ON_TV:
+ case ovutils::OV_UI_VIDEO_TV:
// Play external
if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) {
ALOGE("%s: queueBuffer failed for external", __FUNCTION__);