Merge "hwc: Avoid MDP comp for RGB downscaled layer"
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 5bd7931..e2c4677 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -55,6 +55,7 @@
int (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL;
int (*MDPComp::sPerfLockRelease)(int value) = NULL;
int MDPComp::sPerfHintWindow = -1;
+float MDPComp::sDownscaleThreshold = 1.0;
enum AllocOrder { FORMAT_YUV, FORMAT_RGB, FORMAT_MAX };
@@ -212,6 +213,10 @@
}
}
+ if(property_get("persist.hwc.downscale_threshold", property, "1.0") > 0) {
+ sDownscaleThreshold = (float)atof(property);
+ }
+
return true;
}
@@ -430,6 +435,24 @@
//More conditions here, sRGB+Blend etc
return false;
}
+
+ //In targets with fewer pipes, frequent composition switch between MDP/GPU
+ //can happen for a layer due to lack of pipes. When this switch happens
+ //continuously for RGB downscaled layer with downscale greater than
+ //threshold, it appears as flicker as output
+ //of MDP and GPU are different as they use different filters for downscale.
+ //To avoid this flicker, punt RGB downscaled layer with downscale greater
+ //than threshold value to GPU always.
+ if((sDownscaleThreshold > 1.0)) {
+ if(((not isYuvBuffer(hnd))
+ and (not isDownscaleWithinThreshold(layer,
+ sDownscaleThreshold)))) {
+ ALOGD_IF(isDebug(), "%s: required downscale is greater than \
+ threshold %f", __FUNCTION__, sDownscaleThreshold);
+ return false;
+ }
+ }
+
return true;
}
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index db68e82..5c43aa7 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -283,6 +283,7 @@
static int (*sPerfLockAcquire)(int, int, int*, int);
static int (*sPerfLockRelease)(int value);
static int sPerfHintWindow;
+ static float sDownscaleThreshold;
};
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index aeda428..79235ff 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -972,6 +972,27 @@
return false;
}
+
+bool isDownscaleWithinThreshold(hwc_layer_1_t const* layer, float threshold) {
+ hwc_rect_t displayFrame = layer->displayFrame;
+ hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
+ int dst_w, dst_h, src_w, src_h;
+ float downscale = 1.0;
+ dst_w = displayFrame.right - displayFrame.left;
+ dst_h = displayFrame.bottom - displayFrame.top;
+ src_w = sourceCrop.right - sourceCrop.left;
+ src_h = sourceCrop.bottom - sourceCrop.top;
+ if(dst_w && dst_h) {
+ float w_scale = ((float)src_w / (float)dst_w);
+ float h_scale = ((float)src_h / (float)dst_h);
+
+ if((w_scale > threshold) or (h_scale > threshold))
+ return false;
+ }
+
+ return true;
+}
+
bool needsScaling(hwc_layer_1_t const* layer) {
int dst_w, dst_h, src_w, src_h;
hwc_rect_t displayFrame = layer->displayFrame;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index da0182b..4849baf 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -309,6 +309,7 @@
bool isAlphaScaled(hwc_layer_1_t const* layer);
bool needsScaling(hwc_layer_1_t const* layer);
bool isDownscaleRequired(hwc_layer_1_t const* layer);
+bool isDownscaleWithinThreshold(hwc_layer_1_t const* layer, float threshold);
bool needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
const int& dpy);
void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,