hwc: Avoid MDP comp for RGB downscaled layer

- In targets with fewer pipes, composition switch can happen
  continuously for a layer based on whether it is updating or not.
  If that updating layer requires downscaling, because of the
  difference in the downscale filters between MDP and GPU,
  the output of MDP and GPU will differ. This difference could be
  perceived as flicker. To avoid this flicker, mark RGB downscaled layer
  with downscale more than threshold to GPU always.
- property persist.hwc.downscale_threshold defines the threshold value
  for downscale beyond which the layer will be marked for GPU composition.

Change-Id: Ifd26d7eb1eff0096b0391a0552d0fd97386c1a19
This commit is contained in:
radhakrishna
2015-04-08 17:20:43 +05:30
parent ff9c4b5afd
commit 35e3307665
4 changed files with 46 additions and 0 deletions

View File

@@ -55,6 +55,7 @@ int MDPComp::sPerfLockHandle = 0;
int (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL; int (*MDPComp::sPerfLockAcquire)(int, int, int*, int) = NULL;
int (*MDPComp::sPerfLockRelease)(int value) = NULL; int (*MDPComp::sPerfLockRelease)(int value) = NULL;
int MDPComp::sPerfHintWindow = -1; int MDPComp::sPerfHintWindow = -1;
float MDPComp::sDownscaleThreshold = 1.0;
enum AllocOrder { FORMAT_YUV, FORMAT_RGB, FORMAT_MAX }; enum AllocOrder { FORMAT_YUV, FORMAT_RGB, FORMAT_MAX };
@@ -211,6 +212,10 @@ bool MDPComp::init(hwc_context_t *ctx) {
} }
} }
if(property_get("persist.hwc.downscale_threshold", property, "1.0") > 0) {
sDownscaleThreshold = (float)atof(property);
}
return true; return true;
} }
@@ -429,6 +434,24 @@ bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) {
//More conditions here, sRGB+Blend etc //More conditions here, sRGB+Blend etc
return false; 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; return true;
} }

View File

@@ -283,6 +283,7 @@ protected:
static int (*sPerfLockAcquire)(int, int, int*, int); static int (*sPerfLockAcquire)(int, int, int*, int);
static int (*sPerfLockRelease)(int value); static int (*sPerfLockRelease)(int value);
static int sPerfHintWindow; static int sPerfHintWindow;
static float sDownscaleThreshold;
}; };

View File

@@ -942,6 +942,27 @@ bool isDownscaleRequired(hwc_layer_1_t const* layer) {
return false; 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) { bool needsScaling(hwc_layer_1_t const* layer) {
int dst_w, dst_h, src_w, src_h; int dst_w, dst_h, src_w, src_h;
hwc_rect_t displayFrame = layer->displayFrame; hwc_rect_t displayFrame = layer->displayFrame;

View File

@@ -309,6 +309,7 @@ bool isRotationDoable(hwc_context_t *ctx, private_handle_t *hnd);
bool isAlphaScaled(hwc_layer_1_t const* layer); bool isAlphaScaled(hwc_layer_1_t const* layer);
bool needsScaling(hwc_layer_1_t const* layer); bool needsScaling(hwc_layer_1_t const* layer);
bool isDownscaleRequired(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, bool needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
const int& dpy); const int& dpy);
void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR, void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,