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

📄 bltfuncs.cpp

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************
 * Name        : bltfuncs.cpp
 * Title       : MBX WinCE driver GPE class
 * Author(s)   : Imagination Technologies
 * Created	   : 29th January 2003
 *
 * Copyright   : 2003 by Imagination Technologies. 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 : MBX WinCE driver mode related components of GPE class.
 *
 * Platform    : WinCE
 *
 * Modifications:-
 * $Log: bltfuncs.cpp $
 *
 ****************************************************************************/

#include	"precomp.h"

#ifdef SUPPORT_CLEARTYPE
#include   <ctblt.h>
#endif /* SUPPORT_CLEARTYPE */

#include	<aablt.h>

extern "C"
{
#include	"bltfuncs.h"
#include	"hwfix.h"

#define DISPPERF_DECLARE
#include	"dispperf.h"
}


// Gradfill iDComplexity fix
BOOL (*pfnMSDrvGradientFill)(SURFOBJ *, CLIPOBJ *, XLATEOBJ *, TRIVERTEX *, ULONG, PVOID, ULONG, RECTL *, POINTL *, ULONG)=0;


#ifdef ENABLE_2D_PROFILE
PROFILE_NODE gProfile[NODE_MAX];
LONGLONG 	 g_i64EntryTime = 0;
BOOL     	 g_bTimingOfBltActive = FALSE;
#endif

#define CAPTURE_SYSMEM_BLT		0
#define ENABLE_TRACE			0

#if CAPTURE_SYSMEM_BLT
static BOOL CreateBmp(LPCTSTR pwszFileName,
					  PVOID pvData,
					  ULONG ulX,
					  ULONG ulY,
					  ULONG ulStride,
					  ULONG ulBPP,
					  EGPEFormat eDstFmt,
					  PULONG pulPalette,
					  ULONG ulRotationDegrees);

DWORD gdwCaptureSysmemBlt=0;
#endif

#if ENABLE_TRACE
DWORD gdwTrace=0;
DWORD gdwTraceCounter=0;


static int SurfRotate(GPESurfRotate  *pSurf)
{
	switch (pSurf->Rotate())
	{
		case DMDO_90:
			return 90;

		case DMDO_180:
			return 180;

		case DMDO_270:
			return 270;
	}
	
	return 0;
}


static LPWSTR FormatStr(EGPEFormat format)
{
	switch(format)
	{
		case gpe1Bpp: return (L"gpe1Bpp");
		case gpe2Bpp: return (L"gpe2Bpp");
		case gpe4Bpp: return (L"gpe4Bpp");
		case gpe8Bpp: return (L"gpe8Bpp");
		case gpe16Bpp: return (L"gpe16Bpp");
		case gpe24Bpp: return (L"gpe24Bpp");
		case gpe32Bpp: return (L"gpe32Bpp");
		default: return (L"?format?");
	}
}


static LPWSTR GetBltInfo(GPEBltParms *psBlitParameters)
{
	static WORD temp[255];
	LPWSTR lpWstr = (LPWSTR) &temp[0];

	temp[0] = 0;

	if (psBlitParameters->bltFlags & BLT_TRANSPARENT)
	{
		wcscat(lpWstr, L"BLT_TRANSPARENT ");
	}

	if (psBlitParameters->bltFlags & BLT_STRETCH)
	{
		wcscat(lpWstr, L"BLT_STRETCH");
	}

#if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
	if (psBlitParameters->bltFlags & BLT_ALPHABLEND)
	{
		wcscat(lpWstr, L"BLT_ALPHABLEND");
	}
#endif

	if ((psBlitParameters->rop4 & 0xffff) == 0xaaf0) 
	{
		switch (psBlitParameters->pMask->Format())
		{
			case gpe4Bpp:
			{
				wcscat(lpWstr, L"AAtext");
				break;
			}

			case gpe8Bpp:
			{
				wcscat(lpWstr, L"ClearType");
				break;
			}

			case gpe1Bpp:
			{
				wcscat(lpWstr, L"Text");
				break;
			}

			default:
			{
				wcscat(lpWstr, L"Unknown text format");
				break;
			}
		}
	}

	return lpWstr;
}

#endif//#if ENABLE_TRACE


