static void FlushInternalVSyncQueue(S3C_LCD_DEVINFO*psDevInfo) { S3C_VSYNC_FLIP_ITEM* psFlipItem; S3C_DisableVSyncInterrupt(); psFlipItem = &psDevInfo->asVSyncFlips[psDevInfo->ulRemoveIndex]; while(psFlipItem->bValid) { if(psFlipItem->bFlipped ==S3C_FALSE) { S3C_Flip (psDevInfo, psFlipItem->psFb); } if(psFlipItem->bCmdCompleted == S3C_FALSE) { psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, IMG_FALSE); } AdvanceFlipIndex(psDevInfo, &psDevInfo->ulRemoveIndex); psFlipItem->bFlipped = S3C_FALSE; psFlipItem->bCmdCompleted = S3C_FALSE; psFlipItem->bValid = S3C_FALSE; psFlipItem = &psDevInfo->asVSyncFlips[psDevInfo->ulRemoveIndex]; } psDevInfo->ulInsertIndex = 0; psDevInfo->ulRemoveIndex = 0; S3C_EnableVSyncInterrupt(); }
static IMG_BOOL ProcessFlip(IMG_HANDLE hCmdCookie, IMG_UINT32 ui32DataSize, IMG_VOID *pvData) { DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; S3C_LCD_DEVINFO *psDevInfo; S3C_FRAME_BUFFER *fb; S3C_VSYNC_FLIP_ITEM* psFlipItem; if(!hCmdCookie || !pvData) { return IMG_FALSE; } psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)pvData; if (psFlipCmd == IMG_NULL || sizeof(DISPLAYCLASS_FLIP_COMMAND) != ui32DataSize) { return IMG_FALSE; } psDevInfo = (S3C_LCD_DEVINFO*)psFlipCmd->hExtDevice; fb = (S3C_FRAME_BUFFER*)psFlipCmd->hExtBuffer; if (psDevInfo->bFlushCommands) { psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete(hCmdCookie, IMG_FALSE); return IMG_TRUE; } if(psFlipCmd->ui32SwapInterval == 0) { S3C_Flip(psDevInfo, fb); psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete(hCmdCookie, IMG_FALSE); return IMG_TRUE; } mutex_lock(&psDevInfo->sVsyncFlipItemMutex); psFlipItem = &psDevInfo->asVSyncFlips[psDevInfo->ulInsertIndex]; if(!psFlipItem->bValid) { if(psDevInfo->ulInsertIndex == psDevInfo->ulRemoveIndex) { S3C_Flip(psDevInfo, fb); psFlipItem->bFlipped = S3C_TRUE; } else { psFlipItem->bFlipped = S3C_FALSE; } psFlipItem->hCmdComplete = hCmdCookie; psFlipItem->psFb= fb; psFlipItem->ulSwapInterval = (unsigned long)psFlipCmd->ui32SwapInterval; psFlipItem->bValid = S3C_TRUE; AdvanceFlipIndex(psDevInfo, &psDevInfo->ulInsertIndex); mutex_unlock(&psDevInfo->sVsyncFlipItemMutex); return IMG_TRUE; } mutex_unlock(&psDevInfo->sVsyncFlipItemMutex); return IMG_FALSE; }
static void VsyncWorkqueueFunc(struct work_struct *psWork) { S3C_VSYNC_FLIP_ITEM *psFlipItem; S3C_LCD_DEVINFO *psDevInfo = container_of(psWork, S3C_LCD_DEVINFO, sWork); if(psDevInfo == NULL) { return; } mutex_lock(&psDevInfo->sVsyncFlipItemMutex); psFlipItem = &psDevInfo->asVSyncFlips[psDevInfo->ulRemoveIndex]; while(psFlipItem->bValid) { if(psFlipItem->bFlipped) { if(!psFlipItem->bCmdCompleted) { IMG_BOOL bScheduleMISR; #if 0 bScheduleMISR = IMG_TRUE; #else bScheduleMISR = IMG_FALSE; #endif psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, bScheduleMISR); psFlipItem->bCmdCompleted = S3C_TRUE; } psFlipItem->ulSwapInterval--; if(psFlipItem->ulSwapInterval == 0) { AdvanceFlipIndex(psDevInfo, &psDevInfo->ulRemoveIndex); psFlipItem->bCmdCompleted = S3C_FALSE; psFlipItem->bFlipped = S3C_FALSE; psFlipItem->bValid = S3C_FALSE; } else { break; } } else { S3C_Flip (psDevInfo, psFlipItem->psFb); psFlipItem->bFlipped = S3C_TRUE; break; } psFlipItem = &psDevInfo->asVSyncFlips[psDevInfo->ulRemoveIndex]; } mutex_unlock(&psDevInfo->sVsyncFlipItemMutex); }
static irqreturn_t S3C_VSyncISR(int irq, void *dev_id) { S3C_LCD_DEVINFO *psDevInfo = g_psLCDInfo; S3C_VSYNC_FLIP_ITEM *psFlipItem; S3C_Clear_interrupt(); if(psDevInfo == NULL) goto Handled; S3C_DisableVSyncInterrupt(); if(!psDevInfo->psSwapChain) { S3C_EnableVSyncInterrupt(); goto Handled; } psFlipItem = &psDevInfo->asVSyncFlips[psDevInfo->ulRemoveIndex]; while(psFlipItem->bValid) { if(psFlipItem->bFlipped) { if(!psFlipItem->bCmdCompleted) { IMG_BOOL bScheduleMISR; #if 1 bScheduleMISR = IMG_TRUE; #else bScheduleMISR = IMG_FALSE; #endif psDevInfo->sPVRJTable.pfnPVRSRVCmdComplete((IMG_HANDLE)psFlipItem->hCmdComplete, bScheduleMISR); psFlipItem->bCmdCompleted = S3C_TRUE; } psFlipItem->ulSwapInterval--; if(psFlipItem->ulSwapInterval == 0) { AdvanceFlipIndex(psDevInfo, &psDevInfo->ulRemoveIndex); psFlipItem->bCmdCompleted = S3C_FALSE; psFlipItem->bFlipped = S3C_FALSE; psFlipItem->bValid = S3C_FALSE; } else { break; } } else { S3C_Flip (psDevInfo, psFlipItem->psFb); psFlipItem->bFlipped = S3C_TRUE; break; } psFlipItem = &psDevInfo->asVSyncFlips[psDevInfo->ulRemoveIndex]; } Handled: S3C_EnableVSyncInterrupt(); return IRQ_HANDLED; }