/* * Swap handler. * Called from the swap chain work queue handler. * There is no need to take the swap chain creation lock in here, or use * some other method of stopping the swap chain from being destroyed. * This is because the swap chain creation lock is taken when queueing work, * and the work queue is flushed before the swap chain is destroyed. */ static void DC_SUNXISwapHandler(DC_SUNXI_BUFFER *psBuffer) { DC_SUNXI_DEVINFO *psDevInfo = psBuffer->psDevInfo; DC_SUNXI_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; bool bPreviouslyNotVSynced; DC_SUNXIFlip(psDevInfo, psBuffer); bPreviouslyNotVSynced = psSwapChain->bNotVSynced; psSwapChain->bNotVSynced = true; if (!DontWaitForVSync(psDevInfo)) { psSwapChain->bNotVSynced = false; if (bPreviouslyNotVSynced) { psSwapChain->bNotVSynced = !WaitForVSyncSettle(psDevInfo); } else if (psBuffer->ulSwapInterval != 0) { psSwapChain->bNotVSynced = IMG_FALSE; } } psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psBuffer->hCmdComplete, IMG_TRUE); }
static OMAPLFB_BOOL WaitForVSyncSettle(OMAPLFB_DEVINFO *psDevInfo) { unsigned i; for(i = 0; i < OMAPLFB_VSYNC_SETTLE_COUNT; i++) { if (DontWaitForVSync(psDevInfo) || !OMAPLFBWaitForVSync(psDevInfo)) { return OMAPLFB_FALSE; } } return OMAPLFB_TRUE; }
/* * Called after the screen has unblanked, or after any other occasion * when we didn't wait for vsync, but now need to. Not doing this after * unblank leads to screen jitter on some screens. * Returns true if the screen has been deemed to have settled. */ static bool WaitForVSyncSettle(DC_SUNXI_DEVINFO *psDevInfo) { unsigned int i; for(i = 0; i < DC_SUNXI_VSYNC_SETTLE_COUNT; i++) { if (DontWaitForVSync(psDevInfo)) { return false; } } return true; }
void OMAPLFBSwapHandler(OMAPLFB_BUFFER *psBuffer) { OMAPLFB_DEVINFO *psDevInfo = psBuffer->psDevInfo; OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; OMAPLFB_BOOL bPreviouslyNotVSynced; #if defined(SUPPORT_DRI_DRM) if (!OMAPLFBAtomicBoolRead(&psDevInfo->sLeaveVT)) #endif { OMAPLFBFlip(psDevInfo, psBuffer); } bPreviouslyNotVSynced = psSwapChain->bNotVSynced; psSwapChain->bNotVSynced = OMAPLFB_TRUE; if (!DontWaitForVSync(psDevInfo)) { OMAPLFB_UPDATE_MODE eMode = OMAPLFBGetUpdateMode(psDevInfo); int iBlankEvents = OMAPLFBAtomicIntRead(&psDevInfo->sBlankEvents); switch(eMode) { case OMAPLFB_UPDATE_MODE_AUTO: psSwapChain->bNotVSynced = OMAPLFB_FALSE; if (bPreviouslyNotVSynced || psSwapChain->iBlankEvents != iBlankEvents) { psSwapChain->iBlankEvents = iBlankEvents; psSwapChain->bNotVSynced = !WaitForVSyncSettle(psDevInfo); } else if (psBuffer->ulSwapInterval != 0) { psSwapChain->bNotVSynced = !OMAPLFBWaitForVSync(psDevInfo); } break; #if defined(PVR_OMAPFB3_MANUAL_UPDATE_SYNC_IN_SWAP) case OMAPLFB_UPDATE_MODE_MANUAL: if (psBuffer->ulSwapInterval != 0) { (void) OMAPLFBManualSync(psDevInfo); } break; #endif default: break; } } psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psBuffer->hCmdComplete, IMG_TRUE); }