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

📄 blitsw.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

	do
	{
		if((*psDestMemInfo->psSyncInfo->pui32LastWriteOp   == ui32DstNextWriteOpVal - 1) 
	    && (psDestMemInfo->psSyncInfo->ui32ReadOpsComplete == ui32DstReadOpsPending))
		{
			if(psSourceSurface != IMG_NULL)
			{
				if(*psSourceMemInfo->psSyncInfo->pui32LastWriteOp == ui32SrcNextWriteOpVal - 1)
				{
					bTimeout = IMG_FALSE;
					break;
				}
			}
			else
			{
				bTimeout = IMG_FALSE;
				break;
			}
		}

		if(bStart == IMG_FALSE)
		{
			bStart = IMG_TRUE;
			uiStart = HostClockus();
		}

		HostWaitus(MAX_HW_TIME_US/(WAIT_TRY_COUNT));
		if(GetDevInfo(psDestSurface->psContext)->sDeviceSpecific.s3D.b3DIdle)
		{
			SysKickCmdProc(GetKickerAddress(psDestSurface->psContext));
		}

	} while ((HostClockus() - uiStart) < MAX_HW_TIME_US);
	
	if(bTimeout == IMG_TRUE)
	{
		D3DM_DPF((DPF_ERROR,"SoftwareBlit: Dependencies failed - Blitting anyway -"));
	}

	/* Get dest details */
	psDestFMT				= GetFormatDescriptorD3DM(psDestSurface->psContext, psDestSurface->eFormat);
	if(psDestFMT == IMG_NULL) return FALSE;

	ui32TargetWidth			= (psDestRect->right  - psDestRect->left);
	ui32TargetHeight		= (psDestRect->bottom - psDestRect->top);
	bFilter					= Filter == D3DMTEXF_LINEAR;
	ui32DestBytesPerPixel	= psDestFMT->dwBpp / 8;
	ui32DestStrideBytes		= psDestSurface->dwStrideByte;
	ui32DestSurfaceWidth	= (psDestSurface->eSurfaceType == D3DMRTYPE_TEXTURE) ?
							   psDestSurface->sDescription.sTexture.dwScaledWidth :
							   psDestSurface->dwWidth;
	ui32DestSurfaceHeight	= (psDestSurface->eSurfaceType == D3DMRTYPE_TEXTURE) ?
							   psDestSurface->sDescription.sTexture.dwScaledHeight :
							   psDestSurface->dwHeight;

	/* Catch and perform ColourFill case */
	if(psSourceSurface == IMG_NULL)
	{
		ui32TargetColour = ConvertFillColourToHWFormat(psDestSurface->eFormat, dwFillColour);
		pui8Dest = ((IMG_UINT8*)psDestSurface->psMemInfo->pvLinAddr)  +
					psDestRect->top  * ui32DestStrideBytes			  +
					psDestRect->left * ui32DestBytesPerPixel;

		for(i=0; i < ui32TargetHeight; i++)
		{
			for(j=0; j < ui32TargetWidth; j++)
			{
				WritePixelToBuffer(pui8Dest,
								   ui32TargetColour,
								   ui32DestStrideBytes, 
								   j,
								   i,
								   ui32DestBytesPerPixel);
			}
		}
		/* Update Syncs */
		(*psDestMemInfo->psSyncInfo->pui32LastWriteOp)++;
		return TRUE;
	}

	/* Get Source details */
 	psSourceFMT				= GetFormatDescriptorD3DM(psSourceSurface->psContext, psSourceSurface->eFormat);
	if(psSourceFMT == IMG_NULL) return FALSE;

	ui32SourceWidth			= (psSourceRect->right  - psSourceRect->left);
	ui32SourceHeight		= (psSourceRect->bottom - psSourceRect->top);

	if(dwRotationAngle == 0 || dwRotationAngle == 180)
	{
		bStretch			= (ui32TargetWidth  != ui32SourceWidth) ||
							  (ui32TargetHeight != ui32SourceHeight);
	}
	else
	{
		bStretch			= (ui32TargetWidth  != ui32SourceHeight) ||
							  (ui32TargetHeight != ui32SourceWidth);
	}
	ui32SrcBytesPerPixel	= psSourceFMT->dwBpp / 8;
	ui32SrcStrideBytes		= psSourceSurface->dwStrideByte;
	ui32SourceSurfaceWidth	= (psSourceSurface->eSurfaceType == D3DMRTYPE_TEXTURE) ?
							   psSourceSurface->sDescription.sTexture.dwScaledWidth :
							   psSourceSurface->dwWidth;
	ui32SourceSurfaceHeight	= (psSourceSurface->eSurfaceType == D3DMRTYPE_TEXTURE) ?
							   psSourceSurface->sDescription.sTexture.dwScaledHeight :
							   psSourceSurface->dwHeight;

	/* We need to assess the twiddle status of these surfaces */
	if(psSourceSurface->dwFlags & D3DM_SURFACE_FLAGS_TWIDDLED)
	{
		UnTwiddleSurface(psSourceSurface);
	}
	if(psDestSurface->dwFlags & D3DM_SURFACE_FLAGS_TWIDDLED)
	{
		UnTwiddleSurface(psDestSurface);
	}

	/* Setup pointer to source Data */
	pui8Src =  ((IMG_UINT8*)psSourceSurface->psMemInfo->pvLinAddr)    +
				psSourceRect->top  * ui32SrcStrideBytes				  +
				psSourceRect->left * ui32SrcBytesPerPixel;

	if(bStretch)
	{
		IMG_FLOAT	fX, fY, fXRatio, fYRatio;
		IMG_UINT32  ui32X1, ui32Y1, ui32X2, ui32Y2, ui32X3, ui32Y3, ui32X4, ui32Y4;

		/* Allocate temporary surface for scale */
		pui8Dest = D3DMAllocate((psDestRect->right  - psDestRect->left) * 
							    (psDestRect->bottom - psDestRect->top)  *
							    (psSourceFMT->dwBpp / 8));

		if(dwRotationAngle == 0 || dwRotationAngle == 180)
		{
			fXRatio = ((IMG_FLOAT) ui32SourceWidth)  / ((IMG_FLOAT) ui32TargetWidth);
			fYRatio = ((IMG_FLOAT) ui32SourceHeight) / ((IMG_FLOAT) ui32TargetHeight);
		}
		else
		{
			fXRatio = ((IMG_FLOAT) ui32SourceWidth)  / ((IMG_FLOAT) ui32TargetHeight);
			fYRatio = ((IMG_FLOAT) ui32SourceHeight) / ((IMG_FLOAT) ui32TargetWidth);
		}

		fX		= 0.0f;
		fY		= 0.0f;

		/* Scale and filter to temporary surface */
		for(i=0; i < ui32TargetHeight; i++)
		{
			for(j=0; j < ui32TargetWidth; j++)
			{
				fX = ((IMG_FLOAT) j) * fXRatio;
				fY = ((IMG_FLOAT) i) * fYRatio;

				if(bFilter)
				{
					/* Linear interpolation of pixel values */
					IMG_FLOAT fXFractPart, fXInvFractPart, fYFractPart, fYInvFractPart;
					IMG_UINT32 ui32XPairInterpolated1, ui32XPairInterpolated2;

					fXFractPart		= fX - ((IMG_FLOAT)((IMG_UINT32)fX));
					fYFractPart		= fY - ((IMG_FLOAT)((IMG_UINT32)fY));
					fXInvFractPart	= 1.0f - fXFractPart;
					fYInvFractPart	= 1.0f - fYFractPart;

					/* Grab the 4 nearest pixels */
					GetNearestPixels(fX, fY, &ui32X1, &ui32Y1, &ui32X2, &ui32Y2, &ui32X3, &ui32Y3, &ui32X4, &ui32Y4);

					/* Interpolate 1st horizontal pair */
					ui32XPairInterpolated1 =  InterpolatePixels(psSourceFMT,
																GetPixelFromBuffer(pui8Src, ui32SrcStrideBytes, ui32X1, ui32Y1, ui32SrcBytesPerPixel), 
																fXInvFractPart, 
																GetPixelFromBuffer(pui8Src, ui32SrcStrideBytes, ui32X2, ui32Y2, ui32SrcBytesPerPixel), 
																fXFractPart);

					/* Interpolate 2nd horizontal pair */
					ui32XPairInterpolated2 =  InterpolatePixels(psSourceFMT,
																GetPixelFromBuffer(pui8Src, ui32SrcStrideBytes, ui32X3, ui32Y3, ui32SrcBytesPerPixel), 
																fXInvFractPart, 
																GetPixelFromBuffer(pui8Src, ui32SrcStrideBytes, ui32X4, ui32Y4, ui32SrcBytesPerPixel), 
																fXFractPart);

					/* Interpolate Vertically */
					ui32TargetColour = InterpolatePixels(psSourceFMT,
														 ui32XPairInterpolated1, 
														 fYInvFractPart, 
														 ui32XPairInterpolated2, 
														 fYFractPart);
				}
				else
				{
					/* Find nearest pixel */
					RoundPixel(fX, fY, &ui32X1, &ui32Y1);

					ui32TargetColour = GetPixelFromBuffer(pui8Src,
														  ui32SrcStrideBytes, 
														  ui32X1,
														  ui32Y1,
														  ui32SrcBytesPerPixel);
				}

				/* Copy pixel to temp buffer */
				WritePixelToBuffer(pui8Dest,
								   ui32TargetColour,
								   (ui32TargetWidth * ui32SrcBytesPerPixel), 
								   j,
								   i,
								   ui32SrcBytesPerPixel);
			}
		}

		/* Modify the Src stride value */
		ui32SrcStrideBytes = (ui32TargetWidth * ui32SrcBytesPerPixel);

		/* Modify source width and height */
		ui32SourceHeight = ui32TargetHeight;
		ui32SourceWidth  = ui32TargetWidth;

		pui8Src = pui8Dest;
	}

	/* Set up pointer to destination buffer */
	pui8Dest = ((IMG_UINT8*)psDestSurface->psMemInfo->pvLinAddr)  +
				psDestRect->top  * ui32DestStrideBytes			  +
				psDestRect->left * ui32DestBytesPerPixel;


	/* Do copy convert with clipping and rotation */
	for(i=0; i < ui32SourceHeight; i++)
	{
		for(j=0; j < ui32SourceWidth; j++)
		{
			IMG_UINT32 ui32X, ui32Y;
			switch(dwRotationAngle)
			{
				case 0:
				{
					ui32X = j;
					ui32Y = i;
					break;
				}
				case 90:
				case 180:
				case 270:
				{
					RotatePixelCoords(j, i, &ui32X, &ui32Y, ui32TargetWidth, ui32TargetHeight, dwRotationAngle);
					break;
				}
			}

			if(dwNumClipRects > 0 && PixelIsClipped(psClipRects, dwNumClipRects, psDestSurface, psDestRect, ui32X, ui32Y))
			{
				continue;
			}
			else
			{
				if(psSourceFMT->sD3DDevFormat.Format == psDestFMT->sD3DDevFormat.Format)
				{


					/* Staight pixel copy */
					WritePixelToBuffer(pui8Dest,
									   GetPixelFromBuffer(pui8Src, ui32SrcStrideBytes, j, i, ui32SrcBytesPerPixel),
									   ui32DestStrideBytes, 
									   ui32X,
									   ui32Y,
									   ui32DestBytesPerPixel);
				}
				else
				{
					/* Copy Convert Pixel */
					CopyConvertPixel(psSourceFMT,
									 pui8Src,
									 ui32SrcStrideBytes,
									 ui32SrcBytesPerPixel,
									 psDestFMT,
									 pui8Dest,
									 ui32DestStrideBytes,
									 ui32DestBytesPerPixel,
									 j,
									 i,
									 dwRotationAngle,
									 ui32TargetWidth,
									 ui32TargetHeight);
				}
			}
		}
	}

	/* Update Sync Objects */
	(*psDestMemInfo->psSyncInfo->pui32LastWriteOp)++;
	psSourceMemInfo->psSyncInfo->ui32ReadOpsComplete++;

 	if(bStretch)
	{
		D3DMFree(pui8Src);
	}

	PROFILE_STOP_FUNC(SOFTWARE_BLIT);

	return TRUE;
}
/*----------------------------------------------------------------------------
<function>
 FUNCTION	: SoftwareRotateBlit
    
 PURPOSE	: performs a software rotation blit to or from a temp buffer
		  
 RETURNS	: 
</function>
------------------------------------------------------------------------------*/
IMG_VOID  SoftwareRotateBlit(LPD3DM_CONTEXT		psContext,
							 LPD3DM_SURFACE		psSourceSurface,
							 RECT				*psSourceRect,
							 IMG_UINT8			*pui8DestSurface,
							 IMG_BOOL			bBlitDesttoSource)
{
	LONG		i, j;
	DWORD		k;
	DWORD		dwDestByteStride, dwDestWidth, dwDestHeight, dwBytesPerPixel;
	IMG_BOOL	bFullScreen = IMG_FALSE;
	D3DMRECT	sRotatedSourceRect;
	DWORD		dwDestX, dwDestY;
	IMG_UINT8	*pui8SourceData = (IMG_UINT8*)psSourceSurface->psMemInfo->pvLinAddr;

	bFullScreen =  (IMG_BOOL) RotateRects(psContext, 
						   				  &sRotatedSourceRect, 
										  (LPD3DMRECT)psSourceRect,
										  1,
										  psSourceSurface->dwWidth,
										  psSourceSurface->dwHeight);

	dwDestWidth		 = (psSourceRect->right - psSourceRect->left);
	dwDestHeight	 = (psSourceRect->bottom - psSourceRect->top);
	dwBytesPerPixel	 = (psSourceSurface->dwBpp / 8);
	dwDestByteStride = dwDestWidth * dwBytesPerPixel;

	/* Select dest starting pixel */
	switch(psContext->dwRotationAngle)
	{
		case 90:
		{
			dwDestX = dwDestWidth - 1;
			dwDestY = 0;
			break;
		}
		case 180:
		{
			dwDestX = dwDestWidth - 1;
			dwDestY = dwDestHeight - 1;
			break;
		}
		case 270:
		{
			dwDestX = 0;
			dwDestY = dwDestHeight - 1;
			break;
		}
	}

	for(i = sRotatedSourceRect.y1; i < sRotatedSourceRect.y2; i++)
	{
		for(j = sRotatedSourceRect.x1; j < sRotatedSourceRect.x2; j++)
		{
			for(k = 0; k < dwBytesPerPixel; k++)
			{
				if(bBlitDesttoSource)
				{
					pui8SourceData[(i * psSourceSurface->dwStrideByte) + (j * dwBytesPerPixel) + k] =
						pui8DestSurface[(dwDestY * dwDestByteStride) + (dwDestX * dwBytesPerPixel) + k];
				}
				else
				{
					pui8DestSurface[(dwDestY * dwDestByteStride) + (dwDestX * dwBytesPerPixel) + k] = 
						pui8SourceData[(i * psSourceSurface->dwStrideByte) + (j * dwBytesPerPixel) + k];
				}
			}

			/* Select dest target pixel movement */
			switch(psContext->dwRotationAngle)
			{
				case 90:
				{
					dwDestY++;
					break;
				}
				case 180:
				{
					dwDestX--;
					break;
				}
				case 270:
				{
					dwDestY--;
					break;
				}
			}
		}

		/* Select dest target pixel movement */
		switch(psContext->dwRotationAngle)
		{
			case 90:
			{
				dwDestX--;
				dwDestY = 0;
				break;
			}
			case 180:
			{
				dwDestX = dwDestWidth - 1;
				dwDestY--;
				break;
			}
			case 270:
			{
				dwDestX++;
				dwDestY = dwDestHeight - 1;
				break;
			}
		}
	}
}
/*****************************************************************************
 End of file (Blitsw.c)
*****************************************************************************/

⌨️ 快捷键说明

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