📄 bltfuncs.cpp
字号:
* 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 + -