📄 pvrsrv.c
字号:
Maps memory (which should be contiguous!!) into the mmu of the device.
(typically used for mapping the video area which was allocated by a third
party display driver)
@Input psDevData : DevData for the device this memory will primarily be used with
@Input ui32Flags : Some combination of PVRSRV_MEMFLG_ flags
@Input ui32Size : Number of bytes to allocate
@Input ui32Alignment :
@Input baseAddr: physical address of the memory
@Output **ppsMemInfo : On success, receives a pointer to the created MEM_INFO structure
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_EXPORT PVRSRV_ERROR IMG_CALLCONV
PVRSRVWrapDeviceMem (PVRSRV_DEV_DATA *psDevData,
IMG_UINT32 ui32Flags,
IMG_UINT32 ui32Size,
IMG_UINT32 ui32Alignment,
IMG_SYS_PHYADDR baseAddr,
PVRSRV_MEM_INFO **ppsMemInfo)
{
PVRSRV_MEM_INFO* psMemInfo = (PVRSRV_MEM_INFO*)IMG_NULL;
PVRSRV_DEV_DATA *psNewDevData;
BM_HANDLE hBuffer;
/* Pointer to implementation details within the mem_info */
PVRSRV_MEMBLK *psMemBlock;
IMG_UINT32 ui3BM2Flags;
IMG_BOOL bBMError;
PPVRSRV_DEV_INFO psDevInfo;
if ((psDevData == IMG_NULL) || (ppsMemInfo == IMG_NULL))
{
return PVRSRV_ERROR_INVALID_PARAMS;
}
psDevInfo = psDevData->psDevInfoKM;
/* Start with an invalid pointer for the output value */
*ppsMemInfo = IMG_NULL;
if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP,
sizeof(PVRSRV_MEM_INFO ),
(IMG_VOID **)&psMemInfo, 0) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapDeviceMem : Failed to alloc memory for block"));
return (PVRSRV_ERROR_OUT_OF_MEMORY);
}
if(HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP,
sizeof(IMG_UINT32),
(IMG_VOID **)&psMemInfo->pui32Flags, 0) != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapDeviceMem : Failed to alloc memory for flag word"));
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psMemInfo);
return PVRSRV_ERROR_OUT_OF_MEMORY;
}
psMemBlock = &(psMemInfo->sMemBlk);
/* Translate to BM flags....*/
ui3BM2Flags = ((ui32Flags&PVRSRV_MEMFLG_CONTIGIOUS) ? BP_CONTIGUOUS : 0 );
/* If requesting memory from alternate heap, request memory from secondary pool */
if(ui32Flags & PVRSRV_MEMFLG_ALTERNATE_HEAP)
{
ui3BM2Flags |= 1;
}
bBMError = BM_Wrap (baseAddr,
ui32Size,
ui3BM2Flags,
ui32Alignment,
&hBuffer);
if (!bBMError)
{
PVR_DPF((PVR_DBG_ERROR,"PVRSRVWrapDeviceMem : BM_Wrap Failed"));
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psMemInfo->pui32Flags);
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psMemInfo);
return PVRSRV_ERROR_OUT_OF_MEMORY;
}
/* Fill in "Implementation dependant" section of mem info */
psMemBlock->sSysPhysAddr = BM_HandleToSysPaddr(hBuffer);
psMemBlock->sDevVirtAddr = BM_HandleToDevVaddr(hBuffer);
/* Convert from BM_HANDLE to external IMG_HANDLE */
psMemBlock->hBuffer = (IMG_HANDLE)hBuffer.h;
/* Fill in the public fields of the MEM_INFO structure */
psMemInfo->pvLinAddr = BM_HandleToCpuVaddr(hBuffer);
psMemInfo->uiDevAddr = psMemBlock->sDevVirtAddr;
*psMemInfo->pui32Flags = ui32Flags;
/* set the fact that the memory is valid */
*psMemInfo->pui32Flags &= ~PVRSRV_MEMFLG_MEMORY_NOT_AVAILABLE;
psMemInfo->ui32AllocSize = ui32Size;
psMemInfo->psSyncInfo = AllocSyncInfo(psDevInfo);
/* Clear the Backup buffer pointer as we do not have one at this point. We only allocate this as we are going up/down */
psMemInfo->pvSysBackupBuffer = IMG_NULL;
psMemInfo->psMemInfoKM = psMemInfo;
/*
* Setup the output.
*/
*ppsMemInfo = psMemInfo;
/* Register Resource */
if(ui32Flags & PVRSRV_MEMFLG_NO_RESMAN)
{
psMemInfo->sMemBlk.psResItem = IMG_NULL;
}
else
{
if(ui32Flags & PVRSRV_MEMFLG_FLIPPABLE)
{
IMG_UINT32 i, ui32NumDevices;
PVRSRV_DEVICE_IDENTIFIER asDeviceID[PVRSRV_MAX_DEVICES];
HostAllocMem( PVRSRV_HOST_NON_PAGEABLE_HEAP,sizeof(PVRSRV_DEV_DATA), (IMG_VOID **)&psNewDevData, 0);
/* FIXME: this really is ugly and might not work on a system with more than one display device */
PVRSRVEnumerateDevices(psDevData->hServices, &ui32NumDevices, asDeviceID);
for(i=0; i < ui32NumDevices; i++)
{
if(asDeviceID[i].eDeviceClass == PVRSRV_DEVICE_CLASS_DISPLAY)
{
PVRSRVAcquireDeviceData( psDevData->hServices,
asDeviceID[i].ui32DeviceIndex,
psNewDevData,
PVRSRV_DEVICE_TYPE_UNKNOWN);
break;
}
}
psMemInfo->sMemBlk.psResItem = ResManRegisterRes((PRESMAN_ITEM)IMG_NULL,
RESMAN_TYPE_FRAMBUFMEM,
psMemInfo,
(IMG_UINT32)psNewDevData,
FreeDeviceMemCallBack,
RESMAN_AUTOFREE_LEV4);
}
else
{
psMemInfo->sMemBlk.psResItem = ResManRegisterRes((PRESMAN_ITEM)IMG_NULL,
RESMAN_TYPE_FRAMBUFMEM,
psMemInfo,
0,
FreeDeviceMemCallBack,
RESMAN_AUTOFREE_LEV4);
}
}
/*
* And I think we're done for now....
*/
return (PVRSRV_OK);
}
/*!
******************************************************************************
@Function FreeDeviceMemCallBack
@Description
ResMan call back to free device memory
@Input ui32ProcessID : process id
@Input pvParam : data packet
@Input ui32Param : packet size
@Return PVRSRV_ERROR :
******************************************************************************/
static PVRSRV_ERROR FreeDeviceMemCallBack(IMG_UINT32 ui32ProcessID, IMG_PVOID pvParam, IMG_UINT32 ui32Param)
{
PVRSRV_MEM_INFO *psMemInfo = (PVRSRV_MEM_INFO *) pvParam;
PVRSRV_DEV_DATA *psDevData = (PVRSRV_DEV_DATA *)ui32Param;
BM_HANDLE hBuffer;
SYS_DATA *psSysData;
PVRSRV_ERROR eError;
PVR_ASSERT(pvParam != IMG_NULL);
eError = SysAcquireData(&psSysData);
if (eError != PVRSRV_OK)
{
return eError;
}
/*
* Check if Device mem was alloc'ed
*/
if (psMemInfo != IMG_NULL)
{
eError = FreeSyncInfo(psMemInfo->psSyncInfo);
if(eError != PVRSRV_OK)
{
PVR_DPF((PVR_DBG_ERROR,"Failed to free sync info"));
return eError;
}
psMemInfo->psSyncInfo = IMG_NULL;
hBuffer.h = (HDL)psMemInfo->sMemBlk.hBuffer;
if( *psMemInfo->pui32Flags & PVRSRV_MEMFLG_FLIPPABLE )
{
PVR_DPF((PVR_DBG_ERROR,"Flip back to the primary!!!"));
psDevData->psDevInfoKM->sDeviceSpecific.sDisplay.pfnFlipDisplay (psDevData->psDevInfoKM, psDevData->psDevInfoKM->sDeviceSpecific.sDisplay.sPrimarySurface.psMemInfo->uiDevAddr.uiAddr);
}
if(psDevData)
{
PVRSRVReleaseDeviceData(psDevData);
}
/*
* It is possible that the BM has been finalised (if the last devicedata has been released correctly).
* In this case the BM allocations have actually already been freed, so don't do that here.
*/
if(psSysData->bBMInitialised)
BM_Free(hBuffer);
if(psMemInfo->pvSysBackupBuffer)
{
/* If we have a System backup buffer */
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psMemInfo->pvSysBackupBuffer);
}
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psMemInfo->pui32Flags);
HostFreeMem(PVRSRV_HOST_NON_PAGEABLE_HEAP, psMemInfo);
}
return(PVRSRV_OK);
}
/*!
******************************************************************************
@Function PVRFreeDeviceMem
@Description
Frees memory allocated with PVRAllocDeviceMem, including the mem_info structure
@Input psDevData :
@Input psMemInfo :
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVFreeDeviceMem ( PVRSRV_DEV_DATA *psDevData,
PVRSRV_MEM_INFO *psMemInfo)
{
PVRSRV_ERROR eRtn;
if ((psDevData == IMG_NULL) || (psMemInfo == IMG_NULL))
{
return PVRSRV_ERROR_INVALID_PARAMS;
}
*psMemInfo->pui32Flags &= (~PVRSRV_MEMFLG_FLIPPABLE);
if(psMemInfo->sMemBlk.psResItem)
{
eRtn = ResManFreeResByPtr(psMemInfo->sMemBlk.psResItem);
}
else
{
/* Allocate not managed by the resource manager call the free callback directly */
eRtn = FreeDeviceMemCallBack(0,(IMG_PVOID) psMemInfo, 0);
}
return(eRtn);
}
/*!
******************************************************************************
@Function PVRSRVGetFreeDeviceMem
@Description
Determines how much memory remains available in the system with the specified
capabilities.
@Input psDevData :
@Input ui32Flags :
@Output pui32Total :
@Output pui32Free :
@Output pui32LargestBlock :
@Return PVRSRV_ERROR :
******************************************************************************/
IMG_EXPORT
PVRSRV_ERROR IMG_CALLCONV PVRSRVGetFreeDeviceMem( PVRSRV_DEV_DATA *psDevData,
IMG_UINT32 ui32Flags,
IMG_UINT32 *pui32Total,
IMG_UINT32 *pui32Free,
IMG_UINT32 *pui32LargestBlock)
{
if (psDevData == IMG_NULL)
{
return PVRSRV_ERROR_INVALID_PARAMS;
}
return PVRSRV_OK;
}
/*!
******************************************************************************
@Function PVRReadRegistryString
@Description
Read a key string from the registry
@Input psRegInfo : registry data structure
@Return PVRSRV_ERROR :
******************************************************************************/
PVRSRV_ERROR IMG_CALLCONV PVRReadRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo)
{
if (psRegInfo == IMG_NULL)
{
return PVRSRV_ERROR_INVALID_PARAMS;
}
/* Read registry */
if (HostReadRegistryString (psRegInfo->ui32DevCookie,
psRegInfo->pszKey,
psRegInfo->pszValue,
psRegInfo->pszBuf,
psRegInfo->ui32BufSize) != IMG_FALSE)
{
return (PVRSRV_OK);
}
else
{
return (PVRSRV_ERROR_GENERIC);
}
}
/*!
******************************************************************************
@Function PVRWriteRegistryString
@Description
Writes a string to a registry key
@Input psRegInfo : registry data structure
@Return PVRSRV_ERROR :
******************************************************************************/
PVRSRV_ERROR IMG_CALLCONV PVRWriteRegistryString (PPVRSRV_REGISTRY_INFO psRegInfo)
{
if (psRegInfo == IMG_NULL)
{
return PVRSRV_ERROR_INVALID_PARAMS;
}
if (HostWriteRegistryString(psRegInfo->ui32DevCookie,
psRegInfo->pszKey,
psRegInfo->pszValue,
psRegInfo->pszBuf) != IMG_FALSE)
{
return(PVRSRV_OK);
}
else
{
return(PVRSRV_ERROR_GENERIC);
}
}
#ifdef SUPPORT_POWER_STATE
/*!
******************************************************************************
@Function PVRSRVSetPowerState
@Description
Set the Device into a new state
@Input psDevData :
@Input bPoweringDown :
@Input ePVRState :
@Return PVRSRV_ERROR IMG_CALLCONV :
******************************************************************************/
PVRSRV_ERROR IMG_CALLCONV PVRSRVSetPowerState (PPVRSRV_DEV_DATA psDevData,
IMG_BOOL bPoweringDown,
PVR_POWER_STATE ePVRState)
{
//PVRSRV_ERROR eError;
SYS_DATA *psSysData;
PVRSRV_DEV_INFO *psCurrDevInfo, *psSysDevInfo;
if(SysAcquireData(&psSysData) != PVRSRV_OK)
{
/*
resort to using the passed Dev Info data,
It should be the 2D/3D entry
*/
psSysDevInfo = psDevData->psDevInfoKM;
}
else
{
psSysDevInfo = psSysData->psDevInfoList;
}
psCurrDevInfo = psSysDevInfo;
while (psCurrDevInfo)
{
if (psCurrDevInfo->pfnSetPowerState)
{
/* eError = psCurrDevInfo->pfnSetPowerState(psCurrDevInfo,
ePVRState,
PVRSRV_SEVERE_LOSS_OF_CONTEXT |
PVRSRV_PRE_STATE_CHANGE_MASK);
if(eError != PVRSRV_OK)
{
return eError;
}*/
psCurrDevInfo->pfnSetPowerState(psCurrDevInfo,
ePVRState,
PVRSRV_SEVERE_LOSS_OF_CONTEXT | PVRSRV_PRE_STATE_CHANGE_MASK);
}
psCurrDevInfo = psCurrDevInfo->psNext;
}
ResManSetPowerState(ePVRState,PVRSRV_SEVERE_LOSS_OF_CONTEXT | PVRSRV_PRE_STATE_CHANGE_MASK);
SysSetPowerState (ePVRState);
ResManSetPowerState(ePVRState,PVRSRV_SEVERE_LOSS_OF_CONTEXT );
psCurrDevInfo = psSysDevInfo;
while (psCurrDevInfo)
{
if (psCurrDevInfo->pfnSetPowerState)
{
/*eError = psCurrDevInfo->pfnSetPowerState(psCurrDevInfo,
ePVRState,
PVRSRV_SEVERE_LOSS_OF_CONTEXT);
if(eError != PVRSRV_OK)
{
return eError;
}*/
psCurrDevInfo->pfnSetPowerState(psCurrDevInfo,
ePVRState,
PVRSRV_SEVERE_LOSS_OF_CONTEXT);
}
psCurrDevInfo = psCurrDevInfo->psNext;
}
return (PVRSRV_OK);
}
#endif /* SUPPORT_POWER_STATE */
/*!
******************************************************************************
@Function CalcBytesPerPixel
@Description
Return Number of bits used to represent the given pixel format.
@Input ePixelFormat :
@Return static IMG_UINT32 : Number of bits used to represent the given pixel format
******************************************************************************/
static IMG_UINT32 CalcBytesPerPixel(PVRSRV_PIXEL_FORMAT ePixelFormat)
{
switch (ePixelFormat)
{
case PVRSRV_PIXEL_FORMAT_RGB565 :
return 2;
case PVRSRV_PIXEL_FORMAT_RGB555 :
return 2;
case PVRSRV_PIXEL_FORMAT_RGB888 :
return 3;
case PVRSRV_PIXEL_FORMAT_BGR888 :
return 3;
case PVRSRV_PIXEL_FORMAT_YUV420 :
return 2;
case PVRSRV_PIXEL_FORMAT_YUV444 :
return 3;
case PVRSRV_PIXEL_FORMAT_VUY444 :
return 3;
case PVRSRV_PIXEL_FORMAT_GREY_SCALE :
return 1;
case PVRSRV_PIXEL_FORMAT_YUYV :
return 2;
case PVRSRV_PIXEL_FORMAT_YVYU :
return 2;
case PVRSRV_PIXEL_FORMAT_UYVY :
return 2;
case PVRSRV_PIXEL_FORMAT_VYUY :
return 2;
case PVRSRV_PIXEL_FORMAT_PAL8 :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -