Merge "hwc/overlay: Get rot dest dimensions instead of manipulating source"
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 942b8b2..de4cd05 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -109,8 +109,7 @@
mRot = NULL;
return false;
}
- info.format = (mRot)->getDstFormat();
- updateSource(orient, info, sourceCrop);
+ updateSource(orient, info, sourceCrop, mRot);
rotFlags |= ovutils::ROT_PREROTATED;
}
return true;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index fdc3f2e..37b211d 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -2345,8 +2345,7 @@
ALOGE("%s: configRotator failed!", __FUNCTION__);
return -1;
}
- whf.format = (*rot)->getDstFormat();
- updateSource(orient, whf, crop);
+ updateSource(orient, whf, crop, *rot);
rotFlags |= ROT_PREROTATED;
}
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index bf4582c..cc18686 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -1528,18 +1528,8 @@
if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
qdutils::MDSS_V5) {
- uint32_t crop_w = (crop.right - crop.left);
- uint32_t crop_h = (crop.bottom - crop.top);
- if (ovutils::isYuv(whf.format)) {
- ovutils::normalizeCrop((uint32_t&)crop.left, crop_w);
- ovutils::normalizeCrop((uint32_t&)crop.top, crop_h);
- // For interlaced, crop.h should be 4-aligned
- if ((mdpFlags & ovutils::OV_MDP_DEINTERLACE) && (crop_h % 4))
- crop_h = ovutils::aligndown(crop_h, 4);
- crop.right = crop.left + crop_w;
- crop.bottom = crop.top + crop_h;
- }
- Dim rotCrop(crop.left, crop.top, crop_w, crop_h);
+ Dim rotCrop(crop.left, crop.top, crop.right - crop.left,
+ crop.bottom - crop.top);
rot->setCrop(rotCrop);
}
@@ -1614,28 +1604,27 @@
}
void updateSource(eTransform& orient, Whf& whf,
- hwc_rect_t& crop) {
- Dim srcCrop(crop.left, crop.top,
+ hwc_rect_t& crop, Rotator *rot) {
+ Dim transformedCrop(crop.left, crop.top,
crop.right - crop.left,
crop.bottom - crop.top);
- orient = static_cast<eTransform>(ovutils::getMdpOrient(orient));
- preRotateSource(orient, whf, srcCrop);
if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
qdutils::MDSS_V5) {
- // Source for overlay will be the cropped (and rotated)
- crop.left = 0;
- crop.top = 0;
- crop.right = srcCrop.w;
- crop.bottom = srcCrop.h;
- // Set width & height equal to sourceCrop w & h
- whf.w = srcCrop.w;
- whf.h = srcCrop.h;
+ //B-family rotator internally could modify destination dimensions if
+ //downscaling is supported
+ whf = rot->getDstWhf();
+ transformedCrop = rot->getDstDimensions();
} else {
- crop.left = srcCrop.x;
- crop.top = srcCrop.y;
- crop.right = srcCrop.x + srcCrop.w;
- crop.bottom = srcCrop.y + srcCrop.h;
+ //A-family rotator rotates entire buffer irrespective of crop, forcing
+ //us to recompute the crop based on transform
+ orient = static_cast<eTransform>(ovutils::getMdpOrient(orient));
+ preRotateSource(orient, whf, transformedCrop);
}
+
+ crop.left = transformedCrop.x;
+ crop.top = transformedCrop.y;
+ crop.right = transformedCrop.x + transformedCrop.w;
+ crop.bottom = transformedCrop.y + transformedCrop.h;
}
int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
@@ -1701,8 +1690,7 @@
ALOGE("%s: configRotator failed!", __FUNCTION__);
return -1;
}
- whf.format = (*rot)->getDstFormat();
- updateSource(orient, whf, crop);
+ updateSource(orient, whf, crop, *rot);
rotFlags |= ovutils::ROT_PREROTATED;
}
@@ -1807,8 +1795,7 @@
ALOGE("%s: configRotator failed!", __FUNCTION__);
return -1;
}
- whf.format = (*rot)->getDstFormat();
- updateSource(orient, whf, crop);
+ updateSource(orient, whf, crop, *rot);
rotFlags |= ROT_PREROTATED;
}
@@ -1941,8 +1928,7 @@
ALOGE("%s: configRotator failed!", __FUNCTION__);
return -1;
}
- whf.format = (*rot)->getDstFormat();
- updateSource(orient, whf, crop);
+ updateSource(orient, whf, crop, *rot);
rotFlags |= ROT_PREROTATED;
}
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index ad06e89..d2d1846 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -356,7 +356,7 @@
ovutils::eIsFg& isFg, const ovutils::eDest& dest);
void updateSource(ovutils::eTransform& orient, ovutils::Whf& whf,
- hwc_rect_t& crop);
+ hwc_rect_t& crop, overlay::Rotator *rot);
//Routine to configure low resolution panels (<= 2048 width)
int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
diff --git a/liboverlay/overlayMdpRot.cpp b/liboverlay/overlayMdpRot.cpp
index f456029..bb985d7 100755
--- a/liboverlay/overlayMdpRot.cpp
+++ b/liboverlay/overlayMdpRot.cpp
@@ -19,6 +19,7 @@
#include "overlayUtils.h"
#include "overlayRotator.h"
+#include "gr.h"
namespace ovutils = overlay::utils;
@@ -47,6 +48,24 @@
return mRotImgInfo.dst.format;
}
+//Added for completeness. Not expected to be called.
+utils::Whf MdpRot::getDstWhf() const {
+ int alW = 0, alH = 0;
+ int halFormat = ovutils::getHALFormat(mRotImgInfo.dst.format);
+ getBufferSizeAndDimensions(mRotImgInfo.dst.width, mRotImgInfo.dst.height,
+ halFormat, alW, alH);
+ return utils::Whf(alW, alH, mRotImgInfo.dst.format);
+}
+
+//Added for completeness. Not expected to be called.
+utils::Dim MdpRot::getDstDimensions() const {
+ int alW = 0, alH = 0;
+ int halFormat = ovutils::getHALFormat(mRotImgInfo.dst.format);
+ getBufferSizeAndDimensions(mRotImgInfo.dst.width, mRotImgInfo.dst.height,
+ halFormat, alW, alH);
+ return utils::Dim(0, 0, alW, alH);
+}
+
uint32_t MdpRot::getSessId() const { return mRotImgInfo.session_id; }
void MdpRot::setDownscale(int ds) {
diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp
index f7bc87a..5783dcb 100644
--- a/liboverlay/overlayMdssRot.cpp
+++ b/liboverlay/overlayMdssRot.cpp
@@ -63,6 +63,21 @@
return mRotInfo.src.format;
}
+utils::Whf MdssRot::getDstWhf() const {
+ //For Mdss dst_rect itself represents buffer dimensions. We ignore actual
+ //aligned values during buffer allocation. Also the driver overwrites the
+ //src.format field if destination format is different.
+ //This implementation detail makes it possible to retrieve w,h even before
+ //buffer allocation, which happens in queueBuffer.
+ return utils::Whf(mRotInfo.dst_rect.w, mRotInfo.dst_rect.h,
+ mRotInfo.src.format);
+}
+
+utils::Dim MdssRot::getDstDimensions() const {
+ return utils::Dim(mRotInfo.dst_rect.x, mRotInfo.dst_rect.y,
+ mRotInfo.dst_rect.w, mRotInfo.dst_rect.h);
+}
+
uint32_t MdssRot::getSessId() const { return mRotInfo.id; }
bool MdssRot::init() {
@@ -82,16 +97,10 @@
}
void MdssRot::setCrop(const utils::Dim& crop) {
-
mRotInfo.src_rect.x = crop.x;
mRotInfo.src_rect.y = crop.y;
mRotInfo.src_rect.w = crop.w;
mRotInfo.src_rect.h = crop.h;
-
- mRotInfo.dst_rect.x = 0;
- mRotInfo.dst_rect.y = 0;
- mRotInfo.dst_rect.w = crop.w;
- mRotInfo.dst_rect.h = crop.h;
}
void MdssRot::setDownscale(int /*ds*/) {
@@ -119,7 +128,22 @@
}
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);
+ }
+
+ 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;
+
doTransform();
+
mRotInfo.flags |= MDSS_MDP_ROT_ONLY;
mEnabled = true;
if(!overlay::mdp_wrapper::setOverlay(mFd.getFD(), mRotInfo)) {
diff --git a/liboverlay/overlayRotator.h b/liboverlay/overlayRotator.h
index e0f542c..64387cd 100644
--- a/liboverlay/overlayRotator.h
+++ b/liboverlay/overlayRotator.h
@@ -74,9 +74,14 @@
virtual void setTransform(const utils::eTransform& rot) = 0;
virtual bool commit() = 0;
virtual void setDownscale(int ds) = 0;
+ //Mem id and offset should be retrieved only after rotator kickoff
virtual int getDstMemId() const = 0;
virtual uint32_t getDstOffset() const = 0;
+ //Destination width, height, format, position should be retrieved only after
+ //rotator configuration is committed via commit API
virtual uint32_t getDstFormat() const = 0;
+ virtual utils::Whf getDstWhf() const = 0;
+ virtual utils::Dim getDstDimensions() const = 0;
virtual uint32_t getSessId() const = 0;
virtual bool queueBuffer(int fd, uint32_t offset) = 0;
virtual void dump() const = 0;
@@ -112,6 +117,8 @@
virtual int getDstMemId() const;
virtual uint32_t getDstOffset() const;
virtual uint32_t getDstFormat() const;
+ virtual utils::Whf getDstWhf() const;
+ virtual utils::Dim getDstDimensions() const;
virtual uint32_t getSessId() const;
virtual bool queueBuffer(int fd, uint32_t offset);
virtual void dump() const;
@@ -169,6 +176,8 @@
virtual int getDstMemId() const;
virtual uint32_t getDstOffset() const;
virtual uint32_t getDstFormat() const;
+ virtual utils::Whf getDstWhf() const;
+ virtual utils::Dim getDstDimensions() const;
virtual uint32_t getSessId() const;
virtual bool queueBuffer(int fd, uint32_t offset);
virtual void dump() const;
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 2fcc4ef..530377b 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -543,6 +543,14 @@
value--;
}
+/* Prerotation adjusts crop co-ordinates to the new transformed values within
+ * destination buffer. This is necessary only when the entire buffer is rotated
+ * irrespective of crop (A-family). If only the crop portion of the buffer is
+ * rotated into a destination buffer matching the size of crop, we don't need to
+ * use this helper (B-family).
+ * @Deprecated as of now, retained for the case where a full buffer needs
+ * transform and also as a reference.
+ */
void preRotateSource(const eTransform& tr, Whf& whf, Dim& srcCrop);
void getDump(char *buf, size_t len, const char *prefix, const mdp_overlay& ov);
void getDump(char *buf, size_t len, const char *prefix, const msmfb_img& ov);