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

📄 bltfuncs.cpp

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		 * In 32Bpp the alpha byte is wrongly calculated
		 * In 16Bpp rounding differences between SW and HW arise and CE tk fails
		 * If Src is 1Bpp MBX gets it very wrong
		 */
		goto DoSyncWithHost;
	}
	#endif

	#ifdef SUPPORT_CLEARTYPE
	if (((psBlitParameters->rop4 & 0xffff) == 0xaaf0 ) && (psBlitParameters->pMask->Format() == gpe8Bpp))
	{
		switch (m_ulColorDepth)
		{
			case 8:
				psBlitParameters->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) ClearTypeBlt::ClearTypeBltDst8;
				break;
			case 16:
				psBlitParameters->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) ClearTypeBlt::ClearTypeBltDst16;
				break;
			case 24:
				psBlitParameters->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) ClearTypeBlt::ClearTypeBltDst24;
				break;
			case 32:
				psBlitParameters->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) ClearTypeBlt::ClearTypeBltDst32;
				break;
			default:
				break;
		}

		SyncWithHost();
#ifdef LOCAL_MEMORY_SELF_REFRESH
		SysLocalMemoryDisable(m_sDevData.psDevInfoKM);
#endif //LOCAL_MEMORY_SELF_REFRESH
		return (S_OK);
	}
	#else
	ASSERT (!(((psBlitParameters->rop4 & 0xffff) == 0xaaf0 ) && (psBlitParameters->pMask->Format() == gpe8Bpp)));
	#endif // SUPPORT_CLEARTYPE

	if (((psBlitParameters->rop4 & 0xffff) == 0xaaf0 ) && (psBlitParameters->pMask->Format() == gpe4Bpp))
	{
		switch (m_ulColorDepth)
		{
			case 8:
				psBlitParameters->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) AATextBlt::AATextBltDst8;
				break;
			case 16:
				psBlitParameters->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) AATextBlt::AATextBltDst16;
				/* workaround for Hardware PRN 676 */
				if (gdwHPRN676HwFix==0)
				{
					goto DoSyncWithHost;
				}
				break;
			case 24:
				psBlitParameters->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) AATextBlt::AATextBltDst24;
				break;
			case 32:
				psBlitParameters->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) AATextBlt::AATextBltDst32;
				break;
		}
	}

	#ifdef DEBUG
	if (m_bPunt || !PrepareHardwareBlt(psBlitParameters))
	#else
	if (!PrepareHardwareBlt(psBlitParameters))
	#endif
	{
		/*
		 * Goto here to manually sync before our own punt code
		 */
DoSyncWithHost:

		#ifdef ENABLE_2D_PROFILE
		profile_reassign(m_sActiveNode, NODE_PUNT);
		#endif

		/* Flag sw blit */
		m_bHardwareUsed	 = FALSE;

		/* Punts such as ClearType DO NOT call WaitForNotBusy()
		 * so we must test early */
		if (m_bMBXBltActioned || m_bForceSyncWithHost)
		{
			/* release slave port */
			SyncWithHost();
		}

		DispPerfType(DISPPERF_ACCEL_GPE);
		DPFX(PVR_ZONE_BLT,(L"EmulBlt: rop4=%04X", psBlitParameters->rop4));
	}

	#ifdef DO_DISPPERF
	if (psBlitParameters->prclDst)
	{
		DispPerfPixelsDrawn(RectWidth((RECT *)psBlitParameters->prclDst) *
							RectHeight((RECT *)psBlitParameters->prclDst));
	}
	else
	{
		DispPerfPixelsDrawn(psBlitParameters->pDst->Width() *
							psBlitParameters->pDst->Height());
	}

	DispPerfParam(psBlitParameters);
	#endif /* DO_DISPPERF */

	#ifdef ENABLE_2D_PROFILE
	profile_setup_end(m_sActiveNode);
	#endif

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

	return (S_OK);
} /* BltPrepare */

