📄 bltfuncs.cpp
字号:
if (psBlitParameters->pBrush != NULL)
{
m_ulSurfsPresent |= PAT_PRESENT;
}
else
{
m_ulSurfsPresent |= FILL_PRESENT;
}
}
else
{
/* BLACKNESS, WHITENEESS, and DSTINVERT */
if (byRop3[Foreground] == 0x00 || byRop3[Foreground] == 0xFF
/* Send DSTINVERT as a solid fill because the ROP does the dest invert */
|| byRop3[Foreground] == 0x55)
{
m_ulSurfsPresent |= FILL_PRESENT;
}
}
if (m_ulSurfsPresent & MASK_PRESENT)
{
if ( ( (byRop3[Background]>>2) ^ byRop3[Background] ) & 0x33 )
{
m_ulSurfsPresent |= SRC_PRESENT;
}
if ( ( (byRop3[Background]>>4) ^ byRop3[Background] ) & 0x0F )
{
if (psBlitParameters->pBrush != NULL)
{
m_ulSurfsPresent |= PAT_PRESENT;
}
else
{
m_ulSurfsPresent |= FILL_PRESENT;
}
}
/*
* Masked BLACKNESS, WHITENEESS, and DSTINVERT
* Send DSTINVERT as a solid fill because the ROP does the dest invert
*/
if (byRop3[Background] == 0x00 || // blackness
byRop3[Background] == 0xFF || // whiteness
byRop3[Background] == 0x55)
{
m_ulSurfsPresent |= FILL_PRESENT;
}
}
/* Hw 537 bug fix */
if (gdwHPRN537HwFix==0)
{
if ((m_ulSurfsPresent & SRC_PRESENT) &&
(m_ulSurfsPresent & PAT_PRESENT) &&
(psBlitParameters->pDst == psBlitParameters->pSrc) )
{
return (FALSE);
}
}
#ifdef ENABLE_2D_PROFILE
if (m_ulSurfsPresent & SRC_PRESENT)
{
// Profile : detect sys mem blts
if (psBlitParameters->pSrc && !psBlitParameters->pSrc->InVideoMemory())
{
// The source is in sys mem
profile_sysmem(m_sActiveNode);
}
}
if (m_ulSurfsPresent & MASK_PRESENT)
{
if (psBlitParameters->pMask && !psBlitParameters->pMask->InVideoMemory())
{
// Profile : detect sys mem mask blts
profile_sysmem(m_sActiveNode);
}
}
#endif /* ENABLE_2D_PROFILE */
/* Check the surfaces are all in order for HW acceleration */
/////////////////////////////////////////////////
// DST
/////////////////////////////////////////////////
if (psBlitParameters->prclDst)
{
rclDst = *psBlitParameters->prclDst;
/* trap cases where the Dst Rect is too big */
if (rclDst.right > MAX_2D_WIDTH)
{
rclDst.right = MAX_2D_WIDTH;
}
if (rclDst.bottom > MAX_2D_HEIGHT)
{
rclDst.bottom = MAX_2D_HEIGHT;
}
}
else
{
rclDst.top = rclDst.left = 0;
rclDst.right = psBlitParameters->pDst->Width();
rclDst.bottom = psBlitParameters->pDst->Height();
}
if (m_ulSurfsPresent & SRC_PRESENT)
{
m_ulXFPStretch = MBX2D_NO_STRETCH;
m_ulYFPStretch = MBX2D_NO_STRETCH;
rclSrc = *psBlitParameters->prclSrc;
ASSERT (rclSrc.left <= rclSrc.right);
ASSERT (rclSrc.top <= rclSrc.bottom);
#if (_WINCEOSVER < 500)
/* rclSrc is not necessarily well ordered for us!! */
if (rclSrc.left > rclSrc.right)
{
LONG tmp = rclSrc.left;
rclSrc.left = rclSrc.right;
rclSrc.right = tmp;
}
if (rclSrc.top > rclSrc.bottom)
{
LONG tmp = rclDst.top;
rclSrc.top = rclSrc.bottom;
rclSrc.bottom = tmp;
}
#endif /* (_WINCEOSVER < 500) */
if (psBlitParameters->bltFlags & BLT_STRETCH)
{
LONG lDW = rclDst.right - rclDst.left;
LONG lDH = rclDst.bottom - rclDst.top;
LONG lSW = rclSrc.right - rclSrc.left;
LONG lSH = rclSrc.bottom - rclSrc.top;
ULONG ulScaleFactor;
/* Test this because sometimes BLT_STRETCH is wrongly set. */
if ((lDW == lSW) && (lDH == lSH))
{
psBlitParameters->bltFlags &= ~BLT_STRETCH;
}
else
{
if (gdwCPRN620HwFix==0)
{
/*
* test for totally clipped destinations as as MBX cannot scale the source rectangle
*/
if (psBlitParameters->prclClip)
{
if (rclDst.left < rclDst.right)
{
/* normal stretch */
if ((psBlitParameters->prclClip->right < rclDst.left) ||
(psBlitParameters->prclClip->left > rclDst.right))
{
#ifdef LOCAL_MEMORY_SELF_REFRESH
SysLocalMemoryDisable(m_sDevData.psDevInfoKM);
#endif // LOCAL_MEMORY_SELF_REFRESH
return (FALSE);
}
}
else
{
/* flipped in x dirn */
/* don't even think about handling mirrored */
#ifdef LOCAL_MEMORY_SELF_REFRESH
SysLocalMemoryDisable(m_sDevData.psDevInfoKM);
#endif // LOCAL_MEMORY_SELF_REFRESH
return (FALSE);
}
if (rclDst.top < rclDst.bottom)
{
/* normal stretch */
if ((psBlitParameters->prclClip->bottom < rclDst.top) ||
(psBlitParameters->prclClip->top > rclDst.bottom))
{
#ifdef LOCAL_MEMORY_SELF_REFRESH
SysLocalMemoryDisable(m_sDevData.psDevInfoKM);
#endif // LOCAL_MEMORY_SELF_REFRESH
return (FALSE);
}
}
else
{
/* flipped in y dirn */
/* don't even think about handling mirrored */
#ifdef LOCAL_MEMORY_SELF_REFRESH
SysLocalMemoryDisable(m_sDevData.psDevInfoKM);
#endif // LOCAL_MEMORY_SELF_REFRESH
return (FALSE);
}
}
} /* gdwCPRN620HwFix */
#ifdef PDUMP
PDumpScript("-- Stretch / Shrink Control");
#endif
if ((lDW == 0) || (lDH == 0))
{
/* stretch to nothing */
return (FALSE);
}
if (lDW != lSW)
{
// here we need to check we can handle then stretch/shrink
// we have 10bits to represent the scale-factor
ulScaleFactor = abs((lSW<<16)/lDW);
// are there any bits outside our range?
if ((ulScaleFactor & 0xFFE007FF) ||
(ulScaleFactor==0) ||
(ulScaleFactor>(16<<16))) /* compress by x16 */
{
/* we can't handle this */
return (FALSE);
}
m_ulXFPStretch = ulScaleFactor >> (16-MBX2D_STRETCH_FPSHIFT);
}
else
{
m_ulXFPStretch = MBX2D_NO_STRETCH;
}
if (lDH != lSH)
{
// here we need to check we can handle then stretch/shrink
// we have 10bits to represent the scale-factor
ulScaleFactor = abs((lSH<<16)/lDH);
// are there any bits outside our range?
if ((ulScaleFactor & 0xFFE007FF) ||
(ulScaleFactor==0) ||
(ulScaleFactor>(16<<16))) /* compress x16 */
{
// we can't handle this
return (FALSE);
}
m_ulYFPStretch = ulScaleFactor >> (16-MBX2D_STRETCH_FPSHIFT);
}
else
{
m_ulYFPStretch = MBX2D_NO_STRETCH;
}
}
}
SlavePortWrite( MBX2D_STRETCH_BH
| (m_ulXFPStretch<<MBX2D_X_STRETCH_SHIFT)
| (m_ulYFPStretch<<MBX2D_Y_STRETCH_SHIFT) );
}
else
{
/* even though there is no source surface,
MBX still uses the stretch control setting,
so we must reset it every time */
SlavePortWrite( MBX2D_STRETCH_BH
| (MBX2D_NO_STRETCH<<MBX2D_X_STRETCH_SHIFT)
| (MBX2D_NO_STRETCH<<MBX2D_Y_STRETCH_SHIFT) );
}
#ifdef ENABLE_2D_PROFILE
if (psBlitParameters->bltFlags & BLT_STRETCH)
{
profile_stretch(m_sActiveNode);
}
#endif
/* Local copies of the backward blt flags that we can modify. */
m_bXPositive = psBlitParameters->xPositive;
m_bYPositive = psBlitParameters->yPositive;
#if !defined NO_2D_CLOCKCONTROL
#if defined TIMED2DGATING
/* inc Ops count, Enable if OP count was zero or if we're synchronised*/
m_sDevData.psDevInfoKM->sDeviceSpecific.s3D.ui32OpsCount++;
if (SysCoreQuery(DEV_CGCORE_MBX_2D) == IMG_FALSE)
{
SysCoreEnable(m_sDevData.psDevInfoKM, DEV_CGCORE_MBX_2D, IMG_TRUE);
}
#else
SysCoreEnable(m_sDevData.psDevInfoKM, DEV_CGCORE_MBX_2D, IMG_TRUE);
#endif
#endif /* NO_2D_CLOCKCONTROL */
m_pfnSWBlt = psBlitParameters->pBlt;
#if HW_VERIFY
m_clHwVer.PrepareToPDumpThisBlt();
#endif
DispPerfType(DISPPERF_ACCEL_HARDWARE);
#ifdef ROTATE_ENABLE
m_bMapToUnrotated = FALSE;
if (m_lPrimaryRotation)
{
LONG lSrcRotation;
LONG lBltRotation;
//////////////////////////
// Rotation :
// There are four cases :
// Src -> Dst no rotation < supported >
// Src ->RotDst off-screen to rotated primary < supported >
// RotSrc-> RotDst rotated primary to rotated primary < supported >
// RotSrc-> Dst rotated primary to off screen < supported >
//////////////////////////
/* we know that the dest is in Video memory so we own the surface */
lDestRotation = ((MBXSurf*)(psBlitParameters->pDst))->m_lRotationAngle;
#ifdef ENABLE_2D_PROFILE
if (lDestRotation)
{
profile_rotate(m_sActiveNode);
}
#endif
if (lDestRotation == 90 || lDestRotation == 270)
{
m_PhysDestWidth = psBlitParameters->pDst->Height();
m_PhysDestHeight = psBlitParameters->pDst->Width();
}
else
{
m_PhysDestWidth = psBlitParameters->pDst->Width();
m_PhysDestHeight = psBlitParameters->pDst->Height();
}
//
// It is assumed that the Mask surface cannot be rotated because it
// is always 1BPP and will never be the primary surface.
// If anyone switches to 1BPP primary, then uses it as a mask, this will not work.
//
if ((m_ulSurfsPresent & SRC_PRESENT) && (psBlitParameters->pSrc->InVideoMemory()))
{
// Get source surface rotation in degrees
/* again, as the source is in video memory we own the surface */
lSrcRotation = ((MBXSurf*)(psBlitParameters->pSrc))->m_lRotationAngle;
if (lSrcRotation)
{
// Try to do the blt unrotated if possible, it's much quicker.
//
// This is how we accelerate rotated SrcCopy blts when both the source
// and destination are on a rotated surface :
// The source, destination, and clip rectangles are all unrotated,
// and the backwards flags are then re-calculated.
// The blt is then done unrotated.
if ( (lSrcRotation == lDestRotation)
&& !(m_ulSurfsPresent & MASK_PRESENT) // UnRotate won't work with a mask
&& !(m_ulSurfsPresent & PAT_PRESENT) // UnRotate won't work with a pattern
&& !(psBlitParameters->bltFlags & BLT_STRETCH)
)
{
// Flag that Source X and Y params must be unrotated in software.
m_bMapToUnrotated = TRUE;
// Unrotate the source and dest rects THEY ARE BOTH ON THE DEST SURFACE
UnRotate(&rclDst, (MBXSurf*)psBlitParameters->pDst);
UnRotate(&rclSrc, (MBXSurf*)psBlitParameters->pSrc);
// Now see if there are any backwards blt requirements.
m_bXPositive = TRUE;
m_bYPositive = TRUE;
/*
* if lSrcRotation == lDestRotation then both must be the primary surface
* Retest for intersection then for forwards/backwards requirements.
*/
if ( (rclSrc.bottom > rclDst.top) &&
(rclSrc.top < rclDst.bottom) &&
(rclSrc.right > rclDst.left) &&
(rclSrc.left < rclDst.right) )
{
if (rclSrc.top == rclDst.top)
{
// Horizontal blt, just set m_bXPositive appropriately
m_bXPositive = (rclSrc.left >= rclDst.left);
}
else
{
// Non horizontal blts, just set m_bYPositive appropriately
m_bYPositive = (rclSrc.top >= rclDst.top);
}
}
}
else
{
// MBX will not be able to accelerate this.
goto HWPrepExit;
}
}
}
else
{
/* There is no source in video memory. */
lSrcRotation = 0;
}
/* Calculate what output rotation is required for this blt */
lBltRotation = lDestRotation - lSrcRotation; /* WinCE rotation */
switch (lBltRotation)
{
/* CE 90 anticlockwise. */
case 90:
case -270:
/* MBX 270 clockwise */
m_ulBltRotationHw = MBX2D_TEXTROT_270DEGS;
break;
/* CE 180 */
case 180:
case -180:
/* MBX 180 */
m_ulBltRotationHw = MBX2D_TEXTROT_180DEGS;
break;
/* CE 270 anticlockwise */
case 270:
case -90:
/* MBX 90 clockwise */
m_ulBltRotationHw = MBX2D_TEXTROT_90DEGS;
break;
default:
/* No rotation */
m_ulBltRotationHw = MBX2D_TEXTROT_NONE;
}
#ifdef PDUMP
if (lBltRotation > 0)
{
if (m_ulSurfsPresent & SRC_PRESENT)
{
if (!psBlitParameters->pSrc->InVideoMemory())
{
/* The source will need uploading via the stripe buffer */
PDumpScript("-- Rotated source upload from system memory");
}
else
{
/* Yes we can do all blts where the source is already in Video memory. */
PDumpScript("-- Rotated source blt, source is in Video memory");
}
}
/* The mask surface is always 1BPP */
if (m_ulSurfsPresent & MASK_PRESENT)
{
if (psBlitParameters->pMask->InVideoMemory())
{
/* Yes we can do this. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -