/* * Internal stream APIs to server part of Transport Layer, declared in * header tlintern.h. Direct pointers to stream objects are used here as * these functions are internal. */ IMG_UINT32 TLStreamAcquireReadPos(PTL_STREAM psStream, IMG_UINT32* puiReadOffset) { IMG_UINT32 uiReadLen = 0; IMG_UINT32 ui32LRead, ui32LWrite; PVR_DPF_ENTERED; PVR_ASSERT(psStream); PVR_ASSERT(puiReadOffset); /* Grab a local copy */ ui32LRead = psStream->ui32Read; ui32LWrite = psStream->ui32Write; /* No data available and CB defined - try and get data */ if ((ui32LRead == ui32LWrite) && psStream->pfProducerCallback) { PVRSRV_ERROR eRc; IMG_UINT32 ui32Resp = 0; eRc = ((TL_STREAM_SOURCECB)psStream->pfProducerCallback)(psStream, TL_SOURCECB_OP_CLIENT_EOS, &ui32Resp, psStream->pvProducerUserData); PVR_LOG_IF_ERROR(eRc, "TLStream->pfProducerCallback"); ui32LWrite = psStream->ui32Write; } /* No data available... */ if (ui32LRead == ui32LWrite) { PVR_DPF_RETURN_VAL(0); } /* Data is available to read... */ *puiReadOffset = ui32LRead; /*PVR_DPF((PVR_DBG_VERBOSE, * "TLStreamAcquireReadPos Start before: Write:%d, Read:%d, size:%d", * ui32LWrite, ui32LRead, psStream->ui32Size)); */ if ( ui32LRead > ui32LWrite ) { /* CB has wrapped around. * Return the first contiguous piece of memory, ie [ReadLen,EndOfBuffer] * and let a subsequent AcquireReadPos read the rest of the Buffer */ /*PVR_DPF((PVR_DBG_VERBOSE, "TLStreamAcquireReadPos buffer has wrapped"));*/ uiReadLen = psStream->ui32Size - ui32LRead; } else { // CB has not wrapped uiReadLen = ui32LWrite - ui32LRead; } PVR_DPF_RETURN_VAL(uiReadLen); }
PVRSRV_ERROR TLStreamOpen(IMG_HANDLE *phStream, IMG_CHAR *szStreamName) { PTL_SNODE psTmpSNode; PVR_DPF_ENTERED; if ( IMG_NULL == phStream || IMG_NULL == szStreamName ) { PVR_DPF_RETURN_RC(PVRSRV_ERROR_INVALID_PARAMS); } /* Search for a stream node with a matching stream name */ psTmpSNode = TLFindStreamNodeByName(szStreamName); if ( IMG_NULL == psTmpSNode ) { PVR_DPF_RETURN_RC(PVRSRV_ERROR_NOT_FOUND); } else { /* Found a stream to open. lock and increase reference count */ //Thread Safety: Not yet implemented OSLockAcquire(psTmpStream->hLock); psTmpSNode->psStream->uiRefCount++; *phStream = (IMG_HANDLE)psTmpSNode->psStream; //Thread Safety: Not yet implemented OSLockRelease(psTmpStream->hLock); PVR_DPF_RETURN_VAL(PVRSRV_OK); } }
IMG_BOOL TLTryRemoveStreamAndFreeStreamNode(PTL_SNODE psRemove) { PVR_DPF_ENTERED; PVR_ASSERT(psRemove); /* If there is a client connected to this stream, defer stream's deletion */ if (psRemove->psRDesc != IMG_NULL) { PVR_DPF_RETURN_VAL (IMG_FALSE); } /* Remove stream from TL_GLOBAL_DATA's list and free stream node */ psRemove->psStream = IMG_NULL; RemoveAndFreeStreamNode(psRemove); PVR_DPF_RETURN_VAL (IMG_TRUE); }
PTL_SNODE TLFindStreamNodeByDesc(PTL_STREAM_DESC psRDesc) { TL_GLOBAL_DATA* psGD = TLGGD(); PTL_SNODE psn; PVR_DPF_ENTERED; PVR_ASSERT(psRDesc); for (psn = psGD->psHead; psn; psn=psn->psNext) { if (psn->psRDesc == psRDesc) { PVR_DPF_RETURN_VAL(psn); } } PVR_DPF_RETURN_VAL(IMG_NULL); }
DEVMEM_EXPORTCOOKIE* TLStreamGetBufferCookie(PTL_STREAM psStream) { PVR_DPF_ENTERED; PVR_ASSERT(psStream); PVR_DPF_RETURN_VAL(&psStream->sExportCookie); }
PTL_SNODE TLFindStreamNodeByName(IMG_PCHAR pszName) { TL_GLOBAL_DATA* psGD = TLGGD(); PTL_SNODE psn; PVR_DPF_ENTERED; PVR_ASSERT(pszName); for (psn = psGD->psHead; psn; psn=psn->psNext) { if (psn->psStream && OSStringCompare(psn->psStream->szName, pszName)==0) { PVR_DPF_RETURN_VAL(psn); } } PVR_DPF_RETURN_VAL(IMG_NULL); }
IMG_BOOL TLStreamEOS(PTL_STREAM psStream) { PVR_DPF_ENTERED; PVR_ASSERT(psStream); /* If both pointers are equal then the buffer is empty */ PVR_DPF_RETURN_VAL( psStream->ui32Read == psStream->ui32Write ); }
IMG_BOOL TLRemoveDescAndTryFreeStreamNode(PTL_SNODE psRemove) { PVR_DPF_ENTERED; PVR_ASSERT(psRemove); /* Remove stream descriptor (i.e. stream reader context) */ psRemove->psRDesc = IMG_NULL; /* Do not Free Stream Node if there is a write reference (a producer context) to the stream */ if (0 != psRemove->uiWRefCount) { PVR_DPF_RETURN_VAL (IMG_FALSE); } /* Make stream pointer NULL to prevent it from being destroyed in RemoveAndFreeStreamNode * Cleanup of stream should be done by the calling context */ psRemove->psStream = IMG_NULL; RemoveAndFreeStreamNode(psRemove); PVR_DPF_RETURN_VAL (IMG_TRUE); }