hwc: Dynamic Resolution support on Primary
* Useful to estimate GPU/MDP performance for different resolutions.
* MDP:
Every layer is downscaled/upscaled to primary panel resolution.
* GPU:
All layers will be composed in required resolution to FB.
FB is downscaled/upscaled to primary panel resolution.
* Steps to follow:
step 1: adb root
step 2: adb shell setprop debug.hwc.fbsize XRESxYRES
step 3: adb shell stop
step 4: adb shell start
Change-Id: I82a032df87c91549c49a9cdbd981ff02f105ff2e
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index dcad00b..8048f32 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are retained
* for attribution purposes only.
@@ -132,6 +132,38 @@
ctx->mHWCVirtual->destroy(ctx, numDisplays, displays);
}
+bool isEqual(float f1, float f2) {
+ return ((int)(f1*100) == (int)(f2*100)) ? true : false;
+}
+
+static void scaleDisplayFrame(hwc_context_t *ctx, int dpy,
+ hwc_display_contents_1_t *list) {
+ float origXres = ctx->dpyAttr[dpy].xres_orig;
+ float origYres = ctx->dpyAttr[dpy].yres_orig;
+ float fakeXres = ctx->dpyAttr[dpy].xres;
+ float fakeYres = ctx->dpyAttr[dpy].yres;
+ float xresRatio = origXres / fakeXres;
+ float yresRatio = origYres / fakeYres;
+ for (size_t i = 0; i < list->numHwLayers; i++) {
+ hwc_layer_1_t *layer = &list->hwLayers[i];
+ hwc_rect_t& displayFrame = layer->displayFrame;
+ hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
+ float layerWidth = displayFrame.right - displayFrame.left;
+ float layerHeight = displayFrame.bottom - displayFrame.top;
+ float sourceWidth = sourceCrop.right - sourceCrop.left;
+ float sourceHeight = sourceCrop.bottom - sourceCrop.top;
+
+ if (isEqual(layerWidth / sourceWidth, xresRatio) &&
+ isEqual(layerHeight / sourceHeight, yresRatio))
+ break;
+
+ displayFrame.left = xresRatio * displayFrame.left;
+ displayFrame.top = yresRatio * displayFrame.top;
+ displayFrame.right = displayFrame.left + layerWidth * xresRatio;
+ displayFrame.bottom = displayFrame.top + layerHeight * yresRatio;
+ }
+}
+
static int hwc_prepare_primary(hwc_composer_device_1 *dev,
hwc_display_contents_1_t *list) {
ATRACE_CALL();
@@ -139,6 +171,10 @@
const int dpy = HWC_DISPLAY_PRIMARY;
if (LIKELY(list && list->numHwLayers > 1) &&
ctx->dpyAttr[dpy].isActive) {
+
+ if (ctx->dpyAttr[dpy].customFBSize)
+ scaleDisplayFrame(ctx, dpy, list);
+
reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
setListStats(ctx, list, dpy);
#ifdef VPU_TARGET
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 6bc2e75..0123452 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are
* retained for attribution purposes only.
@@ -167,12 +167,12 @@
// Dont do wormhole calculation when extDownscale is enabled on External
if(ctx->listStats[mDpy].isDisplayAnimating && mDpy) {
sourceCrop = layer->displayFrame;
- displayFrame = sourceCrop;
} else if((!mDpy ||
- (mDpy && !extOrient
- && !ctx->dpyAttr[mDpy].mDownScaleMode))
- && (extOnlyLayerIndex == -1)) {
- if(!qdutils::MDPVersion::getInstance().is8x26()) {
+ (mDpy && !extOrient
+ && !ctx->dpyAttr[mDpy].mDownScaleMode))
+ && (extOnlyLayerIndex == -1)) {
+ if(!qdutils::MDPVersion::getInstance().is8x26() &&
+ !ctx->dpyAttr[mDpy].customFBSize) {
getNonWormholeRegion(list, sourceCrop);
displayFrame = sourceCrop;
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index d47e120..dce1e0e 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2013, The Linux Foundation All rights reserved.
+ * Copyright (C) 2012-2014, The Linux Foundation All rights reserved.
*
* Not a Contribution, Apache license notifications and license are retained
* for attribution purposes only.
@@ -54,6 +54,34 @@
namespace qhwc {
+bool isValidResolution(hwc_context_t *ctx, uint32_t xres, uint32_t yres)
+{
+ return !((xres > qdutils::MAX_DISPLAY_DIM &&
+ !isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY)) ||
+ (xres < MIN_DISPLAY_XRES || yres < MIN_DISPLAY_YRES));
+}
+
+void changeResolution(hwc_context_t *ctx, int xres_orig, int yres_orig) {
+ //Store original display resolution.
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_orig = xres_orig;
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_orig = yres_orig;
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = false;
+
+ char property[PROPERTY_VALUE_MAX] = {'\0'};
+ char *yptr = NULL;
+ if (property_get("debug.hwc.fbsize", property, NULL) > 0) {
+ yptr = strcasestr(property,"x");
+ int xres = atoi(property);
+ int yres = atoi(yptr + 1);
+ if (isValidResolution(ctx,xres,yres) &&
+ xres != xres_orig && yres != yres_orig) {
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = xres;
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = yres;
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = true;
+ }
+ }
+}
+
static int openFramebufferDevice(hwc_context_t *ctx)
{
struct fb_fix_screeninfo finfo;
@@ -117,6 +145,9 @@
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period = 1000000000l / fps;
+ //To change resolution of primary display
+ changeResolution(ctx, info.xres, info.yres);
+
//Unblank primary on first boot
if(ioctl(fb_fd, FBIOBLANK,FB_BLANK_UNBLANK) < 0) {
ALOGE("%s: Failed to unblank display", __FUNCTION__);
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index e64f89c..22debaf 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -35,6 +35,8 @@
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
#define MAX_NUM_APP_LAYERS 32
+#define MIN_DISPLAY_XRES 200
+#define MIN_DISPLAY_YRES 200
//Fwrd decls
struct hwc_context_t;
@@ -95,6 +97,13 @@
bool mActionSafePresent;
int mAsWidthRatio;
int mAsHeightRatio;
+
+ //If property fbsize set via adb shell debug.hwc.fbsize = XRESxYRES
+ //following fields are used.
+ bool customFBSize;
+ uint32_t xres_orig;
+ uint32_t yres_orig;
+
};
struct ListStats {