Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
framebuffer: Remove extraneous update on HDMI
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Saurabh Shah authored and Linux Build Service Account committed May 13, 2012
1 parent b27f92a commit dafdd9a
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 82 deletions.
163 changes: 83 additions & 80 deletions libgralloc/framebuffer.cpp
Expand Up @@ -217,14 +217,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)
{
Expand Down Expand Up @@ -267,6 +259,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;
}

#ifdef USE_OVERLAY2
/* Determine overlay state based on whether hardware supports true UI
mirroring and whether video is playing or not */
Expand Down Expand Up @@ -450,74 +513,13 @@ static void *hdmi_ui_loop(void *ptr)
setOverlayState(ovutils::OV_CLOSED);
}
#else
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);
}
#endif // USE_OVERLAY2
pthread_mutex_unlock(&m->overlayLock);
Expand All @@ -541,7 +543,7 @@ static int fb_videoOverlayStarted(struct framebuffer_device_t* dev, int started)
ovutils::eOverlayState state = getOverlayState(m);
setOverlayState(state);
#else
closeHDMIChannel(m);
closeExternalChannel(m);
#endif
} else if (m->enableHDMIOutput)
m->hdmiMirroringState = HDMI_UI_MIRRORING;
Expand Down Expand Up @@ -579,11 +581,12 @@ static int fb_enableHDMIOutput(struct framebuffer_device_t* dev, int externaltyp
ovutils::eOverlayState state = getOverlayState(m);
setOverlayState(state);
#else
closeHDMIChannel(m);
closeExternalChannel(m);
#endif
}
m->hdmiStateChanged = true;
pthread_cond_signal(&(m->overlayPost));
if(m->hdmiMirroringState == HDMI_UI_MIRRORING) {
startExternalChannel(m);
}
pthread_mutex_unlock(&m->overlayLock);
return 0;
}
Expand All @@ -602,7 +605,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;
}
Expand All @@ -626,7 +629,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;
}
Expand Down
11 changes: 9 additions & 2 deletions libhwcomposer/hwcomposer.cpp
Expand Up @@ -115,6 +115,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;
Expand Down Expand Up @@ -1144,6 +1145,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);
Expand Down Expand Up @@ -1222,8 +1230,6 @@ static void handleHDMIStateChange(hwc_composer_device_t *dev, int externaltype)
}
#ifndef USE_OVERLAY2
hwc_context_t* ctx = (hwc_context_t*)(dev);
// 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) {
Expand Down Expand Up @@ -2211,6 +2217,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);
}
}
Expand Down

0 comments on commit dafdd9a

Please sign in to comment.