diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp index aa68467e..b0ea0fcd 100644 --- a/libhwcomposer/hwc_utils.cpp +++ b/libhwcomposer/hwc_utils.cpp @@ -733,12 +733,6 @@ void setMdpFlags(hwc_layer_1_t *layer, if(transform & HWC_TRANSFORM_ROT_90) { ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SOURCE_ROTATED_90); - // enable bandwidth compression only if src width < 2048 - if(qdutils::MDPVersion::getInstance().supportsBWC() && - hnd->width < qdutils::MAX_DISPLAY_DIM) { - ovutils::setMdpFlags(mdpFlags, - ovutils::OV_MDSS_MDP_BWC_EN); - } } } @@ -920,6 +914,7 @@ int configureLowRes(hwc_context_t *ctx, hwc_layer_1_t *layer, ((transform & HWC_TRANSFORM_ROT_90) || downscale)) { *rot = ctx->mRotMgr->getNext(); if(*rot == NULL) return -1; + BwcPM::setBwc(ctx, crop, dst, transform, mdpFlags); //Configure rotator for pre-rotation if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) { ALOGE("%s: configRotator failed!", __FUNCTION__); @@ -1087,4 +1082,43 @@ bool canUseRotator(hwc_context_t *ctx) { return true; } + +void BwcPM::setBwc(hwc_context_t *ctx, const hwc_rect_t& crop, + const hwc_rect_t& dst, const int& transform, + ovutils::eMdpFlags& mdpFlags) { + //Target doesnt support Bwc + if(!qdutils::MDPVersion::getInstance().supportsBWC()) { + return; + } + //src width > MAX mixer supported dim + if((crop.right - crop.left) > qdutils::MAX_DISPLAY_DIM) { + return; + } + //External connected + if(ctx->mExtDisplay->isExternalConnected()) { + return; + } + //Decimation necessary, cannot use BWC. H/W requirement. + if(qdutils::MDPVersion::getInstance().supportsDecimation()) { + int src_w = crop.right - crop.left; + int src_h = crop.bottom - crop.top; + int dst_w = dst.right - dst.left; + int dst_h = dst.bottom - dst.top; + if(transform & HAL_TRANSFORM_ROT_90) { + swap(src_w, src_h); + } + float horDscale = 0.0f; + float verDscale = 0.0f; + ovutils::getDecimationFactor(src_w, src_h, dst_w, dst_h, horDscale, + verDscale); + if(horDscale || verDscale) return; + } + //Property + char value[PROPERTY_VALUE_MAX]; + property_get("debug.disable.bwc", value, "0"); + if(atoi(value)) return; + + ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDSS_MDP_BWC_EN); +} + };//namespace qhwc diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h index fb5e8717..729a6499 100644 --- a/libhwcomposer/hwc_utils.h +++ b/libhwcomposer/hwc_utils.h @@ -109,6 +109,12 @@ struct VsyncState { bool fakevsync; }; +struct BwcPM { + static void setBwc(hwc_context_t *ctx, const hwc_rect_t& crop, + const hwc_rect_t& dst, const int& transform, + ovutils::eMdpFlags& mdpFlags); +}; + // LayerProp::flag values enum { HWC_MDPCOMP = 0x00000001, diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp index 0de62769..71e7e5bb 100644 --- a/liboverlay/overlayMdp.cpp +++ b/liboverlay/overlayMdp.cpp @@ -144,19 +144,11 @@ void MdpCtrl::doDownscale() { minHorDeci = 2; } - float horDscale = ceilf((float)mOVInfo.src_rect.w / - (float)mOVInfo.dst_rect.w); - float verDscale = ceilf((float)mOVInfo.src_rect.h / - (float)mOVInfo.dst_rect.h); + float horDscale = 0.0f; + float verDscale = 0.0f; - //Next power of 2, if not already - horDscale = powf(2.0f, ceilf(log2f(horDscale))); - verDscale = powf(2.0f, ceilf(log2f(verDscale))); - - //Since MDP can do 1/4 dscale and has better quality, split the task - //between decimator and MDP downscale - horDscale /= 4.0f; - verDscale /= 4.0f; + utils::getDecimationFactor(mOVInfo.src_rect.w, mOVInfo.src_rect.h, + mOVInfo.dst_rect.w, mOVInfo.dst_rect.h, horDscale, verDscale); if(horDscale < minHorDeci) horDscale = minHorDeci; diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp index 4b81ed3f..9bfa34e1 100644 --- a/liboverlay/overlayUtils.cpp +++ b/liboverlay/overlayUtils.cpp @@ -244,6 +244,27 @@ int getDownscaleFactor(const int& src_w, const int& src_h, return dscale_factor; } +//Since this is unavailable on Android, defining it in terms of base 10 +static inline float log2f(const float& x) { + return log(x) / log(2); +} + +void getDecimationFactor(const int& src_w, const int& src_h, + const int& dst_w, const int& dst_h, float& horDscale, + float& verDscale) { + horDscale = ceilf((float)src_w / (float)dst_w); + verDscale = ceilf((float)src_h / (float)dst_h); + + //Next power of 2, if not already + horDscale = powf(2.0f, ceilf(log2f(horDscale))); + verDscale = powf(2.0f, ceilf(log2f(verDscale))); + + //Since MDP can do 1/4 dscale and has better quality, split the task + //between decimator and MDP downscale + horDscale /= 4.0f; + verDscale /= 4.0f; +} + static inline int compute(const uint32_t& x, const uint32_t& y, const uint32_t& z) { return x - ( y + z ); diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h index 3fa09796..4bb21519 100644 --- a/liboverlay/overlayUtils.h +++ b/liboverlay/overlayUtils.h @@ -393,6 +393,9 @@ int getMdpFormat(int format); int getHALFormat(int mdpFormat); int getDownscaleFactor(const int& src_w, const int& src_h, const int& dst_w, const int& dst_h); +void getDecimationFactor(const int& src_w, const int& src_h, + const int& dst_w, const int& dst_h, float& horDscale, + float& verDscale); /* flip is upside down and such. V, H flip * rotation is 90, 180 etc