enum PVRSRV_ERROR PVRSRVSwapToDCSystemKM(void *hDeviceKM, void *hSwapChain) { enum PVRSRV_ERROR eError; struct PVRSRV_QUEUE_INFO *psQueue; struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo; struct PVRSRV_DC_SWAPCHAIN *psSwapChain; struct DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; IMG_BOOL bStart = IMG_FALSE; u32 uiStart = 0; u32 ui32NumSrcSyncs = 1; struct PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; struct PVRSRV_COMMAND *psCommand; if (!hDeviceKM || !hSwapChain) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCSystemKM: Invalid parameters"); return PVRSRV_ERROR_INVALID_PARAMS; } psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); psSwapChain = (struct PVRSRV_DC_SWAPCHAIN *)hSwapChain; psQueue = psSwapChain->psQueue; apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo; if (psSwapChain->psLastFlipBuffer) { apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer. psKernelSyncInfo; ui32NumSrcSyncs++; } eError = PVRSRVInsertCommandKM(psQueue, &psCommand, psDCInfo->ui32DeviceID, DC_FLIP_COMMAND, 0, NULL, ui32NumSrcSyncs, apsSrcSync, sizeof(struct DISPLAYCLASS_FLIP_COMMAND)); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCSystemKM: " "Failed to get space in queue"); goto Exit; } psFlipCmd = (struct DISPLAYCLASS_FLIP_COMMAND *)psCommand->pvData; psFlipCmd->hExtDevice = psDCInfo->hExtDevice; psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain; psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer; psFlipCmd->hPrivateTag = NULL; psFlipCmd->ui32ClipRectCount = 0; psFlipCmd->ui32SwapInterval = 1; eError = PVRSRVSubmitCommandKM(psQueue, psCommand); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCSystemKM: Failed to submit command"); goto Exit; } do { if (PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != PVRSRV_ERROR_PROCESSING_BLOCKED) goto ProcessedQueues; if (bStart == IMG_FALSE) { uiStart = OSClockus(); bStart = IMG_TRUE; } OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT); } while ((OSClockus() - uiStart) < MAX_HW_TIME_US); PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCSystemKM: Failed to process queues"); eError = PVRSRV_ERROR_GENERIC; goto Exit; ProcessedQueues: psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer; eError = PVRSRV_OK; Exit: return eError; }
enum PVRSRV_ERROR PVRSRVSwapToDCBufferKM(void *hDeviceKM, void *hBuffer, u32 ui32SwapInterval, void *hPrivateTag, u32 ui32ClipRectCount, struct IMG_RECT *psClipRect) { enum PVRSRV_ERROR eError; struct PVRSRV_DISPLAYCLASS_INFO *psDCInfo; struct PVRSRV_DC_BUFFER *psBuffer; struct PVRSRV_QUEUE_INFO *psQueue; struct DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; u32 i; u32 ui32NumSrcSyncs = 1; struct PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; struct PVRSRV_COMMAND *psCommand; if (!hDeviceKM || !hBuffer || !psClipRect) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCBufferKM: Invalid parameters"); return PVRSRV_ERROR_INVALID_PARAMS; } psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); psBuffer = (struct PVRSRV_DC_BUFFER *)hBuffer; psQueue = psBuffer->psSwapChain->psQueue; apsSrcSync[0] = psBuffer->sDeviceClassBuffer.psKernelSyncInfo; if (psBuffer->psSwapChain->psLastFlipBuffer && psBuffer != psBuffer->psSwapChain->psLastFlipBuffer) { apsSrcSync[1] = psBuffer->psSwapChain->psLastFlipBuffer->sDeviceClassBuffer. psKernelSyncInfo; ui32NumSrcSyncs++; } eError = PVRSRVInsertCommandKM(psQueue, &psCommand, psDCInfo->ui32DeviceID, DC_FLIP_COMMAND, 0, NULL, ui32NumSrcSyncs, apsSrcSync, sizeof(struct DISPLAYCLASS_FLIP_COMMAND) + (sizeof(struct IMG_RECT) * ui32ClipRectCount)); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCBufferKM: Failed to get space in queue"); goto Exit; } psFlipCmd = (struct DISPLAYCLASS_FLIP_COMMAND *)psCommand->pvData; psFlipCmd->hExtDevice = psDCInfo->hExtDevice; psFlipCmd->hExtSwapChain = psBuffer->psSwapChain->hExtSwapChain; psFlipCmd->hExtBuffer = psBuffer->sDeviceClassBuffer.hExtBuffer; psFlipCmd->hPrivateTag = hPrivateTag; psFlipCmd->ui32ClipRectCount = ui32ClipRectCount; psFlipCmd->psClipRect = (struct IMG_RECT *)((u8 *) psFlipCmd + sizeof(struct DISPLAYCLASS_FLIP_COMMAND)); for (i = 0; i < ui32ClipRectCount; i++) psFlipCmd->psClipRect[i] = psClipRect[i]; psFlipCmd->ui32SwapInterval = ui32SwapInterval; eError = PVRSRVSubmitCommandKM(psQueue, psCommand); if (eError != PVRSRV_OK) { PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCBufferKM: Failed to submit command"); goto Exit; } LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) { if (PVRSRVProcessQueues(IMG_FALSE) != PVRSRV_ERROR_PROCESSING_BLOCKED) { goto ProcessedQueues; } OSWaitus(MAX_HW_TIME_US / WAIT_TRY_COUNT); } END_LOOP_UNTIL_TIMEOUT(); PVR_DPF(PVR_DBG_ERROR, "PVRSRVSwapToDCBufferKM: Failed to process queues"); eError = PVRSRV_ERROR_GENERIC; goto Exit; ProcessedQueues: psBuffer->psSwapChain->psLastFlipBuffer = psBuffer; Exit: return eError; }
IMG_EXPORT PVRSRV_ERROR PVRSRVSwapToDCSystemKM(IMG_HANDLE hDeviceKM, IMG_HANDLE hSwapChain) { PVRSRV_ERROR eError; PVRSRV_QUEUE_INFO *psQueue; PVRSRV_DISPLAYCLASS_INFO *psDCInfo; PVRSRV_DC_SWAPCHAIN *psSwapChain; DISPLAYCLASS_FLIP_COMMAND *psFlipCmd; IMG_UINT32 ui32NumSrcSyncs = 1; PVRSRV_KERNEL_SYNC_INFO *apsSrcSync[2]; PVRSRV_COMMAND *psCommand; if(!hDeviceKM || !hSwapChain) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Invalid parameters")); return PVRSRV_ERROR_INVALID_PARAMS; } #if defined(SUPPORT_LMA) eError = PVRSRVPowerLock(KERNEL_ID, IMG_FALSE); if(eError != PVRSRV_OK) { return eError; } #endif psDCInfo = DCDeviceHandleToDCInfo(hDeviceKM); psSwapChain = (PVRSRV_DC_SWAPCHAIN*)hSwapChain; psQueue = psSwapChain->psQueue; apsSrcSync[0] = psDCInfo->sSystemBuffer.sDeviceClassBuffer.psKernelSyncInfo; if(psSwapChain->psLastFlipBuffer) { if (apsSrcSync[0] != psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo) { apsSrcSync[1] = psSwapChain->psLastFlipBuffer->sDeviceClassBuffer.psKernelSyncInfo; ui32NumSrcSyncs++; } } eError = PVRSRVInsertCommandKM (psQueue, &psCommand, psDCInfo->ui32DeviceID, DC_FLIP_COMMAND, 0, IMG_NULL, ui32NumSrcSyncs, apsSrcSync, sizeof(DISPLAYCLASS_FLIP_COMMAND)); if(eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to get space in queue")); goto Exit; } psFlipCmd = (DISPLAYCLASS_FLIP_COMMAND*)psCommand->pvData; psFlipCmd->hExtDevice = psDCInfo->hExtDevice; psFlipCmd->hExtSwapChain = psSwapChain->hExtSwapChain; psFlipCmd->hExtBuffer = psDCInfo->sSystemBuffer.sDeviceClassBuffer.hExtBuffer; psFlipCmd->hPrivateTag = IMG_NULL; psFlipCmd->ui32ClipRectCount = 0; psFlipCmd->ui32SwapInterval = 1; eError = PVRSRVSubmitCommandKM (psQueue, psCommand); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to submit command")); goto Exit; } LOOP_UNTIL_TIMEOUT(MAX_HW_TIME_US) { if(PVRSRVProcessQueues(KERNEL_ID, IMG_FALSE) != PVRSRV_ERROR_PROCESSING_BLOCKED) { goto ProcessedQueues; } OSWaitus(MAX_HW_TIME_US/WAIT_TRY_COUNT); } END_LOOP_UNTIL_TIMEOUT(); PVR_DPF((PVR_DBG_ERROR,"PVRSRVSwapToDCSystemKM: Failed to process queues")); eError = PVRSRV_ERROR_GENERIC; goto Exit; ProcessedQueues: psSwapChain->psLastFlipBuffer = &psDCInfo->sSystemBuffer; eError = PVRSRV_OK; Exit: #if defined(SUPPORT_LMA) PVRSRVPowerUnlock(KERNEL_ID); #endif return eError; }