Merge "hwc: Perform MDP downscaling for WFD/HDMI Scenario"

This commit is contained in:
Linux Build Service Account
2013-08-29 04:40:10 -07:00
committed by Gerrit - the friendly Code Review server
9 changed files with 199 additions and 29 deletions

View File

@@ -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

View File

@@ -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,15 +570,38 @@ 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) {

View File

@@ -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;

View File

@@ -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);

View File

@@ -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,20 +485,60 @@ 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,
@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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,12 +91,35 @@ 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()

View File

@@ -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;