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:
parent
1e2be7b5b0
commit
7015a91bc8
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user