framebuffer: Remove extraneous update on HDMI

HDMI should be updated only in conjunction with primary.
Which means on a resume from suspend (which is treated as
cable connect in HALs) we need not draw ahead of primary.

A good way (already existing) is to call invalidate() on SF
on cable connect so that primary is updated and only then HDMI,
by a trigger from disp_loop thread.

Change-Id: I7d5268b2f0e27adb04aade757c36483cdfc1333e
CRs-fixed: 335763

Conflicts:

	libgralloc/framebuffer.cpp
	libhwcomposer/hwcomposer.cpp
This commit is contained in:
Saurabh Shah 2012-05-08 14:58:29 -07:00 committed by Andrew Sutherland
parent 1e2be7b5b0
commit 7015a91bc8
2 changed files with 92 additions and 82 deletions

View File

@ -210,14 +210,6 @@ static void *disp_loop(void *ptr)
}
#if defined(HDMI_DUAL_DISPLAY)
static int closeHDMIChannel(private_module_t* m)
{
Overlay* pTemp = m->pobjOverlay;
if(pTemp != NULL)
pTemp->closeChannel();
return 0;
}
static void getSecondaryDisplayDestinationInfo(private_module_t* m, overlay_rect&
rect, int& orientation)
{
@ -260,6 +252,77 @@ static void getSecondaryDisplayDestinationInfo(private_module_t* m, overlay_rect
return;
}
static int closeExternalChannel(private_module_t *m)
{
Overlay* pTemp = m->pobjOverlay;
if(pTemp != NULL)
pTemp->closeChannel();
return 0;
}
static int startExternalChannel(private_module_t *m)
{
Overlay *pTemp = m->pobjOverlay;
bool success = true;
int flags = WAIT_FOR_VSYNC;
if (!pTemp->isChannelUP()) {
int alignedW = ALIGN(m->info.xres, 32);
private_handle_t const* hnd =
reinterpret_cast<private_handle_t const*>(m->framebuffer);
overlay_buffer_info info;
info.width = alignedW;
info.height = hnd->height;
info.format = hnd->format;
info.size = hnd->size;
if (m->trueMirrorSupport)
flags &= ~WAIT_FOR_VSYNC;
// External display connected during secure video playback
// Open secure UI session
// NOTE: when external display is already connected and then secure
// playback is started, we dont have to do anything
if(m->secureVideoOverlay)
flags |= SECURE_OVERLAY_SESSION;
// start the overlay Channel for mirroring
// m->enableHDMIOutput corresponds to the fbnum
success = pTemp->startChannel(info, m->enableHDMIOutput,
false, true, 0, VG0_PIPE, flags) &&
pTemp->setFd(m->framebuffer->fd) &&
pTemp->setCrop(0, 0, m->info.xres, m->info.yres);
}
overlay_rect destRect;
int rot = 0;
int currOrientation = 0;
int currentX = 0, currentY = 0;
uint32_t currentW = 0, currentH = 0;
getSecondaryDisplayDestinationInfo(m, destRect, rot);
pTemp->getOrientation(currOrientation);
if(rot != currOrientation) {
success &= pTemp->setTransform(rot);
}
pTemp->getPosition(currentX, currentY, currentW, currentH);
if ((currentX != destRect.x) || (currentY != destRect.y) ||
(currentW != destRect.w) || (currentH != destRect.h)) {
success &= pTemp->setPosition(destRect.x, destRect.y, destRect.w,
destRect.h);
}
if (m->trueMirrorSupport) {
// if video is started the UI channel should be NO_WAIT.
flags = !m->videoOverlay ? WAIT_FOR_VSYNC : 0;
pTemp->updateOverlayFlags(flags);
}
return success ? 0 : -1;
}
static void *hdmi_ui_loop(void *ptr)
{
private_module_t* m = reinterpret_cast<private_module_t*>(
@ -273,74 +336,13 @@ static void *hdmi_ui_loop(void *ptr)
pthread_mutex_unlock(&m->overlayLock);
return NULL;
}
bool waitForVsync = true;
int flags = WAIT_FOR_VSYNC;
if (m->pobjOverlay) {
Overlay* pTemp = m->pobjOverlay;
if (m->hdmiMirroringState == HDMI_NO_MIRRORING)
closeHDMIChannel(m);
else if(m->hdmiMirroringState == HDMI_UI_MIRRORING) {
if (!pTemp->isChannelUP()) {
int alignedW = ALIGN(m->info.xres, 32);
private_handle_t const* hnd =
reinterpret_cast<private_handle_t const*>(m->framebuffer);
overlay_buffer_info info;
info.width = alignedW;
info.height = hnd->height;
info.format = hnd->format;
info.size = hnd->size;
if (m->trueMirrorSupport)
flags &= ~WAIT_FOR_VSYNC;
// External display connected during secure video playback
// Open secure UI session
// NOTE: when external display is already connected and then secure
// playback is started, we dont have to do anything
if(m->secureVideoOverlay)
flags |= SECURE_OVERLAY_SESSION;
// start the overlay Channel for mirroring
// m->enableHDMIOutput corresponds to the fbnum
if (pTemp->startChannel(info, m->enableHDMIOutput,
false, true, 0, VG0_PIPE, flags)) {
pTemp->setFd(m->framebuffer->fd);
pTemp->setCrop(0, 0, m->info.xres, m->info.yres);
} else
closeHDMIChannel(m);
}
if (pTemp->isChannelUP()) {
overlay_rect destRect;
int rot = 0;
int currOrientation = 0;
getSecondaryDisplayDestinationInfo(m, destRect, rot);
pTemp->getOrientation(currOrientation);
if(rot != currOrientation) {
pTemp->setTransform(rot);
}
EVEN_OUT(destRect.x);
EVEN_OUT(destRect.y);
EVEN_OUT(destRect.w);
EVEN_OUT(destRect.h);
int currentX = 0, currentY = 0;
uint32_t currentW = 0, currentH = 0;
if (pTemp->getPosition(currentX, currentY, currentW, currentH)) {
if ((currentX != destRect.x) || (currentY != destRect.y) ||
(currentW != destRect.w) || (currentH != destRect.h)) {
pTemp->setPosition(destRect.x, destRect.y, destRect.w,
destRect.h);
}
}
if (m->trueMirrorSupport) {
// if video is started the UI channel should be NO_WAIT.
flags = !m->videoOverlay ? WAIT_FOR_VSYNC : 0;
pTemp->updateOverlayFlags(flags);
}
pTemp->queueBuffer(m->currentOffset);
}
const int NO_ERROR = 0;
Overlay* pTemp = m->pobjOverlay;
if(m->hdmiMirroringState == HDMI_UI_MIRRORING) {
if (startExternalChannel(m) == NO_ERROR) {
pTemp->queueBuffer(m->currentOffset);
}
else
closeHDMIChannel(m);
}
pthread_mutex_unlock(&m->overlayLock);
}
@ -359,7 +361,7 @@ static int fb_videoOverlayStarted(struct framebuffer_device_t* dev, int started)
m->hdmiStateChanged = true;
if (started && pTemp) {
m->hdmiMirroringState = HDMI_NO_MIRRORING;
closeHDMIChannel(m);
closeExternalChannel(m);
} else if (m->enableHDMIOutput)
m->hdmiMirroringState = HDMI_UI_MIRRORING;
pthread_cond_signal(&(m->overlayPost));
@ -388,10 +390,11 @@ static int fb_enableHDMIOutput(struct framebuffer_device_t* dev, int externaltyp
}
} else if (!externaltype && pTemp) {
m->hdmiMirroringState = HDMI_NO_MIRRORING;
closeHDMIChannel(m);
closeExternalChannel(m);
}
if(m->hdmiMirroringState == HDMI_UI_MIRRORING) {
startExternalChannel(m);
}
m->hdmiStateChanged = true;
pthread_cond_signal(&(m->overlayPost));
pthread_mutex_unlock(&m->overlayLock);
return 0;
}
@ -410,7 +413,7 @@ static int handle_open_secure_start(private_module_t* m) {
pthread_mutex_lock(&m->overlayLock);
m->hdmiMirroringState = HDMI_NO_MIRRORING;
m->secureVideoOverlay = true;
closeHDMIChannel(m);
closeExternalChannel(m);
pthread_mutex_unlock(&m->overlayLock);
return 0;
}
@ -434,7 +437,7 @@ static int handle_close_secure_start(private_module_t* m) {
pthread_mutex_lock(&m->overlayLock);
m->hdmiMirroringState = HDMI_NO_MIRRORING;
m->secureVideoOverlay = false;
closeHDMIChannel(m);
closeExternalChannel(m);
pthread_mutex_unlock(&m->overlayLock);
return 0;
}

View File

@ -100,6 +100,7 @@ struct hwc_context_t {
#if defined HDMI_DUAL_DISPLAY
external_display_type mHDMIEnabled; // Type of external display
bool pendingHDMI;
bool forceComposition; //Used to force composition on HDMI connection.
#endif
int previousLayerCount;
eHWCOverlayStatus hwcOverlayStatus;
@ -831,6 +832,13 @@ bool canSkipComposition(hwc_context_t* ctx, int yuvBufferCount, int currentLayer
return false;
}
#if defined HDMI_DUAL_DISPLAY
if(ctx->forceComposition) {
ctx->forceComposition = false;
return false;
}
#endif
hwc_composer_device_t* dev = (hwc_composer_device_t *)(ctx);
private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
dev->common.module);
@ -898,8 +906,6 @@ static void handleHDMIStateChange(hwc_composer_device_t *dev, int externaltype)
if (fbDev) {
fbDev->perform(fbDev, EVENT_EXTERNAL_DISPLAY, externaltype);
}
// Yield - Allows the UI channel(with zorder 0) to be opened first
sched_yield();
if(ctx && ctx->mOverlayLibObject) {
overlay::Overlay *ovLibObject = ctx->mOverlayLibObject;
if (!externaltype) {
@ -1719,6 +1725,7 @@ static int hwc_set(hwc_composer_device_t *dev,
* Used when the video is paused and external
* display is connected
*/
ctx->forceComposition = true;
proc->invalidate(proc);
}
}