/***********************************************************************************
 Function Name	: BltComplete
 Inputs			: psBlitParameters
 Outputs		: psBlitParameters
 Returns		: Error code
 Globals Used	: None
 Description	: Driver entry point. (see WinCE documentation)
************************************************************************************/
SCODE	MBX::BltComplete(GPEBltParms *psBlitParameters)
{
	SCODE scRtn = S_OK;
	BOOL bHwVerified=FALSE;

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

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

#if defined ROTATE_ENABLE && (_WINCEOSVER < 500)
	// Detect and fix WinCE 4.2 bug
	if (!psBlitParameters->pDst->InVideoMemory())
	if (psBlitParameters->pDst->Buffer() == m_pvMostRecentAllocSurfaceAddr)
	{
		psBlitParameters->pDst = m_psMostRecentMBXSurf;
	}
#endif /* ROTATE_ENABLE && (_WINCEOSVER < 500) */

	#if HW_VERIFY
	if (m_eHWBltState == BLT_Verify)
	{
		/* force sync */
		m_bMBXBltActioned = TRUE;
		SyncWithHost();

		/* Release slave port */
		if (m_bSlavePortAquired)
		{
			PVRSRVReleaseSlavePort(	m_sDevData.psDevInfoKM, PVRSRV_SLAVEPORT_2D);
			m_bSlavePortAquired = FALSE;
		}

		m_clHwVer.VerifyHW (psBlitParameters);
		m_eHWBltState = BLT_Idle;				/* resource already released */
		bHwVerified = TRUE;
	}

	ASSERT ((m_eHWBltState == BLT_Idle) || (m_eHWBltState == BLT_Setup) || (m_eHWBltState == BLT_InContProgress));
	#endif

	#ifdef USE_SW_CURSOR
	/*
	  see if cursor was forced off because of overlap with
	  source or destination and turn back on
	*/
	if (m_bCursorForcedOff)
	{
		m_bCursorForcedOff = FALSE;
		CursorOn();
	}
	#endif /* USE_SW_CURSOR */
	
	/*
	 * m_eHWBltState should be in one of 3 states here
	 * BLT_Idle	- no acceleration/ punted
	 * BLT_Setup	- Can accelerate but nothing to do (all clipped)
	 * BLT_Complete - Accelerated Blit done
	 */
#if ENABLE_TRACE
	if (gdwTrace)
	{
		switch (m_eHWBltState)
		{
			case BLT_Idle:
			{
				if (!bHwVerified)
				{
					DPFINFO ((L"Punted"));

#if CAPTURE_SYSMEM_BLT
					// Capture source and destination if destination is in system memory
					if ( gdwCaptureSysmemBlt && !psBlitParameters->pDst->InVideoMemory() && psBlitParameters->rop4 == 0xCCCC)
					{
						// Capture the off-screen destination.
						BOOL bSucess = CreateBmp(	L"\\release\\dest.bmp",				// LPCTSTR pwszFileName,
													psBlitParameters->pDst->Buffer(),	// PVOID pvData,
													psBlitParameters->pDst->Width(),	// ULONG ulX,
													psBlitParameters->pDst->Height(),	// ULONG ulY,
													psBlitParameters->pDst->Stride(),	// ULONG ulStride,
													EGPEFormatToBpp[psBlitParameters->pDst->Format()],// ULONG ulBPP,
													psBlitParameters->pDst->Format(),	// EGPEFormat eDstFmt,
													0,									// PULONG pulPalette
													(psBlitParameters->pDst->InVideoMemory()) ? ((MBXSurf*)(psBlitParameters->pDst))->m_lRotationAngle : 0	// ULONG ulRotationDegrees
												);
						DebugBreak();

						// Capture the on-screen source.
						bSucess = CreateBmp(	L"\\release\\source.bmp",			// LPCTSTR pwszFileName,
													psBlitParameters->pSrc->Buffer(),	// PVOID pvData,
													psBlitParameters->pSrc->Width(),	// ULONG ulX,
													psBlitParameters->pSrc->Height(),	// ULONG ulY,
													psBlitParameters->pSrc->Stride(),	// ULONG ulStride,
													EGPEFormatToBpp[psBlitParameters->pSrc->Format()],// ULONG ulBPP,
													psBlitParameters->pSrc->Format(),	// EGPEFormat eDstFmt,
													0,									// PULONG pulPalette
													(psBlitParameters->pSrc->InVideoMemory()) ? ((MBXSurf*)(psBlitParameters->pSrc))->m_lRotationAngle : 0	// ULONG ulRotationDegrees
												);
						DebugBreak();
					}
#endif /*CAPTURE_SYSMEM_BLT */
				}
				else
				{
					DPFINFO ((L"Accelerated+verified"));
				}
				break;
			}

			case BLT_Setup:
			{
				DPFINFO ((L"All clipped"));
				break;
			}

			case BLT_Complete:
			case BLT_InContProgress:
			{
				DPFINFO ((L"Accelerated"));
				break;
			}

			default:
			{
				DebugBreak();
			}
		}
	}
#endif /* ENABLE_TRACE */

	if ((m_eHWBltState != BLT_Idle) && (m_eHWBltState != BLT_Setup))
	{
		ASSERT ((m_eHWBltState == BLT_Complete) || m_eHWBltState == BLT_InContProgress);

		/* record that a sync is required if we fallback to SW */
		m_bMBXBltActioned = TRUE;

		if (m_bForceSyncWithHost == TRUE)
		{
			SyncWithHost();
		}
	}
	
	/* Release slave port */
	if (m_bSlavePortAquired)
	{
		PVRSRVReleaseSlavePort(	m_sDevData.psDevInfoKM, PVRSRV_SLAVEPORT_2D);
		m_bSlavePortAquired = FALSE;
	}
	
	m_eHWBltState = BLT_Idle;
	
	/* If the destination was on-screen then update the single shot mode */
	if (psBlitParameters->pDst == m_pPrimarySurface)
	{
		m_clDisplay.PDP_ScreenUpdate();
	}
	
#if !defined TIMED2DGATING && !defined NO_2D_CLOCKCONTROL
	if (SysCoreQuery(DEV_CGCORE_MBX_2D) == IMG_TRUE)
	{
		SysCoreDisable(m_sDevData.psDevInfoKM, DEV_CGCORE_MBX_2D, IMG_FALSE);
	}
#endif

	#ifdef ENABLE_2D_PROFILE
	profile_end(m_sActiveNode);
	#endif

	DispPerfEnd(0);

	/* Coarse grain synchronsiation required - Flush the blit and unlock the primary */
	if(m_bPrimaryLocked)
	{
		PVRSRV_SYNC_INFO	*psPrimarySyncInfo  = ((MBXSurf*)m_pPrimarySurface)->GetMemInfo()->psSyncInfo;
		if(m_bHardwareUsed)
		{
			PVRSRV_BLT_CMD_INFO	*psBltCmd;
			IMG_UINT32			ui32CommandSize;

			ui32CommandSize = sizeof(PVRSRV_BLT_CMD_INFO) - sizeof(IMG_UINT32);

			/*
				round to 4byte units
			*/
			ui32CommandSize =  (ui32CommandSize+3) & ~3L;
		
			psBltCmd = (PVRSRV_BLT_CMD_INFO *) PVRSRVGetQueueSpace(m_pQueueInfo, ui32CommandSize);

			if(!psBltCmd)
			{
				DPFINFO((L"Couldn't get space in queue - manually unlocking primary!!"));
				psPrimarySyncInfo->ui32LastWriteOpVal++;
				return (scRtn);
			}

			psBltCmd->sCmdInfo.ui32CommandID = PVRSRV_CMD_ID_BLT;

			psBltCmd->sCmdInfo.ui32Size = ui32CommandSize;


			psBltCmd->ui32DstReadOpsPending = PVRSRVGetReadOpsPending(psPrimarySyncInfo, IMG_FALSE);
			psBltCmd->psDstSyncInfoKM = psPrimarySyncInfo->psKernSyncInfo;
			psBltCmd->ui32NumSrcSyncInfos = 0;
			psPrimarySyncInfo->ui32BlitOpsPending++;
		
			psBltCmd->ui32DstNextOpVal	= psPrimarySyncInfo->ui32NextWriteOp - 1;

			psBltCmd->ui32DataCount = 0;

			PVRSRVUpdateQueue(m_pQueueInfo, ui32CommandSize);

			PVRSRVReleaseQueue(m_pQueueInfo);

		}
		else
		{
			/* manually update write ops */
			psPrimarySyncInfo->ui32LastWriteOpVal++;
		}

		/* Flag that the primary is unlocked */
		m_bPrimaryLocked = FALSE;
	}

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

	return (scRtn);
}


