qdutils : Read max mixer width from drivers.
Read the maximum width mixer can output from drivers
and consider this in identifying if dual pipes are required
to support a layer. So far above 2K dimensions we are using dual
pipes, but 8x39 mixer output can be upto 2560. So there is no
need of dual pipes as long as pipe data is less than this limit.
Compare layer/panel resolutions against this limit to deduce
if there is a need for dual pipes or split.
Change-Id: I52e1d28e381327d4f0b00f5ea8547c1e6157313c
diff --git a/libhwcomposer/hwc_ad.cpp b/libhwcomposer/hwc_ad.cpp
index 49e7e2a..a26f659 100644
--- a/libhwcomposer/hwc_ad.cpp
+++ b/libhwcomposer/hwc_ad.cpp
@@ -130,7 +130,8 @@
int nYuvIndex = ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndices[0];
const hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
private_handle_t *hnd = (private_handle_t *)layer->handle;
- if(hnd && hnd->width <= qdutils::MAX_DISPLAY_DIM) {
+ qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
+ if(hnd && hnd->width <= mdpHw.getMaxMixerWidth()) {
mDoable = true;
}
}
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index de4cd05..5014af9 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -474,7 +474,7 @@
ovutils::eDest destR = ovutils::OV_INVALID;
/* Use 2 pipes IF
- a) FB's width is > 2048 or
+ a) FB's width is > Mixer width or
b) On primary, driver has indicated with caps to split always. This is
based on an empirically derived value of panel height.
*/
@@ -483,7 +483,7 @@
qdutils::MDPVersion::getInstance().isSrcSplitAlways();
if(((fbUpdatingRect.right - fbUpdatingRect.left) >
- qdutils::MAX_DISPLAY_DIM) or
+ (int)qdutils::MDPVersion::getInstance().getMaxMixerWidth()) or
primarySplitAlways) {
destR = ov.getPipe(pipeSpecs);
if(destR == ovutils::OV_INVALID) {
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 3a60fa3..adf30fe 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -349,6 +349,7 @@
int dst_h = dst.bottom - dst.top;
float w_scale = ((float)crop_w / (float)dst_w);
float h_scale = ((float)crop_h / (float)dst_h);
+ MDPVersion& mdpHw = MDPVersion::getInstance();
/* Workaround for MDP HW limitation in DSI command mode panels where
* FPS will not go beyond 30 if buffers on RGB pipes are of width or height
@@ -360,29 +361,29 @@
return false;
if((w_scale > 1.0f) || (h_scale > 1.0f)) {
- const uint32_t maxMDPDownscale =
- qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
+ const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
const float w_dscale = w_scale;
const float h_dscale = h_scale;
if(ctx->mMDP.version >= qdutils::MDSS_V5) {
- if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
+ if(!mdpHw.supportsDecimation()) {
/* On targets that doesnt support Decimation (eg.,8x26)
* maximum downscale support is overlay pipe downscale.
*/
- if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale ||
+ if(crop_w > mdpHw.getMaxMixerWidth() ||
+ w_dscale > maxMDPDownscale ||
h_dscale > maxMDPDownscale)
return false;
} else {
// Decimation on macrotile format layers is not supported.
if(isTileRendered(hnd)) {
- /* MDP can read maximum MAX_DISPLAY_DIM width.
- * Bail out if
- * 1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp
+ /* Bail out if
+ * 1. Src crop > Mixer limit on nonsplit MDPComp
* 2. exceeds maximum downscale limit
*/
- if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) ||
+ if(((crop_w > mdpHw.getMaxMixerWidth()) &&
+ !sSrcSplitEnabled) ||
w_dscale > maxMDPDownscale ||
h_dscale > maxMDPDownscale) {
return false;
@@ -397,8 +398,7 @@
}
if((w_scale < 1.0f) || (h_scale < 1.0f)) {
- const uint32_t upscale =
- qdutils::MDPVersion::getInstance().getMaxMDPUpscale();
+ const uint32_t upscale = mdpHw.getMaxMDPUpscale();
const float w_uscale = 1.0f / w_scale;
const float h_uscale = 1.0f / h_scale;
@@ -688,8 +688,10 @@
return false;
}
- if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) &&
- (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) {
+ MDPVersion& mdpHw = MDPVersion::getInstance();
+ if(mDpy > HWC_DISPLAY_PRIMARY &&
+ (priDispW > mdpHw.getMaxMixerWidth()) &&
+ (ctx->dpyAttr[mDpy].xres < mdpHw.getMaxMixerWidth())) {
// Disable MDP comp on Secondary when the primary is highres panel and
// the secondary is a normal 1080p, because, MDP comp on secondary under
// in such usecase, decimation gets used for downscale and there will be
@@ -721,11 +723,9 @@
//For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp
// may not need it if Gfx pre-rotation can handle all flips & rotations
int transform = (layer->flags & HWC_COLOR_FILL) ? 0 : layer->transform;
- if(qdutils::MDPVersion::getInstance().is8x26() &&
- (ctx->dpyAttr[mDpy].xres > 1024) &&
- (transform & HWC_TRANSFORM_FLIP_H) &&
- (!isYuvBuffer(hnd)))
- return false;
+ if( mdpHw.is8x26() && (ctx->dpyAttr[mDpy].xres > 1024) &&
+ (transform & HWC_TRANSFORM_FLIP_H) && (!isYuvBuffer(hnd)))
+ return false;
}
if(ctx->mAD->isDoable()) {
@@ -2259,14 +2259,15 @@
if the layer's width is > mixer's width
*/
+ MDPVersion& mdpHw = MDPVersion::getInstance();
bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
- qdutils::MDPVersion::getInstance().isSrcSplitAlways();
+ mdpHw.isSrcSplitAlways();
int lSplit = getLeftSplit(ctx, mDpy);
int dstWidth = dst.right - dst.left;
int cropWidth = crop.right - crop.left;
- if(dstWidth > qdutils::MAX_DISPLAY_DIM or
- cropWidth > qdutils::MAX_DISPLAY_DIM or
+ if(dstWidth > mdpHw.getMaxMixerWidth() or
+ cropWidth > mdpHw.getMaxMixerWidth() or
(primarySplitAlways and (cropWidth > lSplit))) {
pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
if(pipe_info.rIndex == ovutils::OV_INVALID) {
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 879e4bd..4447cfd 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -78,7 +78,7 @@
bool isValidResolution(hwc_context_t *ctx, uint32_t xres, uint32_t yres)
{
- return !((xres > qdutils::MAX_DISPLAY_DIM &&
+ return !((xres > qdutils::MDPVersion::getInstance().getMaxMixerWidth() &&
!isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY)) ||
(xres < MIN_DISPLAY_XRES || yres < MIN_DISPLAY_YRES));
}
@@ -2034,12 +2034,12 @@
}
bool isDisplaySplit(hwc_context_t* ctx, int dpy) {
- if(ctx->dpyAttr[dpy].xres > qdutils::MAX_DISPLAY_DIM) {
+ qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
+ if(ctx->dpyAttr[dpy].xres > mdpHw.getMaxMixerWidth()) {
return true;
}
//For testing we could split primary via device tree values
- if(dpy == HWC_DISPLAY_PRIMARY &&
- qdutils::MDPVersion::getInstance().getRightSplit()) {
+ if(dpy == HWC_DISPLAY_PRIMARY && mdpHw.getRightSplit()) {
return true;
}
return false;
@@ -2173,7 +2173,8 @@
const hwc_rect_t& dst, const int& transform,
ovutils::eMdpFlags& mdpFlags) {
//Target doesnt support Bwc
- if(!qdutils::MDPVersion::getInstance().supportsBWC()) {
+ qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
+ if(!mdpHw.supportsBWC()) {
return;
}
int src_w = crop.right - crop.left;
@@ -2184,7 +2185,7 @@
swap(src_w, src_h);
}
//src width > MAX mixer supported dim
- if(src_w > qdutils::MAX_DISPLAY_DIM) {
+ if(src_w > qdutils::MDPVersion::getInstance().getMaxMixerWidth()) {
return;
}
//Decimation necessary, cannot use BWC. H/W requirement.
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index 6b53522..48f7cb7 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -37,6 +37,12 @@
#define TOKEN_PARAMS_DELIM "="
+// chip variants have same major number and minor numbers usually vary
+// for e.g., MDSS_MDP_HW_REV_101 is 0x10010000
+// 1001 - major number
+// 0000 - minor number
+// 8x26 v1 minor number is 0000
+// v2 minor number is 0001 etc..
#ifndef MDSS_MDP_HW_REV_100
#define MDSS_MDP_HW_REV_100 0x10000000 //8974 v1
#endif
@@ -92,6 +98,10 @@
mRGBHasNoScalar = false;
mRotDownscale = false;
+ // this is the default limit of mixer unless driver reports it.
+ // For resolutions beyond this, we use dual/split overlay pipes.
+ mMaxMixerWidth = 2048;
+
updatePanelInfo();
if(!updateSysFsInfo()) {
@@ -279,6 +289,9 @@
} else if(!strncmp(tokens[0], "max_bandwidth_high",
strlen("max_bandwidth_high"))) {
mHighBw = atol(tokens[1]);
+ } else if(!strncmp(tokens[0], "max_mixer_width",
+ strlen("max_mixer_width"))) {
+ mMaxMixerWidth = atoi(tokens[1]);
} else if(!strncmp(tokens[0], "features", strlen("features"))) {
for(int i=1; i<index;i++) {
if(!strncmp(tokens[i], "bwc", strlen("bwc"))) {
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index 6c4a3f4..ced414e 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -57,17 +57,6 @@
MDSS_V5 = 500,
};
-// chip variants have same major number and minor numbers usually vary
-// for e.g., MDSS_MDP_HW_REV_101 is 0x10010000
-// 1001 - major number
-// 0000 - minor number
-// 8x26 v1 minor number is 0000
-// v2 minor number is 0001 etc..
-
-enum {
- MAX_DISPLAY_DIM = 2048,
-};
-
#define NO_PANEL '0'
#define MDDI_PANEL '1'
#define EBI2_PANEL '2'
@@ -140,6 +129,7 @@
unsigned long getLowBw() { return mLowBw; }
unsigned long getHighBw() { return mHighBw; }
bool isRotDownscaleEnabled() { return mRotDownscale; }
+ int getMaxMixerWidth() const { return mMaxMixerWidth; }
bool isSrcSplit() const;
bool isSrcSplitAlways() const;
bool isRGBScalarSupported() const;
@@ -177,6 +167,7 @@
bool mSourceSplitAlways;
bool mRGBHasNoScalar;
bool mRotDownscale;
+ uint32_t mMaxMixerWidth; //maximum x-res of a given mdss mixer.
};
}; //namespace qdutils
#endif //INCLUDE_LIBQCOMUTILS_MDPVER