display: Add support orientation control on ext display
- The required orientation on External can be set using the
properyt sys.ext_orientation.
- Values can be HAL_TRANSFORM_ROT_90, HAL_TRANSFORM_ROT_270
- According to the value set, the FB_TARGET for External will
be rotated and positioned as per aspect ratio on Ext
- For YUV(video layer) it just calculates the position, as the
rotation should be the source orientation
- This feature is supported only for low resolution panel.
Change-Id: I3d532ee0cb8dca3c37869537b55cd8044fd9047e
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 439432e..b9be4d4 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -19,12 +19,17 @@
*/
#define DEBUG_FBUPDATE 0
+#include <cutils/properties.h>
#include <gralloc_priv.h>
+#include <overlayRotator.h>
#include "hwc_fbupdate.h"
#include "mdp_version.h"
+#include "external.h"
using namespace qdutils;
+using overlay::Rotator;
+
namespace qhwc {
namespace ovutils = overlay::utils;
@@ -38,6 +43,7 @@
inline void IFBUpdate::reset() {
mModeOn = false;
+ mRot = NULL;
}
//================= Low res====================================
@@ -87,46 +93,71 @@
mDest = dest;
ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
-
+ ovutils::eIsFg isFg = ovutils::IS_FG_OFF;
ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
- ovutils::PipeArgs parg(mdpFlags,
- info,
- zOrder,
- ovutils::IS_FG_OFF,
- ovutils::ROT_FLAGS_NONE);
- ov.setSource(parg, dest);
-
hwc_rect_t sourceCrop = layer->sourceCrop;
hwc_rect_t displayFrame = layer->displayFrame;
- if(extOnlyLayerIndex == -1) {
+ int transform = layer->transform;
+ int fbWidth = ctx->dpyAttr[mDpy].xres;
+ int fbHeight = ctx->dpyAttr[mDpy].yres;
+ int rotFlags = ovutils::ROT_FLAGS_NONE;
+
+ ovutils::eTransform orient =
+ static_cast<ovutils::eTransform>(transform);
+ if(mDpy && ctx->mExtOrientation) {
+ // If there is a external orientation set, use that
+ transform = ctx->mExtOrientation;
+ orient = static_cast<ovutils::eTransform >(ctx->mExtOrientation);
+ }
+
+ // Dont do wormhole calculation when extorientation is set on External
+ if((!mDpy || (mDpy && !ctx->mExtOrientation))
+ && extOnlyLayerIndex == -1) {
getNonWormholeRegion(list, sourceCrop);
displayFrame = sourceCrop;
}
-
- // x,y,w,h
- ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
- sourceCrop.right - sourceCrop.left,
- sourceCrop.bottom - sourceCrop.top);
- ov.setCrop(dcrop, dest);
-
- int transform = layer->transform;
- ovutils::eTransform orient =
- static_cast<ovutils::eTransform>(transform);
- ov.setTransform(orient, dest);
-
ovutils::Dim dpos(displayFrame.left,
displayFrame.top,
displayFrame.right - displayFrame.left,
displayFrame.bottom - displayFrame.top);
// Calculate the actionsafe dimensions for External(dpy = 1 or 2)
- if(mDpy)
+ if(mDpy && !ctx->mExtOrientation)
getActionSafePosition(ctx, mDpy, dpos.x, dpos.y, dpos.w, dpos.h);
- ov.setPosition(dpos, dest);
+ if(mDpy) {
+ getAspectRatioPosition(ctx, mDpy, ctx->mExtOrientation, dpos.x,
+ dpos.y, dpos.w, dpos.h);
+ // Convert dim to hwc_rect_t
+ displayFrame.left = dpos.x;
+ displayFrame.top = dpos.y;
+ displayFrame.right = dpos.w + displayFrame.left;
+ displayFrame.bottom = dpos.h + displayFrame.top;
+ }
+ setMdpFlags(layer, mdpFlags, 0);
+ // For External use rotator if there is a rotation value set
+ if(mDpy && (ctx->mExtOrientation & HWC_TRANSFORM_ROT_90)) {
+ mRot = ctx->mRotMgr->getNext();
+ if(mRot == NULL) return -1;
+ //Configure rotator for pre-rotation
+ if(configRotator(mRot, info, sourceCrop, mdpFlags, orient, 0) < 0) {
+ ALOGE("%s: configRotator Failed!", __FUNCTION__);
+ mRot = NULL;
+ return -1;
+ }
+ info.format = (mRot)->getDstFormat();
+ updateSource(orient, info, sourceCrop);
+ rotFlags |= ovutils::ROT_PREROTATED;
+ }
+ //For the mdp, since either we are pre-rotating or MDP does flips
+ orient = ovutils::OVERLAY_TRANSFORM_0;
+ transform = 0;
+ ovutils::PipeArgs parg(mdpFlags, info, zOrder, isFg,
+ static_cast<ovutils::eRotFlags>(rotFlags));
ret = true;
- if (!ov.commit(dest)) {
- ALOGE("%s: commit fails", __FUNCTION__);
+ if(configMdp(ctx->mOverlay, parg, orient, sourceCrop, displayFrame,
+ NULL, mDest) < 0) {
+ ALOGE("%s: ConfigMdp failed for low res", __FUNCTION__);
ret = false;
}
}
@@ -141,7 +172,15 @@
bool ret = true;
overlay::Overlay& ov = *(ctx->mOverlay);
ovutils::eDest dest = mDest;
- if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
+ int fd = hnd->fd;
+ uint32_t offset = hnd->offset;
+ if(mRot) {
+ if(!mRot->queueBuffer(fd, offset))
+ return false;
+ fd = mRot->getDstMemId();
+ offset = mRot->getDstOffset();
+ }
+ if (!ov.queueBuffer(fd, offset, dest)) {
ALOGE("%s: queueBuffer failed for FBUpdate", __FUNCTION__);
ret = false;
}
@@ -155,6 +194,7 @@
IFBUpdate::reset();
mDestLeft = ovutils::OV_INVALID;
mDestRight = ovutils::OV_INVALID;
+ mRot = NULL;
}
bool FBUpdateHighRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,