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

📄 blitsw.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
<module>
* Name         : Blitsw.c
* Title        : Software blitting functions
* Author(s)    : Imagination Technologies
* Created      : 2 March 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  : Functions for software blitting and colourfilling.
*
* Platform     : Windows CE
*
</module>
********************************************************************************/

#include "context.h"

/*----------------------------------------------------------------------------
<function>
 FUNCTION	: RotatePixelCoords
    
 PURPOSE	: Takes a pixel location and gives its equivalent rotated coords
</function>
------------------------------------------------------------------------------*/
IMG_VOID RotatePixelCoords(IMG_UINT32 ui32Xin, 
						   IMG_UINT32 ui32Yin, 
						   IMG_UINT32 *pui32Xout, 
						   IMG_UINT32 *pui32Yout, 
						   IMG_UINT32 ui32TargetWidth, 
						   IMG_UINT32 ui32TargetHeight, 
						   IMG_UINT32 ui32RotationAngle)
{
	switch(ui32RotationAngle)
	{
		case 0:
		{
			*pui32Xout = ui32Xin;
			*pui32Yout = ui32Yin;
			break;
		}
		case 90:
		{
			*pui32Xout = ui32Yin;
			*pui32Yout = ui32TargetHeight - ui32Xin - 1;
			break;	
		}
		case 180:
		{
			*pui32Xout = ui32TargetWidth - ui32Xin - 1;
			*pui32Yout = ui32TargetHeight - ui32Yin - 1;

			break;			
		}
		case 270:
		{
			*pui32Xout	 = ui32TargetWidth - ui32Yin - 1;
			*pui32Yout	 = ui32Xin;
			break;
		}
	}
}
/*----------------------------------------------------------------------------
<function>
 FUNCTION	: PixelIsClipped
    
 PURPOSE	: Checks to see if a point is clipped out or not
</function>
------------------------------------------------------------------------------*/
IMG_BOOL PixelIsClipped(RECT			*psClipRects, 
						IMG_UINT32		ui32NumClipRects, 
						LPD3DM_SURFACE	psDestSurface,
						RECT			*psDestRect,
						IMG_UINT32		ui32X,
						IMG_UINT32		ui32Y)
{
	IMG_INT32 i32XSurfaceValue, i32YSurfaceValue;
	IMG_UINT32 i;

	i32XSurfaceValue = (IMG_INT32) ui32X + psDestRect->left;
	i32YSurfaceValue = (IMG_INT32) ui32Y + psDestRect->top;

	for(i=0; i< ui32NumClipRects; i++, psClipRects++)
	{
		 
		if(i32XSurfaceValue > psClipRects->left	    &&
		   i32XSurfaceValue < psClipRects->right	&&
		   i32YSurfaceValue > psClipRects->top		&&
		   i32YSurfaceValue < psClipRects->bottom)
		{
			/* Pixel isn't clipped */
			return FALSE;
		}
	}
	return TRUE;
}
/*----------------------------------------------------------------------------
<function>
 FUNCTION	: GetPixelFromBuffer
    
 PURPOSE	: Grabs a pixel from a buffer
</function>
------------------------------------------------------------------------------*/
IMG_UINT32 GetPixelFromBuffer(IMG_UINT8		*pui8Pixels,
							  IMG_UINT32	ui32StrideByte, 
							  IMG_UINT32	ui32X,
							  IMG_UINT32	ui32Y,
							  IMG_UINT32	ui32BytesPerPixel)
{
	IMG_UINT32 ui32TargetColour;

	switch(ui32BytesPerPixel)
	{
		case 1:
		{
			ui32TargetColour = (IMG_UINT32) *(pui8Pixels					+ 
											 (ui32Y * ui32StrideByte)		+
											 (ui32X * ui32BytesPerPixel));
			break;
		}
		case 2:
		{
			ui32TargetColour = (IMG_UINT32) *((IMG_UINT16*) (pui8Pixels						+ 
															(ui32Y * ui32StrideByte)		+
															(ui32X * ui32BytesPerPixel)));
			break;
		}
		case 4:
		{
			ui32TargetColour = *((IMG_UINT32*) (pui8Pixels						    + 
											   (ui32Y * ui32StrideByte)				+
											   (ui32X * ui32BytesPerPixel)));
			break;
		}
	}
	return ui32TargetColour;
}
/*----------------------------------------------------------------------------
<function>
 FUNCTION	: WritePixelToBuffer
    
 PURPOSE	: Writes a pixel to a buffer
</function>
------------------------------------------------------------------------------*/
IMG_VOID   WritePixelToBuffer(IMG_UINT8		*pui8Pixels,
							  IMG_UINT32	ui32PixelValue,
							  IMG_UINT32	ui32StrideByte, 
							  IMG_UINT32	ui32X,
							  IMG_UINT32	ui32Y,
							  IMG_UINT32	ui32BytesPerPixel)
{
	/* Copy pixel to buffer */
	switch(ui32BytesPerPixel)
	{
		case 1:
		{
			*(pui8Pixels + (ui32Y * ui32StrideByte) + 
						   (ui32X * ui32BytesPerPixel)) 
					     = ((IMG_UINT8) ui32PixelValue);
			break;
		}
		case 2:
		{
			*((IMG_UINT16*)(pui8Pixels					+
						   (ui32Y * ui32StrideByte)		+ 
						   (ui32X * ui32BytesPerPixel))) 
						 = ((IMG_UINT16) ui32PixelValue);
			break;
		}
		case 4:
		{
			*((IMG_UINT32*)(pui8Pixels					+ 
						   (ui32Y * ui32StrideByte)		+ 
						   (ui32X * ui32BytesPerPixel))) 
						 =  ui32PixelValue;
			break;
		}
	}
}
/*----------------------------------------------------------------------------
<function>
 FUNCTION	: ScaleColour
    
 PURPOSE	: Scales a colour value
</function>
------------------------------------------------------------------------------*/
IMG_VOID ScaleColour(IMG_UINT32 *pui32ColourVal, IMG_UINT32 ui32MaxSource, IMG_UINT32 ui32MaxDest)
{
	IMG_UINT8 ui8Shift = 0;
	if(ui32MaxSource > ui32MaxDest)
	{
		/* Dest value has smaller headroom (fewer bits) */
		while(ui32MaxSource != ui32MaxDest)
		{
			ui32MaxSource = ui32MaxSource >> 1;
			ui8Shift++;
		}

		*pui32ColourVal = *pui32ColourVal >> ui8Shift;
	}
	else if(ui32MaxDest > ui32MaxSource)
	{
		/* Dest value has greater headroom (more bits) */
		while(ui32MaxDest != ui32MaxSource)
		{
			ui32MaxSource = (ui32MaxSource << 1) | 0x1;
			ui8Shift++;
		}
		*pui32ColourVal = *pui32ColourVal << ui8Shift;
	}
	else return; /* No change */
}
/*----------------------------------------------------------------------------
<function>
 FUNCTION	: CopyConvertPixel
    
 PURPOSE	: Copys and converts the given pixel
</function>
------------------------------------------------------------------------------*/
IMG_VOID CopyConvertPixel(PVR_DEVFORMAT	*psSourceFMT,
						  IMG_UINT8		*pui8Src,
						  IMG_UINT32	ui32SrcStrideByte,
						  IMG_UINT32	ui32SrcBytesPerPixel,
						  PVR_DEVFORMAT	*psDestFMT,
						  IMG_UINT8		*pui8Dest,
						  IMG_UINT32	ui32DestStrideByte,
						  IMG_UINT32	ui32DestBytesPerPixel,
						  IMG_UINT32	ui32X,
						  IMG_UINT32	ui32Y,
						  IMG_UINT32	ui32RotationAngle,
						  IMG_UINT32	ui32TargetWidth,
						  IMG_UINT32	ui32TargetHeight)
{
	IMG_UINT32 ui32Pixel;
	IMG_UINT32 ui32Alpha, ui32Red, ui32Green, ui32Blue;
	IMG_UINT32 ui32XRotate, ui32YRotate;

	/* Grab source pixel */
	ui32Pixel = GetPixelFromBuffer(pui8Src, ui32SrcStrideByte, ui32X, ui32Y, ui32SrcBytesPerPixel);

	/* Unpack Source pixel */
	ui32Alpha = ((ui32Pixel & psSourceFMT->ui32AMask) >> psSourceFMT->ui32AShift);
	ui32Red   = ((ui32Pixel & psSourceFMT->ui32RMask) >> psSourceFMT->ui32RShift);
	ui32Green = ((ui32Pixel & psSourceFMT->ui32GMask) >> psSourceFMT->ui32GShift);
	ui32Blue  = ((ui32Pixel & psSourceFMT->ui32BMask) >> psSourceFMT->ui32BShift);

	/* Scale Colour Values */
	ScaleColour(&ui32Alpha, psSourceFMT->ui32AMask >> psSourceFMT->ui32AShift, psDestFMT->ui32AMask >> psDestFMT->ui32AShift);
	ScaleColour(&ui32Red,	psSourceFMT->ui32RMask >> psSourceFMT->ui32RShift, psDestFMT->ui32RMask >> psDestFMT->ui32RShift);
	ScaleColour(&ui32Green, psSourceFMT->ui32GMask >> psSourceFMT->ui32GShift, psDestFMT->ui32GMask >> psDestFMT->ui32GShift);
	ScaleColour(&ui32Blue,	psSourceFMT->ui32BMask >> psSourceFMT->ui32BShift, psDestFMT->ui32BMask >> psDestFMT->ui32BShift);

	/* Repack pixel */
	ui32Pixel   =   (ui32Alpha	<< psDestFMT->ui32AShift)
				|	(ui32Red	<< psDestFMT->ui32RShift)
				|	(ui32Green	<< psDestFMT->ui32GShift)
				|	(ui32Blue	<< psDestFMT->ui32BShift);

	switch(ui32RotationAngle)
	{
		case 0:
		{
			ui32XRotate = ui32X;
			ui32YRotate = ui32Y;
			break;
		}
		case 90:
		case 180:
		case 270:
		{
			RotatePixelCoords(ui32X, ui32Y, &ui32XRotate, &ui32YRotate, ui32TargetWidth, ui32TargetHeight, ui32RotationAngle);
			break;
		}
	}

	/* Write new pixel to dest */
	WritePixelToBuffer(pui8Dest, ui32Pixel, ui32DestStrideByte, ui32XRotate, ui32YRotate, ui32DestBytesPerPixel);
}
/*----------------------------------------------------------------------------
<function>
 FUNCTION	: InterpolatePixels
    
 PURPOSE	: Interpolates between 2 pixel values
</function>
------------------------------------------------------------------------------*/
IMG_UINT32 InterpolatePixels(PVR_DEVFORMAT	*psPixelFormat, 
							 IMG_UINT32		ui32PixValA, 
							 IMG_FLOAT		fPixScaleA, 
							 IMG_UINT32		ui32PixValB, 
							 IMG_FLOAT		fPixScaleB)
{
	IMG_FLOAT fPixAAlpha, fPixARed, fPixAGreen, fPixABlue;	
	IMG_FLOAT fPixBAlpha, fPixBRed, fPixBGreen, fPixBBlue;
	IMG_FLOAT fPixOutAlpha, fPixOutRed, fPixOutGreen, fPixOutBlue;

	/* Unpack Pixel A */
	fPixAAlpha = (IMG_FLOAT) ((ui32PixValA & psPixelFormat->ui32AMask) >> psPixelFormat->ui32AShift);
	fPixARed   = (IMG_FLOAT) ((ui32PixValA & psPixelFormat->ui32RMask) >> psPixelFormat->ui32RShift);
	fPixAGreen = (IMG_FLOAT) ((ui32PixValA & psPixelFormat->ui32GMask) >> psPixelFormat->ui32GShift);
	fPixABlue  = (IMG_FLOAT) ((ui32PixValA & psPixelFormat->ui32BMask) >> psPixelFormat->ui32BShift);

	/* Unpack Pixel B */
	fPixBAlpha = (IMG_FLOAT) ((ui32PixValB & psPixelFormat->ui32AMask) >> psPixelFormat->ui32AShift);
	fPixBRed   = (IMG_FLOAT) ((ui32PixValB & psPixelFormat->ui32RMask) >> psPixelFormat->ui32RShift);
	fPixBGreen = (IMG_FLOAT) ((ui32PixValB & psPixelFormat->ui32GMask) >> psPixelFormat->ui32GShift);
	fPixBBlue  = (IMG_FLOAT) ((ui32PixValB & psPixelFormat->ui32BMask) >> psPixelFormat->ui32BShift);

	/* Scale and accumulate */
	fPixOutAlpha = (fPixAAlpha * fPixScaleA) + (fPixBAlpha * fPixScaleB);
	fPixOutRed   = (fPixARed   * fPixScaleA) + (fPixBRed   * fPixScaleB);
	fPixOutGreen = (fPixAGreen * fPixScaleA) + (fPixBGreen * fPixScaleB);
	fPixOutBlue  = (fPixABlue  * fPixScaleA) + (fPixBBlue  * fPixScaleB);

	/* Repack and return */
	return	(((IMG_UINT32) (fPixOutAlpha + 0.5f)) << psPixelFormat->ui32AShift)
		|	(((IMG_UINT32) (fPixOutRed   + 0.5f)) << psPixelFormat->ui32RShift)
		|	(((IMG_UINT32) (fPixOutGreen + 0.5f)) << psPixelFormat->ui32GShift)
		|	(((IMG_UINT32) (fPixOutBlue  + 0.5f)) << psPixelFormat->ui32BShift);
}
/*----------------------------------------------------------------------------
<function>
 FUNCTION	: RoundPixel
    
 PURPOSE	: Rounds floating point pixel to nearest pixel
</function>
------------------------------------------------------------------------------*/
IMG_VOID RoundPixel(IMG_FLOAT fX, IMG_FLOAT fY, IMG_UINT32 *pui32X1, IMG_UINT32 *pui32Y1)
{
	*pui32X1 = (IMG_UINT32) (fX + 0.5f);
	*pui32Y1 = (IMG_UINT32) (fY + 0.5f);
}
/*----------------------------------------------------------------------------
<function>
 FUNCTION	: GetNearestPixels
    
 PURPOSE	: Finds the 4 nearest pixels to given floating point pixel values
</function>
------------------------------------------------------------------------------*/
IMG_VOID GetNearestPixels(IMG_FLOAT fX,
						  IMG_FLOAT fY, 
						  IMG_UINT32 *pui32X1, 
						  IMG_UINT32 *pui32Y1,
						  IMG_UINT32 *pui32X2, 
						  IMG_UINT32 *pui32Y2,
						  IMG_UINT32 *pui32X3, 
						  IMG_UINT32 *pui32Y3,
						  IMG_UINT32 *pui32X4, 
						  IMG_UINT32 *pui32Y4)
{
	*pui32X1 = (IMG_UINT32) fX;
	*pui32Y1 = (IMG_UINT32) fY;

	*pui32X2 = (IMG_UINT32) (fX + 1.0f);
	*pui32Y2 = (IMG_UINT32) fY;

	*pui32X3 = (IMG_UINT32) fX;
	*pui32Y3 = (IMG_UINT32) (fY + 1.0f);

	*pui32X4 = (IMG_UINT32) (fX + 1.0f);
	*pui32Y4 = (IMG_UINT32) (fY + 1.0f);
}
/*----------------------------------------------------------------------------
<function>
 FUNCTION	: SoftwareBlit
    
 PURPOSE	: Performs software blits - last chance blitting - will be slow
		  
 RETURNS	: DDHAL return code.
</function>
------------------------------------------------------------------------------*/
BOOL  SoftwareBlit(LPD3DM_SURFACE			psSourceSurface,
				   RECT						*psSourceRect,
				   LPD3DM_SURFACE			psDestSurface,
				   RECT						*psDestRect,
				   D3DMTEXTUREFILTERTYPE	Filter,
				   DWORD					dwFillColour,
				   RECT						*psClipRects,
				   DWORD					dwNumClipRects,
				   DWORD					dwRotationAngle)
{

	/*	TODO - 
		Verify supported Format
		Scale Source To temp with Filtering
		Copy convert with clipping
		If dest is texture see if we can twiddle ?
	*/
	PVR_DEVFORMAT		*psSourceFMT = IMG_NULL, *psDestFMT = IMG_NULL;
	IMG_UINT8			*pui8Dest, *pui8Src;
	IMG_UINT32			ui32TargetWidth, ui32TargetHeight, ui32SourceWidth, ui32SourceHeight;
	IMG_BOOL			bStretch;
	IMG_BOOL			bFilter;
	IMG_UINT32			i, j;
	IMG_UINT32			ui32TargetColour;
	IMG_UINT32			ui32SrcBytesPerPixel, ui32DestBytesPerPixel;
	IMG_UINT32			ui32SrcStrideBytes, ui32DestStrideBytes;
	IMG_UINT32			ui32SourceSurfaceWidth, ui32SourceSurfaceHeight;
	IMG_UINT32			ui32DestSurfaceWidth, ui32DestSurfaceHeight;
	IMG_UINT32			ui32SrcNextWriteOpVal = 0, ui32DstNextWriteOpVal = 0, ui32DstReadOpsPending = 0;
	PVRSRV_MEM_INFO		*psSourceMemInfo, *psDestMemInfo = psDestSurface->psMemInfo;
	IMG_BOOL			bTimeout = IMG_TRUE;
	IMG_BOOL			bStart = IMG_FALSE;
	IMG_UINT32			uiStart = 0;

	PROFILE_START_FUNC(SOFTWARE_BLIT);

	/* Surface Synchronisation */
	ui32DstReadOpsPending = PVRSRVGetReadOpsPending(psDestMemInfo->psSyncInfo, IMG_FALSE);

	if(psSourceSurface != IMG_NULL)
	{
		psSourceMemInfo = psSourceSurface->psMemInfo;

		ui32SrcNextWriteOpVal = PVRSRVGetNextWriteOp(psSourceMemInfo->psSyncInfo, IMG_TRUE);

		PVRSRVGetReadOpsPending(psSourceMemInfo->psSyncInfo, IMG_TRUE);
	}

	ui32DstNextWriteOpVal = PVRSRVGetNextWriteOp(psDestSurface->psMemInfo->psSyncInfo, IMG_FALSE);

⌨️ 快捷键说明

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