HWC: Update DisplayFrame of all layers properly in Dynamic FB
Use change in HWC_GEOMETRY_CHANGED flag appropriately to avoid
redundant and unintentional overwrites of DisplayFrame values,
which may result fall back to GPU.
Change-Id: Ifb0f8dc5d356c965b6e80644f32392c460fb1ae7
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index f4baa25..f176d79 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -226,31 +226,20 @@
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) {
- uint32_t origXres = ctx->dpyAttr[dpy].xres_orig;
- uint32_t origYres = ctx->dpyAttr[dpy].yres_orig;
- uint32_t fakeXres = ctx->dpyAttr[dpy].xres;
- uint32_t fakeYres = ctx->dpyAttr[dpy].yres;
- float xresRatio = (float)origXres / (float)fakeXres;
- float yresRatio = (float)origYres / (float)fakeYres;
+ uint32_t origXres = ctx->dpyAttr[dpy].xres;
+ uint32_t origYres = ctx->dpyAttr[dpy].yres;
+ uint32_t newXres = ctx->dpyAttr[dpy].xres_new;
+ uint32_t newYres = ctx->dpyAttr[dpy].yres_new;
+ float xresRatio = (float)origXres / (float)newXres;
+ float yresRatio = (float)origYres / (float)newYres;
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);
uint32_t layerWidth = displayFrame.right - displayFrame.left;
uint32_t layerHeight = displayFrame.bottom - displayFrame.top;
- uint32_t sourceWidth = sourceCrop.right - sourceCrop.left;
- uint32_t sourceHeight = sourceCrop.bottom - sourceCrop.top;
-
- if (isEqual(((float)layerWidth / (float)sourceWidth), xresRatio) &&
- isEqual(((float)layerHeight / (float)sourceHeight), yresRatio))
- break;
-
displayFrame.left = (int)(xresRatio * (float)displayFrame.left);
displayFrame.top = (int)(yresRatio * (float)displayFrame.top);
displayFrame.right = (int)((float)displayFrame.left +
@@ -311,7 +300,8 @@
if (LIKELY(list && list->numHwLayers > 1) &&
ctx->dpyAttr[dpy].isActive) {
- if (ctx->dpyAttr[dpy].customFBSize)
+ if (ctx->dpyAttr[dpy].customFBSize &&
+ list->flags & HWC_GEOMETRY_CHANGED)
scaleDisplayFrame(ctx, dpy, list);
reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
@@ -824,14 +814,21 @@
values[i] = ctx->dpyAttr[disp].vsync_period;
break;
case HWC_DISPLAY_WIDTH:
- values[i] = ctx->dpyAttr[disp].xres;
+ if (ctx->dpyAttr[disp].customFBSize)
+ values[i] = ctx->dpyAttr[disp].xres_new;
+ else
+ values[i] = ctx->dpyAttr[disp].xres;
+
ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
- ctx->dpyAttr[disp].xres);
+ values[i]);
break;
case HWC_DISPLAY_HEIGHT:
- values[i] = ctx->dpyAttr[disp].yres;
+ if (ctx->dpyAttr[disp].customFBSize)
+ values[i] = ctx->dpyAttr[disp].yres_new;
+ else
+ values[i] = ctx->dpyAttr[disp].yres;
ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
- ctx->dpyAttr[disp].yres);
+ values[i]);
break;
case HWC_DISPLAY_DPI_X:
values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index c733523..fb0a613 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -49,8 +49,15 @@
IFBUpdate::IFBUpdate(hwc_context_t *ctx, const int& dpy) : mDpy(dpy) {
size_t size = 0;
- getBufferAttributes(ctx->dpyAttr[mDpy].xres,
- ctx->dpyAttr[mDpy].yres,
+ uint32_t xres = ctx->dpyAttr[mDpy].xres;
+ uint32_t yres = ctx->dpyAttr[mDpy].yres;
+ if (ctx->dpyAttr[dpy].customFBSize) {
+ //GPU will render and compose at new resolution
+ //So need to have FB at new resolution
+ xres = ctx->dpyAttr[mDpy].xres_new;
+ yres = ctx->dpyAttr[mDpy].yres_new;
+ }
+ getBufferAttributes((int)xres, (int)yres,
HAL_PIXEL_FORMAT_RGBA_8888,
0,
mAlignedFBWidth,
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 976b23d..0bb71f0 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -108,8 +108,13 @@
Parcel* outParcel) {
int dpy = inParcel->readInt32();
outParcel->writeInt32(ctx->dpyAttr[dpy].vsync_period);
- outParcel->writeInt32(ctx->dpyAttr[dpy].xres);
- outParcel->writeInt32(ctx->dpyAttr[dpy].yres);
+ if (ctx->dpyAttr[dpy].customFBSize) {
+ outParcel->writeInt32(ctx->dpyAttr[dpy].xres_new);
+ outParcel->writeInt32(ctx->dpyAttr[dpy].yres_new);
+ } else {
+ outParcel->writeInt32(ctx->dpyAttr[dpy].xres);
+ outParcel->writeInt32(ctx->dpyAttr[dpy].yres);
+ }
outParcel->writeFloat(ctx->dpyAttr[dpy].xdpi);
outParcel->writeFloat(ctx->dpyAttr[dpy].ydpi);
//XXX: Need to check what to return for HDMI
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 7499ba5..60a853a 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -85,20 +85,19 @@
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].xres_new = xres_orig;
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = 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;
+ int xres_new = atoi(property);
+ int yres_new = atoi(yptr + 1);
+ if (isValidResolution(ctx,xres_new,yres_new) &&
+ xres_new != xres_orig && yres_new != yres_orig) {
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_new;
+ ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_new;
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = true;
}
}
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 6f527aa..0883a51 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -104,8 +104,8 @@
//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;
+ uint32_t xres_new;
+ uint32_t yres_new;
};