Merge "gralloc: Mark buffers used by HWC"
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index b1ee2da..3b08fc5 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -13,7 +13,6 @@
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdhwcomposer\"
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_SRC_FILES := hwc.cpp \
- hwc_video.cpp \
hwc_utils.cpp \
hwc_uevents.cpp \
hwc_vsync.cpp \
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index a81e761..42f5c85 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -30,7 +30,6 @@
#include <overlayRotator.h>
#include <mdp_version.h>
#include "hwc_utils.h"
-#include "hwc_video.h"
#include "hwc_fbupdate.h"
#include "hwc_mdpcomp.h"
#include "external.h"
@@ -102,8 +101,6 @@
if(ctx->mFBUpdate[i])
ctx->mFBUpdate[i]->reset();
- if(ctx->mVidOv[i])
- ctx->mVidOv[i]->reset();
if(ctx->mCopyBit[i])
ctx->mCopyBit[i]->reset();
}
@@ -139,21 +136,18 @@
uint32_t last = list->numHwLayers - 1;
hwc_layer_1_t *fbLayer = &list->hwLayers[last];
if(fbLayer->handle) {
- if(list->numHwLayers > MAX_NUM_LAYERS) {
- ctx->mFBUpdate[dpy]->prepare(ctx, list);
- return 0;
- }
setListStats(ctx, list, dpy);
- bool ret = ctx->mMDPComp->prepare(ctx, list);
- if(!ret) {
- // IF MDPcomp fails use this route
- ctx->mVidOv[dpy]->prepare(ctx, list);
- ctx->mFBUpdate[dpy]->prepare(ctx, list);
- // Use Copybit, when MDP comp fails
- if(ctx->mCopyBit[dpy])
- ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
- ctx->mLayerCache[dpy]->updateLayerCache(list);
- }
+ int fbZOrder = ctx->mMDPComp[dpy]->prepare(ctx, list);
+ if(fbZOrder >= 0)
+ ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZOrder);
+
+ /* Temporarily commenting out C2D until we support partial
+ copybit composition for mixed mode MDP
+
+ // Use Copybit, when MDP comp fails
+ if((fbZOrder >= 0) && ctx->mCopyBit[dpy])
+ ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
+ */
}
}
return 0;
@@ -172,16 +166,17 @@
if(!ctx->dpyAttr[dpy].isPause) {
if(fbLayer->handle) {
ctx->mExtDispConfiguring = false;
- if(list->numHwLayers > MAX_NUM_LAYERS) {
- ctx->mFBUpdate[dpy]->prepare(ctx, list);
- return 0;
- }
setListStats(ctx, list, dpy);
- ctx->mVidOv[dpy]->prepare(ctx, list);
- ctx->mFBUpdate[dpy]->prepare(ctx, list);
- ctx->mLayerCache[dpy]->updateLayerCache(list);
- if(ctx->mCopyBit[dpy])
+ int fbZOrder = ctx->mMDPComp[dpy]->prepare(ctx, list);
+ if(fbZOrder >= 0)
+ ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZOrder);
+
+ /* Temporarily commenting out C2D until we support partial
+ copybit composition for mixed mode MDP
+
+ if((fbZOrder >= 0) && ctx->mCopyBit[dpy])
ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
+ */
}
} else {
// External Display is in Pause state.
@@ -299,7 +294,8 @@
// so that any pipe unsets gets committed
if (display_commit(ctx, dpy) < 0) {
ret = -1;
- ALOGE("%s:post failed for external display !! ", __FUNCTION__);
+ ALOGE("%s:post failed for external display !! ",
+ __FUNCTION__);
}
} else {
}
@@ -360,11 +356,8 @@
copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
if(list->numHwLayers > 1)
hwc_sync(ctx, list, dpy, fd);
- if (!ctx->mVidOv[dpy]->draw(ctx, list)) {
- ALOGE("%s: VideoOverlay draw failed", __FUNCTION__);
- ret = -1;
- }
- if (!ctx->mMDPComp->draw(ctx, list)) {
+
+ if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
ALOGE("%s: MDPComp draw failed", __FUNCTION__);
ret = -1;
}
@@ -413,8 +406,8 @@
if(list->numHwLayers > 1)
hwc_sync(ctx, list, dpy, fd);
- if (!ctx->mVidOv[dpy]->draw(ctx, list)) {
- ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
+ if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
+ ALOGE("%s: MDPComp draw failed", __FUNCTION__);
ret = -1;
}
@@ -558,7 +551,10 @@
dumpsys_log(aBuf, "Qualcomm HWC state:\n");
dumpsys_log(aBuf, " MDPVersion=%d\n", ctx->mMDP.version);
dumpsys_log(aBuf, " DisplayPanel=%c\n", ctx->mMDP.panel);
- ctx->mMDPComp->dump(aBuf);
+ for(int dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
+ if(ctx->mMDPComp[dpy])
+ ctx->mMDPComp[dpy]->dump(aBuf);
+ }
char ovDump[2048] = {'\0'};
ctx->mOverlay->getDump(ovDump, 2048);
dumpsys_log(aBuf, ovDump);
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 6d0b85f..f1f81c1 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -21,7 +21,6 @@
#define DEBUG_FBUPDATE 0
#include <gralloc_priv.h>
#include "hwc_fbupdate.h"
-#include "hwc_video.h"
namespace qhwc {
@@ -38,16 +37,6 @@
mModeOn = false;
}
-bool IFBUpdate::needFbUpdate(hwc_context_t *ctx,
- const hwc_display_contents_1_t *list, int dpy) {
- // if Video Overlay is on and and YUV layers are passed through overlay
- // , no need to configure FB layer.
- if(ctx->mVidOv[dpy]->isModeOn() &&
- (ctx->listStats[dpy].yuvCount == ctx->listStats[dpy].numAppLayers))
- return false;
-
- return true;
-}
//================= Low res====================================
FBUpdateLowRes::FBUpdateLowRes(const int& dpy): IFBUpdate(dpy) {}
@@ -56,79 +45,65 @@
mDest = ovutils::OV_INVALID;
}
-bool FBUpdateLowRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list)
-{
+bool FBUpdateLowRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
+ int fbZorder) {
if(!ctx->mMDP.hasOverlay) {
ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
- __FUNCTION__);
- return false;
+ __FUNCTION__);
+ return false;
}
- mModeOn = configure(ctx, list);
- ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
+ mModeOn = configure(ctx, list, fbZorder);
return mModeOn;
}
// Configure
-bool FBUpdateLowRes::configure(hwc_context_t *ctx,
- hwc_display_contents_1 *list)
-{
+bool FBUpdateLowRes::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
+ int fbZorder) {
bool ret = false;
hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
if (LIKELY(ctx->mOverlay)) {
- // When Video overlay is in use and there are no UI layers to
- // be composed to FB , no need to configure FbUpdate.
- if(!needFbUpdate(ctx, list, mDpy))
- return false;
-
overlay::Overlay& ov = *(ctx->mOverlay);
private_handle_t *hnd = (private_handle_t *)layer->handle;
ovutils::Whf info(hnd->width, hnd->height,
- ovutils::getMdpFormat(hnd->format), hnd->size);
+ ovutils::getMdpFormat(hnd->format), hnd->size);
//Request an RGB pipe
- ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
+ ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy);
if(dest == ovutils::OV_INVALID) { //None available
return false;
}
mDest = dest;
- ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
- // If any of the layers has pre-multiplied alpha, set Pre multiplied
- // Flag as the compositied output is alpha pre-multiplied.
- if(ctx->listStats[mDpy].preMultipliedAlpha == true)
- ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_BLEND_FG_PREMULT);
+ ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
- ovutils::eZorder z_order =
- ctx->mVidOv[mDpy]->isModeOn()?ovutils::ZORDER_1:ovutils::ZORDER_0;
- ovutils::eIsFg is_fg =
- ctx->mVidOv[mDpy]->isModeOn()? ovutils::IS_FG_OFF:ovutils::IS_FG_SET;
+ ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
ovutils::PipeArgs parg(mdpFlags,
- info,
- z_order,
- is_fg,
- ovutils::ROT_FLAGS_NONE);
+ info,
+ zOrder,
+ ovutils::IS_FG_OFF,
+ ovutils::ROT_FLAGS_NONE);
ov.setSource(parg, dest);
hwc_rect_t sourceCrop;
getNonWormholeRegion(list, sourceCrop);
// x,y,w,h
ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
- sourceCrop.right - sourceCrop.left,
- sourceCrop.bottom - sourceCrop.top);
+ sourceCrop.right - sourceCrop.left,
+ sourceCrop.bottom - sourceCrop.top);
ov.setCrop(dcrop, dest);
int transform = layer->transform;
ovutils::eTransform orient =
- static_cast<ovutils::eTransform>(transform);
+ static_cast<ovutils::eTransform>(transform);
ov.setTransform(orient, dest);
hwc_rect_t displayFrame = sourceCrop;
ovutils::Dim dpos(displayFrame.left,
- displayFrame.top,
- displayFrame.right - displayFrame.left,
- displayFrame.bottom - displayFrame.top);
+ displayFrame.top,
+ displayFrame.right - displayFrame.left,
+ displayFrame.bottom - displayFrame.top);
// Calculate the actionsafe dimensions for External(dpy = 1 or 2)
if(mDpy)
getActionSafePosition(ctx, mDpy, dpos.x, dpos.y, dpos.w, dpos.h);
@@ -167,34 +142,28 @@
mDestRight = ovutils::OV_INVALID;
}
-bool FBUpdateHighRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list)
-{
+bool FBUpdateHighRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
+ int fbZorder) {
if(!ctx->mMDP.hasOverlay) {
ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
- __FUNCTION__);
- return false;
+ __FUNCTION__);
+ return false;
}
ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
- mModeOn = configure(ctx, list);
+ mModeOn = configure(ctx, list, fbZorder);
return mModeOn;
}
// Configure
bool FBUpdateHighRes::configure(hwc_context_t *ctx,
- hwc_display_contents_1 *list)
-{
+ hwc_display_contents_1 *list, int fbZorder) {
bool ret = false;
hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
if (LIKELY(ctx->mOverlay)) {
- // When Video overlay is in use and there are no UI layers to
- // be composed to FB , no need to configure FbUpdate.
- if(!needFbUpdate(ctx, list, mDpy))
- return false;
-
overlay::Overlay& ov = *(ctx->mOverlay);
private_handle_t *hnd = (private_handle_t *)layer->handle;
ovutils::Whf info(hnd->width, hnd->height,
- ovutils::getMdpFormat(hnd->format), hnd->size);
+ ovutils::getMdpFormat(hnd->format), hnd->size);
//Request left RGB pipe
ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
@@ -210,49 +179,42 @@
mDestLeft = destL;
mDestRight = destR;
- ovutils::eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
- //If any layer has pre-multiplied alpha, set Pre multiplied
- //Flag as the compositied output is alpha pre-multiplied.
- if(ctx->listStats[mDpy].preMultipliedAlpha == true)
- ovutils::setMdpFlags(mdpFlagsL, ovutils::OV_MDP_BLEND_FG_PREMULT);
+ ovutils::eMdpFlags mdpFlagsL = ovutils::OV_MDP_BLEND_FG_PREMULT;
- ovutils::eZorder z_order =
- ctx->mVidOv[mDpy]->isModeOn()?ovutils::ZORDER_1:ovutils::ZORDER_0;
- ovutils::eIsFg is_fg =
- ctx->mVidOv[mDpy]->isModeOn()? ovutils::IS_FG_OFF:ovutils::IS_FG_SET;
+ ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
ovutils::PipeArgs pargL(mdpFlagsL,
- info,
- z_order,
- is_fg,
- ovutils::ROT_FLAGS_NONE);
+ info,
+ zOrder,
+ ovutils::IS_FG_OFF,
+ ovutils::ROT_FLAGS_NONE);
ov.setSource(pargL, destL);
ovutils::eMdpFlags mdpFlagsR = mdpFlagsL;
ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER);
ovutils::PipeArgs pargR(mdpFlagsR,
- info,
- z_order,
- is_fg,
- ovutils::ROT_FLAGS_NONE);
+ info,
+ zOrder,
+ ovutils::IS_FG_OFF,
+ ovutils::ROT_FLAGS_NONE);
ov.setSource(pargR, destR);
hwc_rect_t sourceCrop;
getNonWormholeRegion(list, sourceCrop);
ovutils::Dim dcropL(sourceCrop.left, sourceCrop.top,
- (sourceCrop.right - sourceCrop.left) / 2,
- sourceCrop.bottom - sourceCrop.top);
+ (sourceCrop.right - sourceCrop.left) / 2,
+ sourceCrop.bottom - sourceCrop.top);
ovutils::Dim dcropR(
- sourceCrop.left + (sourceCrop.right - sourceCrop.left) / 2,
- sourceCrop.top,
- (sourceCrop.right - sourceCrop.left) / 2,
- sourceCrop.bottom - sourceCrop.top);
+ sourceCrop.left + (sourceCrop.right - sourceCrop.left) / 2,
+ sourceCrop.top,
+ (sourceCrop.right - sourceCrop.left) / 2,
+ sourceCrop.bottom - sourceCrop.top);
ov.setCrop(dcropL, destL);
ov.setCrop(dcropR, destR);
int transform = layer->transform;
ovutils::eTransform orient =
- static_cast<ovutils::eTransform>(transform);
+ static_cast<ovutils::eTransform>(transform);
ov.setTransform(orient, destL);
ov.setTransform(orient, destR);
@@ -260,14 +222,14 @@
//For FB left, top will always be 0
//That should also be the case if using 2 mixers for single display
ovutils::Dim dposL(displayFrame.left,
- displayFrame.top,
- (displayFrame.right - displayFrame.left) / 2,
- displayFrame.bottom - displayFrame.top);
+ displayFrame.top,
+ (displayFrame.right - displayFrame.left) / 2,
+ displayFrame.bottom - displayFrame.top);
ov.setPosition(dposL, destL);
ovutils::Dim dposR(0,
- displayFrame.top,
- (displayFrame.right - displayFrame.left) / 2,
- displayFrame.bottom - displayFrame.top);
+ displayFrame.top,
+ (displayFrame.right - displayFrame.left) / 2,
+ displayFrame.bottom - displayFrame.top);
ov.setPosition(dposR, destR);
ret = true;
@@ -294,12 +256,12 @@
ovutils::eDest destR = mDestRight;
if (!ov.queueBuffer(hnd->fd, hnd->offset, destL)) {
ALOGE("%s: queue failed for left of dpy = %d",
- __FUNCTION__, mDpy);
+ __FUNCTION__, mDpy);
ret = false;
}
if (!ov.queueBuffer(hnd->fd, hnd->offset, destR)) {
ALOGE("%s: queue failed for right of dpy = %d",
- __FUNCTION__, mDpy);
+ __FUNCTION__, mDpy);
ret = false;
}
return ret;
diff --git a/libhwcomposer/hwc_fbupdate.h b/libhwcomposer/hwc_fbupdate.h
index ddd24d7..4291a50 100644
--- a/libhwcomposer/hwc_fbupdate.h
+++ b/libhwcomposer/hwc_fbupdate.h
@@ -34,17 +34,15 @@
explicit IFBUpdate(const int& dpy) : mDpy(dpy) {}
virtual ~IFBUpdate() {};
// Sets up members and prepares overlay if conditions are met
- virtual bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list) = 0;
+ virtual bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
+ int fbZorder) = 0;
// Draws layer
virtual bool draw(hwc_context_t *ctx, private_handle_t *hnd) = 0;
//Reset values
virtual void reset();
//Factory method that returns a low-res or high-res version
static IFBUpdate *getObject(const int& width, const int& dpy);
- //To know if configuring FbUpdate is needed.
- static bool needFbUpdate(hwc_context_t *ctx,
- const hwc_display_contents_1_t *list,
- int dpy);
+
protected:
const int mDpy; // display to update
bool mModeOn; // if prepare happened
@@ -55,12 +53,13 @@
public:
explicit FBUpdateLowRes(const int& dpy);
virtual ~FBUpdateLowRes() {};
- bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list);
-
+ bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
+ int fbZorder);
bool draw(hwc_context_t *ctx, private_handle_t *hnd);
void reset();
private:
- bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list);
+ bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
+ int fbZorder);
ovutils::eDest mDest; //pipe to draw on
};
@@ -69,11 +68,13 @@
public:
explicit FBUpdateHighRes(const int& dpy);
virtual ~FBUpdateHighRes() {};
- bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list);
+ bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
+ int fbZorder);
bool draw(hwc_context_t *ctx, private_handle_t *hnd);
void reset();
private:
- bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list);
+ bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
+ int fbZorder);
ovutils::eDest mDestLeft; //left pipe to draw on
ovutils::eDest mDestRight; //right pipe to draw on
};
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index e8559ac..30178a0 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -35,20 +35,44 @@
bool MDPComp::sIdleFallBack = false;
bool MDPComp::sDebugLogs = false;
bool MDPComp::sEnabled = false;
+int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
-MDPComp* MDPComp::getObject(const int& width) {
+MDPComp* MDPComp::getObject(const int& width, int dpy) {
if(width <= MAX_DISPLAY_DIM) {
- return new MDPCompLowRes();
+ return new MDPCompLowRes(dpy);
} else {
- return new MDPCompHighRes();
+ return new MDPCompHighRes(dpy);
}
}
+MDPComp::MDPComp(int dpy):mDpy(dpy){};
+
void MDPComp::dump(android::String8& buf)
{
- dumpsys_log(buf, " MDP Composition: ");
- dumpsys_log(buf, "MDPCompState=%d\n", mState);
- //XXX: Log more info
+ dumpsys_log(buf,"HWC Map for Dpy: %s \n",
+ mDpy ? "\"EXTERNAL\"" : "\"PRIMARY\"");
+ dumpsys_log(buf,"PREV_FRAME: layerCount:%2d mdpCount:%2d \
+ cacheCount:%2d \n", mCachedFrame.layerCount,
+ mCachedFrame.mdpCount, mCachedFrame.cacheCount);
+ dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d \
+ fbCount:%2d \n", mCurrentFrame.layerCount,
+ mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
+ dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n",
+ (mCurrentFrame.needsRedraw? "YES" : "NO"),
+ mCurrentFrame.mdpCount, sMaxPipesPerMixer);
+ dumpsys_log(buf," --------------------------------------------- \n");
+ dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n");
+ dumpsys_log(buf," --------------------------------------------- \n");
+ for(int index = 0; index < mCurrentFrame.layerCount; index++ )
+ dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
+ index,
+ (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
+ mCurrentFrame.layerToMDP[index],
+ (mCurrentFrame.isFBComposed[index] ?
+ (mCurrentFrame.needsRedraw ? "GLES" : "CACHE") : "MDP"),
+ (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
+ mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
+ dumpsys_log(buf,"\n");
}
bool MDPComp::init(hwc_context_t *ctx) {
@@ -67,8 +91,8 @@
sEnabled = false;
if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
- (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+ (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+ (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
sEnabled = true;
}
@@ -78,6 +102,12 @@
sDebugLogs = true;
}
+ sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
+ if(property_get("debug.mdpcomp.maxpermixer", property, NULL) > 0) {
+ if(atoi(property) != 0)
+ sMaxPipesPerMixer = true;
+ }
+
unsigned long idle_timeout = DEFAULT_IDLE_TIME;
if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
if(atoi(property) != 0)
@@ -88,7 +118,7 @@
idleInvalidator = IdleInvalidator::getInstance();
if(idleInvalidator == NULL) {
- ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
+ ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
} else {
idleInvalidator->init(timeout_handler, ctx, idle_timeout);
}
@@ -113,33 +143,24 @@
}
void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- const int dpy = HWC_DISPLAY_PRIMARY;
- LayerProp *layerProp = ctx->layerProp[dpy];
+ hwc_display_contents_1_t* list) {
+ LayerProp *layerProp = ctx->layerProp[mDpy];
- for(int index = 0; index < ctx->listStats[dpy].numAppLayers; index++ ) {
+ for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
hwc_layer_1_t* layer = &(list->hwLayers[index]);
- layerProp[index].mFlags |= HWC_MDPCOMP;
- layer->compositionType = HWC_OVERLAY;
- layer->hints |= HWC_HINT_CLEAR_FB;
- }
-}
-
-void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx,
- hwc_display_contents_1_t* list) {
- const int dpy = HWC_DISPLAY_PRIMARY;
- LayerProp *layerProp = ctx->layerProp[dpy];
-
- for (int index = 0 ;
- index < ctx->listStats[dpy].numAppLayers; index++) {
- if(layerProp[index].mFlags & HWC_MDPCOMP) {
- layerProp[index].mFlags &= ~HWC_MDPCOMP;
- }
-
- if(list->hwLayers[index].compositionType == HWC_OVERLAY) {
- list->hwLayers[index].compositionType = HWC_FRAMEBUFFER;
+ if(!mCurrentFrame.isFBComposed[index]) {
+ layerProp[index].mFlags |= HWC_MDPCOMP;
+ layer->compositionType = HWC_OVERLAY;
+ layer->hints |= HWC_HINT_CLEAR_FB;
+ mCachedFrame.hnd[index] = NULL;
+ } else {
+ if(!mCurrentFrame.needsRedraw)
+ layer->compositionType = HWC_OVERLAY;
}
}
+ mCachedFrame.mdpCount = mCurrentFrame.mdpCount;
+ mCachedFrame.cacheCount = mCurrentFrame.fbCount;
+ mCachedFrame.layerCount = ctx->listStats[mDpy].numAppLayers;
}
/*
@@ -169,41 +190,58 @@
if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) {
ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
- strerror(errno));
+ strerror(errno));
return false;
}
ovData.id = ovInfo.id;
if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) {
ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
- strerror(errno));
+ strerror(errno));
return false;
}
return true;
}
+MDPComp::FrameInfo::FrameInfo() {
+ layerCount = 0;
+ reset();
+}
-void MDPComp::reset(hwc_context_t *ctx,
- hwc_display_contents_1_t* list ) {
- //Reset flags and states
- unsetMDPCompLayerFlags(ctx, list);
- if(mCurrentFrame.pipeLayer) {
- for(int i = 0 ; i < mCurrentFrame.count; i++ ) {
- if(mCurrentFrame.pipeLayer[i].pipeInfo) {
- delete mCurrentFrame.pipeLayer[i].pipeInfo;
- mCurrentFrame.pipeLayer[i].pipeInfo = NULL;
- //We dont own the rotator
- mCurrentFrame.pipeLayer[i].rot = NULL;
- }
+void MDPComp::FrameInfo::reset() {
+
+ for(int i = 0 ; i < MAX_PIPES_PER_MIXER && layerCount; i++ ) {
+ if(mdpToLayer[i].pipeInfo) {
+ delete mdpToLayer[i].pipeInfo;
+ mdpToLayer[i].pipeInfo = NULL;
+ //We dont own the rotator
+ mdpToLayer[i].rot = NULL;
}
- free(mCurrentFrame.pipeLayer);
- mCurrentFrame.pipeLayer = NULL;
}
- mCurrentFrame.count = 0;
+
+ memset(&mdpToLayer, 0, sizeof(mdpToLayer));
+ memset(&layerToMDP, -1, sizeof(layerToMDP));
+ memset(&isFBComposed, 0, sizeof(isFBComposed));
+
+ layerCount = 0;
+ mdpCount = 0;
+ fbCount = 0;
+ needsRedraw = false;
+ fbZ = 0;
+}
+
+MDPComp::LayerCache::LayerCache() {
+ reset();
+}
+
+void MDPComp::LayerCache::reset() {
+ memset(&hnd, 0, sizeof(buffer_handle_t));
+ mdpCount = 0;
+ cacheCount = 0;
+ layerCount = 0;
}
bool MDPComp::isWidthValid(hwc_context_t *ctx, hwc_layer_1_t *layer) {
- const int dpy = HWC_DISPLAY_PRIMARY;
private_handle_t *hnd = (private_handle_t *)layer->handle;
if(!hnd) {
@@ -211,8 +249,8 @@
return false;
}
- int hw_w = ctx->dpyAttr[dpy].xres;
- int hw_h = ctx->dpyAttr[dpy].yres;
+ int hw_w = ctx->dpyAttr[mDpy].xres;
+ int hw_h = ctx->dpyAttr[mDpy].yres;
hwc_rect_t sourceCrop = layer->sourceCrop;
hwc_rect_t displayFrame = layer->displayFrame;
@@ -226,98 +264,107 @@
int dst_h = dst.bottom - dst.top;
if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) {
- hwc_rect_t scissor = {0, 0, hw_w, hw_h };
- qhwc::calculate_crop_rects(crop, dst, scissor, layer->transform);
- crop_w = crop.right - crop.left;
- crop_h = crop.bottom - crop.top;
+ hwc_rect_t scissor = {0, 0, hw_w, hw_h };
+ qhwc::calculate_crop_rects(crop, dst, scissor, layer->transform);
+ crop_w = crop.right - crop.left;
+ crop_h = crop.bottom - crop.top;
}
- //Workaround for MDP HW limitation in DSI command mode panels where
- //FPS will not go beyond 30 if buffers on RGB pipes are of width < 5
+ /* Workaround for MDP HW limitation in DSI command mode panels where
+ * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
+ * less than 5 pixels
+ * */
- if(crop_w < 5)
+ if((crop_w < 5)||(crop_h < 5))
return false;
return true;
}
ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type) {
- const int dpy = HWC_DISPLAY_PRIMARY;
overlay::Overlay& ov = *ctx->mOverlay;
ovutils::eDest mdp_pipe = ovutils::OV_INVALID;
switch(type) {
- case MDPCOMP_OV_DMA:
- mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, dpy);
- if(mdp_pipe != ovutils::OV_INVALID) {
- ctx->mDMAInUse = true;
- return mdp_pipe;
- }
- case MDPCOMP_OV_ANY:
- case MDPCOMP_OV_RGB:
- mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, dpy);
- if(mdp_pipe != ovutils::OV_INVALID) {
- return mdp_pipe;
- }
+ case MDPCOMP_OV_DMA:
+ mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, mDpy);
+ if(mdp_pipe != ovutils::OV_INVALID) {
+ ctx->mDMAInUse = true;
+ return mdp_pipe;
+ }
+ case MDPCOMP_OV_ANY:
+ case MDPCOMP_OV_RGB:
+ mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
+ if(mdp_pipe != ovutils::OV_INVALID) {
+ return mdp_pipe;
+ }
- if(type == MDPCOMP_OV_RGB) {
- //Requested only for RGB pipe
- break;
- }
- case MDPCOMP_OV_VG:
- return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy);
- default:
- ALOGE("%s: Invalid pipe type",__FUNCTION__);
- return ovutils::OV_INVALID;
+ if(type == MDPCOMP_OV_RGB) {
+ //Requested only for RGB pipe
+ break;
+ }
+ case MDPCOMP_OV_VG:
+ return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
+ default:
+ ALOGE("%s: Invalid pipe type",__FUNCTION__);
+ return ovutils::OV_INVALID;
};
return ovutils::OV_INVALID;
}
-bool MDPComp::isDoable(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- //Number of layers
- const int dpy = HWC_DISPLAY_PRIMARY;
- int numAppLayers = ctx->listStats[dpy].numAppLayers;
- int numDMAPipes = qdutils::MDPVersion::getInstance().getDMAPipes();
+bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
+ int numAppLayers = ctx->listStats[mDpy].numAppLayers;
- overlay::Overlay& ov = *ctx->mOverlay;
- int availablePipes = ov.availablePipes(dpy);
-
- if(ctx->mNeedsRotator)
- availablePipes -= numDMAPipes;
-
- if(numAppLayers < 1 || numAppLayers > MAX_PIPES_PER_MIXER ||
- pipesNeeded(ctx, list) > availablePipes) {
- ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
+ if(!isEnabled()) {
+ ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
return false;
}
if(ctx->mExtDispConfiguring) {
ALOGD_IF( isDebug(),"%s: External Display connection is pending",
- __FUNCTION__);
+ __FUNCTION__);
return false;
}
- if(isSecuring(ctx)) {
- ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
- return false;
- }
-
- if(ctx->mSecureMode)
- return false;
-
- //Check for skip layers
- if(isSkipPresent(ctx, dpy)) {
- ALOGD_IF(isDebug(), "%s: Skip layers are present",__FUNCTION__);
- return false;
- }
-
- if(ctx->listStats[dpy].needsAlphaScale
- && ctx->mMDP.version < qdutils::MDSS_V5) {
+ if(ctx->listStats[mDpy].needsAlphaScale
+ && ctx->mMDP.version < qdutils::MDSS_V5) {
ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
return false;
}
+ return true;
+}
+
+/* Checks for conditions where all the layers marked for MDP comp cannot be
+ * bypassed. On such conditions we try to bypass atleast YUV layers */
+bool MDPComp::isFullFrameDoable(hwc_context_t *ctx,
+ hwc_display_contents_1_t* list){
+
+ int numAppLayers = ctx->listStats[mDpy].numAppLayers;
+ int mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount;
+ int fbNeeded = int(mCurrentFrame.fbCount != 0);
+
+ if(mDpy > HWC_DISPLAY_PRIMARY){
+ ALOGD_IF(isDebug(), "%s: Cannot support External display(s)",
+ __FUNCTION__);
+ return false;
+ }
+
+ if(mdpCount > (sMaxPipesPerMixer-fbNeeded)) {
+ ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
+ return false;
+ }
+
+ if(pipesNeeded(ctx, list) > getAvailablePipes(ctx)) {
+ ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes",__FUNCTION__);
+ return false;
+ }
+
+ if(isSkipPresent(ctx, mDpy)) {
+ ALOGD_IF(isDebug(), "%s: Skip layers present",__FUNCTION__);
+ return false;
+ }
+
//FB composition on idle timeout
if(sIdleFallBack) {
sIdleFallBack = false;
@@ -325,11 +372,6 @@
return false;
}
- if(ctx->mNeedsRotator && ctx->mDMAInUse) {
- ALOGD_IF(isDebug(), "%s: DMA not available for Rotator",__FUNCTION__);
- return false;
- }
-
//MDP composition is not efficient if layer needs rotator.
for(int i = 0; i < numAppLayers; ++i) {
// As MDP h/w supports flip operation, use MDP comp only for
@@ -350,65 +392,258 @@
return true;
}
-bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
- const int dpy = HWC_DISPLAY_PRIMARY;
- if(!ctx) {
- ALOGE("%s: invalid context", __FUNCTION__);
- return -1;
- }
+/* Checks for conditions where YUV layers cannot be bypassed */
+bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
- ctx->mDMAInUse = false;
- if(!allocLayerPipes(ctx, list, mCurrentFrame)) {
- ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
+ if(isSkipLayer(layer)) {
+ ALOGE("%s: Unable to bypass skipped YUV", __FUNCTION__);
return false;
}
- for (int index = 0 ; index < mCurrentFrame.count; index++) {
- hwc_layer_1_t* layer = &list->hwLayers[index];
- if(configure(ctx, layer, mCurrentFrame.pipeLayer[index]) != 0 ) {
- ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \
- layer %d",__FUNCTION__, index);
+ if(ctx->mNeedsRotator && ctx->mDMAInUse) {
+ ALOGE("%s: No DMA for Rotator",__FUNCTION__);
+ return false;
+ }
+
+ if(isSecuring(ctx, layer)) {
+ ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
+ return false;
+ }
+
+ /* Workaround for downscales larger than 4x. Will be removed once decimator
+ * block is enabled for MDSS*/
+ if(ctx->mMDP.version == qdutils::MDSS_V5) {
+ hwc_rect_t crop = layer->sourceCrop;
+ hwc_rect_t dst = layer->displayFrame;
+
+ int cWidth = crop.right - crop.left;
+ int cHeight = crop.bottom - crop.top;
+ int dWidth = dst.right - dst.left;
+ int dHeight = dst.bottom - dst.top;
+
+ if((cWidth/dWidth) > 4 || (cHeight/dHeight) > 4)
return false;
- }
}
return true;
}
-bool MDPComp::prepare(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- if(!isEnabled()) {
- ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
- return false;
+void MDPComp::batchLayers() {
+ /* Idea is to keep as many contiguous non-updating(cached) layers in FB and
+ * send rest of them through MDP. NEVER mark an updating layer for caching.
+ * But cached ones can be marked for MDP*/
+
+ int maxBatchStart = -1;
+ int maxBatchCount = 0;
+
+ /* All or Nothing is cached. No batching needed */
+ if(!mCurrentFrame.fbCount ||
+ (mCurrentFrame.fbCount == mCurrentFrame.layerCount))
+ return;
+
+ /* Search for max number of contiguous (cached) layers */
+ int i = 0;
+ while (i < mCurrentFrame.layerCount) {
+ int count = 0;
+ while(mCurrentFrame.isFBComposed[i] && i < mCurrentFrame.layerCount) {
+ count++; i++;
+ }
+ if(count > maxBatchCount) {
+ maxBatchCount = count;
+ maxBatchStart = i - count;
+ }
+ if(i < mCurrentFrame.layerCount) i++;
}
+ /* reset rest of the layers for MDP comp */
+ for(int i = 0; i < mCurrentFrame.layerCount; i++) {
+ if(i != maxBatchStart){
+ mCurrentFrame.isFBComposed[i] = false;
+ } else {
+ i += maxBatchCount;
+ }
+ }
+
+ mCurrentFrame.fbCount = maxBatchCount;
+
+ ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
+ mCurrentFrame.fbCount);
+}
+void MDPComp::updateLayerCache(hwc_context_t* ctx,
+ hwc_display_contents_1_t* list) {
+
+ int numAppLayers = ctx->listStats[mDpy].numAppLayers;
+ int numCacheableLayers = 0;
+
+ if((list->flags & HWC_GEOMETRY_CHANGED) || (isSkipPresent(ctx, mDpy))) {
+ ALOGD_IF(isDebug(),"%s: No Caching: \
+ GEOMETRY change: %d SKIP present: %d", __FUNCTION__,
+ (list->flags & HWC_GEOMETRY_CHANGED),isSkipPresent(ctx, mDpy));
+ mCachedFrame.reset();
+ return;
+ }
+
+ for(int i = 0; i < numAppLayers; i++) {
+ if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
+ numCacheableLayers++;
+ mCurrentFrame.isFBComposed[i] = true;
+ } else {
+ mCachedFrame.hnd[i] = list->hwLayers[i].handle;
+ }
+ }
+ mCurrentFrame.fbCount = numCacheableLayers;
+ ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, numCacheableLayers);
+}
+
+int MDPComp::getAvailablePipes(hwc_context_t* ctx) {
+ int numDMAPipes = qdutils::MDPVersion::getInstance().getDMAPipes();
overlay::Overlay& ov = *ctx->mOverlay;
- bool isMDPCompUsed = true;
+
+ int numAvailable = ov.availablePipes(mDpy);
+
+ //Reserve DMA for rotator
+ if(ctx->mNeedsRotator)
+ numAvailable -= numDMAPipes;
+
+ //Reserve pipe(s)for FB
+ if(mCurrentFrame.fbCount)
+ numAvailable -= pipesForFB();
+
+ return numAvailable;
+}
+
+void MDPComp::resetFrameForFB(hwc_context_t* ctx,
+ hwc_display_contents_1_t* list) {
+ mCurrentFrame.fbCount = mCurrentFrame.layerCount;
+ memset(&mCurrentFrame.isFBComposed, 1,
+ sizeof(mCurrentFrame.isFBComposed));
+ mCurrentFrame.needsRedraw = true;
+}
+
+void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
+
+ int nYuvCount = ctx->listStats[mDpy].yuvCount;
+ for(int index = 0;index < nYuvCount; index++){
+ int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
+ hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
+
+ if(!isYUVDoable(ctx, layer)) {
+ if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
+ mCurrentFrame.isFBComposed[nYuvIndex] = true;
+ mCurrentFrame.fbCount++;
+ }
+ } else {
+ if(mCurrentFrame.isFBComposed[nYuvIndex]) {
+ mCurrentFrame.isFBComposed[nYuvIndex] = false;
+ mCurrentFrame.fbCount--;
+ }
+ }
+ }
+ ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
+ mCurrentFrame.fbCount);
+}
+
+int MDPComp::programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
+ int fbZOrder = -1;
+ ctx->mDMAInUse = false;
+
+ if(!allocLayerPipes(ctx, list)) {
+ ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
+ goto fn_exit;
+ }
+
+ for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
+ index++) {
+ if(!mCurrentFrame.isFBComposed[index]) {
+
+ int mdpIndex = mCurrentFrame.layerToMDP[index];
+ hwc_layer_1_t* layer = &list->hwLayers[index];
+
+ MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
+ cur_pipe->zOrder = mdpNextZOrder++;
+
+ if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
+ ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
+ layer %d",__FUNCTION__, index);
+ goto fn_exit;
+ }
+ } else if(fbZOrder < 0) {
+ fbZOrder = mdpNextZOrder++;
+ };
+ }
+
+ return fbZOrder;
+
+ fn_exit:
+ //Complete fallback to FB
+ resetFrameForFB(ctx, list);
+ return 0;
+}
+
+int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
//reset old data
- reset(ctx, list);
+ mCurrentFrame.reset();
- bool doable = isDoable(ctx, list);
- if(doable) {
- if(setup(ctx, list)) {
- setMDPCompLayerFlags(ctx, list);
- } else {
- ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__);
- isMDPCompUsed = false;
+ if(!isFrameDoable(ctx)) {
+ ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
+ __FUNCTION__);
+ return 0;
+ }
+
+ mCurrentFrame.layerCount = ctx->listStats[mDpy].numAppLayers;
+
+ //Iterate layer list for cached layers
+ updateLayerCache(ctx, list);
+
+ //Add YUV layers to cached list
+ updateYUV(ctx, list);
+
+ //Optimze for bypass
+ batchLayers();
+
+ //list is already parsed / batched for optimal mixed mode composition.
+ //Check whether layers marked for MDP Composition is actually doable.
+ if(!isFullFrameDoable(ctx, list)){
+ //All layers marked for MDP comp cannot be bypassed.
+ //Try to compose atleast YUV layers through MDP comp and let
+ //all the RGB layers compose in FB
+ resetFrameForFB(ctx, list);
+ updateYUV(ctx, list);
+ }
+
+ mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
+ mCurrentFrame.fbCount;
+
+ if(mCurrentFrame.mdpCount) {
+ // populate layer and MDP maps
+ for(int idx = 0, mdpIdx = 0; idx < mCurrentFrame.layerCount; idx++) {
+ if(!mCurrentFrame.isFBComposed[idx]) {
+ mCurrentFrame.mdpToLayer[mdpIdx].listIndex = idx;
+ mCurrentFrame.layerToMDP[idx] = mdpIdx++;
+ }
}
- } else {
- ALOGD_IF( isDebug(),"%s: MDP Comp not possible[%d]",__FUNCTION__,
- doable);
- isMDPCompUsed = false;
+ //Acquire and Program MDP pipes
+ mCurrentFrame.fbZ = programMDP(ctx, list);
}
- //Reset states
- if(!isMDPCompUsed) {
- //Reset current frame
- reset(ctx, list);
+ /* Any change in composition types needs an FB refresh*/
+ if(mCurrentFrame.fbCount &&
+ ((mCurrentFrame.mdpCount != mCachedFrame.mdpCount) ||
+ (mCurrentFrame.fbCount != mCachedFrame.cacheCount) ||
+ !mCurrentFrame.mdpCount)) {
+ mCurrentFrame.needsRedraw = true;
}
- mState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF;
- return isMDPCompUsed;
+ //UpdateLayerFlags
+ setMDPCompLayerFlags(ctx, list);
+
+ if(isDebug()) {
+ android::String8 sDump("");
+ dump(sDump);
+ ALOGE("%s",sDump.string());
+ }
+
+ return mCurrentFrame.fbZ;
}
//=============MDPCompLowRes===================================================
@@ -417,64 +652,66 @@
* Configures pipe(s) for MDP composition
*/
int MDPCompLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& pipeLayerPair) {
- const int dpy = HWC_DISPLAY_PRIMARY;
+ PipeLayerPair& PipeLayerPair) {
MdpPipeInfoLowRes& mdp_info =
- *(static_cast<MdpPipeInfoLowRes*>(pipeLayerPair.pipeInfo));
+ *(static_cast<MdpPipeInfoLowRes*>(PipeLayerPair.pipeInfo));
eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
eIsFg isFg = IS_FG_OFF;
eDest dest = mdp_info.index;
- return configureLowRes(ctx, layer, dpy, mdpFlags, zOrder, isFg, dest,
- &pipeLayerPair.rot);
+ ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
+ __FUNCTION__, layer, zOrder, dest);
+
+ return configureLowRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
+ &PipeLayerPair.rot);
}
int MDPCompLowRes::pipesNeeded(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- const int dpy = HWC_DISPLAY_PRIMARY;
- return ctx->listStats[dpy].numAppLayers;
+ hwc_display_contents_1_t* list) {
+ return mCurrentFrame.mdpCount;
}
bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list,
- FrameInfo& currentFrame) {
- const int dpy = HWC_DISPLAY_PRIMARY;
- overlay::Overlay& ov = *ctx->mOverlay;
- int layer_count = ctx->listStats[dpy].numAppLayers;
+ hwc_display_contents_1_t* list) {
+ if(isYuvPresent(ctx, mDpy)) {
+ int nYuvCount = ctx->listStats[mDpy].yuvCount;
- currentFrame.count = layer_count;
- currentFrame.pipeLayer = (PipeLayerPair*)
- malloc(sizeof(PipeLayerPair) * currentFrame.count);
+ for(int index = 0; index < nYuvCount ; index ++) {
+ int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
- if(isYuvPresent(ctx, dpy)) {
- int nYuvCount = ctx->listStats[dpy].yuvCount;
+ if(mCurrentFrame.isFBComposed[nYuvIndex])
+ continue;
- for(int index = 0; index < nYuvCount; index ++) {
- int nYuvIndex = ctx->listStats[dpy].yuvIndices[index];
hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
- PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
+
+ int mdpIndex = mCurrentFrame.layerToMDP[nYuvIndex];
+
+ PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
info.pipeInfo = new MdpPipeInfoLowRes;
info.rot = NULL;
MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo;
+
pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
if(pipe_info.index == ovutils::OV_INVALID) {
ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
- __FUNCTION__);
+ __FUNCTION__);
return false;
}
- pipe_info.zOrder = nYuvIndex;
}
}
- for(int index = 0 ; index < layer_count ; index++ ) {
+ for(int index = 0 ; index < mCurrentFrame.layerCount; index++ ) {
+ if(mCurrentFrame.isFBComposed[index]) continue;
hwc_layer_1_t* layer = &list->hwLayers[index];
private_handle_t *hnd = (private_handle_t *)layer->handle;
if(isYuvBuffer(hnd))
continue;
- PipeLayerPair& info = currentFrame.pipeLayer[index];
+ int mdpIndex = mCurrentFrame.layerToMDP[index];
+
+ PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
info.pipeInfo = new MdpPipeInfoLowRes;
info.rot = NULL;
MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo;
@@ -482,7 +719,7 @@
ePipeType type = MDPCOMP_OV_ANY;
if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator
- && ctx->mMDP.version >= qdutils::MDSS_V5) {
+ && ctx->mMDP.version >= qdutils::MDSS_V5) {
type = MDPCOMP_OV_DMA;
}
@@ -491,14 +728,13 @@
ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
return false;
}
- pipe_info.zOrder = index;
}
return true;
}
bool MDPCompLowRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
- if(!isEnabled() || !isUsed()) {
+ if(!isEnabled()) {
ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
return true;
}
@@ -509,16 +745,17 @@
}
/* reset Invalidator */
- if(idleInvalidator)
+ if(idleInvalidator && mCurrentFrame.mdpCount)
idleInvalidator->markForSleep();
- const int dpy = HWC_DISPLAY_PRIMARY;
overlay::Overlay& ov = *ctx->mOverlay;
- LayerProp *layerProp = ctx->layerProp[dpy];
+ LayerProp *layerProp = ctx->layerProp[mDpy];
- int numHwLayers = ctx->listStats[dpy].numAppLayers;
- for(int i = 0; i < numHwLayers; i++ )
+ int numHwLayers = ctx->listStats[mDpy].numAppLayers;
+ for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
{
+ if(mCurrentFrame.isFBComposed[i]) continue;
+
hwc_layer_1_t *layer = &list->hwLayers[i];
private_handle_t *hnd = (private_handle_t *)layer->handle;
if(!hnd) {
@@ -526,8 +763,10 @@
return false;
}
+ int mdpIndex = mCurrentFrame.layerToMDP[i];
+
MdpPipeInfoLowRes& pipe_info =
- *(MdpPipeInfoLowRes*)mCurrentFrame.pipeLayer[i].pipeInfo;
+ *(MdpPipeInfoLowRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
ovutils::eDest dest = pipe_info.index;
if(dest == ovutils::OV_INVALID) {
ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
@@ -539,12 +778,12 @@
}
ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
- using pipe: %d", __FUNCTION__, layer,
- hnd, dest );
+ using pipe: %d", __FUNCTION__, layer,
+ hnd, dest );
int fd = hnd->fd;
uint32_t offset = hnd->offset;
- Rotator *rot = mCurrentFrame.pipeLayer[i].rot;
+ Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
if(rot) {
if(!rot->queueBuffer(fd, offset))
return false;
@@ -565,77 +804,70 @@
//=============MDPCompHighRes===================================================
int MDPCompHighRes::pipesNeeded(hwc_context_t *ctx,
- hwc_display_contents_1_t* list) {
- const int dpy = HWC_DISPLAY_PRIMARY;
- int numAppLayers = ctx->listStats[dpy].numAppLayers;
+ hwc_display_contents_1_t* list) {
int pipesNeeded = 0;
+ int hw_w = ctx->dpyAttr[mDpy].xres;
- int hw_w = ctx->dpyAttr[dpy].xres;
-
- for(int i = 0; i < numAppLayers; ++i) {
- hwc_layer_1_t* layer = &list->hwLayers[i];
- hwc_rect_t dst = layer->displayFrame;
- if(dst.left > hw_w/2) {
- pipesNeeded++;
- } else if(dst.right <= hw_w/2) {
- pipesNeeded++;
- } else {
- pipesNeeded += 2;
- }
+ for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
+ if(!mCurrentFrame.isFBComposed[i]) {
+ hwc_layer_1_t* layer = &list->hwLayers[i];
+ hwc_rect_t dst = layer->displayFrame;
+ if(dst.left > hw_w/2) {
+ pipesNeeded++;
+ } else if(dst.right <= hw_w/2) {
+ pipesNeeded++;
+ } else {
+ pipesNeeded += 2;
+ }
+ }
}
return pipesNeeded;
}
bool MDPCompHighRes::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
- MdpPipeInfoHighRes& pipe_info, ePipeType type) {
- const int dpy = HWC_DISPLAY_PRIMARY;
- int hw_w = ctx->dpyAttr[dpy].xres;
+ MdpPipeInfoHighRes& pipe_info,
+ ePipeType type) {
+ int hw_w = ctx->dpyAttr[mDpy].xres;
- hwc_rect_t dst = layer->displayFrame;
- if(dst.left > hw_w/2) {
- pipe_info.lIndex = ovutils::OV_INVALID;
- pipe_info.rIndex = getMdpPipe(ctx, type);
- if(pipe_info.rIndex == ovutils::OV_INVALID)
- return false;
- } else if (dst.right <= hw_w/2) {
- pipe_info.rIndex = ovutils::OV_INVALID;
- pipe_info.lIndex = getMdpPipe(ctx, type);
- if(pipe_info.lIndex == ovutils::OV_INVALID)
- return false;
- } else {
- pipe_info.rIndex = getMdpPipe(ctx, type);
- pipe_info.lIndex = getMdpPipe(ctx, type);
- if(pipe_info.rIndex == ovutils::OV_INVALID ||
- pipe_info.lIndex == ovutils::OV_INVALID)
- return false;
- }
- return true;
+ hwc_rect_t dst = layer->displayFrame;
+ if(dst.left > hw_w/2) {
+ pipe_info.lIndex = ovutils::OV_INVALID;
+ pipe_info.rIndex = getMdpPipe(ctx, type);
+ if(pipe_info.rIndex == ovutils::OV_INVALID)
+ return false;
+ } else if (dst.right <= hw_w/2) {
+ pipe_info.rIndex = ovutils::OV_INVALID;
+ pipe_info.lIndex = getMdpPipe(ctx, type);
+ if(pipe_info.lIndex == ovutils::OV_INVALID)
+ return false;
+ } else {
+ pipe_info.rIndex = getMdpPipe(ctx, type);
+ pipe_info.lIndex = getMdpPipe(ctx, type);
+ if(pipe_info.rIndex == ovutils::OV_INVALID ||
+ pipe_info.lIndex == ovutils::OV_INVALID)
+ return false;
+ }
+ return true;
}
bool MDPCompHighRes::allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list,
- FrameInfo& currentFrame) {
- const int dpy = HWC_DISPLAY_PRIMARY;
+ hwc_display_contents_1_t* list) {
overlay::Overlay& ov = *ctx->mOverlay;
- int layer_count = ctx->listStats[dpy].numAppLayers;
+ int layer_count = ctx->listStats[mDpy].numAppLayers;
- currentFrame.count = layer_count;
- currentFrame.pipeLayer = (PipeLayerPair*)
- malloc(sizeof(PipeLayerPair) * currentFrame.count);
-
- if(isYuvPresent(ctx, dpy)) {
- int nYuvCount = ctx->listStats[dpy].yuvCount;
+ if(isYuvPresent(ctx, mDpy)) {
+ int nYuvCount = ctx->listStats[mDpy].yuvCount;
for(int index = 0; index < nYuvCount; index ++) {
- int nYuvIndex = ctx->listStats[dpy].yuvIndices[index];
+ int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
- PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
+ PipeLayerPair& info = mCurrentFrame.mdpToLayer[nYuvIndex];
info.pipeInfo = new MdpPipeInfoHighRes;
info.rot = NULL;
MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo;
if(!acquireMDPPipes(ctx, layer, pipe_info,MDPCOMP_OV_VG)) {
ALOGD_IF(isDebug(),"%s: Unable to get pipe for videos",
- __FUNCTION__);
+ __FUNCTION__);
//TODO: windback pipebook data on fail
return false;
}
@@ -650,7 +882,7 @@
if(isYuvBuffer(hnd))
continue;
- PipeLayerPair& info = currentFrame.pipeLayer[index];
+ PipeLayerPair& info = mCurrentFrame.mdpToLayer[index];
info.pipeInfo = new MdpPipeInfoHighRes;
info.rot = NULL;
MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo;
@@ -658,7 +890,7 @@
ePipeType type = MDPCOMP_OV_ANY;
if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator
- && ctx->mMDP.version >= qdutils::MDSS_V5)
+ && ctx->mMDP.version >= qdutils::MDSS_V5)
type = MDPCOMP_OV_DMA;
if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
@@ -674,22 +906,25 @@
* Configures pipe(s) for MDP composition
*/
int MDPCompHighRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& pipeLayerPair) {
- const int dpy = HWC_DISPLAY_PRIMARY;
+ PipeLayerPair& PipeLayerPair) {
MdpPipeInfoHighRes& mdp_info =
- *(static_cast<MdpPipeInfoHighRes*>(pipeLayerPair.pipeInfo));
+ *(static_cast<MdpPipeInfoHighRes*>(PipeLayerPair.pipeInfo));
eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
eIsFg isFg = IS_FG_OFF;
eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
eDest lDest = mdp_info.lIndex;
eDest rDest = mdp_info.rIndex;
- return configureHighRes(ctx, layer, dpy, mdpFlagsL, zOrder, isFg, lDest,
- rDest, &pipeLayerPair.rot);
+
+ ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
+ "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
+
+ return configureHighRes(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
+ rDest, &PipeLayerPair.rot);
}
bool MDPCompHighRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
- if(!isEnabled() || !isUsed()) {
+ if(!isEnabled()) {
ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
return true;
}
@@ -700,16 +935,17 @@
}
/* reset Invalidator */
- if(idleInvalidator)
+ if(idleInvalidator && mCurrentFrame.mdpCount)
idleInvalidator->markForSleep();
- const int dpy = HWC_DISPLAY_PRIMARY;
overlay::Overlay& ov = *ctx->mOverlay;
- LayerProp *layerProp = ctx->layerProp[dpy];
+ LayerProp *layerProp = ctx->layerProp[mDpy];
- int numHwLayers = ctx->listStats[dpy].numAppLayers;
- for(int i = 0; i < numHwLayers; i++ )
+ int numHwLayers = ctx->listStats[mDpy].numAppLayers;
+ for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
{
+ if(mCurrentFrame.isFBComposed[i]) continue;
+
hwc_layer_1_t *layer = &list->hwLayers[i];
private_handle_t *hnd = (private_handle_t *)layer->handle;
if(!hnd) {
@@ -721,12 +957,15 @@
continue;
}
+ int mdpIndex = mCurrentFrame.layerToMDP[i];
+
MdpPipeInfoHighRes& pipe_info =
- *(MdpPipeInfoHighRes*)mCurrentFrame.pipeLayer[i].pipeInfo;
- Rotator *rot = mCurrentFrame.pipeLayer[i].rot;
+ *(MdpPipeInfoHighRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
+ Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
ovutils::eDest indexL = pipe_info.lIndex;
ovutils::eDest indexR = pipe_info.rIndex;
+
int fd = hnd->fd;
int offset = hnd->offset;
@@ -740,7 +979,7 @@
if(indexL != ovutils::OV_INVALID) {
ovutils::eDest destL = (ovutils::eDest)indexL;
ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
- using pipe: %d", __FUNCTION__, layer, hnd, indexL );
+ using pipe: %d", __FUNCTION__, layer, hnd, indexL );
if (!ov.queueBuffer(fd, offset, destL)) {
ALOGE("%s: queueBuffer failed for left mixer", __FUNCTION__);
return false;
@@ -751,7 +990,7 @@
if(indexR != ovutils::OV_INVALID) {
ovutils::eDest destR = (ovutils::eDest)indexR;
ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
- using pipe: %d", __FUNCTION__, layer, hnd, indexR );
+ using pipe: %d", __FUNCTION__, layer, hnd, indexR );
if (!ov.queueBuffer(fd, offset, destR)) {
ALOGE("%s: queueBuffer failed for right mixer", __FUNCTION__);
return false;
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index d847f56..7970cd3 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -29,7 +29,7 @@
#define MAX_PIPES_PER_MIXER 4
namespace overlay {
- class Rotator;
+class Rotator;
};
namespace qhwc {
@@ -37,74 +37,104 @@
class MDPComp {
public:
+ explicit MDPComp(int);
virtual ~MDPComp(){};
/*sets up mdp comp for the current frame */
- bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list);
+ int prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list);
/* draw */
virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) = 0;
-
+ /* dumpsys */
void dump(android::String8& buf);
- bool isUsed() { return (mState == MDPCOMP_ON); };
- static MDPComp* getObject(const int& width);
+ static MDPComp* getObject(const int& width, const int dpy);
/* Handler to invoke frame redraw on Idle Timer expiry */
static void timeout_handler(void *udata);
+ /* Initialize MDP comp*/
static bool init(hwc_context_t *ctx);
protected:
- enum eState {
- MDPCOMP_ON = 0,
- MDPCOMP_OFF,
- };
-
enum ePipeType {
MDPCOMP_OV_RGB = ovutils::OV_MDP_PIPE_RGB,
MDPCOMP_OV_VG = ovutils::OV_MDP_PIPE_VG,
MDPCOMP_OV_DMA = ovutils::OV_MDP_PIPE_DMA,
MDPCOMP_OV_ANY,
};
+
+ /* mdp pipe data */
struct MdpPipeInfo {
int zOrder;
virtual ~MdpPipeInfo(){};
};
+
+ /* per layer data */
struct PipeLayerPair {
MdpPipeInfo *pipeInfo;
- native_handle_t* handle;
overlay::Rotator* rot;
+ int listIndex;
};
- /* introduced for mixed mode implementation */
+ /* per frame data */
struct FrameInfo {
- int count;
- struct PipeLayerPair* pipeLayer;
+ /* maps layer list to mdp list */
+ int layerCount;
+ int layerToMDP[MAX_NUM_LAYERS];
+
+ /* maps mdp list to layer list */
+ int mdpCount;
+ struct PipeLayerPair mdpToLayer[MAX_PIPES_PER_MIXER];
+
+ /* layer composing on FB? */
+ int fbCount;
+ bool isFBComposed[MAX_NUM_LAYERS];
+
+ bool needsRedraw;
+ int fbZ;
+
+ /* c'tor */
+ FrameInfo();
+ /* clear old frame data */
+ void reset();
};
+ /* cached data */
+ struct LayerCache {
+ int layerCount;
+ int mdpCount;
+ int cacheCount;
+ buffer_handle_t hnd[MAX_NUM_LAYERS];
+
+ /* c'tor */
+ LayerCache();
+ /* clear caching info*/
+ void reset();
+ };
+
+ /* No of pipes needed for Framebuffer */
+ virtual int pipesForFB() = 0;
/* calculates pipes needed for the panel */
virtual int pipesNeeded(hwc_context_t *ctx,
hwc_display_contents_1_t* list) = 0;
/* allocates pipe from pipe book */
virtual bool allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list,FrameInfo& current_frame) = 0;
+ hwc_display_contents_1_t* list) = 0;
/* configures MPD pipes */
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& pipeLayerPair) = 0;
+ PipeLayerPair& pipeLayerPair) = 0;
/* set/reset flags for MDPComp */
void setMDPCompLayerFlags(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
- void unsetMDPCompLayerFlags(hwc_context_t* ctx,
- hwc_display_contents_1_t* list);
- /* get/set states */
- eState getState() { return mState; };
- /* reset state */
- void reset( hwc_context_t *ctx, hwc_display_contents_1_t* list );
+ hwc_display_contents_1_t* list);
/* allocate MDP pipes from overlay */
ovutils::eDest getMdpPipe(hwc_context_t *ctx, ePipeType type);
+
/* checks for conditions where mdpcomp is not possible */
- bool isDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- /* sets up MDP comp for current frame */
- bool setup(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+ bool isFrameDoable(hwc_context_t *ctx);
+ /* checks for conditions where RGB layers cannot be bypassed */
+ bool isFullFrameDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
+ /* checks for conditions where YUV layers cannot be bypassed */
+ bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
+
/* set up Border fill as Base pipe */
static bool setupBasePipe(hwc_context_t*);
/* Is debug enabled */
@@ -113,20 +143,34 @@
static bool isEnabled() { return sEnabled; };
/* checks for mdp comp width limitation */
bool isWidthValid(hwc_context_t *ctx, hwc_layer_1_t *layer);
+ /* tracks non updating layers*/
+ void updateLayerCache(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+ /* resets cache for complete fallback */
+ void resetFrameForFB(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+ /* optimize layers for mdp comp*/
+ void batchLayers();
+ /* gets available pipes for mdp comp */
+ int getAvailablePipes(hwc_context_t* ctx);
+ /* updates cache map with YUV info */
+ void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+ int programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list);
- eState mState;
+ int mDpy;
static bool sEnabled;
static bool sDebugLogs;
static bool sIdleFallBack;
+ static int sMaxPipesPerMixer;
static IdleInvalidator *idleInvalidator;
struct FrameInfo mCurrentFrame;
+ struct LayerCache mCachedFrame;
};
class MDPCompLowRes : public MDPComp {
public:
- virtual ~MDPCompLowRes(){};
- virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
+ explicit MDPCompLowRes(int dpy):MDPComp(dpy){};
+ virtual ~MDPCompLowRes(){};
+ virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
private:
struct MdpPipeInfoLowRes : public MdpPipeInfo {
@@ -134,21 +178,21 @@
virtual ~MdpPipeInfoLowRes() {};
};
+ virtual int pipesForFB() { return 1; };
/* configure's overlay pipes for the frame */
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& pipeLayerPair);
+ PipeLayerPair& pipeLayerPair);
/* allocates pipes to selected candidates */
virtual bool allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list,
- FrameInfo& current_frame);
+ hwc_display_contents_1_t* list);
- virtual int pipesNeeded(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
+ virtual int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list);
};
class MDPCompHighRes : public MDPComp {
public:
+ explicit MDPCompHighRes(int dpy):MDPComp(dpy){};
virtual ~MDPCompHighRes(){};
virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
private:
@@ -159,16 +203,16 @@
};
bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
- MdpPipeInfoHighRes& pipe_info, ePipeType type);
+ MdpPipeInfoHighRes& pipe_info, ePipeType type);
+ virtual int pipesForFB() { return 2; };
/* configure's overlay pipes for the frame */
virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
- PipeLayerPair& pipeLayerPair);
+ PipeLayerPair& pipeLayerPair);
/* allocates pipes to selected candidates */
virtual bool allocLayerPipes(hwc_context_t *ctx,
- hwc_display_contents_1_t* list,
- FrameInfo& current_frame);
+ hwc_display_contents_1_t* list);
virtual int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list);
};
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index b98db73..eb525a6 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -27,7 +27,7 @@
#include <stdlib.h>
#include "hwc_utils.h"
#include "hwc_fbupdate.h"
-#include "hwc_video.h"
+#include "hwc_mdpcomp.h"
#include "hwc_copybit.h"
#include "comptype.h"
#include "external.h"
@@ -53,12 +53,10 @@
static void setup(hwc_context_t* ctx, int dpy, bool usecopybit)
{
- ctx->mFBUpdate[dpy] =
- IFBUpdate::getObject(ctx->dpyAttr[dpy].xres, dpy);
+ ctx->mFBUpdate[dpy] = IFBUpdate::getObject(ctx->dpyAttr[dpy].xres, dpy);
+ ctx->mMDPComp[dpy] = MDPComp::getObject(ctx->dpyAttr[dpy].xres, dpy);
if(usecopybit)
ctx->mCopyBit[dpy] = new CopyBit();
- ctx->mVidOv[dpy] =
- IVideoOverlay::getObject(ctx->dpyAttr[dpy].xres, dpy);
}
static void clear(hwc_context_t* ctx, int dpy)
@@ -71,9 +69,9 @@
delete ctx->mCopyBit[dpy];
ctx->mCopyBit[dpy] = NULL;
}
- if(ctx->mVidOv[dpy]) {
- delete ctx->mVidOv[dpy];
- ctx->mVidOv[dpy] = NULL;
+ if(ctx->mMDPComp[dpy]) {
+ delete ctx->mMDPComp[dpy];
+ ctx->mMDPComp[dpy] = NULL;
}
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 3245889..57f94fe 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -29,7 +29,6 @@
#include "hwc_utils.h"
#include "hwc_mdpcomp.h"
#include "hwc_fbupdate.h"
-#include "hwc_video.h"
#include "mdp_version.h"
#include "hwc_copybit.h"
#include "external.h"
@@ -118,10 +117,6 @@
IFBUpdate::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
HWC_DISPLAY_PRIMARY);
- ctx->mVidOv[HWC_DISPLAY_PRIMARY] =
- IVideoOverlay::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
- HWC_DISPLAY_PRIMARY);
-
// Check if the target supports copybit compostion (dyn/mdp/c2d) to
// decide if we need to open the copybit module.
int compositionType =
@@ -134,9 +129,11 @@
}
ctx->mExtDisplay = new ExternalDisplay(ctx);
- for (uint32_t i = 0; i < MAX_DISPLAYS; i++)
- ctx->mLayerCache[i] = new LayerCache();
- ctx->mMDPComp = MDPComp::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres);
+
+ ctx->mMDPComp[HWC_DISPLAY_PRIMARY] =
+ MDPComp::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
+ HWC_DISPLAY_PRIMARY);
+
MDPComp::init(ctx);
pthread_mutex_init(&(ctx->vstate.lock), NULL);
@@ -191,16 +188,12 @@
delete ctx->mFBUpdate[i];
ctx->mFBUpdate[i] = NULL;
}
- if(ctx->mVidOv[i]) {
- delete ctx->mVidOv[i];
- ctx->mVidOv[i] = NULL;
+ if(ctx->mMDPComp[i]) {
+ delete ctx->mMDPComp[i];
+ ctx->mMDPComp[i] = NULL;
}
}
- if(ctx->mMDPComp) {
- delete ctx->mMDPComp;
- ctx->mMDPComp = NULL;
- }
pthread_mutex_destroy(&(ctx->vstate.lock));
pthread_cond_destroy(&(ctx->vstate.cond));
@@ -361,12 +354,28 @@
}
}
-bool isSecuring(hwc_context_t* ctx) {
+bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer) {
if((ctx->mMDP.version < qdutils::MDSS_V5) &&
(ctx->mMDP.version > qdutils::MDP_V3_0) &&
ctx->mSecuring) {
return true;
}
+ if (isSecureModePolicy(ctx->mMDP.version)) {
+ private_handle_t *hnd = (private_handle_t *)layer->handle;
+ if(ctx->mSecureMode) {
+ if (! isSecureBuffer(hnd)) {
+ ALOGD_IF(HWC_UTILS_DEBUG,"%s:Securing Turning ON ...",
+ __FUNCTION__);
+ return true;
+ }
+ } else {
+ if (isSecureBuffer(hnd)) {
+ ALOGD_IF(HWC_UTILS_DEBUG,"%s:Securing Turning OFF ...",
+ __FUNCTION__);
+ return true;
+ }
+ }
+ }
return false;
}
@@ -693,12 +702,12 @@
getMdpFormat(hnd->format), hnd->size);
if(isYuvBuffer(hnd) && ctx->mMDP.version >= qdutils::MDP_V4_2 &&
- ctx->mMDP.version < qdutils::MDSS_V5) {
- downscale = getDownscaleFactor(
- crop.right - crop.left,
- crop.bottom - crop.top,
- dst.right - dst.left,
- dst.bottom - dst.top);
+ ctx->mMDP.version < qdutils::MDSS_V5) {
+ downscale = getDownscaleFactor(
+ crop.right - crop.left,
+ crop.bottom - crop.top,
+ dst.right - dst.left,
+ dst.bottom - dst.top);
if(downscale) {
rotFlags = ROT_DOWNSCALE_ENABLED;
}
@@ -839,71 +848,4 @@
return 0;
}
-
-void LayerCache::resetLayerCache(int num) {
- for(uint32_t i = 0; i < MAX_NUM_LAYERS; i++) {
- hnd[i] = NULL;
- }
- numHwLayers = num;
-}
-
-void LayerCache::updateLayerCache(hwc_display_contents_1_t* list) {
-
- int numFbLayers = 0;
- int numCacheableLayers = 0;
-
- canUseLayerCache = false;
- //Bail if geometry changed or num of layers changed
- if(list->flags & HWC_GEOMETRY_CHANGED ||
- list->numHwLayers != numHwLayers ) {
- resetLayerCache(list->numHwLayers);
- return;
- }
-
- for(uint32_t i = 0; i < list->numHwLayers; i++) {
- //Bail on skip layers
- if(list->hwLayers[i].flags & HWC_SKIP_LAYER) {
- resetLayerCache(list->numHwLayers);
- return;
- }
-
- if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER) {
- numFbLayers++;
- if(hnd[i] == NULL) {
- hnd[i] = list->hwLayers[i].handle;
- } else if (hnd[i] ==
- list->hwLayers[i].handle) {
- numCacheableLayers++;
- } else {
- hnd[i] = NULL;
- return;
- }
- } else {
- hnd[i] = NULL;
- }
- }
- if(numFbLayers == numCacheableLayers)
- canUseLayerCache = true;
-
- //XXX: The marking part is separate, if MDP comp wants
- // to use it in the future. Right now getting MDP comp
- // to use this is more trouble than it is worth.
- markCachedLayersAsOverlay(list);
-}
-
-void LayerCache::markCachedLayersAsOverlay(hwc_display_contents_1_t* list) {
- //This optimization only works if ALL the layer handles
- //that were on the framebuffer didn't change.
- if(canUseLayerCache){
- for(uint32_t i = 0; i < list->numHwLayers; i++) {
- if (list->hwLayers[i].handle &&
- list->hwLayers[i].handle == hnd[i] &&
- list->hwLayers[i].compositionType != HWC_FRAMEBUFFER_TARGET)
- {
- list->hwLayers[i].compositionType = HWC_OVERLAY;
- }
- }
- }
-}
-
};//namespace qhwc
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index e1f0995..9da10f4 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -106,26 +106,6 @@
HWC_COPYBIT = 0x00000002,
};
-class LayerCache {
- public:
- LayerCache() {
- canUseLayerCache = false;
- numHwLayers = 0;
- for(uint32_t i = 0; i < MAX_NUM_LAYERS; i++) {
- hnd[i] = NULL;
- }
- }
- //LayerCache optimization
- void updateLayerCache(hwc_display_contents_1_t* list);
- void resetLayerCache(int num);
- void markCachedLayersAsOverlay(hwc_display_contents_1_t* list);
- private:
- uint32_t numHwLayers;
- bool canUseLayerCache;
- buffer_handle_t hnd[MAX_NUM_LAYERS];
-
-};
-
// -----------------------------------------------------------------------------
// Utility functions - implemented in hwc_utils.cpp
void dumpLayer(hwc_layer_1_t const* l);
@@ -138,7 +118,7 @@
const hwc_rect_t& scissor, int orient);
void getNonWormholeRegion(hwc_display_contents_1_t* list,
hwc_rect_t& nwr);
-bool isSecuring(hwc_context_t* ctx);
+bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer);
bool isSecureModePolicy(int mdpVersion);
bool isExternalActive(hwc_context_t* ctx);
bool needsScaling(hwc_layer_1_t const* layer);
@@ -272,15 +252,13 @@
//Primary and external FB updater
qhwc::IFBUpdate *mFBUpdate[MAX_DISPLAYS];
- qhwc::IVideoOverlay *mVidOv[MAX_DISPLAYS];
// External display related information
qhwc::ExternalDisplay *mExtDisplay;
qhwc::MDPInfo mMDP;
qhwc::DisplayAttributes dpyAttr[MAX_DISPLAYS];
qhwc::ListStats listStats[MAX_DISPLAYS];
- qhwc::LayerCache *mLayerCache[MAX_DISPLAYS];
qhwc::LayerProp *layerProp[MAX_DISPLAYS];
- qhwc::MDPComp *mMDPComp;
+ qhwc::MDPComp *mMDPComp[MAX_DISPLAYS];
//Securing in progress indicator
bool mSecuring;
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
deleted file mode 100644
index f95456b..0000000
--- a/libhwcomposer/hwc_video.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are retained for
- * attribution purposes only
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define VIDEO_DEBUG 0
-#include <overlay.h>
-#include "hwc_video.h"
-#include "hwc_utils.h"
-#include "qdMetaData.h"
-#include "mdp_version.h"
-#include <overlayRotator.h>
-
-using overlay::Rotator;
-
-namespace qhwc {
-
-namespace ovutils = overlay::utils;
-
-//===========IVideoOverlay=========================
-IVideoOverlay* IVideoOverlay::getObject(const int& width, const int& dpy) {
- if(width > MAX_DISPLAY_DIM) {
- return new VideoOverlayHighRes(dpy);
- }
- return new VideoOverlayLowRes(dpy);
-}
-
-//===========VideoOverlayLowRes=========================
-
-VideoOverlayLowRes::VideoOverlayLowRes(const int& dpy): IVideoOverlay(dpy) {}
-
-//Cache stats, figure out the state, config overlay
-bool VideoOverlayLowRes::prepare(hwc_context_t *ctx,
- hwc_display_contents_1_t *list) {
-
- if(ctx->listStats[mDpy].yuvCount > 1)
- return false;
-
- int yuvIndex = ctx->listStats[mDpy].yuvIndices[0];
- int hw_w = ctx->dpyAttr[mDpy].xres;
- mModeOn = false;
-
- if(hw_w > MAX_DISPLAY_DIM) {
- ALOGD_IF(VIDEO_DEBUG,"%s, \
- Cannot use video path for High Res Panels", __FUNCTION__);
- return false;
- }
-
- if(!ctx->mMDP.hasOverlay) {
- ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__);
- return false;
- }
-
- if(isSecuring(ctx)) {
- ALOGD_IF(VIDEO_DEBUG,"%s: MDP Secure is active", __FUNCTION__);
- return false;
- }
-
- if(yuvIndex == -1 || ctx->listStats[mDpy].yuvCount != 1) {
- return false;
- }
-
- //index guaranteed to be not -1 at this point
- hwc_layer_1_t *layer = &list->hwLayers[yuvIndex];
- if (isSecureModePolicy(ctx->mMDP.version)) {
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(ctx->mSecureMode) {
- if (! isSecureBuffer(hnd)) {
- ALOGD_IF(VIDEO_DEBUG, "%s: Handle non-secure video layer"
- "during secure playback gracefully", __FUNCTION__);
- return false;
- }
- } else {
- if (isSecureBuffer(hnd)) {
- ALOGD_IF(VIDEO_DEBUG, "%s: Handle secure video layer"
- "during non-secure playback gracefully", __FUNCTION__);
- return false;
- }
- }
- }
-
- if((layer->transform & HWC_TRANSFORM_ROT_90) && ctx->mDMAInUse) {
- ctx->mDMAInUse = false;
- ALOGD_IF(VIDEO_DEBUG, "%s: Rotator not available since \
- DMA Pipe(s) are in use",__FUNCTION__);
- return false;
- }
-
- if(configure(ctx, layer)) {
- markFlags(layer);
- mModeOn = true;
- }
-
- return mModeOn;
-}
-
-void VideoOverlayLowRes::markFlags(hwc_layer_1_t *layer) {
- if(layer) {
- layer->compositionType = HWC_OVERLAY;
- layer->hints |= HWC_HINT_CLEAR_FB;
- }
-}
-
-bool VideoOverlayLowRes::configure(hwc_context_t *ctx,
- hwc_layer_1_t *layer) {
-
- overlay::Overlay& ov = *(ctx->mOverlay);
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- ovutils::Whf info(hnd->width, hnd->height,
- ovutils::getMdpFormat(hnd->format), hnd->size);
-
- //Request a VG pipe
- ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
- if(dest == ovutils::OV_INVALID) { //None available
- return false;
- }
-
- mDest = dest;
- ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
- ovutils::eZorder zOrder = ovutils::ZORDER_0;
- ovutils::eIsFg isFg = ovutils::IS_FG_OFF;
- if (ctx->listStats[mDpy].numAppLayers == 1) {
- isFg = ovutils::IS_FG_SET;
- }
-
- return (configureLowRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
- &mRot) == 0 );
-}
-
-bool VideoOverlayLowRes::draw(hwc_context_t *ctx,
- hwc_display_contents_1_t *list) {
- if(!mModeOn) {
- return true;
- }
-
- int yuvIndex = ctx->listStats[mDpy].yuvIndices[0];
- if(yuvIndex == -1) {
- return true;
- }
-
- private_handle_t *hnd = (private_handle_t *)
- list->hwLayers[yuvIndex].handle;
-
- overlay::Overlay& ov = *(ctx->mOverlay);
- int fd = hnd->fd;
- uint32_t offset = hnd->offset;
- Rotator *rot = mRot;
-
- if(rot) {
- if(!rot->queueBuffer(fd, offset))
- return false;
- fd = rot->getDstMemId();
- offset = rot->getDstOffset();
- }
-
- if (!ov.queueBuffer(fd, offset, mDest)) {
- ALOGE("%s: queueBuffer failed for dpy=%d", __FUNCTION__, mDpy);
- return false;
- }
-
- return true;
-}
-
-bool VideoOverlayLowRes::isModeOn() {
- return mModeOn;
-}
-
-//===========VideoOverlayHighRes=========================
-
-VideoOverlayHighRes::VideoOverlayHighRes(const int& dpy): IVideoOverlay(dpy) {}
-
-//Cache stats, figure out the state, config overlay
-bool VideoOverlayHighRes::prepare(hwc_context_t *ctx,
- hwc_display_contents_1_t *list) {
-
- int yuvIndex = ctx->listStats[mDpy].yuvIndices[0];
- int hw_w = ctx->dpyAttr[mDpy].xres;
- mModeOn = false;
-
- if(!ctx->mMDP.hasOverlay) {
- ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__);
- return false;
- }
-
- if(yuvIndex == -1 || ctx->listStats[mDpy].yuvCount != 1) {
- return false;
- }
-
- //index guaranteed to be not -1 at this point
- hwc_layer_1_t *layer = &list->hwLayers[yuvIndex];
- if(configure(ctx, layer)) {
- markFlags(layer);
- mModeOn = true;
- }
-
- return mModeOn;
-}
-
-void VideoOverlayHighRes::markFlags(hwc_layer_1_t *layer) {
- if(layer) {
- layer->compositionType = HWC_OVERLAY;
- layer->hints |= HWC_HINT_CLEAR_FB;
- }
-}
-
-bool VideoOverlayHighRes::configure(hwc_context_t *ctx,
- hwc_layer_1_t *layer) {
-
- int hw_w = ctx->dpyAttr[mDpy].xres;
- overlay::Overlay& ov = *(ctx->mOverlay);
- private_handle_t *hnd = (private_handle_t *)layer->handle;
- ovutils::Whf info(hnd->width, hnd->height,
- ovutils::getMdpFormat(hnd->format), hnd->size);
-
- //Request a VG pipe
- mDestL = ovutils::OV_INVALID;
- mDestR = ovutils::OV_INVALID;
- hwc_rect_t dst = layer->displayFrame;
- if(dst.left > hw_w/2) {
- mDestR = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
- if(mDestR == ovutils::OV_INVALID)
- return false;
- } else if (dst.right <= hw_w/2) {
- mDestL = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
- if(mDestL == ovutils::OV_INVALID)
- return false;
- } else {
- mDestL = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
- mDestR = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
- if(mDestL == ovutils::OV_INVALID ||
- mDestR == ovutils::OV_INVALID)
- return false;
- }
-
- ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
- ovutils::eZorder zOrder = ovutils::ZORDER_0;
- ovutils::eIsFg isFg = ovutils::IS_FG_OFF;
- if (ctx->listStats[mDpy].numAppLayers == 1) {
- isFg = ovutils::IS_FG_SET;
- }
-
- return (configureHighRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, mDestL,
- mDestR, &mRot) == 0 );
-}
-
-bool VideoOverlayHighRes::draw(hwc_context_t *ctx,
- hwc_display_contents_1_t *list) {
- if(!mModeOn) {
- return true;
- }
-
- int yuvIndex = ctx->listStats[mDpy].yuvIndices[0];
- if(yuvIndex == -1) {
- return true;
- }
-
- private_handle_t *hnd = (private_handle_t *)
- list->hwLayers[yuvIndex].handle;
-
- overlay::Overlay& ov = *(ctx->mOverlay);
- int fd = hnd->fd;
- uint32_t offset = hnd->offset;
- Rotator *rot = mRot;
-
- if(rot) {
- if(!rot->queueBuffer(fd, offset))
- return false;
- fd = rot->getDstMemId();
- offset = rot->getDstOffset();
- }
-
- if(mDestL != ovutils::OV_INVALID) {
- if (!ov.queueBuffer(fd, offset, mDestL)) {
- ALOGE("%s: queueBuffer failed for dpy=%d's left mixer",
- __FUNCTION__, mDpy);
- return false;
- }
- }
-
- if(mDestR != ovutils::OV_INVALID) {
- if (!ov.queueBuffer(fd, offset, mDestR)) {
- ALOGE("%s: queueBuffer failed for dpy=%d's right mixer"
- , __FUNCTION__, mDpy);
- return false;
- }
- }
-
- return true;
-}
-
-bool VideoOverlayHighRes::isModeOn() {
- return mModeOn;
-}
-
-}; //namespace qhwc
diff --git a/libhwcomposer/hwc_video.h b/libhwcomposer/hwc_video.h
deleted file mode 100644
index 80a47f1..0000000
--- a/libhwcomposer/hwc_video.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef HWC_VIDEO_H
-#define HWC_VIDEO_H
-
-#include "hwc_utils.h"
-#include "overlayUtils.h"
-
-#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
-#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
-
-namespace overlay {
- class Rotator;
-}
-
-namespace qhwc {
-namespace ovutils = overlay::utils;
-
-class IVideoOverlay {
-public:
- explicit IVideoOverlay(const int& dpy) : mDpy(dpy), mModeOn(false),
- mRot(NULL) {}
- virtual ~IVideoOverlay() {};
- virtual bool prepare(hwc_context_t *ctx,
- hwc_display_contents_1_t *list) = 0;
- virtual bool draw(hwc_context_t *ctx,
- hwc_display_contents_1_t *list) = 0;
- virtual void reset() = 0;
- virtual bool isModeOn() = 0;
- //Factory method that returns a low-res or high-res version
- static IVideoOverlay *getObject(const int& width, const int& dpy);
-
-protected:
- const int mDpy; // display to update
- bool mModeOn; // if prepare happened
- overlay::Rotator *mRot;
-};
-
-class VideoOverlayLowRes : public IVideoOverlay {
-public:
- explicit VideoOverlayLowRes(const int& dpy);
- virtual ~VideoOverlayLowRes() {};
- bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list);
- bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
- void reset();
- bool isModeOn();
-private:
- //Configures overlay for video prim and ext
- bool configure(hwc_context_t *ctx, hwc_layer_1_t *yuvlayer);
- //Marks layer flags if this feature is used
- void markFlags(hwc_layer_1_t *yuvLayer);
- //Flags if this feature is on.
- bool mModeOn;
- ovutils::eDest mDest;
-};
-
-class VideoOverlayHighRes : public IVideoOverlay {
-public:
- explicit VideoOverlayHighRes(const int& dpy);
- virtual ~VideoOverlayHighRes() {};
- bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list);
- bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
- void reset();
- bool isModeOn();
-private:
- //Configures overlay for video prim and ext
- bool configure(hwc_context_t *ctx, hwc_layer_1_t *yuvlayer);
- //Marks layer flags if this feature is used
- void markFlags(hwc_layer_1_t *yuvLayer);
- //Flags if this feature is on.
- bool mModeOn;
- ovutils::eDest mDestL;
- ovutils::eDest mDestR;
-};
-
-//=================Inlines======================
-inline void VideoOverlayLowRes::reset() {
- mModeOn = false;
- mDest = ovutils::OV_INVALID;
- mRot = NULL;
-}
-
-inline void VideoOverlayHighRes::reset() {
- mModeOn = false;
- mDestL = ovutils::OV_INVALID;
- mDestR = ovutils::OV_INVALID;
- mRot = NULL;
-}
-
-}; //namespace qhwc
-
-#endif //HWC_VIDEO_H
diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp
index 70bf52b..cf6d6fa 100644
--- a/liboverlay/overlayMdssRot.cpp
+++ b/liboverlay/overlayMdssRot.cpp
@@ -93,6 +93,8 @@
void MdssRot::setTransform(const utils::eTransform& rot)
{
+ // reset rotation flags to avoid stale orientation values
+ mRotInfo.flags &= ~MDSS_ROT_MASK;
int flags = utils::getMdpOrient(rot);
if (flags != -1)
setRotations(flags);
@@ -117,8 +119,6 @@
return (mEnabled = false);
}
mRotData.id = mRotInfo.id;
- // reset rotation flags to avoid stale orientation values
- mRotInfo.flags &= ~MDSS_ROT_MASK;
return true;
}