📄 displaycommon.c
字号:
else
{
PVR_DPF((PVR_DBG_ERROR,"invalid flip command"));
PVR_ASSERT(0);
}
}
/*!
******************************************************************************
@Function InsertFlip
@Description
All dependencies of the Flip command have been checked.
The flip is now inserted into a private flip Q
to be serviced on Vsync
@input psDevInfo : device info structure
@input psFlipCmd : flip cmd
@Return none
******************************************************************************/
IMG_VOID InsertVsyncFlip(PVRSRV_DEV_INFO *psDevInfo, PVRSRV_FLIP_CMD_INFO *psFlipCmd)
{
VSYNC_FLIP_CMD_INFO *psFlip = psDevInfo->sDeviceSpecific.sDisplay.psVSyncFlipHead;
/* find the end of the list */
while (psFlip->bValidCmd)
{
psFlip = psFlip->psNext;
if(psFlip == IMG_NULL)
{
break;
}
}
if (psFlip == IMG_NULL)
{
PVR_DPF((PVR_DBG_ERROR,"No space in VSync Flip Q"));
PVR_ASSERT(0);
}
else
{
/* insert the flip */
psFlip->bThisIsOverlayFlip = IMG_FALSE;
psFlip->ui32FlipPhysAddr = psFlipCmd->ui32FlipPhysAddr;
psFlip->ui32FlipInterval = psFlipCmd->ui32FlipInterval;
psFlip->psFromSyncInfo = psFlipCmd->psFromSyncInfoKM;
psFlip->psToSyncInfo = psFlipCmd->psToSyncInfoKM;
psFlip->bValidCmd = IMG_TRUE;
}
}
/***********************************************************************************
Function Name : InsertVsyncFlipOverlay
Inputs : psDevInfo
psFlipCmd
Outputs : psDevInfo
Returns : void
Description : Insert overlay flip into a flip queue (to be serviced on
Vsync).
************************************************************************************/
IMG_VOID InsertVsyncFlipOverlay(PVRSRV_DEV_INFO *psDevInfo, PVRSRV_FLIP_OVERLAY_CMD_INFO *psFlipCmd)
{
VSYNC_FLIP_CMD_INFO *psFlip = psDevInfo->sDeviceSpecific.sDisplay.psVSyncFlipHead;
/* find the end of the list */
while (psFlip->bValidCmd)
{
psFlip = psFlip->psNext;
if(psFlip == IMG_NULL)
{
break;
}
}
if (psFlip == IMG_NULL)
{
PVR_DPF((PVR_DBG_ERROR,"No space in VSync Flip Q"));
PVR_ASSERT(0);
}
else
{
/* insert the flip */
psFlip->pui32OverlayConfig = psFlipCmd->pui32OverlayConfig;
psFlip->ui32OverlayConfigSize = psFlipCmd->ui32OverlayConfigSize;
psFlip->bThisIsOverlayFlip = IMG_TRUE;
psFlip->ui32FlipPhysAddr = psFlipCmd->ui32FlipPhysAddr;
psFlip->ui32FlipInterval = psFlipCmd->ui32FlipInterval;
psFlip->psFromSyncInfo = psFlipCmd->psFromSyncInfoKM;
psFlip->psToSyncInfo = psFlipCmd->psToSyncInfoKM;
psFlip->bValidCmd = IMG_TRUE;
}
}
/*!
******************************************************************************
@Function ProcessVsyncFlip
@Description Processes Flip from the private Flip Q on the Vsync interrupt
@input psDevInfo : device info structure
@Return none
******************************************************************************/
IMG_VOID ProcessVsyncFlip (PVRSRV_DEV_INFO *psDevInfo)
{
DEVICEDISPLAY *psDisplay = &psDevInfo->sDeviceSpecific.sDisplay;
VSYNC_FLIP_CMD_INFO *psFlipHead = psDisplay->psVSyncFlipHead;
if (psFlipHead->bValidCmd)
{
VSYNC_FLIP_CMD_INFO *psFlip = psFlipHead;
if (psFlip->ui32FlipInterval == 0)
{
/* zero vsync count */
psDisplay->ui32VSyncCount = 0;
/* here we only process the latest flip command, let's find it */
while(IMG_TRUE)
{
if(psFlip->psNext == IMG_NULL ||
!psFlip->psNext->bValidCmd)
{
/*
This is the last valid command and\or
the end of the queue
*/
break;
}
/*
Update surface read ops on flips we skip and
invalidate the commands
*/
psFlip->psFromSyncInfo->ui32ReadOpsComplete++;
psFlip->psToSyncInfo->ui32ReadOpsComplete++;
psFlip->bValidCmd = IMG_FALSE;
psFlip = psFlip->psNext;
}
/* do the flip */
Flip(psDevInfo, psFlip);
/* invalidate the command */
psFlip->bValidCmd = IMG_FALSE;
/*
- head and tail don't move
- all slots invalid
- disable VSync processing
*/
psDevInfo->sDeviceSpecific.sDisplay.bProcVsyncFlip = IMG_FALSE;
}
else if(psFlip->ui32FlipInterval <= psDisplay->ui32VSyncCount)
{
/* zero vsync count */
psDisplay->ui32VSyncCount = 0;
/* do the flip */
Flip(psDevInfo, psFlip);
/* invalidate teh flip command */
psFlip->bValidCmd = IMG_FALSE;
/* save tail */
psFlip = psDisplay->psVSyncFlipTail;
/* set new tail */
psDisplay->psVSyncFlipTail = psDisplay->psVSyncFlipHead;
/* set new head */
psDisplay->psVSyncFlipHead = psDisplay->psVSyncFlipHead->psNext;
/* link old tail to new tail*/
psFlip->psNext = psDisplay->psVSyncFlipTail;
/* terminate new tail */
psDisplay->psVSyncFlipTail->psNext = IMG_NULL;
if(psDisplay->psVSyncFlipHead->bValidCmd == IMG_FALSE)
{
/* Queue is empty */
psDevInfo->sDeviceSpecific.sDisplay.bProcVsyncFlip = IMG_FALSE;
}
}
}
psDisplay->ui32VSyncCount++;
}
/*!
******************************************************************************
@Function ProcessFlip
@Description processes a flip command from a Q
@input psDevInfo - device info structure
@input psQueue - for ROff update
@input psFlipCmd - the flip command
@Return none
******************************************************************************/
IMG_VOID ProcessFlip (PVRSRV_DEV_INFO *psDevInfo,
PVRSRV_QUEUE_INFO *psQueue,
PVRSRV_FLIP_CMD_INFO *psFlipCmd)
{
/*
check for:
- all writes have completed on FLIP-FROM
- all writes have completed on FLIP-TO
*/
/* Enable Vsync interrupts now we have a pending flip command */
if(psFlipCmd->bFlipOnVsync)
psDevInfo->sDeviceSpecific.sDisplay.bProcVsyncFlip = IMG_TRUE;
if ((*psFlipCmd->psToSyncInfoKM->pui32LastWriteOp == psFlipCmd->ui32ToNextOpVal - 1)
&& (*psFlipCmd->psFromSyncInfoKM->pui32LastWriteOp == psFlipCmd->ui32FromNextOpVal - 1))
{
if (psFlipCmd->bFlipOnVsync)
{
/*
insert the flip into the Vsync flip queue
(to be serviced only on vsyncs)
*/
InsertVsyncFlip (psDevInfo, psFlipCmd);
}
else
{
/* flip now (no vsync) */
psDevInfo->sDeviceSpecific.sDisplay.pfnFlipDisplay (psDevInfo, psFlipCmd->ui32FlipPhysAddr);
/* update surface read op */
psFlipCmd->psFromSyncInfoKM->ui32ReadOpsComplete++;
psFlipCmd->psToSyncInfoKM->ui32ReadOpsComplete++;
}
/* update the ROff */
UPDATE_QUEUE_ROFF(psQueue, psFlipCmd->sCmdInfo.ui32Size);
}
}
/***********************************************************************************
Function Name : ProcessFlipOverlay
Inputs : psDevInfo
psFlipCmd
psQueue
Outputs : psDevInfo
Returns : void
Description : Process a flip-overlay command from a queue.
************************************************************************************/
IMG_VOID ProcessFlipOverlay(PVRSRV_DEV_INFO *psDevInfo,
PVRSRV_QUEUE_INFO *psQueue,
PVRSRV_FLIP_OVERLAY_CMD_INFO *psFlipCmd)
{
/*
check for:
- all writes have completed on FLIP-FROM
- all writes have completed on FLIP-TO
*/
/* Enable Vsync interrupts now we have a pending flip command */
if(psFlipCmd->bFlipOnVsync)
psDevInfo->sDeviceSpecific.sDisplay.bProcVsyncFlip = IMG_TRUE;
if ((*psFlipCmd->psToSyncInfoKM->pui32LastWriteOp == psFlipCmd->ui32ToNextOpVal - 1)
//&& (*psFlipCmd->psFromSyncInfoKM->pui32LastWriteOp == psFlipCmd->ui32FromNextOpVal - 1)
)
{
if (psFlipCmd->bFlipOnVsync)
{
/*
insert the flip into the Vsync flip queue
(to be serviced only on vsyncs)
*/
InsertVsyncFlipOverlay (psDevInfo, psFlipCmd);
}
else
{
VSYNC_FLIP_CMD_INFO sFlip;
sFlip.pui32OverlayConfig = psFlipCmd->pui32OverlayConfig;
sFlip.ui32OverlayConfigSize = psFlipCmd->ui32OverlayConfigSize;
/* flip now (no vsync) */
psDevInfo->sDeviceSpecific.sDisplay.pfnFlipOverlay (psDevInfo, (IMG_VOID*) &sFlip);
/* update surface read op */
psFlipCmd->psFromSyncInfoKM->ui32ReadOpsComplete++;
psFlipCmd->psToSyncInfoKM->ui32ReadOpsComplete++;
}
/* update the ROff */
UPDATE_QUEUE_ROFF(psQueue, psFlipCmd->sCmdInfo.ui32Size);
}
}
/*!
******************************************************************************
@Function ProcessUpdateDisplay
@Description processes a flip command from a Q
@input psDevInfo - device info structure
@input psQueue - for ROff update
@input psUpdateCmd - the update command
@Return none
******************************************************************************/
IMG_VOID ProcessUpdateDisplay (PVRSRV_DEV_INFO *psDevInfo,
PVRSRV_QUEUE_INFO *psQueue,
PVRSRV_UPDATE_CMD_INFO *psUpdateCmd)
{
/*
check for:
- all writes have completed on FLIP-FROM
- all writes have completed on FLIP-TO
*/
if (*psUpdateCmd->psDestSyncInfoKM->pui32LastWriteOp == psUpdateCmd->ui32DestNextOpVal - 1)
{
if(psDevInfo->sDeviceSpecific.sDisplay.pfnUpdateDisplay)
psDevInfo->sDeviceSpecific.sDisplay.pfnUpdateDisplay (psDevInfo);
/* update the ROff */
UPDATE_QUEUE_ROFF(psQueue, psUpdateCmd->sCmdInfo.ui32Size);
psUpdateCmd->psDestSyncInfoKM->ui32ReadOpsComplete++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -