diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp index 267815f4..3c224caf 100644 --- a/libhwcomposer/hwc.cpp +++ b/libhwcomposer/hwc.cpp @@ -147,7 +147,8 @@ static void setDMAState(hwc_context_t *ctx, int numDisplays, * to BLOCK_MODE */ if (canUseRotator(ctx, dpy) && - has90Transform(layer) && isRotationDoable(ctx, hnd)) { + (has90Transform(layer) || getRotDownscale(ctx, layer)) + && isRotationDoable(ctx, hnd)) { if(not ctx->mOverlay->isDMAMultiplexingSupported()) { if(ctx->mOverlay->isPipeTypeAttached( overlay::utils::OV_MDP_PIPE_DMA)) diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp index 162ee4fb..1df54194 100644 --- a/libhwcomposer/hwc_mdpcomp.cpp +++ b/libhwcomposer/hwc_mdpcomp.cpp @@ -156,6 +156,7 @@ bool MDPComp::init(hwc_context_t *ctx) { } if(!qdutils::MDPVersion::getInstance().isSrcSplit() && + !qdutils::MDPVersion::getInstance().isRotDownscaleEnabled() && property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 && (!strncmp(property, "1", PROPERTY_VALUE_MAX) || !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) { @@ -2311,6 +2312,10 @@ bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer, int dstWidth = dst.right - dst.left; int cropWidth = crop.right - crop.left; + //TODO Even if a 4k video is going to be rot-downscaled to dimensions under + //pipe line length, we are still using 2 pipes. This is fine just because + //this is source split where destination doesn't matter. Evaluate later to + //see if going through all the calcs to save a pipe is worth it if(dstWidth > mdpHw.getMaxMixerWidth() or cropWidth > mdpHw.getMaxMixerWidth() or (primarySplitAlways and (cropWidth > lSplit))) { @@ -2351,7 +2356,6 @@ int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, hwc_rect_t dst = layer->displayFrame; int transform = layer->transform; eTransform orient = static_cast(transform); - const int downscale = 0; int rotFlags = ROT_FLAGS_NONE; uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd)); Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size); @@ -2367,21 +2371,22 @@ int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888); } + int downscale = getRotDownscale(ctx, layer); eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION; - setMdpFlags(ctx, layer, mdpFlags, 0, transform); + setMdpFlags(ctx, layer, mdpFlags, downscale, transform); if(lDest != OV_INVALID && rDest != OV_INVALID) { //Enable overfetch setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE); } - if(has90Transform(layer) && isRotationDoable(ctx, hnd)) { + if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) { (*rot) = ctx->mRotMgr->getNext(); if((*rot) == NULL) return -1; ctx->mLayerRotMap[mDpy]->add(layer, *rot); //If the video is using a single pipe, enable BWC if(rDest == OV_INVALID) { - BwcPM::setBwc(crop, dst, transform, mdpFlags); + BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags); } //Configure rotator for pre-rotation if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) { @@ -2389,7 +2394,7 @@ int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, return -1; } updateSource(orient, whf, crop, *rot); - rotFlags |= ROT_PREROTATED; + rotFlags |= ovutils::ROT_PREROTATED; } //If 2 pipes being used, divide layer into half, crop and dst diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp index 3696c056..a58eec48 100644 --- a/libhwcomposer/hwc_utils.cpp +++ b/libhwcomposer/hwc_utils.cpp @@ -1633,6 +1633,47 @@ void updateSource(eTransform& orient, Whf& whf, crop.bottom = transformedCrop.y + transformedCrop.h; } +int getRotDownscale(hwc_context_t *ctx, const hwc_layer_1_t *layer) { + if(not qdutils::MDPVersion::getInstance().isRotDownscaleEnabled()) { + return 0; + } + + int downscale = 0; + hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf); + hwc_rect_t dst = layer->displayFrame; + private_handle_t *hnd = (private_handle_t *)layer->handle; + + if(not hnd) { + return 0; + } + + MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; + bool isInterlaced = metadata && (metadata->operation & PP_PARAM_INTERLACED) + && metadata->interlaced; + int transform = layer->transform; + uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd)); + + if(isYuvBuffer(hnd)) { + if(ctx->mMDP.version >= qdutils::MDP_V4_2 && + ctx->mMDP.version < qdutils::MDSS_V5) { + downscale = Rotator::getDownscaleFactor(crop.right - crop.left, + crop.bottom - crop.top, dst.right - dst.left, + dst.bottom - dst.top, format, isInterlaced); + } else { + Dim adjCrop(crop.left, crop.top, crop.right - crop.left, + crop.bottom - crop.top); + Dim pos(dst.left, dst.top, dst.right - dst.left, + dst.bottom - dst.top); + if(transform & HAL_TRANSFORM_ROT_90) { + swap(adjCrop.w, adjCrop.h); + } + downscale = Rotator::getDownscaleFactor(adjCrop.w, adjCrop.h, pos.w, + pos.h, format, isInterlaced); + } + } + return downscale; +} + int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy, eMdpFlags& mdpFlags, eZorder& z, eIsFg& isFg, const eDest& dest, Rotator **rot) { @@ -1654,7 +1695,6 @@ int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, hwc_rect_t dst = layer->displayFrame; int transform = layer->transform; eTransform orient = static_cast(transform); - int downscale = 0; int rotFlags = ovutils::ROT_FLAGS_NONE; uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd)); Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size); @@ -1668,36 +1708,24 @@ int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, } calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient); - - if(isYuvBuffer(hnd) && ctx->mMDP.version >= qdutils::MDP_V4_2 && - ctx->mMDP.version < qdutils::MDSS_V5) { - downscale = getDownscaleFactor( - crop.right - crop.left, - crop.bottom - crop.top, - dst.right - dst.left, - dst.bottom - dst.top); - if(downscale) { - rotFlags = ROT_DOWNSCALE_ENABLED; - } - } - + int downscale = getRotDownscale(ctx, layer); setMdpFlags(ctx, layer, mdpFlags, downscale, transform); //if 90 component or downscale, use rot - if((has90Transform(layer) && isRotationDoable(ctx, hnd)) || downscale) { + if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) { *rot = ctx->mRotMgr->getNext(); if(*rot == NULL) return -1; ctx->mLayerRotMap[dpy]->add(layer, *rot); // BWC is not tested for other formats So enable it only for YUV format if(!dpy && isYuvBuffer(hnd)) - BwcPM::setBwc(crop, dst, transform, mdpFlags); + BwcPM::setBwc(crop, dst, transform, downscale, mdpFlags); //Configure rotator for pre-rotation if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) { ALOGE("%s: configRotator failed!", __FUNCTION__); return -1; } updateSource(orient, whf, crop, *rot); - rotFlags |= ovutils::ROT_PREROTATED; + rotFlags |= ROT_PREROTATED; } //For the mdp, since either we are pre-rotating or MDP does flips @@ -1761,7 +1789,6 @@ int configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, hwc_rect_t dst = layer->displayFrame; int transform = layer->transform; eTransform orient = static_cast(transform); - const int downscale = 0; int rotFlags = ROT_FLAGS_NONE; uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd)); Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size); @@ -1777,8 +1804,8 @@ int configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, /* Calculate the external display position based on MDP downscale, ActionSafe, and extorientation features. */ calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient); - - setMdpFlags(ctx, layer, mdpFlagsL, 0, transform); + int downscale = getRotDownscale(ctx, layer); + setMdpFlags(ctx, layer, mdpFlagsL, downscale, transform); if(lDest != OV_INVALID && rDest != OV_INVALID) { //Enable overfetch @@ -1792,7 +1819,7 @@ int configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, whf.format = wb->getOutputFormat(); } - if(has90Transform(layer) && isRotationDoable(ctx, hnd)) { + if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) { (*rot) = ctx->mRotMgr->getNext(); if((*rot) == NULL) return -1; ctx->mLayerRotMap[dpy]->add(layer, *rot); @@ -1928,7 +1955,7 @@ int configureSourceSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, ctx->mLayerRotMap[dpy]->add(layer, *rot); // BWC is not tested for other formats So enable it only for YUV format if(!dpy && isYuvBuffer(hnd)) - BwcPM::setBwc(crop, dst, transform, mdpFlagsL); + BwcPM::setBwc(crop, dst, transform, downscale, mdpFlagsL); //Configure rotator for pre-rotation if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) { ALOGE("%s: configRotator failed!", __FUNCTION__); @@ -2175,9 +2202,12 @@ bool isPeripheral(const hwc_rect_t& rect1, const hwc_rect_t& rect2) { return (eqBounds == 3); } -void BwcPM::setBwc(const hwc_rect_t& crop, - const hwc_rect_t& dst, const int& transform, - ovutils::eMdpFlags& mdpFlags) { +void BwcPM::setBwc(const hwc_rect_t& crop, const hwc_rect_t& dst, + const int& transform,const int& downscale, + ovutils::eMdpFlags& mdpFlags) { + //BWC not supported with rot-downscale + if(downscale) return; + //Target doesnt support Bwc qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance(); if(!mdpHw.supportsBWC()) { diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h index 66fdc658..28289d59 100644 --- a/libhwcomposer/hwc_utils.h +++ b/libhwcomposer/hwc_utils.h @@ -161,8 +161,8 @@ struct VsyncState { }; struct BwcPM { - static void setBwc(const hwc_rect_t& crop, - const hwc_rect_t& dst, const int& transform, + static void setBwc(const hwc_rect_t& crop, const hwc_rect_t& dst, + const int& transform, const int& downscale, ovutils::eMdpFlags& mdpFlags); }; @@ -387,6 +387,8 @@ int getLeftSplit(hwc_context_t *ctx, const int& dpy); bool isDisplaySplit(hwc_context_t* ctx, int dpy); +int getRotDownscale(hwc_context_t *ctx, const hwc_layer_1_t *layer); + // Set the GPU hint flag to high for MIXED/GPU composition only for // first frame after MDP to GPU/MIXED mode transition. // Set the GPU hint to default if the current composition type is GPU diff --git a/liboverlay/overlayMdpRot.cpp b/liboverlay/overlayMdpRot.cpp index bb985d78..6105736b 100755 --- a/liboverlay/overlayMdpRot.cpp +++ b/liboverlay/overlayMdpRot.cpp @@ -17,6 +17,7 @@ * limitations under the License. */ +#include #include "overlayUtils.h" #include "overlayRotator.h" #include "gr.h" @@ -274,4 +275,35 @@ void MdpRot::getDump(char *buf, size_t len) const { ovutils::getDump(buf, len, "MdpRotData", mRotDataInfo); } +int MdpRot::getDownscaleFactor(const int& src_w, const int& src_h, + const int& dst_w, const int& dst_h, const uint32_t& /*mdpFormat*/, + const bool& /*isInterlaced*/) { + int dscale_factor = utils::ROT_DS_NONE; + // We need this check to engage the rotator whenever possible to assist MDP + // in performing video downscale. + // This saves bandwidth and avoids causing the driver to make too many panel + // -mode switches between BLT (writeback) and non-BLT (Direct) modes. + // Use-case: Video playback [with downscaling and rotation]. + if (dst_w && dst_h) + { + float fDscale = (float)(src_w * src_h) / (float)(dst_w * dst_h); + uint32_t dscale = (int)sqrtf(fDscale); + + if(dscale < 2) { + // Down-scale to > 50% of orig. + dscale_factor = utils::ROT_DS_NONE; + } else if(dscale < 4) { + // Down-scale to between > 25% to <= 50% of orig. + dscale_factor = utils::ROT_DS_HALF; + } else if(dscale < 8) { + // Down-scale to between > 12.5% to <= 25% of orig. + dscale_factor = utils::ROT_DS_FOURTH; + } else { + // Down-scale to <= 12.5% of orig. + dscale_factor = utils::ROT_DS_EIGHTH; + } + } + return dscale_factor; +} + } // namespace overlay diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp index 5783dcb2..8e55362f 100644 --- a/liboverlay/overlayMdssRot.cpp +++ b/liboverlay/overlayMdssRot.cpp @@ -17,6 +17,7 @@ * limitations under the License. */ +#include #include "overlayUtils.h" #include "overlayRotator.h" @@ -103,7 +104,8 @@ void MdssRot::setCrop(const utils::Dim& crop) { mRotInfo.src_rect.h = crop.h; } -void MdssRot::setDownscale(int /*ds*/) { +void MdssRot::setDownscale(int downscale) { + mDownscale = downscale; } void MdssRot::setFlags(const utils::eMdpFlags& flags) { @@ -128,19 +130,25 @@ void MdssRot::doTransform() { } bool MdssRot::commit() { - if (utils::isYuv(mRotInfo.src.format)) { - utils::normalizeCrop(mRotInfo.src_rect.x, mRotInfo.src_rect.w); - utils::normalizeCrop(mRotInfo.src_rect.y, mRotInfo.src_rect.h); - // For interlaced, crop.h should be 4-aligned - if ((mRotInfo.flags & utils::OV_MDP_DEINTERLACE) and - (mRotInfo.src_rect.h % 4)) - mRotInfo.src_rect.h = utils::aligndown(mRotInfo.src_rect.h, 4); - } + Dim adjCrop(mRotInfo.src_rect.x,mRotInfo.src_rect.y, + mRotInfo.src_rect.w,mRotInfo.src_rect.h); + adjCrop = getFormatAdjustedCrop(adjCrop, mRotInfo.src.format, + mRotInfo.flags & utils::OV_MDP_DEINTERLACE); + adjCrop = getDownscaleAdjustedCrop(adjCrop, mDownscale); + + mRotInfo.src_rect.x = adjCrop.x; + mRotInfo.src_rect.y = adjCrop.y; + mRotInfo.src_rect.w = adjCrop.w; + mRotInfo.src_rect.h = adjCrop.h; mRotInfo.dst_rect.x = 0; mRotInfo.dst_rect.y = 0; - mRotInfo.dst_rect.w = mRotInfo.src_rect.w; - mRotInfo.dst_rect.h = mRotInfo.src_rect.h; + mRotInfo.dst_rect.w = mDownscale ? + mRotInfo.src_rect.w / mDownscale : mRotInfo.src_rect.w; + mRotInfo.dst_rect.h = mDownscale ? + mRotInfo.src_rect.h / mDownscale : mRotInfo.src_rect.h; + //Clear for next round + mDownscale = 0; doTransform(); @@ -258,6 +266,7 @@ void MdssRot::reset() { ovutils::memset0(mMem.mRotOffset); mMem.mCurrIndex = 0; mOrientation = utils::OVERLAY_TRANSFORM_0; + mDownscale = 0; } void MdssRot::dump() const { @@ -340,4 +349,54 @@ uint32_t MdssRot::calcCompressedBufSize(const ovutils::Whf& destWhf) { return bufSize; } +int MdssRot::getDownscaleFactor(const int& srcW, const int& srcH, + const int& dstW, const int& dstH, const uint32_t& mdpFormat, + const bool& isInterlaced) { + if(not srcW or not srcH or not dstW or not dstH or isInterlaced) return 0; + + Dim crop(0, 0, srcW, srcH); + Dim adjCrop = getFormatAdjustedCrop(crop, mdpFormat, + false /*isInterlaced */); + + uint32_t downscale = min((adjCrop.w / dstW), (adjCrop.h / dstH)); + //Reduced to a power of 2 + downscale = (uint32_t) powf(2.0f, floorf(log2f((float)downscale))); + + if(downscale < 2 or downscale > 32) return 0; + + //Allow only 1 line or pixel to be chopped off since the source needs to + //be aligned to downscale. Progressively try with smaller downscale to see + //if we can satisfy the threshold + //For YUV the loop shouldnt be needed, unless in exceptional cases + Dim dsAdjCrop = getDownscaleAdjustedCrop(adjCrop, downscale); + while(downscale > 2 and (adjCrop.w > dsAdjCrop.w or + adjCrop.h > dsAdjCrop.h)) { + downscale /= 2; + dsAdjCrop = getDownscaleAdjustedCrop(adjCrop, downscale); + } + + if(not dsAdjCrop.w or not dsAdjCrop.h) return 0; + return downscale; +} + +Dim MdssRot::getFormatAdjustedCrop(const Dim& crop, + const uint32_t& mdpFormat, const bool& isInterlaced) { + Dim adjCrop = crop; + if (isYuv(mdpFormat)) { + normalizeCrop(adjCrop.x, adjCrop.w); + normalizeCrop(adjCrop.y, adjCrop.h); + // For interlaced, crop.h should be 4-aligned + if (isInterlaced and (adjCrop.h % 4)) + adjCrop.h = aligndown(adjCrop.h, 4); + } + return adjCrop; +} + +Dim MdssRot::getDownscaleAdjustedCrop(const Dim& crop, + const uint32_t& downscale) { + uint32_t alignedSrcW = aligndown(crop.w, downscale * 2); + uint32_t alignedSrcH = aligndown(crop.h, downscale * 2); + return Dim(crop.x, crop.y, alignedSrcW, alignedSrcH); +} + } // namespace overlay diff --git a/liboverlay/overlayRotator.cpp b/liboverlay/overlayRotator.cpp index 0671b622..9d569922 100644 --- a/liboverlay/overlayRotator.cpp +++ b/liboverlay/overlayRotator.cpp @@ -42,6 +42,17 @@ Rotator* Rotator::getRotator() { } } +int Rotator::getDownscaleFactor(const int& srcW, const int& srcH, + const int& dstW, const int& dstH, const uint32_t& mdpFormat, + const bool& isInterlaced) { + if(getRotatorHwType() == TYPE_MDSS) { + return MdssRot::getDownscaleFactor(srcW, srcH, dstW, dstH, + mdpFormat, isInterlaced); + } + return MdpRot::getDownscaleFactor(srcW, srcH, dstW, dstH, + mdpFormat, isInterlaced); +} + uint32_t Rotator::calcOutputBufSize(const utils::Whf& destWhf) { //dummy aligned w & h. int alW = 0, alH = 0; diff --git a/liboverlay/overlayRotator.h b/liboverlay/overlayRotator.h index 64387cd7..7d1b0b1e 100644 --- a/liboverlay/overlayRotator.h +++ b/liboverlay/overlayRotator.h @@ -88,6 +88,13 @@ public: virtual void getDump(char *buf, size_t len) const = 0; void setReleaseFd(const int& fence) { mMem.setReleaseFd(fence); } static Rotator *getRotator(); + /* Returns downscale by successfully applying constraints + * Returns 0 if target doesnt support rotator downscaling + * or if any of the constraints are not met + */ + static int getDownscaleFactor(const int& srcW, const int& srcH, + const int& dstW, const int& dstH, const uint32_t& mdpFormat, + const bool& isInterlaced); protected: /* Rotator memory manager */ @@ -146,6 +153,16 @@ private: * knowing the o/p format depending on whether fastYuv is enabled or not */ uint32_t calcOutputBufSize(); + /* Applies downscale by taking areas + * Returns a log(downscale) + * Constraints applied: + * - downscale should be a power of 2 + * - Max downscale is 1/8 + */ + static int getDownscaleFactor(const int& srcW, const int& srcH, + const int& dstW, const int& dstH, const uint32_t& mdpFormat, + const bool& isInterlaced); + /* rot info*/ msm_rotator_img_info mRotImgInfo; /* Last saved rot info*/ @@ -158,6 +175,9 @@ private: OvFD mFd; friend Rotator* Rotator::getRotator(); + friend int Rotator::getDownscaleFactor(const int& srcW, const int& srcH, + const int& dstW, const int& dstH, const uint32_t& mdpFormat, + const bool& isInterlaced); }; /* @@ -202,6 +222,25 @@ private: // Calculate the compressed o/p buffer size for BWC uint32_t calcCompressedBufSize(const utils::Whf& destWhf); + /* Caller's responsibility to swap srcW, srcH if there is a 90 transform + * Returns actual downscale (not a log value) + * Constraints applied: + * - downscale should be a power of 2 + * - Max downscale is 1/32 + * - Equal downscale is applied in both directions + * - {srcW, srcH} mod downscale = 0 + * - Interlaced content is not supported + */ + static int getDownscaleFactor(const int& srcW, const int& srcH, + const int& dstW, const int& dstH, const uint32_t& mdpFormat, + const bool& isInterlaced); + + static utils::Dim getFormatAdjustedCrop(const utils::Dim& crop, + const uint32_t& mdpFormat, const bool& isInterlaced); + + static utils::Dim getDownscaleAdjustedCrop(const utils::Dim& crop, + const uint32_t& downscale); + /* MdssRot info structure */ mdp_overlay mRotInfo; /* MdssRot data structure */ @@ -212,8 +251,12 @@ private: OvFD mFd; /* Enable/Disable Mdss Rot*/ bool mEnabled; + int mDownscale; friend Rotator* Rotator::getRotator(); + friend int Rotator::getDownscaleFactor(const int& srcW, const int& srcH, + const int& dstW, const int& dstH, const uint32_t& mdpFormat, + const bool& isInterlaced); }; // Holder of rotator objects. Manages lifetimes diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp index 0e063ab2..b86cd2d2 100644 --- a/liboverlay/overlayUtils.cpp +++ b/liboverlay/overlayUtils.cpp @@ -248,36 +248,6 @@ int getMdpOrient(eTransform rotation) { return retTrans; } -int getDownscaleFactor(const int& src_w, const int& src_h, - const int& dst_w, const int& dst_h) { - int dscale_factor = utils::ROT_DS_NONE; - // We need this check to engage the rotator whenever possible to assist MDP - // in performing video downscale. - // This saves bandwidth and avoids causing the driver to make too many panel - // -mode switches between BLT (writeback) and non-BLT (Direct) modes. - // Use-case: Video playback [with downscaling and rotation]. - if (dst_w && dst_h) - { - float fDscale = (float)(src_w * src_h) / (float)(dst_w * dst_h); - uint32_t dscale = (int)sqrtf(fDscale); - - if(dscale < 2) { - // Down-scale to > 50% of orig. - dscale_factor = utils::ROT_DS_NONE; - } else if(dscale < 4) { - // Down-scale to between > 25% to <= 50% of orig. - dscale_factor = utils::ROT_DS_HALF; - } else if(dscale < 8) { - // Down-scale to between > 12.5% to <= 25% of orig. - dscale_factor = utils::ROT_DS_FOURTH; - } else { - // Down-scale to <= 12.5% of orig. - dscale_factor = utils::ROT_DS_EIGHTH; - } - } - return dscale_factor; -} - void getDecimationFactor(const int& src_w, const int& src_h, const int& dst_w, const int& dst_h, uint8_t& horzDeci, uint8_t& vertDeci) { diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h index 530377b8..4a989f69 100644 --- a/liboverlay/overlayUtils.h +++ b/liboverlay/overlayUtils.h @@ -379,8 +379,6 @@ struct ScreenInfo { int getMdpFormat(int format); int getMdpFormat(int format, bool tileEnabled); 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, uint8_t& horzDeci, uint8_t& vertDeci); @@ -399,6 +397,10 @@ template inline void swap ( T& a, T& b ) T c(a); a=b; b=c; } +template inline T max(T a, T b) { return (a > b) ? a : b; } + +template inline T min(T a, T b) { return (a < b) ? a : b; } + inline int alignup(int value, int a) { //if align = 0, return the value. Else, do alignment. return a ? ((((value - 1) / a) + 1) * a) : value; diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp index 48f7cb7e..1d524fed 100644 --- a/libqdutils/mdp_version.cpp +++ b/libqdutils/mdp_version.cpp @@ -321,6 +321,10 @@ bool MDPVersion::updateSysFsInfo() { fclose(sysfsFd); } + if(mMDPVersion >= qdutils::MDP_V4_2 and mMDPVersion < qdutils::MDSS_V5) { + mRotDownscale = true; + } + if(mSourceSplit) { memset(sysfsPath, 0, sizeof(sysfsPath)); snprintf(sysfsPath , sizeof(sysfsPath),