/***********************************************************************************
 Function Name	: BltPrepare
 Inputs			: psBlitParameters
 Outputs		: psBlitParameters
 Returns		: Error code
 Globals Used	: None
 Description	: Driver entry point. (see WinCE documentation)
************************************************************************************/
SCODE	MBX::BltPrepare(GPEBltParms *psBlitParameters)
{
	#ifdef USE_SW_CURSOR
	RECTL	sRectl;
	#endif

	DPFX(PVR_ZONE_BLT, (L"MBX::BltPrepare"));

	RECTL				*prclDst			= psBlitParameters->prclDst;
	PVRSRV_SYNC_INFO	*psPrimarySyncInfo  = ((MBXSurf*)m_pPrimarySurface)->GetMemInfo()->psSyncInfo;

#ifdef LOCAL_MEMORY_SELF_REFRESH
	SysLocalMemoryEnable(m_sDevData.psDevInfoKM); 
#endif // LOCAL_MEMORY_SELF_REFRESH

	/* Perform coarse grain synchronisation if any external activity is touching the primary */
	if(psBlitParameters->pDst == m_pPrimarySurface && 
	   psPrimarySyncInfo->ui32LastWriteOpVal != psPrimarySyncInfo->ui32NextWriteOp - 1)
	{
		PVRSRV_DEV_INFO	*psDevInfo	= m_sDevData.psDevInfoKM;
		IMG_BOOL		bTimeout	= IMG_TRUE;
		IMG_BOOL		bStart		= IMG_FALSE;
		IMG_UINT32		uiStart		= 0;

		/* Lock the surface */
		psPrimarySyncInfo->ui32NextWriteOp++;

		do
		{
			if (psPrimarySyncInfo->ui32ReadOpsComplete == 
				psPrimarySyncInfo->ui32ReadOpsPending	&&
				psPrimarySyncInfo->ui32LastWriteOpVal  == 
				psPrimarySyncInfo->ui32NextWriteOp - 2)
			{
				bTimeout = IMG_FALSE;
				break;
			}

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

			HostWaitus(MAX_HW_TIME_US/(WAIT_TRY_COUNT));
			SysKickCmdProc(psDevInfo->pui32KickerAddrKM);

		} while ((HostClockus() - uiStart) < MAX_HW_TIME_US);
		
		if(bTimeout == IMG_TRUE)
		{
			/* 
				manually update write ops - It will look wrong but we can't wait here for ever 
			*/
			psPrimarySyncInfo->ui32LastWriteOpVal++;
			m_bPrimaryLocked = FALSE;
		}
		else
		{
			/* Flag that we've locked the primary */
			m_bPrimaryLocked = TRUE;
			m_bHardwareUsed	 = TRUE;
		}
	}

	DispPerfStart (psBlitParameters->rop4);		

#ifdef ENABLE_2D_PROFILE
	profile_start(m_sActiveNode, NODE_DEFAULT);
#endif

#if defined ROTATE_ENABLE && (_WINCEOSVER < 500)
	/*  Detect and fix GPE bug :

		The test kit generates out-of-order rectangles, and this causes the Microsoft GPE code to set the BLT_STRETCH
		flag even though the source and destination rectangles are exactly the same size. This is because microsoft test
		the width before unscambling the coordinates, and the width goes negative.

		It then runs through the GPE stretch blt code, and because the source and destination are both on the same surface
		(the primary) it allocates some extra video memory and copies the source bitmap into it so it can seperate the
		source and destination before the stretch blt. The GPE code calls our AllocSurface and we give it a correctly
		allocated MBXSurf which is rotated by the same amount as the primary.

		The problem is that after the AllocSurface, GPE contructs it's own internal dummy GPESurf structure instead of using
		the one that AllocSurface gives it (this is not allowed but they do it anyway). There are then two surfaces with the
		same bitmap address, the dummy and the real one. The dummy surface is not constructed correctly, for example the
		flags indicate that it is in system memory but it is really in video memory, also the rotation is changed to 0 but
		the surface has not been properly unrotated and so the stride is wrong. GPE uses the dummy surface as the source,
		and so it fails.

		To fix this, the driver now remembers the address of the last allocated surface, and it then detects the dummy
		surface and switches back to the real one. We have to assume that the linear address of the first pixel of a bitmap
		can be used to identify the surface. This fixes the 219 failure caused by the dummy surface.
	*/
	if ( (!psBlitParameters->pDst->InVideoMemory()) && (psBlitParameters->pDst->Buffer() == m_pvMostRecentAllocSurfaceAddr) )
	{
		psBlitParameters->pDst = m_psMostRecentMBXSurf;
	}
#endif /* ROTATE_ENABLE && _WINCEOSVER < 500 */


	/*
	 * Don't unscramble the dest rect if BLT_STRETCH is set because it might be a mirrored blt.
	 *
	 * The WinCE testkit test 212 generates rectangles with randon co-ordinates thus producing
	 * badly ordered dst rectangles
	 */

	if (prclDst && !(psBlitParameters->bltFlags & BLT_STRETCH) )
	{
		/* rclDst is not necessarily well ordered for us!! */
		if (prclDst->left > prclDst->right)
		{
			LONG tmp = prclDst->left;
			prclDst->left = prclDst->right;
			prclDst->right = tmp;
		}

		if (prclDst->top > prclDst->bottom)
		{
			LONG tmp = prclDst->top;
			prclDst->top = prclDst->bottom;
			prclDst->bottom = tmp;
		}
	}


#if ENABLE_TRACE
	if (gdwTrace)
	{
		gdwTraceCounter++;

		DPFINFO ((L"Rop4=%04X  %s #%d", psBlitParameters->rop4, GetBltInfo(psBlitParameters), gdwTraceCounter ));

		DPFINFO ((L"Dst surf %dx%d %d @%.8lx rect %d,%d to %d,%d %s %s",
						psBlitParameters->pDst->Width(),
						psBlitParameters->pDst->Height(),
						SurfRotate((GPESurfRotate *)psBlitParameters->pDst),
						psBlitParameters->pDst->Buffer(),
						(psBlitParameters->prclDst) ? psBlitParameters->prclDst->left : 0,
						(psBlitParameters->prclDst) ? psBlitParameters->prclDst->top : 0,
						(psBlitParameters->prclDst) ? psBlitParameters->prclDst->right : 0,
						(psBlitParameters->prclDst) ? psBlitParameters->prclDst->bottom : 0,
						FormatStr(psBlitParameters->pDst->Format()),
						(psBlitParameters->pDst->InVideoMemory()) ? "Y" : "N"
				));

		if (psBlitParameters->pSrc)
		{
			DPFINFO ((L"Src surf %dx%d %d @%.8lx rect %d,%d to %d,%d %s %s",
						psBlitParameters->pSrc->Width(),
						psBlitParameters->pSrc->Height(),
						SurfRotate((GPESurfRotate *)psBlitParameters->pSrc),
						psBlitParameters->pSrc->Buffer(),
						(psBlitParameters->prclSrc) ? psBlitParameters->prclSrc->left : 0,
						(psBlitParameters->prclSrc) ? psBlitParameters->prclSrc->top : 0,
						(psBlitParameters->prclSrc) ? psBlitParameters->prclSrc->right : 0,
						(psBlitParameters->prclSrc) ? psBlitParameters->prclSrc->bottom : 0,
						FormatStr(psBlitParameters->pSrc->Format()),
						(psBlitParameters->pSrc->InVideoMemory()) ? "Y" : "N"
					));
		}

		if (psBlitParameters->pMask)
		{
			DPFINFO ((L"Mask surf %dx%d %d @%.8lx rect %d,%d to %d,%d %s %s",
						psBlitParameters->pMask->Width(),
						psBlitParameters->pMask->Height(),
						SurfRotate((GPESurfRotate *)psBlitParameters->pMask),
						psBlitParameters->pMask->Buffer(),
						(psBlitParameters->prclMask) ? psBlitParameters->prclMask->left : 0,
						(psBlitParameters->prclMask) ? psBlitParameters->prclMask->top : 0,
						(psBlitParameters->prclMask) ? psBlitParameters->prclMask->right : 0,
						(psBlitParameters->prclMask) ? psBlitParameters->prclMask->bottom : 0,
						FormatStr(psBlitParameters->pMask->Format()),
						(psBlitParameters->pMask->InVideoMemory()) ? "Y" : "N"
					));
		}


		if (psBlitParameters->pBrush)
		{
			DPFINFO ((L"Brush surf %dx%d %d @%.8lx size %d,%d %s %s",
						psBlitParameters->pBrush->Width(),
						psBlitParameters->pBrush->Height(),
						SurfRotate((GPESurfRotate *)psBlitParameters->pBrush),
						psBlitParameters->pBrush->Buffer(),
						(psBlitParameters->pptlBrush) ? psBlitParameters->pptlBrush->x : 0,
						(psBlitParameters->pptlBrush) ? psBlitParameters->pptlBrush->y : 0,
						FormatStr(psBlitParameters->pBrush->Format()),
						(psBlitParameters->pBrush->InVideoMemory()) ? "Y" : "N"
					));
		}
	#if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
		if ( psBlitParameters->bltFlags & BLT_ALPHABLEND)
		{
			DPFINFO ((L"Blend Info Op:0x%.2X Flags:0x%.2X SrcAlpha:0x%.2X Format:0x%.2X",
						psBlitParameters->blendFunction.BlendOp,
						psBlitParameters->blendFunction.BlendFlags,
						psBlitParameters->blendFunction.SourceConstantAlpha,
						psBlitParameters->blendFunction.AlphaFormat
					));
		}
	#endif
	}

	#endif//#if ENABLE_TRACE

	#ifdef DEBUG
	#ifdef LOCAL_MEMORY_SELF_REFRESH
	// default to base EmulatedBlt routine
		psBlitParameters->pBlt = (SCODE (GPE::*)(GPEBltParms *))WrappedEmulatedBlt;
	#else
	psBlitParameters->pBlt = (SCODE (GPE::*)(GPEBltParms *))EmulatedBlt;
	#endif
	#else
	// for release builds go via exception handled stub
	psBlitParameters->pBlt = (SCODE (GPE::*)(GPEBltParms *))TryEmulatedBlt;
	#endif

	/* init state to idle */
	m_eHWBltState = BLT_Idle;

	#ifdef USE_SW_CURSOR
	if (m_bCursorVisible && !m_bCursorDisabled)
	{
		// check for destination overlap with cursor and turn off cursor if overlaps
		if (psBlitParameters->pDst == m_pPrimarySurface)	// only care if dest is main display surface
		{
			{	
			if (psBlitParameters->prclDst != NULL)		// make sure there is a valid prclDst
			{
				sRectl = *psBlitParameters->prclDst;		// if so, use it
			}
			else
			{
				sRectl = m_sCursorRect;					// if not, use the Cursor rect - this forces the cursor to be turned off in this case
			}

			if (m_sCursorRect.top < sRectl.bottom && m_sCursorRect.bottom > sRectl.top &&
				m_sCursorRect.left < sRectl.right && m_sCursorRect.right > sRectl.left)
			{
				CursorOff();
				m_bCursorForcedOff = TRUE;
			}
		}

		// check for source overlap with cursor and turn off cursor if overlaps
		if (psBlitParameters->pSrc == m_pPrimarySurface)	// only care if source is main display surface
		{
			if (psBlitParameters->prclSrc != NULL)		// make sure there is a valid prclSrc
			{
				sRectl = *psBlitParameters->prclSrc;	// if so, use it
			}
			else
			{
				sRectl = m_sCursorRect;					// if not, use the CUrsor rect - this forces the cursor to be turned off in this case
			}
			if (m_sCursorRect.top < sRectl.bottom && m_sCursorRect.bottom > sRectl.top &&
				m_sCursorRect.left < sRectl.right && m_sCursorRect.right > sRectl.left)
			{
				CursorOff();
				m_bCursorForcedOff = TRUE;
			}
		}
	}
	#endif /* USE_SW_CURSOR */

	#ifdef ROTATE_ENABLE
	/*
	 * only the primary surface is rotated, all offscreen bitmaps are unrotated
	 */
	if (m_iRotate && (psBlitParameters->pSrc == m_pPrimarySurface) || (psBlitParameters->pDst == m_pPrimarySurface))
	{
		#ifdef DEBUG
		#ifdef LOCAL_MEMORY_SELF_REFRESH
			psBlitParameters->pBlt = (SCODE (GPE::*)(GPEBltParms *))WrappedEmulatedBltRotate;
		#else
			psBlitParameters->pBlt = (SCODE (GPE::*)(GPEBltParms *))EmulatedBlt;
		#endif
		#else
		// for release builds go via exception handled stub
		psBlitParameters->pBlt = (SCODE (GPE::*)(GPEBltParms *))TryEmulatedBltRotate;
		#endif
	}
	#endif /* ROTATE_ENABLE */

	#if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
	/* AlphaBlend test */
	if ( psBlitParameters->bltFlags & BLT_ALPHABLEND)
	{
		/*
		 * Punt all as MBX acceleration does not support this type of blending.

⌨️ 快捷键说明

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