hwc/overlay: Get rot dest dimensions instead of manipulating source
Currently for Mdss rotator we manipulate the layer buffer dimensions to be equal to what rotator's destination dimensions would be, so that these could be fed to MDP. Instead, this patch introduces APIs in rotator so that hwc can directly query destination crop, width, height, format from rotator. This also simplifies the updateSource() and configRotator() helpers. Change-Id: I501d998f2e0574683c764af9422742b2426ba0c7
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
parent
a3f48596f3
commit
8ec9b5eda4
@@ -109,8 +109,7 @@ bool FBUpdateNonSplit::preRotateExtDisplay(hwc_context_t *ctx,
|
|||||||
mRot = NULL;
|
mRot = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
info.format = (mRot)->getDstFormat();
|
updateSource(orient, info, sourceCrop, mRot);
|
||||||
updateSource(orient, info, sourceCrop);
|
|
||||||
rotFlags |= ovutils::ROT_PREROTATED;
|
rotFlags |= ovutils::ROT_PREROTATED;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -2345,8 +2345,7 @@ int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
|||||||
ALOGE("%s: configRotator failed!", __FUNCTION__);
|
ALOGE("%s: configRotator failed!", __FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
whf.format = (*rot)->getDstFormat();
|
updateSource(orient, whf, crop, *rot);
|
||||||
updateSource(orient, whf, crop);
|
|
||||||
rotFlags |= ROT_PREROTATED;
|
rotFlags |= ROT_PREROTATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1528,18 +1528,8 @@ int configRotator(Rotator *rot, Whf& whf,
|
|||||||
|
|
||||||
if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
|
if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
|
||||||
qdutils::MDSS_V5) {
|
qdutils::MDSS_V5) {
|
||||||
uint32_t crop_w = (crop.right - crop.left);
|
Dim rotCrop(crop.left, crop.top, crop.right - crop.left,
|
||||||
uint32_t crop_h = (crop.bottom - crop.top);
|
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);
|
|
||||||
rot->setCrop(rotCrop);
|
rot->setCrop(rotCrop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1614,28 +1604,27 @@ int configColorLayer(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateSource(eTransform& orient, Whf& whf,
|
void updateSource(eTransform& orient, Whf& whf,
|
||||||
hwc_rect_t& crop) {
|
hwc_rect_t& crop, Rotator *rot) {
|
||||||
Dim srcCrop(crop.left, crop.top,
|
Dim transformedCrop(crop.left, crop.top,
|
||||||
crop.right - crop.left,
|
crop.right - crop.left,
|
||||||
crop.bottom - crop.top);
|
crop.bottom - crop.top);
|
||||||
orient = static_cast<eTransform>(ovutils::getMdpOrient(orient));
|
|
||||||
preRotateSource(orient, whf, srcCrop);
|
|
||||||
if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
|
if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
|
||||||
qdutils::MDSS_V5) {
|
qdutils::MDSS_V5) {
|
||||||
// Source for overlay will be the cropped (and rotated)
|
//B-family rotator internally could modify destination dimensions if
|
||||||
crop.left = 0;
|
//downscaling is supported
|
||||||
crop.top = 0;
|
whf = rot->getDstWhf();
|
||||||
crop.right = srcCrop.w;
|
transformedCrop = rot->getDstDimensions();
|
||||||
crop.bottom = srcCrop.h;
|
|
||||||
// Set width & height equal to sourceCrop w & h
|
|
||||||
whf.w = srcCrop.w;
|
|
||||||
whf.h = srcCrop.h;
|
|
||||||
} else {
|
} else {
|
||||||
crop.left = srcCrop.x;
|
//A-family rotator rotates entire buffer irrespective of crop, forcing
|
||||||
crop.top = srcCrop.y;
|
//us to recompute the crop based on transform
|
||||||
crop.right = srcCrop.x + srcCrop.w;
|
orient = static_cast<eTransform>(ovutils::getMdpOrient(orient));
|
||||||
crop.bottom = srcCrop.y + srcCrop.h;
|
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,
|
int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
||||||
@@ -1701,8 +1690,7 @@ int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
|||||||
ALOGE("%s: configRotator failed!", __FUNCTION__);
|
ALOGE("%s: configRotator failed!", __FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
whf.format = (*rot)->getDstFormat();
|
updateSource(orient, whf, crop, *rot);
|
||||||
updateSource(orient, whf, crop);
|
|
||||||
rotFlags |= ovutils::ROT_PREROTATED;
|
rotFlags |= ovutils::ROT_PREROTATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1807,8 +1795,7 @@ int configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
|||||||
ALOGE("%s: configRotator failed!", __FUNCTION__);
|
ALOGE("%s: configRotator failed!", __FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
whf.format = (*rot)->getDstFormat();
|
updateSource(orient, whf, crop, *rot);
|
||||||
updateSource(orient, whf, crop);
|
|
||||||
rotFlags |= ROT_PREROTATED;
|
rotFlags |= ROT_PREROTATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1941,8 +1928,7 @@ int configureSourceSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
|||||||
ALOGE("%s: configRotator failed!", __FUNCTION__);
|
ALOGE("%s: configRotator failed!", __FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
whf.format = (*rot)->getDstFormat();
|
updateSource(orient, whf, crop, *rot);
|
||||||
updateSource(orient, whf, crop);
|
|
||||||
rotFlags |= ROT_PREROTATED;
|
rotFlags |= ROT_PREROTATED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ int configColorLayer(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
|
|||||||
ovutils::eIsFg& isFg, const ovutils::eDest& dest);
|
ovutils::eIsFg& isFg, const ovutils::eDest& dest);
|
||||||
|
|
||||||
void updateSource(ovutils::eTransform& orient, ovutils::Whf& whf,
|
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)
|
//Routine to configure low resolution panels (<= 2048 width)
|
||||||
int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
|
int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer, const int& dpy,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "overlayUtils.h"
|
#include "overlayUtils.h"
|
||||||
#include "overlayRotator.h"
|
#include "overlayRotator.h"
|
||||||
|
#include "gr.h"
|
||||||
|
|
||||||
namespace ovutils = overlay::utils;
|
namespace ovutils = overlay::utils;
|
||||||
|
|
||||||
@@ -47,6 +48,24 @@ uint32_t MdpRot::getDstFormat() const {
|
|||||||
return mRotImgInfo.dst.format;
|
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; }
|
uint32_t MdpRot::getSessId() const { return mRotImgInfo.session_id; }
|
||||||
|
|
||||||
void MdpRot::setDownscale(int ds) {
|
void MdpRot::setDownscale(int ds) {
|
||||||
|
|||||||
@@ -63,6 +63,21 @@ uint32_t MdssRot::getDstFormat() const {
|
|||||||
return mRotInfo.src.format;
|
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; }
|
uint32_t MdssRot::getSessId() const { return mRotInfo.id; }
|
||||||
|
|
||||||
bool MdssRot::init() {
|
bool MdssRot::init() {
|
||||||
@@ -82,16 +97,10 @@ void MdssRot::setSource(const overlay::utils::Whf& awhf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MdssRot::setCrop(const utils::Dim& crop) {
|
void MdssRot::setCrop(const utils::Dim& crop) {
|
||||||
|
|
||||||
mRotInfo.src_rect.x = crop.x;
|
mRotInfo.src_rect.x = crop.x;
|
||||||
mRotInfo.src_rect.y = crop.y;
|
mRotInfo.src_rect.y = crop.y;
|
||||||
mRotInfo.src_rect.w = crop.w;
|
mRotInfo.src_rect.w = crop.w;
|
||||||
mRotInfo.src_rect.h = crop.h;
|
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*/) {
|
void MdssRot::setDownscale(int /*ds*/) {
|
||||||
@@ -119,7 +128,22 @@ void MdssRot::doTransform() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool MdssRot::commit() {
|
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();
|
doTransform();
|
||||||
|
|
||||||
mRotInfo.flags |= MDSS_MDP_ROT_ONLY;
|
mRotInfo.flags |= MDSS_MDP_ROT_ONLY;
|
||||||
mEnabled = true;
|
mEnabled = true;
|
||||||
if(!overlay::mdp_wrapper::setOverlay(mFd.getFD(), mRotInfo)) {
|
if(!overlay::mdp_wrapper::setOverlay(mFd.getFD(), mRotInfo)) {
|
||||||
|
|||||||
@@ -74,9 +74,14 @@ public:
|
|||||||
virtual void setTransform(const utils::eTransform& rot) = 0;
|
virtual void setTransform(const utils::eTransform& rot) = 0;
|
||||||
virtual bool commit() = 0;
|
virtual bool commit() = 0;
|
||||||
virtual void setDownscale(int ds) = 0;
|
virtual void setDownscale(int ds) = 0;
|
||||||
|
//Mem id and offset should be retrieved only after rotator kickoff
|
||||||
virtual int getDstMemId() const = 0;
|
virtual int getDstMemId() const = 0;
|
||||||
virtual uint32_t getDstOffset() 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 uint32_t getDstFormat() const = 0;
|
||||||
|
virtual utils::Whf getDstWhf() const = 0;
|
||||||
|
virtual utils::Dim getDstDimensions() const = 0;
|
||||||
virtual uint32_t getSessId() const = 0;
|
virtual uint32_t getSessId() const = 0;
|
||||||
virtual bool queueBuffer(int fd, uint32_t offset) = 0;
|
virtual bool queueBuffer(int fd, uint32_t offset) = 0;
|
||||||
virtual void dump() const = 0;
|
virtual void dump() const = 0;
|
||||||
@@ -112,6 +117,8 @@ public:
|
|||||||
virtual int getDstMemId() const;
|
virtual int getDstMemId() const;
|
||||||
virtual uint32_t getDstOffset() const;
|
virtual uint32_t getDstOffset() const;
|
||||||
virtual uint32_t getDstFormat() const;
|
virtual uint32_t getDstFormat() const;
|
||||||
|
virtual utils::Whf getDstWhf() const;
|
||||||
|
virtual utils::Dim getDstDimensions() const;
|
||||||
virtual uint32_t getSessId() const;
|
virtual uint32_t getSessId() const;
|
||||||
virtual bool queueBuffer(int fd, uint32_t offset);
|
virtual bool queueBuffer(int fd, uint32_t offset);
|
||||||
virtual void dump() const;
|
virtual void dump() const;
|
||||||
@@ -169,6 +176,8 @@ public:
|
|||||||
virtual int getDstMemId() const;
|
virtual int getDstMemId() const;
|
||||||
virtual uint32_t getDstOffset() const;
|
virtual uint32_t getDstOffset() const;
|
||||||
virtual uint32_t getDstFormat() const;
|
virtual uint32_t getDstFormat() const;
|
||||||
|
virtual utils::Whf getDstWhf() const;
|
||||||
|
virtual utils::Dim getDstDimensions() const;
|
||||||
virtual uint32_t getSessId() const;
|
virtual uint32_t getSessId() const;
|
||||||
virtual bool queueBuffer(int fd, uint32_t offset);
|
virtual bool queueBuffer(int fd, uint32_t offset);
|
||||||
virtual void dump() const;
|
virtual void dump() const;
|
||||||
|
|||||||
@@ -543,6 +543,14 @@ inline void even_floor(T& value) {
|
|||||||
value--;
|
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 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 mdp_overlay& ov);
|
||||||
void getDump(char *buf, size_t len, const char *prefix, const msmfb_img& ov);
|
void getDump(char *buf, size_t len, const char *prefix, const msmfb_img& ov);
|
||||||
|
|||||||
Reference in New Issue
Block a user