overlay: Add support for enabling/disabling HDMI

Add support in the overlayLib to enable/disable and queue the buffers
to the primary or secondary based on the hdmi connected parameter.

Change-Id: Ie6c780e4076b0b84e6457a0503ec511ff2b8c452
This commit is contained in:
Naomi Luis 2011-03-07 17:41:08 -08:00 committed by Govind Surti
parent 5a1bf4cb9e
commit 9c8bc18f79
3 changed files with 148 additions and 67 deletions

View File

@ -199,6 +199,13 @@ public:
x, y, w, h);
}
bool getAspectRatioPosition(overlay_rect *rect, int channel) {
if (!mHandle.pobjControlChannel[channel])
return false;
return mHandle.pobjControlChannel[channel]->getAspectRatioPosition(mHandle.w,
mHandle.h, mHandle.format, rect);
}
bool setParameter(int param, int value, int channel) {
if (!mHandle.pobjControlChannel[channel])
return false;
@ -435,45 +442,12 @@ public:
return NULL;
}
else {
int width = w, height = h, x, y;
int fbWidthHDMI = overlay->getFBWidth(1);
int fbHeightHDMI = overlay->getFBHeight(1);
// width and height for YUV TILE format
int tempWidth = w, tempHeight = h;
/* Caculate the width and height if it is YUV TILE format*/
if(format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
tempWidth = w - ( (((w-1)/64 +1)*64) - w);
tempHeight = h - ((((h-1)/32 +1)*32) - h);
overlay_rect rect;
if(overlay->getAspectRatioPosition(&rect, 1)) {
if (!overlay->setPosition(rect.x, rect.y, rect.width, rect.height, 1)) {
LOGE("Failed to upscale for framebuffer 1");
}
}
if (width * fbHeightHDMI >
fbWidthHDMI * height) {
height = fbWidthHDMI * height / width;
EVEN_OUT(height);
width = fbWidthHDMI;
} else if (width * fbHeightHDMI <
fbWidthHDMI * height) {
width = fbHeightHDMI * width / height;
EVEN_OUT(width);
height = fbHeightHDMI;
} else {
width = fbWidthHDMI;
height = fbHeightHDMI;
}
/* Scaling of upto a max of 8 times supported */
if(width >(tempWidth * HW_OVERLAY_MAGNIFICATION_LIMIT)){
width = HW_OVERLAY_MAGNIFICATION_LIMIT * tempWidth;
}
if(height >(tempHeight*HW_OVERLAY_MAGNIFICATION_LIMIT)) {
height = HW_OVERLAY_MAGNIFICATION_LIMIT * tempHeight;
}
if (width > fbWidthHDMI) width = fbWidthHDMI;
if (height > fbHeightHDMI) height = fbHeightHDMI;
x = (fbWidthHDMI - width) / 2;
y = (fbHeightHDMI - height) / 2;
if (!overlay->setPosition(x, y, width, height, 1))
LOGE("Failed to upscale for framebuffer 1");
}
return overlay;

View File

@ -81,56 +81,97 @@ static void reportError(const char* message) {
using namespace overlay;
Overlay::Overlay() : mChannelUP(false) {
Overlay::Overlay() : mChannelUP(false), mHDMIConnected(false) {
}
Overlay::~Overlay() {
closeChannel();
}
int Overlay::getFBWidth() const {
return objOvCtrlChannel.getFBWidth();
int Overlay::getFBWidth(int channel) const {
return objOvCtrlChannel[channel].getFBWidth();
}
int Overlay::getFBHeight() const {
return objOvCtrlChannel.getFBHeight();
int Overlay::getFBHeight(int channel) const {
return objOvCtrlChannel[channel].getFBHeight();
}
bool Overlay::startChannel(int w, int h, int format, int fbnum, bool norot, bool uichannel, unsigned int format3D) {
mChannelUP = objOvCtrlChannel.startControlChannel(w, h, format, fbnum, norot, format3D);
mChannelUP = objOvCtrlChannel[0].startControlChannel(w, h, format, fbnum, norot, format3D);
if (!mChannelUP) {
LOGE("startChannel for fb0 failed");
return mChannelUP;
}
return objOvDataChannel.startDataChannel(objOvCtrlChannel, fbnum, norot, uichannel);
return objOvDataChannel[0].startDataChannel(objOvCtrlChannel[0], fbnum, norot, uichannel);
}
bool Overlay::startChannelHDMI(int w, int h, int format, bool norot) {
if(!mHDMIConnected) {
LOGE(" HDMI has been disabled - close the channel");
objOvCtrlChannel[1].closeControlChannel();
objOvDataChannel[1].closeDataChannel();
return true;
}
bool ret = startChannel(w, h, format, 0, norot);
if(ret) {
if (!objOvCtrlChannel[1].startControlChannel(w, h, format, 1, 1)) {
LOGE("Failed to start control channel for framebuffer 1");
objOvCtrlChannel[1].closeControlChannel();
return false;
} else {
if(!objOvDataChannel[1].startDataChannel(objOvCtrlChannel[1], 1, 1)) {
LOGE("Failed to start data channel for framebuffer 1");
return false;
}
overlay_rect rect;
if(objOvCtrlChannel[1].getAspectRatioPosition(w, h, format, &rect)) {
if(!objOvCtrlChannel[1].setPosition(rect.x, rect.y, rect.width, rect.height)) {
LOGE("Failed to upscale for framebuffer 1");
return false;
}
}
}
}
return ret;
}
bool Overlay::closeChannel() {
if (!mChannelUP)
return true;
objOvCtrlChannel.closeControlChannel();
objOvDataChannel.closeDataChannel();
objOvCtrlChannel[0].closeControlChannel();
objOvDataChannel[0].closeDataChannel();
objOvCtrlChannel[1].closeControlChannel();
objOvDataChannel[1].closeDataChannel();
mChannelUP = false;
return true;
}
bool Overlay::getPosition(int& x, int& y, uint32_t& w, uint32_t& h) {
return objOvCtrlChannel.getPosition(x, y, w, h);
return objOvCtrlChannel[0].getPosition(x, y, w, h);
}
bool Overlay::getOrientation(int& orientation) const {
return objOvCtrlChannel.getOrientation(orientation);
return objOvCtrlChannel[0].getOrientation(orientation);
}
bool Overlay::setPosition(int x, int y, uint32_t w, uint32_t h) {
return objOvCtrlChannel.setPosition(x, y, w, h);
return objOvCtrlChannel[0].setPosition(x, y, w, h);
}
bool Overlay::setSource(uint32_t w, uint32_t h, int format, int orientation) {
if (!objOvCtrlChannel.setSource(w, h, format, orientation)) {
objOvCtrlChannel.closeControlChannel();
objOvDataChannel.closeDataChannel();
bool Overlay::setSource(uint32_t w, uint32_t h, int format, int orientation, bool hdmiConnected) {
if ((hdmiConnected != mHDMIConnected) || !objOvCtrlChannel[0].setSource(w, h, format, orientation)) {
closeChannel();
mChannelUP = false;
return startChannel(w, h, format, 0, !orientation);
mHDMIConnected = hdmiConnected;
if (mHDMIConnected) {
return startChannelHDMI(w, h, format, !orientation);
} else {
return startChannel(w, h, format, 0, !orientation);
}
}
else
return true;
@ -139,23 +180,26 @@ bool Overlay::setSource(uint32_t w, uint32_t h, int format, int orientation) {
bool Overlay::setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h) {
if (!mChannelUP)
return false;
return objOvDataChannel.setCrop(x, y, w, h);
if(mHDMIConnected) {
objOvDataChannel[1].setCrop(x, y, w, h);
}
return objOvDataChannel[0].setCrop(x, y, w, h);
}
bool Overlay::setParameter(int param, int value) {
return objOvCtrlChannel.setParameter(param, value);
return objOvCtrlChannel[0].setParameter(param, value);
}
bool Overlay::setOrientation(int value) {
return objOvCtrlChannel.setParameter(OVERLAY_TRANSFORM, value);
return objOvCtrlChannel[0].setParameter(OVERLAY_TRANSFORM, value);
}
bool Overlay::setFd(int fd) {
return objOvDataChannel.setFd(fd);
return objOvDataChannel[0].setFd(fd);
}
bool Overlay::queueBuffer(uint32_t offset) {
return objOvDataChannel.queueBuffer(offset);
return objOvDataChannel[0].queueBuffer(offset);
}
bool Overlay::queueBuffer(buffer_handle_t buffer) {
@ -163,7 +207,17 @@ bool Overlay::queueBuffer(buffer_handle_t buffer) {
<private_handle_t const*>(buffer);
const size_t offset = hnd->offset;
const int fd = hnd->fd;
if (setFd(fd)) {
bool ret = true;
if(mHDMIConnected) {
ret = objOvDataChannel[1].setFd(fd);
if(!ret) {
reportError("Overlay::queueBuffer channel 1 setFd failed");
return false;
}
ret = objOvDataChannel[1].queueBuffer(offset);
}
if (ret && setFd(fd)) {
return queueBuffer(offset);
}
return false;
@ -179,6 +233,48 @@ OverlayControlChannel::~OverlayControlChannel() {
closeControlChannel();
}
bool OverlayControlChannel::getAspectRatioPosition(int w, int h, int format, overlay_rect *rect)
{
int width = w, height = h, x, y;
int fbWidthHDMI = getFBWidth();
int fbHeightHDMI = getFBHeight();
// width and height for YUV TILE format
int tempWidth = w, tempHeight = h;
/* Calculate the width and height if it is YUV TILE format*/
if(format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
tempWidth = w - ( (((w-1)/64 +1)*64) - w);
tempHeight = h - ((((h-1)/32 +1)*32) - h);
}
if (width * fbHeightHDMI > fbWidthHDMI * height) {
height = fbWidthHDMI * height / width;
EVEN_OUT(height);
width = fbWidthHDMI;
} else if (width * fbHeightHDMI < fbWidthHDMI * height) {
width = fbHeightHDMI * width / height;
EVEN_OUT(width);
height = fbHeightHDMI;
} else {
width = fbWidthHDMI;
height = fbHeightHDMI;
}
/* Scaling of upto a max of 8 times supported */
if(width >(tempWidth * HW_OVERLAY_MAGNIFICATION_LIMIT)){
width = HW_OVERLAY_MAGNIFICATION_LIMIT * tempWidth;
}
if(height >(tempHeight*HW_OVERLAY_MAGNIFICATION_LIMIT)) {
height = HW_OVERLAY_MAGNIFICATION_LIMIT * tempHeight;
}
if (width > fbWidthHDMI) width = fbWidthHDMI;
if (height > fbHeightHDMI) height = fbHeightHDMI;
x = (fbWidthHDMI - width) / 2;
y = (fbHeightHDMI - height) / 2;
rect->x = x;
rect->y = y;
rect->width = width;
rect->height = height;
return true;
}
bool OverlayControlChannel::openDevices(int fbnum) {
if (fbnum < 0)
return false;

View File

@ -70,6 +70,13 @@
namespace overlay {
struct overlay_rect {
int x;
int y;
int width;
int height;
};
class OverlayControlChannel {
bool mNoRot;
@ -110,6 +117,7 @@ public:
int getFormat3D() const { return mFormat3D; }
bool getOrientation(int& orientation) const;
bool setSource(uint32_t w, uint32_t h, int format, int orientation);
bool getAspectRatioPosition(int w, int h, int format, overlay_rect *rect);
};
class OverlayDataChannel {
@ -147,9 +155,10 @@ public:
class Overlay {
bool mChannelUP;
bool mHDMIConnected;
OverlayControlChannel objOvCtrlChannel;
OverlayDataChannel objOvDataChannel;
OverlayControlChannel objOvCtrlChannel[2];
OverlayDataChannel objOvDataChannel[2];
public:
Overlay();
@ -165,17 +174,19 @@ public:
bool queueBuffer(uint32_t offset);
bool getPosition(int& x, int& y, uint32_t& w, uint32_t& h);
bool isChannelUP() const { return mChannelUP; }
int getFBWidth() const;
int getFBHeight() const;
int getFBWidth(int channel = 0) const;
int getFBHeight(int channel = 0) const;
bool getOrientation(int& orientation) const;
bool queueBuffer(buffer_handle_t buffer);
bool setSource(uint32_t w, uint32_t h, int format, int orientation);
bool setSource(uint32_t w, uint32_t h, int format, int orientation, bool hdmiConnected);
bool setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h);
private:
bool startChannelHDMI(int w, int h, int format, bool norot);
};
struct overlay_shared_data {
int readyToQueue;
};
};
#endif