hwc: hwc 1.1 implementation
Bug: 7124159
--External disabled
--MDP comp coded but disabled.
--Videos via overlay, so that secure videos can work.
Change-Id: Ie48b264143d5e4237ab9724e28930e3f68ba49ee
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
index daf3f80..3aa7e7a 100644
--- a/libhwcomposer/hwc_video.cpp
+++ b/libhwcomposer/hwc_video.cpp
@@ -17,9 +17,8 @@
#define VIDEO_DEBUG 0
#include <overlay.h>
-#include "hwc_qbuf.h"
#include "hwc_video.h"
-#include "external.h"
+#include "hwc_utils.h"
namespace qhwc {
@@ -27,88 +26,81 @@
//Static Members
ovutils::eOverlayState VideoOverlay::sState = ovutils::OV_CLOSED;
-int VideoOverlay::sYuvCount = 0;
-int VideoOverlay::sYuvLayerIndex = -1;
-bool VideoOverlay::sIsYuvLayerSkip = false;
-int VideoOverlay::sCCLayerIndex = -1;
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) {
- sIsModeOn = false;
+bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
+ int dpy) {
+ int yuvIndex = ctx->listStats[dpy].yuvIndex;
+
if(!ctx->mMDP.hasOverlay) {
ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__);
return false;
}
- if(sYuvLayerIndex == -1) {
+ if(yuvIndex == -1) {
return false;
}
- chooseState(ctx);
- //if the state chosen above is CLOSED, skip this block.
- if(sState != ovutils::OV_CLOSED) {
- hwc_layer_1_t *yuvLayer = &list->hwLayers[sYuvLayerIndex];
- hwc_layer_1_t *ccLayer = NULL;
- if(sCCLayerIndex != -1)
- ccLayer = &list->hwLayers[sCCLayerIndex];
- if(configure(ctx, yuvLayer, ccLayer)) {
- markFlags(yuvLayer, ccLayer);
- sIsModeOn = true;
- }
+ //index guaranteed to be not -1 at this point
+ hwc_layer_1_t *yuvLayer = &list->hwLayers[yuvIndex];
+ chooseState(ctx, dpy, yuvLayer);
+ if(configure(ctx, dpy, yuvLayer)) {
+ markFlags(yuvLayer);
+ sIsModeOn = true;
}
- ALOGD_IF(VIDEO_DEBUG, "%s: stats: yuvCount = %d, yuvIndex = %d,"
- "IsYuvLayerSkip = %d, ccLayerIndex = %d, IsModeOn = %d",
- __FUNCTION__, sYuvCount, sYuvLayerIndex,
- sIsYuvLayerSkip, sCCLayerIndex, sIsModeOn);
-
return sIsModeOn;
}
-void VideoOverlay::chooseState(hwc_context_t *ctx) {
+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::eOverlayState newState = ovutils::OV_CLOSED;
-
- //Support 1 video layer
- if(sYuvCount == 1) {
- //Skip on primary, display on ext.
- if(sIsYuvLayerSkip && ctx->mExtDisplay->getExternalDisplay()) {
- newState = ovutils::OV_2D_VIDEO_ON_TV;
- } else if(sIsYuvLayerSkip) { //skip on primary, no ext
- newState = ovutils::OV_CLOSED;
- } else if(ctx->mExtDisplay->getExternalDisplay()) {
- //display on both
- newState = ovutils::OV_2D_VIDEO_ON_PANEL_TV;
- } else { //display on primary only
- newState = ovutils::OV_2D_VIDEO_ON_PANEL;
- }
+ private_handle_t *hnd = NULL;
+ if(yuvLayer) {
+ hnd = (private_handle_t *)yuvLayer->handle;
}
+ ovutils::eOverlayState newState = ovutils::OV_CLOSED;
+ switch(dpy) {
+ case HWC_DISPLAY_PRIMARY:
+ if(ctx->listStats[dpy].yuvCount == 1) {
+ newState = ovutils::OV_2D_VIDEO_ON_PANEL;
+ if(isSkipLayer(yuvLayer) && !isSecureBuffer(hnd)) {
+ 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)) {
+ 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;
+ }
+ }
+ }*/
+ break;
+ default:
+ break;
+ }
+
sState = newState;
ALOGD_IF(VIDEO_DEBUG, "%s: new chosen state = %s", __FUNCTION__,
ovutils::getStateString(sState));
}
-void VideoOverlay::markFlags(hwc_layer_1_t *yuvLayer, hwc_layer_1_t *ccLayer) {
- switch(sState) {
- case ovutils::OV_2D_VIDEO_ON_PANEL:
- case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
- if(yuvLayer) {
- yuvLayer->compositionType = HWC_OVERLAY;
- yuvLayer->hints |= HWC_HINT_CLEAR_FB;
- }
- if(ccLayer) {
- ccLayer->compositionType = HWC_OVERLAY;
- }
- break;
- case ovutils::OV_2D_VIDEO_ON_TV:
- if(ccLayer) {
- ccLayer->compositionType = HWC_OVERLAY;
- }
- break; //dont update video layer flags.
- default:
- break;
+void VideoOverlay::markFlags(hwc_layer_1_t *yuvLayer) {
+ if(yuvLayer) {
+ yuvLayer->compositionType = HWC_OVERLAY;
+ yuvLayer->hints |= HWC_HINT_CLEAR_FB;
}
}
@@ -119,7 +111,7 @@
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) {
+ if (isSecureBuffer(hnd)) {
ovutils::setMdpFlags(mdpFlags,
ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
}
@@ -161,7 +153,7 @@
//Only for Primary
ov.setCrop(dcrop, ovutils::OV_PIPE0);
- int transform = layer->transform & FINAL_TRANSFORM_MASK;
+ int transform = layer->transform;
ovutils::eTransform orient =
static_cast<ovutils::eTransform>(transform);
ov.setTransform(orient, ovutils::OV_PIPE0);
@@ -186,7 +178,7 @@
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) {
+ if (isSecureBuffer(hnd)) {
ovutils::setMdpFlags(mdpFlags,
ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
}
@@ -233,144 +225,83 @@
return true;
}
-bool configExtCC(hwc_context_t *ctx, hwc_layer_1_t *layer) {
- if(layer == NULL)
- return true;
-
- 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::eIsFg isFgFlag = ovutils::IS_FG_OFF;
- ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
- ovutils::PipeArgs parg(mdpFlags,
- info,
- ovutils::ZORDER_1,
- isFgFlag,
- ovutils::ROT_FLAG_DISABLED);
- ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
- ov.setSource(pargs, ovutils::OV_PIPE2);
-
- 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_PIPE2);
-
- // FIXME: Use source orientation for TV when source is portrait
- //Only for External
- ov.setTransform(0, ovutils::OV_PIPE2);
-
- //Setting position same as crop
- //FIXME stretch to full screen
- ov.setPosition(dcrop, ovutils::OV_PIPE2);
-
- if (!ov.commit(ovutils::OV_PIPE2)) {
- ALOGE("%s: commit fails", __FUNCTION__);
- return false;
- }
- return true;
-}
-
-bool VideoOverlay::configure(hwc_context_t *ctx, hwc_layer_1_t *yuvLayer,
- hwc_layer_1_t *ccLayer) {
-
+bool VideoOverlay::configure(hwc_context_t *ctx, int dpy,
+ hwc_layer_1_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 &= configExtCC(ctx, ccLayer);
- ret &= configPrimVid(ctx, yuvLayer);
- break;
- case ovutils::OV_2D_VIDEO_ON_TV:
- ret &= configExtVid(ctx, yuvLayer);
- ret &= configExtCC(ctx, ccLayer);
- break;
- default:
- return false;
- }
- } else {
- //Ov null
- return false;
+ overlay::Overlay& ov = *(ctx->mOverlay);
+ switch(dpy) {
+ case HWC_DISPLAY_PRIMARY:
+ // Set overlay state
+ ov.setState(sState);
+ switch(sState) {
+ case ovutils::OV_2D_VIDEO_ON_PANEL:
+ ret &= configPrimVid(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:
+ ret = configExtVid(ctx, yuvLayer);
+ break;
+ default:
+ return false;
+ }
+ break;
}
return ret;
}
-bool VideoOverlay::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list)
+bool VideoOverlay::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
+ int dpy)
{
- if(!sIsModeOn || sYuvLayerIndex == -1) {
+ int yuvIndex = ctx->listStats[dpy].yuvIndex;
+ if(!sIsModeOn || yuvIndex == -1) {
return true;
}
private_handle_t *hnd = (private_handle_t *)
- list->hwLayers[sYuvLayerIndex].handle;
-
- private_handle_t *cchnd = NULL;
- if(sCCLayerIndex != -1) {
- cchnd = (private_handle_t *)list->hwLayers[sCCLayerIndex].handle;
- ctx->qbuf->lockAndAdd(cchnd);
- }
-
- // Lock this buffer for read.
- ctx->qbuf->lockAndAdd(hnd);
+ list->hwLayers[yuvIndex].handle;
bool ret = true;
overlay::Overlay& ov = *(ctx->mOverlay);
ovutils::eOverlayState state = ov.getState();
- switch (state) {
- case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
- // Play external
- if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) {
- ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
- ret = false;
- }
- //Play CC on external
- if (cchnd && !ov.queueBuffer(cchnd->fd, cchnd->offset,
- ovutils::OV_PIPE2)) {
- ALOGE("%s: queueBuffer failed for cc 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;
+ switch(dpy) {
+ case HWC_DISPLAY_PRIMARY:
+ switch (state) {
+ 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;
+ default:
+ ret = false;
+ break;
}
break;
- 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;
+ case HWC_DISPLAY_EXTERNAL:
+ switch(state) {
+ case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
+ 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;
}
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;
- }
- //Play CC on external
- if (cchnd && !ov.queueBuffer(cchnd->fd, cchnd->offset,
- ovutils::OV_PIPE2)) {
- ALOGE("%s: queueBuffer failed for cc external", __FUNCTION__);
- ret = false;
- }
- break;
- default:
- ALOGE("%s Unused state %s", __FUNCTION__,
- ovutils::getStateString(state));
- break;
}
-
return ret;
}