/***********************************************************************************
 Function Name	: InVBlank
 Inputs			:
 Outputs		:
 Returns		:
 Globals Used	:
 Description	: 
************************************************************************************/
INT		MBX::InVBlank(void)
{
	static	BOOL	bValue = FALSE;

	DPFX(PVR_ZONE_BLTVERBOSE, (L"MBX::InVBlank"));
	bValue = !bValue;
	return bValue;
}


/*============================ Acceleration functions ========================*/

/* Local constants. */

const ULONG Foreground = 0;
const ULONG Background = 1;

/***********************************************************************************
 Function Name	: PrepareHardwareBlt
 Inputs			: psBlitParameters
 Outputs		: psBlitParameters
 Returns		: TRUE to accelerate, FALSE to punt.
 Globals Used	: 
 Description	: 
************************************************************************************/
BOOL	MBX::PrepareHardwareBlt(GPEBltParms *psBlitParameters)
{
	// component rop3s of rop4
	BYTE byRop3[2];
	RECTL rclDst;
	RECTL rclSrc;
	EGPEFormat eDstFmt = psBlitParameters->pDst->Format();
	BOOL bRtn = FALSE;
	LONG lDestRotation;
	
	if ((!psBlitParameters->pDst->InVideoMemory()) ||
		(eDstFmt < gpe8Bpp))							/* Don't support 1 and 4Bpp dest */
	{
		return (FALSE);
	}

	/*
	 * a quick and dirty fix to catch src copies to the same place
	 */
	if ((psBlitParameters->rop4 == 0xCCCC) &&
		(psBlitParameters->pDst->Buffer() == psBlitParameters->pSrc->Buffer()) &&
		(psBlitParameters->prclDst->left == psBlitParameters->prclSrc->left) &&
		(psBlitParameters->prclDst->top == psBlitParameters->prclSrc->top))
	{
		return (FALSE);
	}

	if ( eDstFmt == gpe8Bpp)
	{
		if ((psBlitParameters->pSrc) && (psBlitParameters->pSrc->Format() > eDstFmt))
		{
			/* Source Bit depth is too high */
			/* pixel colour conversion is required so punt */
			DPFINFO((L"Punting as Dest is Format 3 and Src GPEformat is %d", psBlitParameters->pSrc->Format()));
			return (FALSE);
		}

		if ((psBlitParameters->pBrush) &&
			(psBlitParameters->pBrush->Format() > eDstFmt) )
		{
			/* Have a brush with either too high a bit depth or no palette */
			/* pixel colour conversion is required so punt */
			DPFINFO((L"Punting as Dest is Format 3 and Brush GPEformat is %d", psBlitParameters->pBrush->Format()));
			return (FALSE);
		}
	}

	byRop3[Foreground] = (BYTE)psBlitParameters->rop4;
	byRop3[Background] = (BYTE)(psBlitParameters->rop4 >> 8);

	m_ulSurfsPresent = 0;		/* initialise */

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

	#if HW_VERIFY
	m_clHwVer.UpdateClipRegions(NULL);
	m_clHwVer.UpdateStripeBufInfo(NULL);
	#endif

	/* Init slaveport batch counter */
	SlavePortInitWrites();

	/* let's see what surfaces we need */
	if (byRop3[Foreground] != byRop3[Background])
	{
		m_ulSurfsPresent |= MASK_PRESENT; /* It's a ROP4 */
	}

	if ( ( (byRop3[Foreground]>>2) ^ byRop3[Foreground] ) & 0x33 )
	{
		m_ulSurfsPresent |= SRC_PRESENT;
	}

	if ( ( (byRop3[Foreground]>>4) ^ byRop3[Foreground] ) & 0x0F )
	{

⌨️ 快捷键说明

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