📄 queue.c
字号:
{
goto ErrorExit;
}
psQueueInfo->psNextKM = psSysData->psQueueList;
psSysData->psQueueList = psQueueInfo;
if (HostUnlockResource(&psSysData->hQProcessResource) != PVRSRV_OK)
{
goto ErrorExit;
}
/* setup the kicker address */
psQueueInfo->pui32KickerAddr = psSysData->pui32KickerAddr;
*ppsQueueInfo = psQueueInfo;
if(HostNoResManOnThisProcess(HostGetCurrentProcessID()))
{
/* We can't do resource management on this process so just return */
return PVRSRV_OK;
}
/* Require resource manager to track resource */
psQueueInfo->psResItem = ResManRegisterRes((PRESMAN_ITEM)IMG_NULL,
RESMAN_TYPE_CMDQUEUE,
(IMG_VOID *)psQueueInfo,
0,
DestroyCommandQueueCallBack,
RESMAN_AUTOFREE_LEV3);
if (psQueueInfo->psResItem == IMG_NULL)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVCreateCommandQueue: Failed to register resource"));
goto ErrorExit;
}
return PVRSRV_OK;
ErrorExit:
if(psQueueInfo && psQueueInfo->pvLinQueueKM)
{
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psQueueInfo->pvLinQueueKM);
}
if(psQueueInfo)
{
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psQueueInfo);
}
return PVRSRV_ERROR_GENERIC;
}
/*!
******************************************************************************
@Function PVRSRVDestroyCommandQueue
@Description
Destroys a command queue.
@Input psDevData :
@Input psQueueInfo :
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVDestroyCommandQueue(PVRSRV_DEV_DATA *psDevData, PVRSRV_QUEUE_INFO *psQueueInfo)
{
PVRSRV_ERROR eError;
if(psQueueInfo->psResItem)
{
eError = ResManFreeResByPtr(psQueueInfo->psResItem);
}
else
{
/* Resource not managed call the free callback directly */
eError = DestroyCommandQueueCallBack(0,(IMG_PVOID)psQueueInfo, 0);
}
return(eError);
}
/*****************************************************************************
Kernel-only functions
******************************************************************************/
/*!
******************************************************************************
@Function ProcessLock
@Description
processes a lock command from a Q
@Input psDevInfo - device info structure
@Input psQueue - for ROff update
@Input psLockCmd - Lock command info
@Return none
******************************************************************************/
IMG_VOID ProcessLock (PVRSRV_DEV_INFO *psDevInfo,
PVRSRV_QUEUE_INFO *psQueue,
PVRSRV_LOCK_CMD_INFO *psLockCmd)
{
if(psLockCmd->bLockSurface)
{
if ((*psLockCmd->psSyncInfoKM->pui32LastWriteOp == psLockCmd->ui32NextWriteOpVal - 1)
&& (psLockCmd->psSyncInfoKM->ui32ReadOpsComplete == psLockCmd->ui32ReadOpsPending)
)
{
/* Open the event for interprocess communication then set it */
HostOpenEvent(&psLockCmd->hWaitEventHandle);
HostSetEvent(psLockCmd->hWaitEventHandle);
/*
Locks can happen, so all read ops complete.
Reset read count
*/
psLockCmd->psSyncInfoKM->ui32ReadOpsComplete = 0;
/* update the ROff */
UPDATE_QUEUE_ROFF(psQueue, psLockCmd->sCmdInfo.ui32Size);
}
}
else /* Unlock */
{
(*psLockCmd->psSyncInfoKM->pui32LastWriteOp)++;
/*
If the lock is on the primary we must update
the Single shot display (if there is one)
*/
if (psLockCmd->bPrimary)
{
#if FIXME
PDP_ScreenUpdate(g_PDPHandle);
#endif
}
/* Open the event for interprocess communication then set it */
HostOpenEvent(&psLockCmd->hWaitEventHandle);
/*
Signal threads waiting on unlock
*/
HostSetEvent(psLockCmd->hWaitEventHandle);
if(HostReleaseEvent(psLockCmd->hWaitEventHandle) != PVRSRV_OK)
{
PVR_ASSERT(0);
}
/* update the ROff */
UPDATE_QUEUE_ROFF(psQueue, psLockCmd->sCmdInfo.ui32Size);
}
}
/*!
******************************************************************************
@Function ProcessDummyLock
@Description
does dummy processing on a lock command from a Q
@Input psDevInfo - device info structure
@Input psQueue - for ROff update
@Input psLockCmd - Lock command info
@Return none
******************************************************************************/
IMG_VOID ProcessDummyLock (PVRSRV_DEV_INFO *psDevInfo,
PVRSRV_QUEUE_INFO *psQueue,
PVRSRV_LOCK_CMD_INFO *psLockCmd)
{
if(psLockCmd->bLockSurface)
{
if ((*psLockCmd->psSyncInfoKM->pui32LastWriteOp == psLockCmd->ui32NextWriteOpVal - 1)
&& (psLockCmd->psSyncInfoKM->ui32ReadOpsComplete == psLockCmd->ui32ReadOpsPending)
)
{
HostSetEvent(psLockCmd->hWaitEventHandle);
/* update the ROff */
UPDATE_QUEUE_ROFF(psQueue, psLockCmd->sCmdInfo.ui32Size);
}
}
else /* Unlock */
{
(*psLockCmd->psSyncInfoKM->pui32LastWriteOp)++;
/*
Signal threads waiting on unlock
*/
HostSetEvent(psLockCmd->hWaitEventHandle);
if(!HostReleaseEvent(psLockCmd->hWaitEventHandle))
{
PVR_ASSERT(0);
}
/* update the ROff */
UPDATE_QUEUE_ROFF(psQueue, psLockCmd->sCmdInfo.ui32Size);
}
}
/*!
******************************************************************************
@Function PVRSRVProcessQueues
@Description
tries to process a command from each Q
@Input psDevInfo - device info structure
@Return PVRSRV_ERROR
******************************************************************************/
#if defined (HOST_REG_UPDATE_WORKAROUND)
/*
FIXME, workaround for instability issue where expected value in not in
the expected place.
*/
PVRSRV_QUEUE_INFO *psQueueStore;
#endif /*HOST_REG_UPDATE_WORKAROUND*/
IMG_EXPORT
PVRSRV_ERROR PVRSRVProcessQueues(PVRSRV_DEV_INFO *psDevInfo)
{
PVRSRV_QUEUE_INFO *psQueue;
SYS_DATA *psSysData;
PVRSRV_CMD_HEADER *psCmdHeader;
PVRSRV_ERROR eError;
IMG_VOID (*pfnProcessCommands) ( PPVRSRV_DEV_INFO, PVRSRV_QUEUE_INFO*, PVRSRV_CMD_HEADER*);
eError = SysAcquireData(&psSysData);
if (eError != PVRSRV_OK)
{
return eError;
}
/* Ensure we don't corrupt queue list, by blocking access */
if(HostLockResource(&psSysData->hQProcessResource, IMG_FALSE) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_MESSAGE,"Couldn't acquire queue processing mutex. Returning"));
return PVRSRV_OK;
}
psQueue = psSysData->psQueueList;
if(!psQueue)
PVR_DPF((PVR_DBG_MESSAGE,"No Queues installed - cannot process commands"));
/* dummy command processing? */
if(psSysData->bDummyProcessing || psDevInfo->bDummyProcessing)
{
pfnProcessCommands = psDevInfo->pfnDummyProcessCommands;
}
else
{
pfnProcessCommands = psDevInfo->pfnProcessCommands;
}
/*! @todo rotate the order of processing for multiple queues */
while (psQueue)
{
#if defined (HOST_REG_UPDATE_WORKAROUND)
/* FIXME: This is a workaround for the instability */
volatile PVRSRV_QUEUE_INFO * psQueueVol;
#endif /*HOST_REG_UPDATE_WORKAROUND*/
psCmdHeader = (PVRSRV_CMD_HEADER *)((IMG_UINT32)psQueue->pvLinQueueKM + psQueue->ui32ReadOffset);
if (psQueue->ui32ReadOffset != psQueue->ui32WriteOffset)
{
pfnProcessCommands(psDevInfo, psQueue, psCmdHeader);
}
#if !defined (HOST_REG_UPDATE_WORKAROUND)
psQueue = psQueue->psNextKM;
#else /*HOST_REG_UPDATE_WORKAROUND*/
/* FIXME: This is a workaround for the instability */
psQueueVol = psQueue;
psQueue = psQueue->psNextKM;
psQueueStore = psQueue;
psQueue = psQueueVol->psNextKM;
#endif /*HOST_REG_UPDATE_WORKAROUND*/
}
return HostUnlockResource(&psSysData->hQProcessResource);
}
#endif /* QUEUE_C */
/*****************************************************************************
End of file (queue.c)
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -