hwc: Do not re-program H/W, if the frame geometry has not changed
There is no need to re-program the H/W, if the frame geometry of all
active displays, has not changed. It will help to improve performance
by avoiding re-configuration of HAL and driver, if it is not needed.
Change-Id: Ie01dce33be89afc7308a8103128d27b4b9fb5c4b
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index cbc42b2..b0d7be7 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();
@@ -338,6 +380,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_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index beb858b..ff73524 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 */