From 7015a91bc83b68e6df618b877a8e190f52351170 Mon Sep 17 00:00:00 2001 From: Saurabh Shah Date: Tue, 8 May 2012 14:58:29 -0700 Subject: [PATCH] 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 --- libgralloc/framebuffer.cpp | 163 ++++++++++++++++++----------------- libhwcomposer/hwcomposer.cpp | 11 ++- 2 files changed, 92 insertions(+), 82 deletions(-) diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp index dd8994e..73d2143 100644 --- a/libgralloc/framebuffer.cpp +++ b/libgralloc/framebuffer.cpp @@ -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(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( @@ -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(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; } diff --git a/libhwcomposer/hwcomposer.cpp b/libhwcomposer/hwcomposer.cpp index 2dec501..bd5771f 100644 --- a/libhwcomposer/hwcomposer.cpp +++ b/libhwcomposer/hwcomposer.cpp @@ -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( 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); } }