Bypass: Turn off only after FB content is displayed.
Synchronize turning off of composition bypass with display, so that close happens only after FB content is displayed. This fixes blinks observed when bypass needs to be turned off, for reasons other than video content. Change-Id: Id98bddd0cb2a89ea8729a188934ae1cd947cf305
This commit is contained in:
parent
599d9a41bc
commit
f2dbabe786
@ -45,8 +45,8 @@ ifeq ($(TARGET_HAVE_HDMI_OUT),true)
|
||||
LOCAL_SHARED_LIBRARIES += liboverlay
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_USES_SF_BYPASS),true)
|
||||
LOCAL_CFLAGS += -DSF_BYPASS
|
||||
ifeq ($(TARGET_HAVE_BYPASS),true)
|
||||
LOCAL_CFLAGS += -DCOMPOSITION_BYPASS
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_GRALLOC_USES_ASHMEM),true)
|
||||
|
@ -319,7 +319,7 @@ static void *disp_loop(void *ptr)
|
||||
pthread_mutex_lock(&(m->qlock));
|
||||
|
||||
// wait (sleep) while display queue is empty;
|
||||
if (m->disp.isEmpty()) {
|
||||
while (m->disp.isEmpty()) {
|
||||
pthread_cond_wait(&(m->qpost),&(m->qlock));
|
||||
}
|
||||
|
||||
@ -347,6 +347,14 @@ static void *disp_loop(void *ptr)
|
||||
LOGE("ERROR FBIOPUT_VSCREENINFO failed; frame not displayed");
|
||||
}
|
||||
|
||||
#if defined COMPOSITION_BYPASS
|
||||
//Signal so that we can close channels if we need to
|
||||
pthread_mutex_lock(&m->bufferPostLock);
|
||||
m->bufferPostDone = true;
|
||||
pthread_cond_signal(&m->bufferPostCond);
|
||||
pthread_mutex_unlock(&m->bufferPostLock);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_CALC_FPS
|
||||
if (debug_fps_level > 0) calc_fps(ns2us(systemTime()));
|
||||
#endif
|
||||
@ -599,6 +607,34 @@ static int fb_orientationChanged(struct framebuffer_device_t* dev, int orientati
|
||||
}
|
||||
#endif
|
||||
|
||||
//Wait until framebuffer content is displayed.
|
||||
//This is called in the context of threadLoop.
|
||||
//Display loop wakes this up after display.
|
||||
static int fb_waitForBufferPost(struct framebuffer_device_t* dev)
|
||||
{
|
||||
#if defined COMPOSITION_BYPASS
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
dev->common.module);
|
||||
pthread_mutex_lock(&m->bufferPostLock);
|
||||
while(m->bufferPostDone == false) {
|
||||
pthread_cond_wait(&(m->bufferPostCond), &(m->bufferPostLock));
|
||||
}
|
||||
pthread_mutex_unlock(&m->bufferPostLock);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fb_resetBufferPostStatus(struct framebuffer_device_t* dev)
|
||||
{
|
||||
#if defined COMPOSITION_BYPASS
|
||||
private_module_t* m = reinterpret_cast<private_module_t*>(
|
||||
dev->common.module);
|
||||
pthread_mutex_lock(&m->bufferPostLock);
|
||||
m->bufferPostDone = false;
|
||||
pthread_mutex_unlock(&m->bufferPostLock);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
|
||||
{
|
||||
if (private_handle_t::validate(buffer) < 0)
|
||||
@ -990,6 +1026,11 @@ int mapFrameBufferLocked(struct private_module_t* module)
|
||||
pthread_t hdmiUIThread;
|
||||
pthread_create(&hdmiUIThread, NULL, &hdmi_ui_loop, (void *) module);
|
||||
#endif
|
||||
#if defined COMPOSITION_BYPASS
|
||||
pthread_mutex_init(&(module->bufferPostLock), NULL);
|
||||
pthread_cond_init(&(module->bufferPostCond), NULL);
|
||||
module->bufferPostDone = false;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1053,6 +1094,11 @@ int fb_device_open(hw_module_t const* module, const char* name,
|
||||
dev->device.setActionSafeHeightRatio = fb_setActionSafeHeightRatio;
|
||||
#endif
|
||||
|
||||
#if defined COMPOSITION_BYPASS
|
||||
dev->device.waitForBufferPost = fb_waitForBufferPost;
|
||||
dev->device.resetBufferPostStatus = fb_resetBufferPostStatus;
|
||||
#endif
|
||||
|
||||
private_module_t* m = (private_module_t*)module;
|
||||
status = mapFrameBuffer(m);
|
||||
if (status >= 0) {
|
||||
|
@ -260,6 +260,11 @@ struct private_module_t {
|
||||
pthread_mutex_t overlayLock;
|
||||
pthread_cond_t overlayPost;
|
||||
#endif
|
||||
#ifdef COMPOSITION_BYPASS
|
||||
pthread_mutex_t bufferPostLock;
|
||||
pthread_cond_t bufferPostCond;
|
||||
bool bufferPostDone;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1091,6 +1091,9 @@ static int hwc_set(hwc_composer_device_t *dev,
|
||||
|
||||
private_hwc_module_t* hwcModule = reinterpret_cast<private_hwc_module_t*>(
|
||||
dev->common.module);
|
||||
|
||||
framebuffer_device_t *fbDev = hwcModule->fbDevice;
|
||||
|
||||
if (!list || !hwcModule) {
|
||||
LOGE("hwc_set invalid list or module");
|
||||
#ifdef COMPOSITION_BYPASS
|
||||
@ -1124,16 +1127,29 @@ static int hwc_set(hwc_composer_device_t *dev,
|
||||
storeLockedBypassHandle(list, ctx);
|
||||
// We have stored the handles, unset the current lock states in the context.
|
||||
unsetBypassBufferLockState(ctx);
|
||||
|
||||
//Setup for waiting until 1 FB post is done before closing bypass mode.
|
||||
if (ctx->bypassState == BYPASS_OFF_PENDING) {
|
||||
fbDev->resetBufferPostStatus(fbDev);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Do not call eglSwapBuffers if we the skip composition flag is set on the list.
|
||||
if (!(list->flags & HWC_SKIP_COMPOSITION)) {
|
||||
EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
|
||||
if (!sucess) {
|
||||
ret = HWC_EGL_ERROR;
|
||||
LOGE("eglSwapBuffers() failed in %s", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
#ifdef COMPOSITION_BYPASS
|
||||
if(ctx->bypassState == BYPASS_OFF_PENDING) {
|
||||
//Close channels only after fb content is displayed.
|
||||
//We have already reset status before eglSwapBuffers.
|
||||
if (!(list->flags & HWC_SKIP_COMPOSITION)) {
|
||||
fbDev->waitForBufferPost(fbDev);
|
||||
}
|
||||
|
||||
closeBypass(ctx);
|
||||
ctx->bypassState = BYPASS_OFF;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user