overlay: Add support for decimation.
Add support for decimation on top of what MDP can downscale,
because decimation can have quality issues.
B-family MDP downscale of 1/4, plus decimation of 1/16 can let
us have a total downscale of 1/64.
Also decimate by 2 (min) if width is greater than what layer mixer
supports and is not handled by the client.
Change-Id: I3b7c4bf321c7561bd98206ad118f4ac1ee2879ae
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 96cb56e..d70ab64 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#include <math.h>
#include <mdp_version.h>
#include "overlayUtils.h"
#include "overlayMdp.h"
@@ -22,10 +23,17 @@
#define HSIC_SETTINGS_DEBUG 0
+using namespace qdutils;
+
static inline bool isEqual(float f1, float f2) {
return ((int)(f1*100) == (int)(f2*100)) ? true : false;
}
+//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);
+}
+
namespace ovutils = overlay::utils;
namespace overlay {
@@ -130,14 +138,52 @@
}
void MdpCtrl::doDownscale() {
- mOVInfo.src_rect.x >>= mDownscale;
- mOVInfo.src_rect.y >>= mDownscale;
- mOVInfo.src_rect.w >>= mDownscale;
- mOVInfo.src_rect.h >>= mDownscale;
+ int mdpVersion = MDPVersion::getInstance().getMDPVersion();
+ if(mdpVersion < MDSS_V5) {
+ mOVInfo.src_rect.x >>= mDownscale;
+ mOVInfo.src_rect.y >>= mDownscale;
+ mOVInfo.src_rect.w >>= mDownscale;
+ mOVInfo.src_rect.h >>= mDownscale;
+ } else if(MDPVersion::getInstance().supportsDecimation()) {
+ //Decimation + MDP Downscale
+ mOVInfo.horz_deci = 0;
+ mOVInfo.vert_deci = 0;
+ int minHorDeci = 0;
+ if(mOVInfo.src_rect.w > 2048) {
+ //If the client sends us something > what a layer mixer supports
+ //then it means it doesn't want to use split-pipe but wants us to
+ //decimate. A minimum decimation of 2 will ensure that the width is
+ //always within layer mixer limits.
+ 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);
+
+ //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;
+
+ if(horDscale < minHorDeci)
+ horDscale = minHorDeci;
+
+ if((int)horDscale)
+ mOVInfo.horz_deci = (int)log2f(horDscale);
+
+ if((int)verDscale)
+ mOVInfo.vert_deci = (int)log2f(verDscale);
+ }
}
bool MdpCtrl::set() {
- int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
+ int mdpVersion = MDPVersion::getInstance().getMDPVersion();
//deferred calcs, so APIs could be called in any order.
doTransform();
doDownscale();
@@ -145,7 +191,7 @@
if(utils::isYuv(whf.format)) {
normalizeCrop(mOVInfo.src_rect.x, mOVInfo.src_rect.w);
normalizeCrop(mOVInfo.src_rect.y, mOVInfo.src_rect.h);
- if(mdpVersion < qdutils::MDSS_V5) {
+ if(mdpVersion < MDSS_V5) {
utils::even_floor(mOVInfo.dst_rect.w);
utils::even_floor(mOVInfo.dst_rect.h);
}