Merge "hwc: Calculate viewframe from layers display frame information."
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index ba8b9d2..4695a4f 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -427,8 +427,7 @@
float copybitsMinScale =
(float)copybit->get(copybit,COPYBIT_MINIFICATION_LIMIT);
- if((layer->transform == HWC_TRANSFORM_ROT_90) ||
- (layer->transform == HWC_TRANSFORM_ROT_270)) {
+ if (layer->transform & HWC_TRANSFORM_ROT_90) {
//swap screen width and height
int tmp = screen_w;
screen_w = screen_h;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 48d9575..b4192b6 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -449,7 +449,7 @@
/* Reset frame ROI when any layer which needs scaling also needs ROI
* cropping */
if((res_w != dst_w || res_h != dst_h) &&
- needsScaling (ctx, layer, mDpy)) {
+ needsScaling (layer)) {
ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__);
memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop));
mCurrentFrame.dropCount = 0;
@@ -530,12 +530,6 @@
return false;
}
- if(ctx->listStats[mDpy].needsAlphaScale
- && ctx->mMDP.version < qdutils::MDSS_V5) {
- ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
- return false;
- }
-
for(int i = 0; i < numAppLayers; ++i) {
hwc_layer_1_t* layer = &list->hwLayers[i];
private_handle_t *hnd = (private_handle_t *)layer->handle;
@@ -568,6 +562,12 @@
} else if(partialMDPComp(ctx, list)) {
ret = true;
}
+
+ if(!hwLimitationsCheck(ctx, list)) {
+ ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__);
+ return false;
+ }
+
return ret;
}
@@ -593,7 +593,7 @@
//pipe and error is reported.
if(qdutils::MDPVersion::getInstance().is8x26() &&
mDpy >= HWC_DISPLAY_EXTERNAL &&
- qhwc::needsScaling(ctx, layer, mDpy))
+ qhwc::needsScaling(layer))
return false;
}
mCurrentFrame.fbCount = 0;
@@ -1222,6 +1222,48 @@
return true;
}
+bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx,
+ hwc_display_contents_1_t* list) {
+
+ //A-family hw limitation:
+ //If a layer need alpha scaling, MDP can not support.
+ if(ctx->mMDP.version < qdutils::MDSS_V5) {
+ for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
+ if(!mCurrentFrame.isFBComposed[i] &&
+ isAlphaScaled( &list->hwLayers[i])) {
+ ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__);
+ return false;
+ }
+ }
+ }
+
+ // On 8x26 & 8974 hw, we have a limitation of downscaling+blending.
+ //If multiple layers requires downscaling and also they are overlapping
+ //fall back to GPU since MDSS can not handle it.
+ if(qdutils::MDPVersion::getInstance().is8x74v2() ||
+ qdutils::MDPVersion::getInstance().is8x26()) {
+ for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) {
+ hwc_layer_1_t* botLayer = &list->hwLayers[i];
+ if(!mCurrentFrame.isFBComposed[i] &&
+ isDownscaleRequired(botLayer)) {
+ //if layer-i is marked for MDP and needs downscaling
+ //check if any MDP layer on top of i & overlaps with layer-i
+ for(int j = i+1; j < mCurrentFrame.layerCount; ++j) {
+ hwc_layer_1_t* topLayer = &list->hwLayers[j];
+ if(!mCurrentFrame.isFBComposed[j] &&
+ isDownscaleRequired(topLayer)) {
+ hwc_rect_t r = getIntersection(botLayer->displayFrame,
+ topLayer->displayFrame);
+ if(isValidRect(r))
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
int ret = 0;
const int numLayers = ctx->listStats[mDpy].numAppLayers;
@@ -1495,7 +1537,7 @@
if(isYuvBuffer(hnd)) {
type = MDPCOMP_OV_VG;
- } else if(!qhwc::needsScaling(ctx, layer, mDpy)
+ } else if(!qhwc::needsScaling(layer)
&& Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
&& ctx->mMDP.version >= qdutils::MDSS_V5) {
type = MDPCOMP_OV_DMA;
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 986b0e6..8e9b1be 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -181,6 +181,9 @@
hwc_display_contents_1_t* list);
/* checks if the required bandwidth exceeds a certain max */
bool bandwidthCheck(hwc_context_t *ctx, const double& size);
+ /* checks if MDP/MDSS can process current list w.r.to HW limitations
+ * All peculiar HW limitations should go here */
+ bool hwLimitationsCheck(hwc_context_t* ctx, hwc_display_contents_1_t* list);
/* generates ROI based on the modified area of the frame */
void generateROI(hwc_context_t *ctx, hwc_display_contents_1_t* list);
bool validateAndApplyROI(hwc_context_t *ctx, hwc_display_contents_1_t* list,
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index ac82443..e632843 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -311,12 +311,12 @@
float xRatio = 1.0;
float yRatio = 1.0;
- float fbWidth = ctx->dpyAttr[dpy].xres;
- float fbHeight = ctx->dpyAttr[dpy].yres;
+ int fbWidth = ctx->dpyAttr[dpy].xres;
+ int fbHeight = ctx->dpyAttr[dpy].yres;
if(ctx->dpyAttr[dpy].mDownScaleMode) {
// if downscale Mode is enabled for external, need to query
// the actual width and height, as that is the physical w & h
- ctx->mExtDisplay->getAttributes((int&)fbWidth, (int&)fbHeight);
+ ctx->mExtDisplay->getAttributes(fbWidth, fbHeight);
}
@@ -329,7 +329,7 @@
float asX = 0;
float asY = 0;
float asW = fbWidth;
- float asH= fbHeight;
+ float asH = fbHeight;
// based on the action safe ratio, get the Action safe rectangle
asW = fbWidth * (1.0f - asWidthRatio / 100.0f);
@@ -607,8 +607,21 @@
return extOrientation;
}
-bool needsScaling(hwc_context_t* ctx, hwc_layer_1_t const* layer,
- const int& dpy) {
+bool isDownscaleRequired(hwc_layer_1_t const* layer) {
+ hwc_rect_t displayFrame = layer->displayFrame;
+ hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
+ int dst_w, dst_h, src_w, src_h;
+ 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(((src_w > dst_w) || (src_h > dst_h)))
+ return true;
+
+ return false;
+}
+bool needsScaling(hwc_layer_1_t const* layer) {
int dst_w, dst_h, src_w, src_h;
hwc_rect_t displayFrame = layer->displayFrame;
@@ -677,9 +690,8 @@
return false;
}
-bool isAlphaScaled(hwc_context_t* ctx, hwc_layer_1_t const* layer,
- const int& dpy) {
- if(needsScaling(ctx, layer, dpy) && isAlphaPresent(layer)) {
+bool isAlphaScaled(hwc_layer_1_t const* layer) {
+ if(needsScaling(layer) && isAlphaPresent(layer)) {
return true;
}
return false;
@@ -734,7 +746,6 @@
ctx->listStats[dpy].numAppLayers = list->numHwLayers - 1;
ctx->listStats[dpy].fbLayerIndex = list->numHwLayers - 1;
ctx->listStats[dpy].skipCount = 0;
- ctx->listStats[dpy].needsAlphaScale = false;
ctx->listStats[dpy].preMultipliedAlpha = false;
ctx->listStats[dpy].isSecurePresent = false;
ctx->listStats[dpy].yuvCount = 0;
@@ -804,9 +815,6 @@
if(layer->blending == HWC_BLENDING_PREMULT)
ctx->listStats[dpy].preMultipliedAlpha = true;
- if(!ctx->listStats[dpy].needsAlphaScale)
- ctx->listStats[dpy].needsAlphaScale =
- isAlphaScaled(ctx, layer, dpy);
if(UNLIKELY(isExtOnly(hnd))){
ctx->listStats[dpy].extOnlyLayerIndex = i;
@@ -1061,7 +1069,7 @@
hwc_rect_t& topframe =
(hwc_rect_t&)list->hwLayers[i].displayFrame;
while(j >= 0) {
- if(!needsScaling(ctx, &list->hwLayers[j], dpy)) {
+ if(!needsScaling(&list->hwLayers[j])) {
hwc_layer_1_t* layer = (hwc_layer_1_t*)&list->hwLayers[j];
hwc_rect_t& bottomframe = layer->displayFrame;
hwc_rect_t& bottomCrop = layer->sourceCrop;
@@ -1069,10 +1077,11 @@
hwc_rect_t irect = getIntersection(bottomframe, topframe);
if(isValidRect(irect)) {
+ hwc_rect_t dest_rect;
//if intersection is valid rect, deduct it
- bottomframe = deductRect(bottomframe, irect);
+ dest_rect = deductRect(bottomframe, irect);
qhwc::calculate_crop_rects(bottomCrop, bottomframe,
- bottomframe, transform);
+ dest_rect, transform);
}
}
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 95ecf2c..7db0f36 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -97,7 +97,6 @@
int yuvCount;
int yuvIndices[MAX_NUM_APP_LAYERS];
int extOnlyLayerIndex;
- bool needsAlphaScale;
bool preMultipliedAlpha;
int yuv4k2kIndices[MAX_NUM_APP_LAYERS];
int yuv4k2kCount;
@@ -205,8 +204,9 @@
bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer);
bool isSecureModePolicy(int mdpVersion);
bool isExternalActive(hwc_context_t* ctx);
-bool needsScaling(hwc_context_t* ctx, hwc_layer_1_t const* layer,
- const int& dpy);
+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 needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
const int& dpy);
void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,