Merge "hwc: Perform MDP downscaling for WFD/HDMI Scenario"
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
commit
c82dcafc53
@@ -6,7 +6,7 @@ LOCAL_MODULE := libexternal
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
|
||||
LOCAL_SHARED_LIBRARIES := $(common_libs) liboverlay
|
||||
LOCAL_SHARED_LIBRARIES := $(common_libs) liboverlay libqdutils
|
||||
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdexternal\"
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
|
||||
LOCAL_SRC_FILES := external.cpp
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "external.h"
|
||||
#include "overlayUtils.h"
|
||||
#include "overlay.h"
|
||||
#include "mdp_version.h"
|
||||
|
||||
using namespace android;
|
||||
|
||||
@@ -65,6 +66,11 @@ int ExternalDisplay::configure() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ExternalDisplay::getAttributes(int& width, int& height) {
|
||||
int fps = 0;
|
||||
getAttrForMode(width, height, fps);
|
||||
}
|
||||
|
||||
int ExternalDisplay::teardown() {
|
||||
closeFrameBuffer();
|
||||
resetInfo();
|
||||
@@ -564,16 +570,39 @@ bool ExternalDisplay::writeHPDOption(int userOption) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void ExternalDisplay::setAttributes() {
|
||||
int width = 0, height = 0, fps = 0;
|
||||
getAttrForMode(width, height, fps);
|
||||
|
||||
ALOGD("ExtDisplay setting xres = %d, yres = %d", width, height);
|
||||
if(mHwcContext) {
|
||||
// Always set dpyAttr res to mVInfo res
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = width;
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = height;
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].mDownScaleMode = false;
|
||||
if(!qdutils::MDPVersion::getInstance().is8x26()) {
|
||||
int priW = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
|
||||
int priH = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
|
||||
// if primary resolution is more than the hdmi resolution
|
||||
// configure dpy attr to primary resolution and set
|
||||
// downscale mode
|
||||
if((priW * priH) > (width * height)) {
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = priW;
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = priH;
|
||||
// HDMI is always in landscape, so always assign the higher
|
||||
// dimension to hdmi's xres
|
||||
if(priH > priW) {
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = priH;
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = priW;
|
||||
}
|
||||
// Set External Display MDP Downscale mode indicator
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].mDownScaleMode =true;
|
||||
}
|
||||
}
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].vsync_period =
|
||||
1000000000l / fps;
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalDisplay::getAttrForMode(int& width, int& height, int& fps) {
|
||||
switch (mCurrentMode) {
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
void setActionSafeDimension(int w, int h);
|
||||
bool isCEUnderscanSupported() { return mUnderscanSupported; }
|
||||
int configure();
|
||||
void getAttributes(int& width, int& height);
|
||||
int teardown();
|
||||
bool isConnected() {
|
||||
return mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].connected;
|
||||
|
||||
@@ -26,10 +26,12 @@
|
||||
#include "hwc_fbupdate.h"
|
||||
#include "mdp_version.h"
|
||||
#include "external.h"
|
||||
#include "virtual.h"
|
||||
|
||||
using namespace qdutils;
|
||||
using namespace overlay;
|
||||
using overlay::Rotator;
|
||||
using namespace overlay::utils;
|
||||
|
||||
namespace qhwc {
|
||||
|
||||
@@ -118,23 +120,28 @@ bool FBUpdateLowRes::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
|
||||
// Do not use getNonWormholeRegion() function to calculate the
|
||||
// sourceCrop during animation on external display and
|
||||
// Dont do wormhole calculation when extorientation is set on External
|
||||
// Dont do wormhole calculation when extDownscale is enabled on External
|
||||
if(ctx->listStats[mDpy].isDisplayAnimating && mDpy) {
|
||||
sourceCrop = layer->displayFrame;
|
||||
displayFrame = sourceCrop;
|
||||
} else if((!mDpy || (mDpy && !ctx->mExtOrientation))
|
||||
&& extOnlyLayerIndex == -1) {
|
||||
} else if((!mDpy ||
|
||||
(mDpy && !ctx->mExtOrientation
|
||||
&& !ctx->dpyAttr[mDpy].mDownScaleMode))
|
||||
&& (extOnlyLayerIndex == -1)) {
|
||||
if(!qdutils::MDPVersion::getInstance().is8x26()) {
|
||||
getNonWormholeRegion(list, sourceCrop);
|
||||
displayFrame = sourceCrop;
|
||||
}
|
||||
}
|
||||
|
||||
if(mDpy && !qdutils::MDPVersion::getInstance().is8x26()) {
|
||||
if(ctx->mExtOrientation) {
|
||||
calcExtDisplayPosition(ctx, mDpy, displayFrame);
|
||||
if(ctx->mExtOrientation || ctx->dpyAttr[mDpy].mDownScaleMode) {
|
||||
calcExtDisplayPosition(ctx, mDpy, sourceCrop, displayFrame);
|
||||
// If there is a external orientation set, use that
|
||||
if(ctx->mExtOrientation) {
|
||||
transform = ctx->mExtOrientation;
|
||||
orient = static_cast<ovutils::eTransform >(ctx->mExtOrientation);
|
||||
orient =
|
||||
static_cast<ovutils::eTransform >(ctx->mExtOrientation);
|
||||
}
|
||||
}
|
||||
// Calculate the actionsafe dimensions for External(dpy = 1 or 2)
|
||||
getActionSafePosition(ctx, mDpy, displayFrame);
|
||||
|
||||
@@ -159,6 +159,9 @@ void initContext(hwc_context_t *ctx)
|
||||
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = false;
|
||||
ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = false;
|
||||
ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected = false;
|
||||
ctx->dpyAttr[HWC_DISPLAY_PRIMARY].mDownScaleMode= false;
|
||||
ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].mDownScaleMode = false;
|
||||
ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].mDownScaleMode = false;
|
||||
|
||||
ctx->mMDPComp[HWC_DISPLAY_PRIMARY] =
|
||||
MDPComp::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
|
||||
@@ -414,6 +417,56 @@ void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
|
||||
"y = %d w = %d h = %d", __FUNCTION__, outPos.x, outPos.y,
|
||||
outPos.w, outPos.h);
|
||||
|
||||
// For sidesync, the dest fb will be in portrait orientation, and the crop
|
||||
// will be updated to avoid the black side bands, and it will be upscaled
|
||||
// to fit the dest RB, so recalculate
|
||||
// the position based on the new width and height
|
||||
if ((extOrientation & HWC_TRANSFORM_ROT_90) &&
|
||||
isOrientationPortrait(ctx)) {
|
||||
hwc_rect_t r;
|
||||
//Calculate the position
|
||||
xRatio = (outPos.x - xPos)/width;
|
||||
// GetaspectRatio -- tricky to get the correct aspect ratio
|
||||
// But we need to do this.
|
||||
getAspectRatioPosition(width, height, width, height, r);
|
||||
xPos = r.left;
|
||||
yPos = r.top;
|
||||
float tempWidth = r.right - r.left;
|
||||
float tempHeight = r.bottom - r.top;
|
||||
yRatio = yPos/height;
|
||||
wRatio = outPos.w/width;
|
||||
hRatio = tempHeight/height;
|
||||
|
||||
//Map the coordinates back to Framebuffer domain
|
||||
outPos.x = (xRatio * fbWidth);
|
||||
outPos.y = (yRatio * fbHeight);
|
||||
outPos.w = wRatio * fbWidth;
|
||||
outPos.h = hRatio * fbHeight;
|
||||
|
||||
ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio for device in"
|
||||
"portrait: x = %d,y = %d w = %d h = %d", __FUNCTION__,
|
||||
outPos.x, outPos.y,
|
||||
outPos.w, outPos.h);
|
||||
}
|
||||
if(ctx->dpyAttr[dpy].mDownScaleMode) {
|
||||
int extW, extH;
|
||||
if(dpy == HWC_DISPLAY_EXTERNAL)
|
||||
ctx->mExtDisplay->getAttributes(extW, extH);
|
||||
else
|
||||
ctx->mVirtualDisplay->getAttributes(extW, extH);
|
||||
fbWidth = ctx->dpyAttr[dpy].xres;
|
||||
fbHeight = ctx->dpyAttr[dpy].yres;
|
||||
//Calculate the position...
|
||||
xRatio = outPos.x/fbWidth;
|
||||
yRatio = outPos.y/fbHeight;
|
||||
wRatio = outPos.w/fbWidth;
|
||||
hRatio = outPos.h/fbHeight;
|
||||
|
||||
outPos.x = xRatio * extW;
|
||||
outPos.y = yRatio * extH;
|
||||
outPos.w = wRatio * extW;
|
||||
outPos.h = hRatio * extH;
|
||||
}
|
||||
// Convert Dim to hwc_rect_t
|
||||
outRect.left = outPos.x;
|
||||
outRect.top = outPos.y;
|
||||
@@ -432,21 +485,61 @@ bool isPrimaryPortrait(hwc_context_t *ctx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void calcExtDisplayPosition(hwc_context_t *ctx,
|
||||
int dpy, hwc_rect_t& displayFrame) {
|
||||
bool isOrientationPortrait(hwc_context_t *ctx) {
|
||||
if(isPrimaryPortrait(ctx)) {
|
||||
return !(ctx->deviceOrientation & 0x1);
|
||||
}
|
||||
return (ctx->deviceOrientation & 0x1);
|
||||
}
|
||||
|
||||
void calcExtDisplayPosition(hwc_context_t *ctx, int dpy,
|
||||
hwc_rect_t& sourceCrop,
|
||||
hwc_rect_t& displayFrame) {
|
||||
// Swap width and height when there is a 90deg transform
|
||||
if(ctx->mExtOrientation & HWC_TRANSFORM_ROT_90) {
|
||||
int dstWidth = ctx->dpyAttr[dpy].xres;
|
||||
int dstHeight = ctx->dpyAttr[dpy].yres;;
|
||||
int srcWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
|
||||
int srcHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
|
||||
// Swap width and height when there is a 90deg transform
|
||||
if(ctx->mExtOrientation & HWC_TRANSFORM_ROT_90) {
|
||||
if(!isPrimaryPortrait(ctx)) {
|
||||
swap(srcWidth, srcHeight);
|
||||
} // Get Aspect Ratio for external
|
||||
getAspectRatioPosition(dstWidth, dstHeight, srcWidth,
|
||||
srcHeight, displayFrame);
|
||||
// Crop - this is needed, because for sidesync, the dest fb will
|
||||
// be in portrait orientation, so update the crop to not show the
|
||||
// black side bands.
|
||||
if (isOrientationPortrait(ctx)) {
|
||||
sourceCrop = displayFrame;
|
||||
displayFrame.left = 0;
|
||||
displayFrame.top = 0;
|
||||
displayFrame.right = dstWidth;
|
||||
displayFrame.bottom = dstHeight;
|
||||
}
|
||||
}
|
||||
if(ctx->dpyAttr[dpy].mDownScaleMode) {
|
||||
int extW, extH;
|
||||
// if downscale is enabled, map the co-ordinates to new
|
||||
// domain(downscaled)
|
||||
float fbWidth = ctx->dpyAttr[dpy].xres;
|
||||
float fbHeight = ctx->dpyAttr[dpy].yres;
|
||||
// query MDP configured attributes
|
||||
if(dpy == HWC_DISPLAY_EXTERNAL)
|
||||
ctx->mExtDisplay->getAttributes(extW, extH);
|
||||
else
|
||||
ctx->mVirtualDisplay->getAttributes(extW, extH);
|
||||
//Calculate the ratio...
|
||||
float wRatio = ((float)extW)/fbWidth;
|
||||
float hRatio = ((float)extH)/fbHeight;
|
||||
|
||||
//convert Dim to hwc_rect_t
|
||||
displayFrame.left *= wRatio;
|
||||
displayFrame.top *= hRatio;
|
||||
displayFrame.right *= wRatio;
|
||||
displayFrame.bottom *= hRatio;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool needsScaling(hwc_context_t* ctx, hwc_layer_1_t const* layer,
|
||||
const int& dpy) {
|
||||
@@ -1093,8 +1186,12 @@ int configureLowRes(hwc_context_t *ctx, hwc_layer_1_t *layer,
|
||||
if(dpy) {
|
||||
// Just need to set the position to portrait as the transformation
|
||||
// will already be set to required orientation on TV
|
||||
if(ctx->mExtOrientation) {
|
||||
if(ctx->mExtOrientation || ctx->dpyAttr[dpy].mDownScaleMode) {
|
||||
getAspectRatioPosition(ctx, dpy, ctx->mExtOrientation, dst, dst);
|
||||
if(ctx->mExtOrientation) {
|
||||
transform = ctx->mExtOrientation;
|
||||
orient = static_cast<eTransform>(transform);
|
||||
}
|
||||
}
|
||||
// Calculate the actionsafe dimensions for External(dpy = 1 or 2)
|
||||
getActionSafePosition(ctx, dpy, dst);
|
||||
|
||||
@@ -83,6 +83,8 @@ struct DisplayAttributes {
|
||||
// To trigger padding round to clean up mdp
|
||||
// pipes
|
||||
bool isConfiguring;
|
||||
// External Display is in MDP Downscale mode indicator
|
||||
bool mDownScaleMode;
|
||||
};
|
||||
|
||||
struct ListStats {
|
||||
@@ -186,8 +188,12 @@ void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
|
||||
|
||||
bool isPrimaryPortrait(hwc_context_t *ctx);
|
||||
|
||||
bool isOrientationPortrait(hwc_context_t *ctx);
|
||||
|
||||
void calcExtDisplayPosition(hwc_context_t *ctx,
|
||||
int dpy, hwc_rect_t& displayFrame);
|
||||
int dpy,
|
||||
hwc_rect_t& sourceCrop,
|
||||
hwc_rect_t& displayFrame);
|
||||
|
||||
//Close acquireFenceFds of all layers of incoming list
|
||||
void closeAcquireFds(hwc_display_contents_1_t* list);
|
||||
|
||||
@@ -6,7 +6,7 @@ LOCAL_MODULE := libvirtual
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_C_INCLUDES := $(common_includes) $(kernel_includes)
|
||||
LOCAL_SHARED_LIBRARIES := $(common_libs) liboverlay
|
||||
LOCAL_SHARED_LIBRARIES := $(common_libs) liboverlay libqdutils
|
||||
LOCAL_CFLAGS := $(common_flags) -DLOG_TAG=\"qdvirtual\"
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
|
||||
LOCAL_SRC_FILES := virtual.cpp
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "virtual.h"
|
||||
#include "overlayUtils.h"
|
||||
#include "overlay.h"
|
||||
#include "mdp_version.h"
|
||||
|
||||
using namespace android;
|
||||
|
||||
@@ -67,6 +68,11 @@ int VirtualDisplay::configure() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VirtualDisplay::getAttributes(int& width, int& height) {
|
||||
width = mVInfo.xres;
|
||||
height = mVInfo.yres;
|
||||
}
|
||||
|
||||
int VirtualDisplay::teardown() {
|
||||
closeFrameBuffer();
|
||||
memset(&mVInfo, 0, sizeof(mVInfo));
|
||||
@@ -85,13 +91,36 @@ VirtualDisplay::~VirtualDisplay()
|
||||
}
|
||||
|
||||
void VirtualDisplay::setAttributes() {
|
||||
if(mHwcContext) {
|
||||
// Always set dpyAttr res to mVInfo res
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].xres = mVInfo.xres;
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].yres = mVInfo.yres;
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].mDownScaleMode = false;
|
||||
if(!qdutils::MDPVersion::getInstance().is8x26()) {
|
||||
uint32_t priW = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
|
||||
uint32_t priH = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
|
||||
// if primary resolution is more than the wfd resolution
|
||||
// configure dpy attr to primary resolution and set
|
||||
// downscale mode
|
||||
if((priW * priH) > (mVInfo.xres * mVInfo.yres)) {
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].xres = priW;
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].yres = priH;
|
||||
// WFD is always in landscape, so always assign the higher
|
||||
// dimension to wfd's xres
|
||||
if(priH > priW) {
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].xres = priH;
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].yres = priW;
|
||||
}
|
||||
// Set External Display MDP Downscale mode indicator
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].mDownScaleMode = true;
|
||||
}
|
||||
}
|
||||
mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].vsync_period =
|
||||
1000000000l /60;
|
||||
ALOGD_IF(DEBUG,"%s: Setting Virtual Attr: res(%d x %d)",__FUNCTION__,
|
||||
mVInfo.xres, mVInfo.yres);
|
||||
}
|
||||
}
|
||||
|
||||
bool VirtualDisplay::openFrameBuffer()
|
||||
{
|
||||
|
||||
@@ -43,6 +43,7 @@ public:
|
||||
VirtualDisplay(hwc_context_t* ctx);
|
||||
~VirtualDisplay();
|
||||
int configure();
|
||||
void getAttributes(int& width, int& height);
|
||||
int teardown();
|
||||
bool isConnected() {
|
||||
return mHwcContext->dpyAttr[HWC_DISPLAY_VIRTUAL].connected;
|
||||
|
||||
Reference in New Issue
Block a user