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:
parent
5a1bf4cb9e
commit
9c8bc18f79
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user