hwc: fix aspect ratio calculations
- Make aspectratio calculations independent of ext dpy w/h
- pass hwc_rect_t to getAspectRatioPosition function instead of
x, y, w, h
- overload getAspectRatioPosition func to return the upscaled
or transformed position for a particular display based on the
values set by SurfaceFlinger
Change-Id: I0be9b2b4b030bdd8e69dc1493dc8cbac31918c27
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index ba3b5d2..b5ac2b8 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -110,17 +110,10 @@
hwc_rect_t sourceCrop = layer->sourceCrop;
hwc_rect_t displayFrame = layer->displayFrame;
int transform = layer->transform;
- int fbWidth = ctx->dpyAttr[mDpy].xres;
- int fbHeight = ctx->dpyAttr[mDpy].yres;
int rotFlags = ovutils::ROT_FLAGS_NONE;
ovutils::eTransform orient =
static_cast<ovutils::eTransform>(transform);
- if(mDpy && ctx->mExtOrientation) {
- // If there is a external orientation set, use that
- transform = ctx->mExtOrientation;
- orient = static_cast<ovutils::eTransform >(ctx->mExtOrientation);
- }
// Do not use getNonWormholeRegion() function to calculate the
// sourceCrop during animation on external display and
@@ -135,23 +128,17 @@
displayFrame = sourceCrop;
}
}
- ovutils::Dim dpos(displayFrame.left,
- displayFrame.top,
- displayFrame.right - displayFrame.left,
- displayFrame.bottom - displayFrame.top);
if(mDpy && !qdutils::MDPVersion::getInstance().is8x26()) {
- // Get Aspect Ratio for external
- getAspectRatioPosition(ctx, mDpy, ctx->mExtOrientation, dpos.x,
- dpos.y, dpos.w, dpos.h);
+ if(ctx->mExtOrientation) {
+ calcExtDisplayPosition(ctx, mDpy, displayFrame);
+ // If there is a external orientation set, use that
+ transform = ctx->mExtOrientation;
+ orient = static_cast<ovutils::eTransform >(ctx->mExtOrientation);
+ }
// Calculate the actionsafe dimensions for External(dpy = 1 or 2)
- getActionSafePosition(ctx, mDpy, dpos.x, dpos.y, dpos.w, dpos.h);
- // Convert dim to hwc_rect_t
- displayFrame.left = dpos.x;
- displayFrame.top = dpos.y;
- displayFrame.right = dpos.w + displayFrame.left;
- displayFrame.bottom = dpos.h + displayFrame.top;
- }
+ getActionSafePosition(ctx, mDpy, displayFrame);
+ }
setMdpFlags(layer, mdpFlags, 0, transform);
// For External use rotator if there is a rotation value set
if(mDpy && (ctx->mExtOrientation & HWC_TRANSFORM_ROT_90)) {
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 0e2eb2e..91cf337 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -262,8 +262,11 @@
}
/* Calculates the destination position based on the action safe rectangle */
-void getActionSafePosition(hwc_context_t *ctx, int dpy, uint32_t& x,
- uint32_t& y, uint32_t& w, uint32_t& h) {
+void getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& rect) {
+ // Position
+ int x = rect.left, y = rect.top;
+ int w = rect.right - rect.left;
+ int h = rect.bottom - rect.top;
// if external supports underscan, do nothing
// it will be taken care in the driver
@@ -317,40 +320,133 @@
w = (wRatio * asW);
h = (hRatio * asH);
+ // Convert it back to hwc_rect_t
+ rect.left = x;
+ rect.top = y;
+ rect.right = w + rect.left;
+ rect.bottom = h + rect.top;
+
return;
}
-/* Calculates the aspect ratio for external based on the primary */
-void getAspectRatioPosition(hwc_context_t *ctx, int dpy, int orientation,
- uint32_t& x, uint32_t& y, uint32_t& w, uint32_t& h) {
- int fbWidth = ctx->dpyAttr[dpy].xres;
- int fbHeight = ctx->dpyAttr[dpy].yres;
+/* Calculates the aspect ratio for based on src & dest */
+void getAspectRatioPosition(int destWidth, int destHeight, int srcWidth,
+ int srcHeight, hwc_rect_t& rect) {
+ int x =0, y =0;
- switch(orientation) {
- case HAL_TRANSFORM_ROT_90:
- case HAL_TRANSFORM_ROT_270:
- y = 0;
- h = fbHeight;
- if (ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres <
- ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres) {
- // Portrait primary panel
- w = (ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres *
- fbHeight/ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres);
- } else {
- //Landscape primary panel
- w = (ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres *
- fbHeight/ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres);
- }
- x = (fbWidth - w)/2;
- break;
- default:
- //Do nothing
- break;
- }
- ALOGD_IF(HWC_UTILS_DEBUG, "%s: Position: x = %d, y = %d w = %d h = %d",
- __FUNCTION__, x, y, w ,h);
+ if (srcWidth * destHeight > destWidth * srcHeight) {
+ srcHeight = destWidth * srcHeight / srcWidth;
+ srcWidth = destWidth;
+ } else if (srcWidth * destHeight < destWidth * srcHeight) {
+ srcWidth = destHeight * srcWidth / srcHeight;
+ srcHeight = destHeight;
+ } else {
+ srcWidth = destWidth;
+ srcHeight = destHeight;
+ }
+ if (srcWidth > destWidth) srcWidth = destWidth;
+ if (srcHeight > destHeight) srcHeight = destHeight;
+ x = (destWidth - srcWidth) / 2;
+ y = (destHeight - srcHeight) / 2;
+ ALOGD_IF(HWC_UTILS_DEBUG, "%s: AS Position: x = %d, y = %d w = %d h = %d",
+ __FUNCTION__, x, y, srcWidth , srcHeight);
+ // Convert it back to hwc_rect_t
+ rect.left = x;
+ rect.top = y;
+ rect.right = srcWidth + rect.left;
+ rect.bottom = srcHeight + rect.top;
}
+// This function gets the destination position for Seconday display
+// based on the position and aspect ratio with orientation
+void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
+ hwc_rect_t& inRect, hwc_rect_t& outRect) {
+ // Physical display resolution
+ float fbWidth = ctx->dpyAttr[dpy].xres;
+ float fbHeight = ctx->dpyAttr[dpy].yres;
+ //display position(x,y,w,h) in correct aspectratio after rotation
+ int xPos = 0;
+ int yPos = 0;
+ float width = fbWidth;
+ float height = fbHeight;
+ // Width/Height used for calculation, after rotation
+ float actualWidth = fbWidth;
+ float actualHeight = fbHeight;
+
+ float wRatio = 1.0;
+ float hRatio = 1.0;
+ float xRatio = 1.0;
+ float yRatio = 1.0;
+ hwc_rect_t rect = {0, 0, (int)fbWidth, (int)fbHeight};
+
+ Dim inPos(inRect.left, inRect.top, inRect.right - inRect.left,
+ inRect.bottom - inRect.top);
+ Dim outPos(outRect.left, outRect.top, outRect.right - outRect.left,
+ outRect.bottom - outRect.top);
+
+ Whf whf(fbWidth, fbHeight, 0);
+ eTransform extorient = static_cast<eTransform>(extOrientation);
+ // To calculate the destination co-ordinates in the new orientation
+ preRotateSource(extorient, whf, inPos);
+
+ if(extOrientation & HAL_TRANSFORM_ROT_90) {
+ // Swap width/height for input position
+ swapWidthHeight(actualWidth, actualHeight);
+ getAspectRatioPosition(fbWidth, fbHeight, (int)actualWidth,
+ (int)actualHeight, rect);
+ xPos = rect.left;
+ yPos = rect.top;
+ width = rect.right - rect.left;
+ height = rect.bottom - rect.top;
+ }
+
+ //Calculate the position...
+ xRatio = inPos.x/actualWidth;
+ yRatio = inPos.y/actualHeight;
+ wRatio = inPos.w/actualWidth;
+ hRatio = inPos.h/actualHeight;
+
+ outPos.x = (xRatio * width) + xPos;
+ outPos.y = (yRatio * height) + yPos;
+ outPos.w = wRatio * width;
+ outPos.h = hRatio * height;
+ ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio Position: x = %d,"
+ "y = %d w = %d h = %d", __FUNCTION__, outPos.x, outPos.y,
+ outPos.w, outPos.h);
+
+ // Convert Dim to hwc_rect_t
+ outRect.left = outPos.x;
+ outRect.top = outPos.y;
+ outRect.right = outPos.x + outPos.w;
+ outRect.bottom = outPos.y + outPos.h;
+
+ return;
+}
+
+bool isPrimaryPortrait(hwc_context_t *ctx) {
+ int fbWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
+ int fbHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
+ if(fbWidth < fbHeight) {
+ return true;
+ }
+ return false;
+}
+
+void calcExtDisplayPosition(hwc_context_t *ctx,
+ int dpy, hwc_rect_t& displayFrame) {
+ int dstWidth = ctx->dpyAttr[dpy].xres;
+ int dstHeight = ctx->dpyAttr[dpy].yres;;
+ int srcWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
+ int srcHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
+ // Swap width and height when there is a 90deg transform
+ if(ctx->mExtOrientation & HWC_TRANSFORM_ROT_90) {
+ if(!isPrimaryPortrait(ctx)) {
+ swap(srcWidth, srcHeight);
+ } // Get Aspect Ratio for external
+ getAspectRatioPosition(dstWidth, dstHeight, srcWidth,
+ srcHeight, displayFrame);
+ }
+}
bool needsScaling(hwc_context_t* ctx, hwc_layer_1_t const* layer,
const int& dpy) {
@@ -975,22 +1071,14 @@
}
}
}
-
- uint32_t x = dst.left, y = dst.top;
- uint32_t w = dst.right - dst.left;
- uint32_t h = dst.bottom - dst.top;
-
if(dpy) {
// Just need to set the position to portrait as the transformation
// will already be set to required orientation on TV
- getAspectRatioPosition(ctx, dpy, ctx->mExtOrientation, x, y, w, h);
+ if(ctx->mExtOrientation) {
+ getAspectRatioPosition(ctx, dpy, ctx->mExtOrientation, dst, dst);
+ }
// Calculate the actionsafe dimensions for External(dpy = 1 or 2)
- getActionSafePosition(ctx, dpy, x, y, w, h);
- // Convert position to hwc_rect_t
- dst.left = x;
- dst.top = y;
- dst.right = w + dst.left;
- dst.bottom = h + dst.top;
+ getActionSafePosition(ctx, dpy, dst);
}
if(isYuvBuffer(hnd) && ctx->mMDP.version >= qdutils::MDP_V4_2 &&
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 9a7ef0d..df1696d 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -175,12 +175,18 @@
void dumpsys_log(android::String8& buf, const char* fmt, ...);
/* Calculates the destination position based on the action safe rectangle */
-void getActionSafePosition(hwc_context_t *ctx, int dpy, uint32_t& x,
- uint32_t& y, uint32_t& w, uint32_t& h);
+void getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& dst);
+void getAspectRatioPosition(int destWidth, int destHeight, int srcWidth,
+ int srcHeight, hwc_rect_t& rect);
-void getAspectRatioPosition(hwc_context_t *ctx, int dpy, int orientation,
- uint32_t& x, uint32_t& y, uint32_t& w, uint32_t& h);
+void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
+ hwc_rect_t& inRect, hwc_rect_t& outRect);
+
+bool isPrimaryPortrait(hwc_context_t *ctx);
+
+void calcExtDisplayPosition(hwc_context_t *ctx,
+ int dpy, hwc_rect_t& displayFrame);
//Close acquireFenceFds of all layers of incoming list
void closeAcquireFds(hwc_display_contents_1_t* list);