📄 halsurf.c
字号:
DWORD WINAPI HALUnlock( LPDDHAL_UNLOCKDATA psData )
{
PSURFDATA psSurfData;
DWORD dwResult = DDHAL_DRIVER_HANDLED;
LPDDRAWI_DDRAWSURFACE_LCL psSurfLcl;
DPFLX(DBG_DD_ENTRY, "HALUnLock() called");
psSurfLcl = psData->lpDDSurface;
/* Extract our surface data */
psSurfData = (PSURFDATA) psSurfLcl->lpGbl->dwReserved1;
if(psSurfData)
{
if(psSurfData->dwFlags & SURFDATAFLAGS_LOCKED)
{
psData->ddRVal = DD_OK;
/*
if the lock is on the primary we must update
the Single shot display (if there is one)
*/
if(psSurfData->dwFlags & SURFDATAFLAGS_PRIMARY)
{
/*Queue Update ?*/
}
(*psSurfData->psMemInfo->psSyncInfo->pui32LastWriteOp)++;
/* Mark the surface as unlocked */
psSurfData->dwFlags &= ~SURFDATAFLAGS_LOCKED;
}
else
{
psData->ddRVal = DDERR_NOTLOCKED;
}
}
else
{
DPFL4("Invalid internal data pointer in surface, not unlocking.");
psData->ddRVal = DDERR_GENERIC;
}
return(dwResult);
}
/*****************************************************************************
<function>
FUNCTION : HALDestroySurface
PARAMETERS : LPDDHAL_DESTROYSURFACEDATA structure
RETURNS : DDHAL return code
<function/>
*****************************************************************************/
DWORD WINAPI HALDestroySurface( LPDDHAL_DESTROYSURFACEDATA psData )
{
PSURFDATA psSurfData;
LPDDRAWI_DDRAWSURFACE_LCL psSurfLcl;
PVRSRV_DEV_INFO *psDevInfo;
DWORD dwResult;
DPFLX(DBG_DD_ENTRY, "HALDestroySurface() called");
psDevInfo = gpsDriverData->sDisplayDevData.psDevInfoKM;
dwResult = DDHAL_DRIVER_HANDLED;
/* Get hold of our internal surface data for this DD surface */
psSurfLcl = psData->lpDDSurface;
psSurfData = (PSURFDATA) psSurfLcl->lpGbl->dwReserved1;
if(!psSurfData)
{
DPFLX(DBG_SURFACE, "HALDestroySurface: No surf-data for DD-surf 0x%8.8lX (handle %d)", psSurfLcl, psSurfLcl->lpSurfMore->dwSurfaceHandle);
psData->ddRVal = DD_OK;
dwResult = DDHAL_DRIVER_NOTHANDLED;
goto HALDestroySurfaceExit;
}
DPFLX(DBG_SURFACE, "HALDestroySurface: Destroying surface %d (surf-data 0x%8.8lX)", psSurfData->dwSurfHandle, psSurfData);
/*
Ignore system-memory surface-destroy notifications - we get told about
destroyed sys-mem surfaces via a call to CreateSurfaceEx.
*/
if(psSurfData->dwDDSCaps & DDSCAPS_SYSTEMMEMORY)
{
psData->ddRVal = DD_OK;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALDestroySurfaceExit;
}
/* If a GPESurf object has been created, so destroy it */
if (psSurfData->pvGPESurf)
{
memset(psSurfData->pvGPESurf, 0, SIZEOF_MBXSURF_CLASS);
psSurfData->pvGPESurf = NULL;
}
/* Is it the primary surface? */
if(psSurfData->dwFlags & SURFDATAFLAGS_PRIMARY)
{
FreeSharedMem(psSurfData);
psData->ddRVal = DD_OK;
goto HALDestroySurfaceExit;
}
/*
If this surface is part of a primary-surface flipping chain,
remove it from the flip-table
*/
if(psSurfData->dwFlags & SURFDATAFLAGS_PRIMARY_FLIP_CHAIN)
{
PPRIM_SURF_TABLE psPrimSurfTable;
PPRIM_SURF_INFO psSurfInfo;
psPrimSurfTable = &gpsDriverData->sPrimFlipTable;
psSurfInfo = &psPrimSurfTable->asSurfaceInfo[psSurfData->dwSurfaceIndex];
psSurfInfo->pvSurfaceData = NULL;
gpsDriverData->sPrimFlipTable.dwActiveSurfaces--;
}
/*
If this surface is an Overlay surface,
remove it from the flip-table
*/
if(psSurfData->dwFlags & SURFDATAFLAGS_OVERLAY)
{
PPRIM_SURF_TABLE psOvlSurfTable;
PPRIM_SURF_INFO psSurfInfo;
psOvlSurfTable = &gpsDriverData->sOvlFlipTable;
psSurfInfo = &psOvlSurfTable->asSurfaceInfo[psSurfData->dwSurfaceIndex];
psSurfInfo->pvSurfaceData = NULL;
gpsDriverData->sOvlFlipTable.dwActiveSurfaces--;
/*
Free device memory allocated for the surface (if not primary) -
On overlay services we need to do this before de-activating the overlay.
*/
if(!(psSurfData->dwFlags & SURFDATAFLAGS_PRIMARY))
{
PVRHALFreeDeviceMem(&gpsDriverData->sDisplayDevData, psSurfData->psMemInfo);
}
if(gpsDriverData->sOvlFlipTable.dwActiveSurfaces == 0)
{
/*
switch off overlay by setting invalid pixel format
*/
gpsDriverData->sOverlayAttributes.wValidFlags = PDP_OVERLAYATTRIB_VALID_PIXFMT;
gpsDriverData->sOverlayAttributes.PixFormat = PDP_OVL_INVALID;
if(PDP_SetOverlayAttributes(g_PDPHandle, &gpsDriverData->sOverlayAttributes) != PDP_ERROR_OK)
{
DPF("HALDestroySurface : failed call to PDP_SetOverlayAttributes");
psData->ddRVal = DDERR_GENERIC;
return DDHAL_DRIVER_NOTHANDLED;
}
if (DisplayStateDeinit() != 0)
{
DPF("HALDestroySurface : failed call to DisplayStateDeinit");
ASSERT(0);
psData->ddRVal = DDERR_GENERIC;
return DDHAL_DRIVER_NOTHANDLED;
}
gpsDriverData->bOverlayInUse = FALSE;
}
FreeSharedMem(psSurfData);
psData->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
/* Free device memory allocated for the surface (if not primary) */
if(!(psSurfData->dwFlags & SURFDATAFLAGS_PRIMARY))
{
PVRHALFreeDeviceMem(&gpsDriverData->sDisplayDevData, psSurfData->psMemInfo);
}
/*
Free the surface-data for this surface
NB: The data for system-memory surfaces is created/destroyed when
we are told about them in MBXCreateSurfaceEx
*/
FreeSharedMem(psSurfData);
psData->ddRVal = DD_OK;
HALDestroySurfaceExit:
psSurfLcl->lpGbl->dwReserved1 = 0;
return(dwResult);
}
/*****************************************************************************
<function>
FUNCTION : HALFlip
PARAMETERS : LPDDHAL_FLIPDATA structure
RETURNS : DDHAL return code
<function/>
*****************************************************************************/
DWORD WINAPI HALFlip(LPDDHAL_FLIPDATA psFlipData)
{
PVRSRV_DEV_INFO *psDevInfo = NULL;
PSURFDATA psFlipFromSurfData = NULL;
PSURFDATA psFlipToSurfData = NULL;
DWORD dwFlipInterval;
IMG_BOOL bOverlay = IMG_FALSE;
PVRSRV_ERROR eError = PVRSRV_OK;
PVRSRV_QUEUE_INFO *psQueueInfo;
#ifdef SUPPORT_OVERLAY
IMG_UINT32* pui32OverlayConfig;
IMG_UINT32 ui32OverlayConfigSize;
#endif
/* Extract our driver data from global object */
psDevInfo = gpsDriverData->sDisplayDevData.psDevInfoKM;
psFlipToSurfData = (PSURFDATA) psFlipData->lpSurfTarg->lpGbl->dwReserved1;
psFlipFromSurfData = (PSURFDATA) psFlipData->lpSurfCurr->lpGbl->dwReserved1;
psFlipData->ddRVal = DD_OK;
/* Queue all flips to the HAL queue object */
psQueueInfo = gpsDriverData->psDDQueueInfo;
/* Check that surfaces are valid */
if(!(psFlipFromSurfData) || !(psFlipToSurfData))
{
psFlipData->ddRVal = DDERR_GENERIC;
return DDHAL_DRIVER_HANDLED;
}
if((psFlipToSurfData) && (psFlipToSurfData->dwFlags & SURFDATAFLAGS_OVERLAY))
{
#ifdef SUPPORT_OVERLAY
PDP_OVERLAY* psFlipToOverlay;
#endif
/* this is an overlay flip */
bOverlay = IMG_TRUE;
#ifdef SUPPORT_OVERLAY
/* Rotate overlay if required */
if (g_DISPState.ui32SourceRotation)
{
/* Rotate overlay before flipping */
PDP_OVERLAY sRotateOverlay;
RotateOverlay(psFlipToSurfData, 0, &sRotateOverlay);
psFlipToOverlay = &sRotateOverlay;
}
else
{
/* Overlay is not rotated before flipping */
psFlipToOverlay = &psFlipToSurfData->sOverlaySurface;
}
/* Generate overlay register configuration data and store in a buffer.
(buffer format: {reg address, data, reg address, data, ...} etc). Get pointers
to the OverlayConfig buffer and OverlayConfigSize. This information will be
passed to PVRSRVQueueOverlayFlip below. Registers will only be written
during a VSYNC interrupt. */
PDP_PrepareOverlayFlip(g_PDPHandle, psFlipToOverlay, &pui32OverlayConfig, &ui32OverlayConfigSize);
#else
/* FIXME Unitl the interrupt code is made overlay aware always do overlay flips immediately */
psFlipData->dwFlags = DDFLIP_NOVSYNC;
#endif
}
/* Set up VSYNC status */
switch(psFlipData->dwFlags)
{
case DDFLIP_INTERVAL2 :
dwFlipInterval = 2;
break;
case DDFLIP_INTERVAL3 :
dwFlipInterval = 3;
break;
case DDFLIP_INTERVAL4 :
dwFlipInterval = 4;
break;
case DDFLIP_NOVSYNC :
dwFlipInterval = 0;
break;
default : // DDFLIP_INTERVAL1
dwFlipInterval = 1;
break;
}
/* Do not allow another flip to be queued for a surface until 'completed reads'
has caught up with 'pending reads'. This prevents the VSYNC flip queue from
overflowing during a rapid sequence of flips - e.g. when surfaces are flipped
over and over again without being locked/written to/unlocked between flips. */
if (psFlipToSurfData->psMemInfo->psSyncInfo->ui32ReadOpsComplete <
psFlipToSurfData->psMemInfo->psSyncInfo->ui32ReadOpsPending)
{
psFlipData->ddRVal = DDERR_WASSTILLDRAWING;
return(DDHAL_DRIVER_HANDLED);
}
#ifdef SUPPORT_OVERLAY
if (bOverlay)
{
/* This is an overlay flip - it is performed during a VSYNC interrupt. */
/* Update the 'last sync object' pointer - the last surface to be 'flipped to' is a
special case and its sync object must be accessible during deinitialization. */
g_DISPState.psLastSyncObject = psFlipToSurfData->psMemInfo->psSyncInfo;
eError = PVRSRVQueueOverlayFlip(psQueueInfo,
psFlipToSurfData->psMemInfo->psSyncInfo,
psFlipFromSurfData->psMemInfo->psSyncInfo,
psFlipToSurfData->psMemInfo,
(psFlipData->dwFlags == DDFLIP_NOVSYNC) ? FALSE : TRUE,
dwFlipInterval,
pui32OverlayConfig,
ui32OverlayConfigSize);
}
else
#endif
{
/* Queue a flush to flush synchronous blits */
eError = PVRSRVQueueBlt(psQueueInfo,
psFlipToSurfData->psMemInfo->psSyncInfo,
0,
IMG_NULL,
0,
IMG_NULL);
if(eError != PVRSRV_OK)
{
psFlipData->ddRVal = DDERR_WASSTILLDRAWING;
return(DDHAL_DRIVER_HANDLED);
}
/* Queue the flip */
eError = PVRSRVQueueFlip(psQueueInfo,
psFlipToSurfData->psMemInfo->psSyncInfo,
psFlipFromSurfData->psMemInfo->psSyncInfo,
psFlipToSurfData->psMemInfo,
(psFlipData->dwFlags == DDFLIP_NOVSYNC) ? FALSE : TRUE,
dwFlipInterval);
}
if(eError != PVRSRV_OK)
{
psFlipData->ddRVal = DDERR_WASSTILLDRAWING;
}
else
{
// Clear LASTOPWASBLT flag for both surfaces.
psFlipToSurfData->dwFlags &= ~SURFDATAFLAGS_LASTOPWASBLT;
psFlipFromSurfData->dwFlags &= ~SURFDATAFLAGS_LASTOPWASBLT;
// setup return value
psFlipData->ddRVal = DD_OK;
}
return(DDHAL_DRIVER_HANDLED);
}
/*****************************************************************************
<function>
FUNCTION : HALSetColorKey
PARAMETERS : LPDDHAL_SETCOLORKEYDATA structure
RETURNS : DDHAL return code
<function/>
*****************************************************************************/
DWORD WINAPI HALSetColorKey( LPDDHAL_SETCOLORKEYDATA psColorKeyData )
{
PSURFDATA psSurfData = psSurfData = (PSURFDATA)psColorKeyData->lpDDSurface->lpGbl->dwReserved1;
/* Precondition checking */
if(psColorKeyData->dwFlags & DDCKEY_SRCOVERLAY)
{
/* We don't allow the source colour keying on Overlays */
psColorKeyData->ddRVal = DDERR_NOOVERLAYHW;
return DDHAL_DRIVER_NOTHANDLED;
}
if((psColorKeyData->dwFlags & DDCKEY_COLORSPACE) ||
(psColorKeyData->ckNew.dwColorSpaceLowValue !=
psColorKeyData->ckNew.dwColorSpaceHighValue))
{
/* We don't support colourkey ranges */
psColorKeyData->ddRVal = DDERR_UNSUPPORTED;
return DDHAL_DRIVER_NOTHANDLED;
}
if(psColorKeyData->dwFlags & DDCKEY_SRCBLT)
{
/* Set or clear the source color key */
if (psColorKeyData->lpDDSurface->dwFlags & DDRAWISURF_HASCKEYSRCBLT)
{
psSurfData->eColorKeyType |= SourceColorKey;
psSurfData->dwDDSrcColorKey = psColorKeyData->ckNew.dwColorSpaceLowValue;
}
else
{
psSurfData->eColorKeyType &= ~SourceColorKey;
}
}
if(psColorKeyData->dwFlags & DDCKEY_DESTBLT)
{
/* Set or clear the destination color key */
if (psColorKeyData->lpDDSurface->dwFlags & DDRAWISURF_HASCKEYDESTBLT)
{
psSurfData->eColorKeyType |= DestColorKey;
psSurfData->dwDDDstColorKey = psColorKeyData->ckNew.dwColorSpaceLowValue;
}
else
{
psSurfData->eColorKeyType &= ~DestColorKey;
}
}
/* Check for overlay case */
if(psColorKeyData->dwFlags & DDCKEY_DESTOVERLAY)
{
if(gpsDriverData->bOverlayInUse && (psSurfData->dwFlags & SURFDATAFLAGS_OVERLAY))
{
/* program up overlay color key and store details in gpsDriverData->sOverlayAttributes */
gpsDriverData->sOverlayAttributes.wValidFlags = PDP_OVERLAYATTRIB_VALID_CKEY;
gpsDriverData->sOverlayAttributes.dwCKeyValue = psColorKeyData->ckNew.dwColorSpaceLowValue;
if(PDP_SetOverlayAttributes(g_PDPHandle, &gpsDriverData->sOverlayAttributes) != PDP_ERROR_OK)
{
/* call failed */
DPF("HALSetColorKey : failed call to PDPAL");
psColorKeyData->ddRVal = DDERR_GENERIC;
return DDHAL_DRIVER_NOTHANDLED;
}
}
else
{
/* is it valid to set the overlay colour key when there is no overlay ? */
psColorKeyData->ddRVal = DDERR_INVALIDSURFACETYPE;
return DDHAL_DRIVER_NOTHANDLED;
}
psColorKeyData->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
psColorKeyData->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
/*****************************************************************************
<function>
FUNCTION : HALGetFlipStatus
PARAMETERS : LPDDHAL_GETFLIPSTATUSDATA structure
RETURNS : DDHAL return code
<function/>
*****************************************************************************/
DWORD WINAPI HALGetFlipStatus( LPDDHAL_GETFLIPSTATUSDATA pd )
{
// FIXME - Implementation
pd->ddRVal = DDERR_UNSUPPORTED;
return DDHAL_DRIVER_HANDLED;
}
/*****************************************************************************
End of file (halsurf.c)
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -