qcom/display: Add support for video rotation on HDMI

- Enable rotator for HDMI for video
- cleanup updateOverlaySource API, it does not need
  orientation info

Change-Id: Id53a42cbc4265015ea2714d25df1b02af60ee5e4
CRs-fixed: 341691, 330719, 342199, 344308
This commit is contained in:
Arun Kumar K.R 2012-02-21 19:24:39 -08:00 committed by Andrew Sutherland
parent 8f3c0e6d8c
commit 0358ea0b84
3 changed files with 66 additions and 43 deletions

View File

@ -1355,6 +1355,8 @@ static int drawLayerUsingCopybit(hwc_composer_device_t *dev, hwc_layer_t *layer,
// this needs to change to accomodate vertical stride
// if needed in the future
src.vert_padding = 0;
// Remove the srcBufferTransform if any
layer->transform = (layer->transform & FINAL_TRANSFORM_MASK);
// Copybit source rect
hwc_rect_t sourceCrop = layer->sourceCrop;

View File

@ -403,7 +403,8 @@ int overlay::initOverlay() {
Overlay::Overlay() : mChannelUP(false), mExternalDisplay(false),
mS3DFormat(0), mCroppedSrcWidth(0),
mCroppedSrcHeight(0), mState(-1) {
mCroppedSrcHeight(0), mState(-1),
mSrcOrientation(0) {
mOVBufferInfo.width = mOVBufferInfo.height = 0;
mOVBufferInfo.format = mOVBufferInfo.size = 0;
mOVBufferInfo.secure = false;
@ -472,7 +473,7 @@ bool Overlay::closeChannel() {
mOVBufferInfo.height = 0;
mOVBufferInfo.format = 0;
mOVBufferInfo.size = 0;
mOVBufferInfo.secure = false;
mSrcOrientation = 0;
mState = -1;
return true;
}
@ -521,8 +522,13 @@ bool Overlay::setPosition(int x, int y, uint32_t w, uint32_t h) {
mCroppedSrcWidth, mCroppedSrcHeight, mDevOrientation,
&priDest, &secDest);
} else {
objOvCtrlChannel[VG1_PIPE].getAspectRatioPosition(
mCroppedSrcWidth, mCroppedSrcHeight, &secDest);
int w = mCroppedSrcWidth, h = mCroppedSrcHeight;
if(mSrcOrientation == HAL_TRANSFORM_ROT_90 ||
mSrcOrientation == HAL_TRANSFORM_ROT_270) {
swapWidthHeight(w, h);
}
objOvCtrlChannel[VG1_PIPE].getAspectRatioPosition(w, h,
&secDest);
}
setChannelPosition(secDest.x, secDest.y, secDest.w, secDest.h,
VG1_PIPE);
@ -574,8 +580,7 @@ bool Overlay::setChannelPosition(int x, int y, uint32_t w, uint32_t h, int chann
return objOvCtrlChannel[channel].setPosition(x, y, w, h);
}
bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int orientation,
int flags) {
bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int flags) {
bool ret = false;
int currentFlags = 0;
@ -598,24 +603,10 @@ bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int orientati
return true;
}
// Disable rotation for the HDMI channels
int orientHdmi = 0;
int orientPrimary = sHDMIAsPrimary ? 0 : orientation;
int orient[2] = {orientPrimary, orientHdmi};
// disable waitForVsync on HDMI, since we call the wait ioctl
int ovFlagsExternal = 0;
int ovFlagsPrimary = sHDMIAsPrimary ? (flags |= WAIT_FOR_VSYNC): flags;
int ovFlags[2] = {flags, ovFlagsExternal};
switch(mState) {
case OV_3D_VIDEO_3D_PANEL:
orient[1] = sHDMIAsPrimary ? 0 : orientation;
break;
case OV_3D_VIDEO_3D_TV:
orient[0] = 0;
break;
default:
break;
}
int numChannelsToUpdate = NUM_CHANNELS;
if (!geometryChanged) {
@ -629,7 +620,7 @@ bool Overlay::updateOverlaySource(const overlay_buffer_info& info, int orientati
// Set the overlay source info
for (int i = 0; i < NUM_CHANNELS; i++) {
if (objOvCtrlChannel[i].isChannelUP()) {
ret = objOvCtrlChannel[i].updateOverlaySource(info, orient[i], ovFlags[i]);
ret = objOvCtrlChannel[i].updateOverlaySource(info, ovFlags[i]);
if (!ret) {
LOGE("objOvCtrlChannel[%d].updateOverlaySource failed", i);
return false;
@ -725,8 +716,6 @@ bool Overlay::setSource(const overlay_buffer_info& info, int orientation,
break;
case OV_2D_VIDEO_ON_TV:
if(isHDMIStateChange) {
//start only HDMI channel
noRot = true;
//DO NOT WAIT for VSYNC for external
flags &= ~WAIT_FOR_VSYNC;
// External display connected, start corresponding channel
@ -748,8 +737,13 @@ bool Overlay::setSource(const overlay_buffer_info& info, int orientation,
mCroppedSrcWidth, mCroppedSrcHeight, mDevOrientation,
&priDest, &secDest);
} else {
objOvCtrlChannel[VG1_PIPE].getAspectRatioPosition(
mCroppedSrcWidth, mCroppedSrcHeight, &secDest);
int w = mCroppedSrcWidth, h = mCroppedSrcHeight;
if(mSrcOrientation == HAL_TRANSFORM_ROT_90 ||
mSrcOrientation == HAL_TRANSFORM_ROT_270) {
swapWidthHeight(w, h);
}
objOvCtrlChannel[VG1_PIPE].getAspectRatioPosition(w, h,
&secDest);
}
return setChannelPosition(secDest.x, secDest.y, secDest.w, secDest.h, VG1_PIPE);
}
@ -759,8 +753,6 @@ bool Overlay::setSource(const overlay_buffer_info& info, int orientation,
fbnum = i;
//start two channels for one for primary and external.
if (fbnum) {
// Disable rotation for external
noRot = true;
//set fbnum to hdmiConnected, which holds the ext display
fbnum = hdmiConnected;
flags &= ~WAIT_FOR_VSYNC;
@ -789,7 +781,7 @@ bool Overlay::setSource(const overlay_buffer_info& info, int orientation,
break;
}
} else {
ret = updateOverlaySource(info, orientation, flags);
ret = updateOverlaySource(info, flags);
}
return true;
}
@ -848,13 +840,28 @@ bool Overlay::updateOverlayFlags(int flags) {
bool Overlay::setTransform(int value) {
int barrier = 0;
// To get the rotation info
int transform = value & FINAL_TRANSFORM_MASK;
int srcTransform = ((value & SRC_TRANSFORM_MASK) >> SHIFT_SRC_TRANSFORM);
mSrcOrientation = srcTransform;
switch (mState) {
case OV_UI_MIRROR_TV:
case OV_2D_VIDEO_ON_PANEL:
case OV_3D_VIDEO_2D_PANEL:
return objOvCtrlChannel[VG0_PIPE].setTransform(value);
return objOvCtrlChannel[VG0_PIPE].setTransform(transform);
break;
case OV_2D_VIDEO_ON_TV:
for (int i=0; i<NUM_CHANNELS; i++) {
//if its the secondary channel set orientation to be srcOrientation
if(i) // i - external display channel
transform = mSrcOrientation;
if(!objOvCtrlChannel[i].setTransform(transform)) {
LOGE("%s:failed for channel %d", __FUNCTION__, i);
return false;
}
}
break;
case OV_3D_VIDEO_2D_TV:
case OV_3D_VIDEO_3D_TV:
for (int i=0; i<NUM_CHANNELS; i++) {
@ -877,7 +884,7 @@ bool Overlay::setTransform(int value) {
LOGE("%s:failed to enable barriers for 3D video", __FUNCTION__);
}
for (int i=0; i<NUM_CHANNELS; i++) {
if(!objOvCtrlChannel[i].setTransform(value)) {
if(!objOvCtrlChannel[i].setTransform(transform)) {
LOGE("%s:failed for channel %d", __FUNCTION__, i);
return false;
}
@ -1373,7 +1380,7 @@ bool OverlayControlChannel::startOVRotatorSessions(
}
bool OverlayControlChannel::updateOverlaySource(const overlay_buffer_info& info,
int orientation, int flags)
int flags)
{
int colorFormat = getColorFormat(info.format);
int hw_format = get_mdp_format(colorFormat);
@ -1589,7 +1596,6 @@ bool OverlayControlChannel::setTransform(int value, bool fetch) {
return true;
int rot = value;
switch(rot) {
case 0:
case HAL_TRANSFORM_FLIP_H:
@ -1751,10 +1757,6 @@ bool OverlayControlChannel::getSize(int& size) const {
OverlayDataChannel::OverlayDataChannel() : mNoRot(false), mFD(-1), mRotFD(-1),
mPmemFD(-1), mPmemAddr(0), mUpdateDataChannel(false)
{
//XXX: getInstance(false) implies that it should only
// use the kernel allocator. Change it to something
// more descriptive later.
mAlloc = gralloc::IAllocController::getInstance(false);
}
OverlayDataChannel::~OverlayDataChannel() {
@ -1830,8 +1832,11 @@ bool OverlayDataChannel::mapRotatorMemory(int num_buffers, bool uiChannel, int r
if((requestType == NEW_REQUEST) && !uiChannel)
allocFlags |= GRALLOC_USAGE_PRIVATE_SMI_HEAP;
}
int err = mAlloc->allocate(data, allocFlags, 0);
//XXX: getInstance(false) implies that it should only
// use the kernel allocator. Change it to something
// more descriptive later.
android::sp<gralloc::IAllocController> allocController = gralloc::IAllocController::getInstance(false);
int err = allocController->allocate(data, allocFlags, 0);
if(err) {
reportError("Cant allocate rotatory memory");
close(mFD);
@ -1888,7 +1893,11 @@ bool OverlayDataChannel::closeDataChannel() {
return true;
if (!mNoRot && mRotFD > 0) {
sp<IMemAlloc> memalloc = mAlloc->getAllocator(mBufferType);
//XXX: getInstance(false) implies that it should only
// use the kernel allocator. Change it to something
// more descriptive later.
android::sp<gralloc::IAllocController> allocController = gralloc::IAllocController::getInstance(false);
sp<IMemAlloc> memalloc = allocController->getAllocator(mBufferType);
memalloc->free_buffer(mPmemAddr, mPmemOffset * mNumBuffers, 0, mPmemFD);
close(mPmemFD);
mPmemFD = -1;
@ -1943,7 +1952,11 @@ bool OverlayDataChannel::queueBuffer(uint32_t offset) {
// Unmap the old PMEM memory after the queueBuffer has returned
if (oldPmemFD != -1 && oldPmemAddr != MAP_FAILED) {
sp<IMemAlloc> memalloc = mAlloc->getAllocator(mBufferType);
//XXX: getInstance(false) implies that it should only
// use the kernel allocator. Change it to something
// more descriptive later.
android::sp<gralloc::IAllocController> allocController = gralloc::IAllocController::getInstance(false);
sp<IMemAlloc> memalloc = allocController->getAllocator(mBufferType);
memalloc->free_buffer(oldPmemAddr, oldPmemOffset * mNumBuffers, 0, oldPmemFD);
oldPmemFD = -1;
}

View File

@ -60,6 +60,13 @@
#define FRAMEBUFFER_0 0
#define FRAMEBUFFER_1 1
#define FRAMEBUFFER_2 2
// To extract the src buffer transform
#define SHIFT_SRC_TRANSFORM 4
#define SRC_TRANSFORM_MASK 0x00F0
#define FINAL_TRANSFORM_MASK 0x000F
#define NUM_SHARPNESS_VALS 256
#define SHARPNESS_RANGE 1.0f
#define HUE_RANGE 180
@ -332,7 +339,7 @@ public:
bool getAspectRatioPosition(int w, int h, int orientation,
overlay_rect *inRect, overlay_rect *outRect);
bool getPositionS3D(int channel, int format, overlay_rect *rect);
bool updateOverlaySource(const overlay_buffer_info& info, int orientation, int flags);
bool updateOverlaySource(const overlay_buffer_info& info, int flags);
bool getFormat() const { return mFormat; }
bool setVisualParam(int8_t paramType, float paramValue);
bool useVirtualFB ();
@ -356,7 +363,6 @@ class OverlayDataChannel {
int mCurrentItem;
int mNumBuffers;
bool mUpdateDataChannel;
android::sp<gralloc::IAllocController> mAlloc;
int mBufferType;
bool openDevices(int fbnum = -1, bool uichannel = false, int num_buffers = 2);
@ -399,6 +405,8 @@ class Overlay {
int mState;
// Stores the current device orientation
int mDevOrientation;
//Store the Actual buffer Orientation
int mSrcOrientation;
OverlayControlChannel objOvCtrlChannel[2];
OverlayDataChannel objOvDataChannel[2];
@ -437,7 +445,7 @@ private:
bool setChannelPosition(int x, int y, uint32_t w, uint32_t h, int channel = 0);
bool setChannelCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h, int channel);
bool queueBuffer(int fd, uint32_t offset, int channel);
bool updateOverlaySource(const overlay_buffer_info& info, int orientation, int flags);
bool updateOverlaySource(const overlay_buffer_info& info, int flags);
int getS3DFormat(int format);
};