⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 halsurf.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
<module>
* Name         : halsurf.c
* Title        : DDraw surface functionality
* Author(s)    : Imagination Technologies
* Created      : 26 May 2004
*
* Copyright    : 2004 by Imagination Technologies Limited.
*                All rights reserved.  No part of this software, either
*                material or conceptual may be copied or distributed,
*                transmitted, transcribed, stored in a retrieval system
*                or translated into any human or computer language in any
*                form by any means, electronic, mechanical, manual or
*                other-wise, or disclosed to third parties without the
*                express written permission of Imagination Technologies
*                Limited, Unit 8, HomePark Industrial Estate,
*                King's Langley, Hertfordshire, WD4 8LZ, U.K.
*
* Description  : ddraw surface functionality
*
* Platform     : Windows CE
*
 $Log: halsurf.c $
********************************************************************************/
#include "ddraw_headers.h"

#include "overlay.h"

extern DISP_STATE g_DISPState;

/*****************************************************************************
<function>
 FUNCTION	: 	CreateSurfaces

 PARAMETERS	:	psDevInfo - pointer to our per device structure
				dwBPP - number of bits per pixel for these surfaces
				psPixelFormat - pointer to pixel format of surface
				psData - pointer to structure passed to MBXCreateSurface() by DirectDraw

 RETURNS	:	DD_OK if successful or a DirectDraw error code
 <function/>
*****************************************************************************/
LONG CreateSurfaces(DWORD dwBPP, DDPIXELFORMAT *psPixelFormat, LPDDHAL_CREATESURFACEDATA psData)
{
	DWORD						dwFirstSurfCaps;
	DWORD						dwSize;
	DWORD						dwIndex;
	DWORD						dwWidth;
	PPVRSRV_MEM_INFO			psMemInfo;
	PSURFDATA					psSurfData;
	DWORD						dwNewSurfIndex=0;
	DWORD						dwSurfIndex;
	LPDDRAWI_DDRAWSURFACE_LCL	psSurfLcl;
	DWORD						i;
	LONG						lErrorCode;
	PVRSRV_ERROR				eError;

	/* Store the caps for the first surface	*/
	dwFirstSurfCaps = psData->lplpSList[0]->ddsCaps.dwCaps;

	/* Create each surface in this request */
	for(i = 0; i < psData->dwSCnt; i++)
	{
		psSurfLcl = psData->lplpSList[i];

		psSurfData = (PSURFDATA) psSurfLcl->lpGbl->dwReserved1;

		/* Init some of the surface data */
		psSurfData->dwFlags = 0;

		/* Check if this surface/surface chain is for the primary surface */
		if(dwFirstSurfCaps & DDSCAPS_PRIMARYSURFACE)
		{
			/* Check if this is the primary surface	*/
			if(psSurfLcl->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
			{
				psSurfData->dwFlags = SURFDATAFLAGS_PRIMARY;
			}
			else
			{
				/* These are already setup for primary in top level create surface FN. */
				psData->lplpSList[0]->lpGbl->fpVidMem = GET_VMIDATA_ELEMENT(gpsDriverData, psData->lpDD, fpPrimary);
#ifdef FIXME // I Think this whole else block is irrelevant
				psSurfData->dwPhysAddress = gpsDriverData->psDisplayDriverSharedData->dwPrimaryPhyBase;
#endif //FIXME
			}
	 

			/* Surface dimension stuff.	(Stride is in pixels) */
			psSurfData->dwWidth		= GET_VMIDATA_ELEMENT(gpsDriverData, psData->lpDD, dwDisplayWidth);
			psSurfData->dwHeight	= GET_VMIDATA_ELEMENT(gpsDriverData, psData->lpDD, dwDisplayHeight);
			psSurfData->lStride		= ((GET_VMIDATA_ELEMENT(gpsDriverData, psData->lpDD, lDisplayPitch) << 3) /
										GET_VMIDATA_ELEMENT(gpsDriverData, psData->lpDD, ddpfDisplay).dwRGBBitCount);

			/* Check if this is the primary surface	*/
			if(dwNewSurfIndex == 0)
			{
				DPFLX(DBG_SURFACE, "Creating primary surface (0x%lx)", psSurfData);

				/* Init the primary flip table */
				gpsDriverData->sPrimFlipTable.dwActiveSurfaces = 0;

				for (dwIndex = 0; dwIndex < MAX_FLIP_SURFACES; dwIndex++)
				{
					gpsDriverData->sPrimFlipTable.asSurfaceInfo[dwIndex].pvSurfaceData = (PVOID) NULL;
				}
			}

			/* Check if this is part of a flipperable chain	*/
			if	(psData->dwSCnt > 1)
			{
				/* Store the fact that this is part of a primary flip chain	*/
				psSurfData->dwFlags |= SURFDATAFLAGS_PRIMARY_FLIP_CHAIN;		

				/* Check if this is the primary surface in a flip chain	*/
				if	(dwNewSurfIndex != 0)
				{
					DPFLX(DBG_SURFACE, "Creating surface in primary flip chain (0x%lx)", psSurfData);

					/* Allocate card memory for surface	*/
					dwWidth = ((DWORD) psSurfLcl->lpGbl->wWidth + 31) & 0xFFFFFFE0;

					dwSize = (dwBPP * dwWidth * (DWORD) psSurfLcl->lpGbl->wHeight) >> 3;

					DPFL2("%d,%d,%d",dwBPP,dwWidth,(DWORD) psSurfLcl->lpGbl->wHeight);
					DPFL2("Allocating 0x%8.8lX bytes for primary back buffer",dwSize);

					psSurfData->psMemInfo = NULL;

					/* FIXME - Flags/alignment may need to be different */
					if((eError = PVRHALAllocDeviceMem (&gpsDriverData->sDisplayDevData,
													   0,
													   dwSize+256,
													   MBX1_TSPPL2_TEXADDRALIGNSIZE,
													   &psMemInfo)) != PVRSRV_OK)
					{
						DPF("Failed to allocate surface memory...");

						if(eError == PVRSRV_ERROR_OUT_OF_MEMORY)
						{
							lErrorCode = DDERR_OUTOFVIDEOMEMORY;
						}
						else
						{
							lErrorCode = DDERR_GENERIC;
						}

						goto CreateSurfaceError;
					}
					
					/*
						Set where the surface was allocated from if it has not
						already been done so by the calling app
					*/
					psSurfLcl->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM;
					
					/* Set up surface data */
					psSurfData->psMemInfo = psMemInfo;

					psSurfData->pvLinAddress	= psSurfData->psMemInfo->pvLinAddr;

					psSurfLcl->lpGbl->lPitch = (LONG) ((dwWidth * dwBPP) >> 3);
					psSurfLcl->lpGbl->fpVidMem = (DWORD) psSurfData->pvLinAddress;
				}

				/* Update primary flip table */
				gpsDriverData->sPrimFlipTable.dwActiveSurfaces++;
				gpsDriverData->sPrimFlipTable.asSurfaceInfo[dwNewSurfIndex].pvSurfaceData = (PVOID) psSurfData;

				/* Store this surfaces flip surface number in surface data */
				psSurfData->dwSurfaceIndex = dwNewSurfIndex;

				/* Move to next surface */
				dwNewSurfIndex++;
			}
			else
			{
				/* Update primary flip table */
				gpsDriverData->sPrimFlipTable.dwActiveSurfaces = 1;
				gpsDriverData->sPrimFlipTable.asSurfaceInfo[0].pvSurfaceData=(PVOID)psSurfData;
			}
		}
		else
		{
			DPFLX(DBG_SURFACE, "Creating non-primary and non-textured surface (0x%lx)", psSurfData);

			/* Round width up to a multiple of 32 pixels */
			dwWidth = ((DWORD) psSurfLcl->lpGbl->wWidth + 31) & 0xFFFFFFE0;

			/* Create size of required surface in bytes. */
			dwSize = (dwBPP * dwWidth * (DWORD) psSurfLcl->lpGbl->wHeight) >> 3;

			DPFL2("%d,%d,%d",dwBPP,dwWidth,(DWORD) psSurfLcl->lpGbl->wHeight);
			DPFL2("Allocating 0x%8.8lX bytes",dwSize);

			psSurfData->psMemInfo = NULL;

			/* Allocate Device mem */
			if((eError = PVRHALAllocDeviceMem(&gpsDriverData->sDisplayDevData,
											  0,
											  dwSize,
											  MBX1_TSPPL2_TEXADDRALIGNSIZE,
											  &psMemInfo)) != PVRSRV_OK)
			{
				DPF("Failed to allocate surface memory...");

				if	(eError == PVRSRV_ERROR_OUT_OF_MEMORY)
				{
					lErrorCode = DDERR_OUTOFVIDEOMEMORY;
				}
				else
				{
					lErrorCode = DDERR_GENERIC;
				}

				goto CreateSurfaceError;
			}

			DPFL2("Mem handle -  0x%8.8lX",psMemInfo);

			/* Record where the surface was allocated */
			psSurfLcl->ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM;
			
			/* Setup some surface data entries.	*/
			psSurfData->psMemInfo = psMemInfo;

			psSurfData->lStride = (LONG) dwWidth;
			psSurfData->dwWidth = (DWORD) psSurfLcl->lpGbl->wWidth;
			psSurfData->dwHeight = (DWORD) psSurfLcl->lpGbl->wHeight;

			psSurfData->pvLinAddress = psSurfData->psMemInfo->pvLinAddr;

			if(dwBPP != 12)
			{
				psSurfLcl->lpGbl->lPitch = (LONG) ((dwWidth * dwBPP) >> 3);
			}
			else
			{
				psSurfLcl->lpGbl->lPitch = (LONG) dwWidth;
			}

			psSurfLcl->lpGbl->fpVidMem = (DWORD) psSurfData->pvLinAddress;

			/* initialise surface with it's physical (FB Base offset) address */
			*((DWORD *)psSurfData->pvLinAddress) = psSurfData->psMemInfo->uiDevAddr.uiAddr;

			/* Now sort out the overlay stuff */
			if(dwFirstSurfCaps & DDSCAPS_OVERLAY)
			{
				/* setup per-surface overlay details */
				DWORD dwSurfBase = psSurfData->psMemInfo->uiDevAddr.uiAddr;// - dwPhysBase;

				psSurfData->sOverlaySurface.wWidth = (WORD)psSurfData->dwWidth;
				psSurfData->sOverlaySurface.wHeight = (WORD)psSurfData->dwHeight;
				psSurfData->sOverlaySurface.wStride = (WORD)psSurfData->lStride;

				psSurfData->sOverlaySurface.pvOvlBase = (PVOID)(dwSurfBase);

				/* for the planar formats setup the additional base addresses */
				if(psSurfData->dwMBXFormat ==  MBXDD_FORMAT_IMC2)
				{
					dwSurfBase+=psSurfData->dwHeight*psSurfData->lStride;
					psSurfData->sOverlaySurface.pvOvlUBase = (PVOID)(dwSurfBase);
					psSurfData->sOverlaySurface.pvOvlVBase = (PVOID)(dwSurfBase + psSurfData->lStride/2);
				}
				else if(psSurfData->dwMBXFormat ==  MBXDD_FORMAT_YV12)
				{
					dwSurfBase+=psSurfData->dwHeight*psSurfData->lStride;
					psSurfData->sOverlaySurface.pvOvlVBase = (PVOID)(dwSurfBase);
					psSurfData->sOverlaySurface.pvOvlUBase = (PVOID)(dwSurfBase + psSurfData->dwHeight*psSurfData->lStride/4);
				}

				/* by default assume no de-interlacing */
				psSurfData->sOverlaySurface.DeInterlace = PDP_WEAVE;

				/* Update Overlay flip table */
				gpsDriverData->sOvlFlipTable.dwActiveSurfaces++;
				gpsDriverData->sOvlFlipTable.asSurfaceInfo[dwNewSurfIndex].pvSurfaceData = (PVOID) psSurfData;

				/* Store this surfaces flip surface number in surface data */
				psSurfData->dwSurfaceIndex = dwNewSurfIndex;

				/* mark the surface flippable */
				psSurfLcl->ddsCaps.dwCaps |= DDSCAPS_FLIP;

				/* mark the surface as an overlay */
				psSurfData->dwFlags |= SURFDATAFLAGS_OVERLAY;

				/* Move to next surface */
				dwNewSurfIndex++;
			}
		}
	}

	return (DD_OK);

CreateSurfaceError:
	/*
		Ok an error occurred, we need to clean up any mess..
		'i' will hold the surface number that was being processed then the error occured
	*/

	/* Check if this was a primary surface chain */
	if(dwFirstSurfCaps & DDSCAPS_PRIMARYSURFACE)
	{
		/* For each surface */
		while (i != 0xffffffff)
		{
			/* Find surface data */
			psSurfLcl = psData->lplpSList[i];
			psSurfData = (PSURFDATA) psSurfLcl->lpGbl->dwReserved1;

			/* Free card memory if it was allocated and indicate that it has been freed */
			if (i != 0 && psSurfData->psMemInfo != NULL)
			{
				PVRHALFreeDeviceMem(&gpsDriverData->sDisplayDevData, psSurfData->psMemInfo);	
				psSurfData->psMemInfo=NULL;
			}

			/* Move to previous surface */
			i--;

		}

		/* Reset primary flip table */
		gpsDriverData->sPrimFlipTable.dwActiveSurfaces=0;

		for (dwSurfIndex=0; dwSurfIndex < MAX_FLIP_SURFACES; dwSurfIndex++)
		{
			gpsDriverData->sPrimFlipTable.asSurfaceInfo[dwSurfIndex].pvSurfaceData=NULL;
		}
	}
	else
	{
		if(dwFirstSurfCaps & DDSCAPS_OVERLAY)
		{
			/* we were setting up an overlay and it failed */
			gpsDriverData->sOvlFlipTable.dwActiveSurfaces = 0;	
		}

		/*For each surface*/
		while (i != 0xffffffff)
		{
			/* Find surface data */
			psSurfLcl = psData->lplpSList[i];
			psSurfData = (PSURFDATA) psSurfLcl->lpGbl->dwReserved1;	

			/* Check if card memory was allocated */
			if(psSurfData->psMemInfo != NULL)
			{
				/* Release card memory and indicate that is has been freed */
				PVRHALFreeDeviceMem(&gpsDriverData->sDisplayDevData, psSurfData->psMemInfo);
				psSurfData->psMemInfo=NULL;
			}

			/*Move to previous surface*/
			i--;
		}
	}

	return(lErrorCode);
}
/*****************************************************************************
<function>
 FUNCTION	: 	HALCreateSurface

 PARAMETERS	: 	LPDDHAL_CREATESURFACEDATA structure 

 RETURNS	:	DDHAL return code
 <function/>
*****************************************************************************/
DWORD WINAPI HALCreateSurface( LPDDHAL_CREATESURFACEDATA psData )
{
	DWORD						i;
	DWORD						dwBPP;
	DWORD						dwSurfaceCaps;
	PVRSRV_DEV_INFO				*psDevInfo;
	PVRSRV_DEV_DATA				*psDevData;
	DDPIXELFORMAT				sPixelFormat;
	DWORD						dwMBXFormat;
	LPDDRAWI_DDRAWSURFACE_LCL	psSurfLcl;
	LONG						lRet;	
	DWORD						dwResult;
	PSURFDATA					psSurfData;
	DDSURFACEDESC				*lpDDSurfDesc;
	
	DPFLX(DBG_DD_ENTRY, "HALCreateSurface() called");

	psDevData		= &gpsDriverData->sDisplayDevData;
	psDevInfo		= psDevData->psDevInfoKM;
	lRet			= DD_OK; 	
	dwResult		= DDHAL_DRIVER_HANDLED;
	lpDDSurfDesc	= psData->lpDDSurfaceDesc;
	dwSurfaceCaps	= psData->lpDDSurfaceDesc->ddsCaps.dwCaps;


	/*
		Ignore system-memory surface-destroy notifications - we get told about
		destroyed sys-mem surfaces via a call to CreateSurfaceEx.
	*/
/*	if(dwSurfaceCaps & DDSCAPS_SYSTEMMEMORY)
	{
		psData->ddRVal = DD_OK;
		dwResult = DDHAL_DRIVER_HANDLED;

		goto HALCreateSurfaceExit;
	}*/

	DPFLX(DBG_SURFACE, "Surfaces    %d",psData->dwSCnt);
	DPFLX(DBG_SURFACE, "Flags     0x%8.8lX",psData->lpDDSurfaceDesc->dwFlags);
	DPFLX(DBG_SURFACE, "ddsCaps   0x%8.8lX",dwSurfaceCaps);
	DPFLX(DBG_SURFACE, "Height      %d",psData->lpDDSurfaceDesc->dwHeight);
	DPFLX(DBG_SURFACE, "Width       %d",psData->lpDDSurfaceDesc->dwWidth);
	DPFLX(DBG_SURFACE, "BPP         %d",psData->lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount);

	/* Driver name should be valid here so copy into driver data */
	memcpy(&gpsDriverData->pszDriverName, &psData->lpDD->cDriverName, MAX_DRIVER_NAME);

	/* Make sure our reserved words are NULL to avoid confusion later */
	for(i = 0; i < psData->dwSCnt; i++)
	{
		psSurfLcl = psData->lplpSList[i];
		psSurfLcl->lpGbl->dwReserved1 = 0;
	}

	/* Extract pixel format information - if not available, use primary surface type */
	if(psData->lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT)
	{
		/* Has valid pixel format */
		sPixelFormat = psData->lpDDSurfaceDesc->ddpfPixelFormat;
	}
	else
	{
		/* No valid pixel format, use primary type */
		DPFL2("Pixel format not valid, pull from primary, 0x%8.8lX", GET_VMIDATA_ELEMENT(gpsDriverData, psData->lpDD,ddpfDisplay));

		/* Copy complete structure */
		sPixelFormat = GET_VMIDATA_ELEMENT(gpsDriverData, psData->lpDD, ddpfDisplay);
	}

	/* Convert DirectDraw pixel format to MBX format */
	dwMBXFormat = ConvertPixelFormatToMBX(&sPixelFormat);

	/* Check if valid value returned, i.e. not */
	if(dwMBXFormat == 0)
	{
		psData->ddRVal = DDERR_INVALIDPIXELFORMAT;
		dwResult = DDHAL_DRIVER_HANDLED;
		goto HALCreateSurfaceExit;
	}

	/* Check for FOURCC's */
	if(sPixelFormat.dwFlags & DDPF_FOURCC)
	{
		dwBPP = GetBPPFromFOURCC(sPixelFormat.dwFourCC);

		/* Change the dwRGBBitCount value since this is the actual value */
		sPixelFormat.dwRGBBitCount = dwBPP;
	}
	else
	{
		dwBPP = sPixelFormat.dwRGBBitCount;
	}

	/* Allocate surface local data blocks */
	for (i = 0; i < psData->dwSCnt; i++)
	{
		psSurfLcl = psData->lplpSList[i];

		/* Allocate our internal surface data struct */
		psSurfData = (PSURFDATA) AllocSharedMem(sizeof(SURFDATA));
		if(!psSurfData)
		{
			psData->ddRVal = DDERR_OUTOFMEMORY;
			dwResult = DDHAL_DRIVER_HANDLED;
			goto HALCreateSurfaceExit;
		}
		DPFLX(DBG_SURFACE, "Allocated surface data (0x%lx)", psSurfData);

		if(psSurfLcl->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -