Merge "hwc: Use layer dirty rect to calculate frame's updating ROI"
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index cbc42b2..f4baa25 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -260,6 +260,48 @@
}
}
+static bool optimizePrepare(hwc_context_t *ctx, int numDisplays,
+ hwc_display_contents_1_t** displays) {
+
+ /* Do not re-program H/W, if frame geometry has not changed.
+ * But honor these exceptions:
+ * 1. Padding round
+ * 2. Idle fallback
+ * 3. Overlay is not configured
+ * 4. External/Virtual display is in Configure state
+ * 5. External/Virtual is Paused OR not connected/active
+ * 6. Non-Overlay device
+ */
+
+ if (ctx->isPaddingRound || MDPComp::isIdleFallback() ||
+ !ctx->mOverlay->isConfigured() || isSecondaryConfiguring(ctx) ||
+ ctx->mMDP.version < qdutils::MDP_V4_0) {
+ return false;
+ }
+
+ bool isOptimized = false;
+ for (uint32_t i = 0; i < numDisplays; i++) {
+ hwc_display_contents_1_t *list = displays[i];
+
+ if (list) {
+ if (list->flags & HWC_GEOMETRY_CHANGED) {
+ return false;
+ }
+ int dpy = getDpyforExternalDisplay(ctx, i);
+ if (dpy && (ctx->dpyAttr[dpy].isPause ||
+ !ctx->dpyAttr[dpy].connected ||
+ !ctx->dpyAttr[dpy].isActive)) {
+ return false;
+ }
+ // Set layer composition type as per last frame
+ ctx->mMDPComp[dpy]->setMDPCompLayerFlags(ctx, list);
+ isOptimized = true;
+ }
+ }
+
+ return isOptimized;
+}
+
static int hwc_prepare_primary(hwc_composer_device_1 *dev,
hwc_display_contents_1_t *list) {
ATRACE_CALL();
@@ -279,7 +321,10 @@
if (fbComp) {
const int fbZ = 0;
- ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ);
+ if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ)) {
+ ctx->mOverlay->clear(dpy);
+ ctx->mLayerRotMap[dpy]->clear();
+ }
}
if (ctx->mMDP.version < qdutils::MDP_V4_0) {
@@ -306,7 +351,11 @@
setListStats(ctx, list, dpy);
if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
const int fbZ = 0;
- ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ);
+ if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ))
+ {
+ ctx->mOverlay->clear(dpy);
+ ctx->mLayerRotMap[dpy]->clear();
+ }
}
} else {
/* External Display is in Pause state.
@@ -338,6 +387,12 @@
setPaddingRound(ctx,numDisplays,displays);
setDMAState(ctx,numDisplays,displays);
setNumActiveDisplays(ctx,numDisplays,displays);
+
+ if (optimizePrepare(ctx, numDisplays, displays)) {
+ // Do not re-program H/W, if it is not needed
+ return ret;
+ }
+
reset(ctx, (int)numDisplays, displays);
ctx->mOverlay->configBegin();
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 74e6da4..c733523 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -208,8 +208,6 @@
sourceCrop, mdpFlags, rotFlags);
if(!ret) {
ALOGE("%s: preRotate for external Failed!", __FUNCTION__);
- ctx->mOverlay->clear(mDpy);
- ctx->mLayerRotMap[mDpy]->clear();
return false;
}
//For the mdp, since either we are pre-rotating or MDP does flips
@@ -224,7 +222,6 @@
if(configMdp(ctx->mOverlay, parg, orient, sourceCrop, displayFrame,
NULL, mDest) < 0) {
ALOGE("%s: configMdp failed for dpy %d", __FUNCTION__, mDpy);
- ctx->mLayerRotMap[mDpy]->clear();
ret = false;
}
}
@@ -387,10 +384,6 @@
ret = false;
}
}
-
- if(ret == false) {
- ctx->mLayerRotMap[mDpy]->clear();
- }
}
return ret;
}
@@ -425,7 +418,6 @@
bool FBSrcSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
hwc_rect_t fbUpdatingRect, int fbZorder) {
- bool ret = false;
hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
// ext only layer present..
@@ -502,7 +494,6 @@
if(configMdp(ctx->mOverlay, parg, orient,
cropL, cropL, NULL /*metadata*/, destL) < 0) {
ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
- ctx->mLayerRotMap[mDpy]->clear();
return false;
}
}
@@ -512,7 +503,6 @@
if(configMdp(ctx->mOverlay, parg, orient,
cropR, cropR, NULL /*metadata*/, destR) < 0) {
ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
- ctx->mLayerRotMap[mDpy]->clear();
return false;
}
}
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 8186fff..7d4214a 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -54,6 +54,9 @@
static void resetIdleFallBack() { sIdleFallBack = false; }
static void reset() { sHandleTimeout = false; };
static bool isIdleFallback() { return sIdleFallBack; }
+ /* set/reset flags for MDPComp */
+ void setMDPCompLayerFlags(hwc_context_t *ctx,
+ hwc_display_contents_1_t* list);
protected:
enum { MAX_SEC_LAYERS = 1 }; //TODO add property support
@@ -142,9 +145,6 @@
/* configures 4kx2k yuv layer*/
virtual int configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer,
PipeLayerPair& PipeLayerPair) = 0;
- /* set/reset flags for MDPComp */
- void setMDPCompLayerFlags(hwc_context_t *ctx,
- hwc_display_contents_1_t* list);
void setRedraw(hwc_context_t *ctx,
hwc_display_contents_1_t* list);
/* checks for conditions where mdpcomp is not possible */
diff --git a/libhwcomposer/hwc_virtual.cpp b/libhwcomposer/hwc_virtual.cpp
index 10ed9d1..97b19ea 100644
--- a/libhwcomposer/hwc_virtual.cpp
+++ b/libhwcomposer/hwc_virtual.cpp
@@ -126,7 +126,11 @@
if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
const int fbZ = 0;
- ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ);
+ if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ))
+ {
+ ctx->mOverlay->clear(dpy);
+ ctx->mLayerRotMap[dpy]->clear();
+ }
}
} else {
/* Virtual Display is in Pause state.
@@ -260,7 +264,11 @@
setListStats(ctx, list, dpy);
if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
const int fbZ = 0;
- ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ);
+ if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ))
+ {
+ ctx->mOverlay->clear(dpy);
+ ctx->mLayerRotMap[dpy]->clear();
+ }
}
} else {
/* Virtual Display is in Pause state.
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index fa19dc3..3e6af22 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -135,6 +135,8 @@
void clear(int dpy);
/* Validate the set of pipes for a display and set them in driver */
bool validateAndSet(const int& dpy, const int& fbFd);
+ /* Returns true if PipeBook has been configured, false otherwise */
+ bool isConfigured();
/* Closes open pipes, called during startup */
static int initOverlay();
@@ -199,6 +201,7 @@
static void resetAllocation(int index);
static bool isAllocated(int index);
static bool isNotAllocated(int index);
+ static bool isConfigured();
static utils::eMdpPipeType getPipeType(utils::eDest dest);
static const char* getDestStr(utils::eDest dest);
@@ -389,6 +392,14 @@
return "Invalid";
}
+inline bool Overlay::PipeBook::isConfigured() {
+ return (sAllocatedBitmap != 0);
+}
+
+inline bool Overlay::isConfigured() {
+ return PipeBook::isConfigured();
+}
+
}; // overlay
#endif // OVERLAY_H