swblt.cpp
来自「Lido PXA270平台开发板的最新BSP,包括源代码」· C++ 代码 · 共 1,766 行 · 第 1/5 页
CPP
1,766 行
case 0x22: src.Value = (~src.Value) & dst.Value; break; // no-name
case 0xB8: src.Value = (brush.Value & ~src.Value)|(src.Value & dst.Value); break; // no-name
case 0x11: src.Value = ~(src.Value | dst.Value); break; // NOTSRCERASE
case 0x33: src.Value = ~src.Value; break; // NOTSRCCOPY
case 0x44: src.Value &= ~dst.Value; break; // SRCERASE
case 0x55: src.Value = ~dst.Value; break; // DSTINVERT
case 0x5A: src.Value = brush.Value ^ dst.Value; break; // PATINVERT
case 0x66: src.Value ^= dst.Value; break; // SRCINVERT
case 0x88: src.Value &= dst.Value; break; // SRCAND
case 0xBB: src.Value = ~src.Value | dst.Value; break; // MERGEPAINT
case 0xC0: src.Value &= brush.Value; break; // MERGECOPY
case 0xEE: src.Value |= dst.Value; break; // SRCPAINT
case 0xF0: src.Value = brush.Value; break; // PATCOPY
case 0xFB: src.Value = brush.Value | ~src.Value | dst.Value; break; // PATPAINT
case 0xFF: src.Value = 0xFFFFFFFF; break; // WHITENESS
case 0xE2: src.Value = ( dst.Value & ~src.Value ) | ( brush.Value & src.Value ); break;
case 0xAC: src.Value = ((src.Value^dst.Value)&brush.Value)^src.Value; break;
default: src.Value = ProcessROP3(dst.Value,src.Value,brush.Value,rop3,dst.Bpp);
}
#if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
// Perform the AlphaBlend
if (alphaBlend)
{
ULONG SrcRed;
ULONG SrcGreen;
ULONG SrcBlue;
ULONG SrcAlpha;
ULONG DstRed;
ULONG DstGreen;
ULONG DstBlue;
ULONG DstAlpha;
BYTE Alpha = pParms->blendFunction.SourceConstantAlpha;
ULONG PalEntries = 0;
ULONG * pPalette = NULL;
int AlphaType = 0;
// If the surface has a palette, get the BGR value of the
// color.
if (BlendPalette)
{
pPalette = pParms->pDst->FormatPtr()->m_pPalette;
PalEntries = pParms->pDst->FormatPtr()->m_PaletteEntries;
// The mask isn't always applied to the destination value.
dst.Value &= dst.Mask;
ASSERT(src.Value < PalEntries);
ASSERT(dst.Value < PalEntries);
src.Value = pPalette[src.Value];
dst.Value = pPalette[dst.Value];
}
SrcRed = (src.Value & RedMask ) >> RedShift;
SrcGreen = (src.Value & GreenMask) >> GreenShift;
SrcBlue = (src.Value & BlueMask ) >> BlueShift;
SrcAlpha = (src.Value & AlphaMask) >> AlphaShift;
DstRed = (dst.Value & RedMask ) >> RedShift;
DstGreen = (dst.Value & GreenMask) >> GreenShift;
DstBlue = (dst.Value & BlueMask ) >> BlueShift;
DstAlpha = (dst.Value & AlphaMask) >> AlphaShift;
if (pParms->blendFunction.AlphaFormat)
{
SrcAlpha = originalSrc & SrcAlphaMask;
SrcAlpha >>= SrcAlphaShift;
if (SrcAlpha == 0)
{
// Just the dst.
src.Value = (DstRed << 16) |
(DstGreen << 8) |
(DstBlue ) |
(DstAlpha << 24);
}
else if (SrcAlpha == 255 && Alpha == 255)
{
// Just the src.
src.Value = (SrcRed << 16) |
(SrcGreen << 8) |
(SrcBlue ) |
(SrcAlpha << 24);
}
else if (SrcAlpha == 255)
{
// Source constant alpha only.
AlphaType = 1;
}
else
{
if (Alpha == 255)
{
AlphaType = 2; // Per-pixel only
}
else
{
AlphaType = 3; // Both;
}
}
}
else
{
AlphaType = 1;
}
if (AlphaType == 3)
{
// Both Per-Pixel and Constant Alpha
ULONG uB00aa00gg = (SrcAlpha << 16) | SrcGreen;
ULONG uB00rr00bb = (SrcRed << 16) | SrcBlue;
ULONG uTaaaagggg = uB00aa00gg * Alpha + 0x00800080;
ULONG uTrrrrbbbb = uB00rr00bb * Alpha + 0x00800080;
ULONG uT00aa00gg = (uTaaaagggg & 0xff00ff00) >> 8;
ULONG uT00rr00bb = (uTrrrrbbbb & 0xff00ff00) >> 8;
ULONG uCaa00gg00 = ((uTaaaagggg + uT00aa00gg) & 0xff00ff00);
ULONG uC00rr00bb = ((uTrrrrbbbb + uT00rr00bb) & 0xff00ff00) >> 8;
src.Value = uCaa00gg00 | uC00rr00bb;
BYTE beta = 255 - (BYTE)((src.Value & 0xff000000) >> 24);
ULONG _D1_00aa00gg = (DstAlpha << 16) | DstGreen;
ULONG _D1_00rr00bb = (DstRed << 16) | DstBlue;
ULONG _D2_aaaagggg = _D1_00aa00gg * beta + 0x00800080;
ULONG _D2_rrrrbbbb = _D1_00rr00bb * beta + 0x00800080;
ULONG _D3_00aa00gg = (_D2_aaaagggg & 0xff00ff00) >> 8;
ULONG _D3_00rr00bb = (_D2_rrrrbbbb & 0xff00ff00) >> 8;
ULONG _D4_00aa00gg = ((_D2_aaaagggg + _D3_00aa00gg) & 0xff00ff00) >> 8;
ULONG _D4_00rr00bb = ((_D2_rrrrbbbb + _D3_00rr00bb) & 0xff00ff00) >> 8;
ULONG _D5_00aa00gg = _D4_00aa00gg + ((src.Value & 0xff00ff00) >> 8);
ULONG _D5_00rr00bb = _D4_00rr00bb + (src.Value & 0x00ff00ff);
// Saturate the ARGB values.
ULONG TempMask = (AlphaMask >> AlphaShift) << 16;
if ((_D5_00aa00gg & 0xffff0000) > TempMask)
{
_D5_00aa00gg = TempMask | (_D5_00aa00gg & 0x0000ffff);
}
TempMask = GreenMask >> GreenShift;
if ((_D5_00aa00gg & 0x0000ffff) > TempMask)
{
_D5_00aa00gg = TempMask | (_D5_00aa00gg & 0x00ff0000);
}
TempMask = (RedMask >> RedShift) << 16;
if ((_D5_00rr00bb & 0xffff0000) > TempMask)
{
_D5_00rr00bb = TempMask | (_D5_00rr00bb & 0x0000ffff);
}
TempMask = BlueMask >> BlueShift;
if ((_D5_00rr00bb & 0x0000ffff) > TempMask)
{
_D5_00rr00bb = TempMask | (_D5_00rr00bb & 0x00ff0000);
}
src.Value = (_D5_00aa00gg << 8) | _D5_00rr00bb;
}
else if (AlphaType == 2)
{
// Per-Pixel Only
ULONG Multa = 255 - SrcAlpha;
ULONG _D1_00aa00gg = (DstAlpha << 16) | DstGreen;
ULONG _D1_00rr00bb = (DstRed << 16) | DstBlue;
ULONG _D2_aaaagggg = _D1_00aa00gg * Multa + 0x00800080;
ULONG _D2_rrrrbbbb = _D1_00rr00bb * Multa + 0x00800080;
ULONG _D3_00aa00gg = (_D2_aaaagggg & 0xff00ff00) >> 8;
ULONG _D3_00rr00bb = (_D2_rrrrbbbb & 0xff00ff00) >> 8;
ULONG _D4_00aa00gg = ((_D2_aaaagggg + _D3_00aa00gg) & 0xff00ff00) >> 8;
ULONG _D4_00rr00bb = ((_D2_rrrrbbbb + _D3_00rr00bb) & 0xff00ff00) >> 8;
ULONG _D5_00aa00gg = _D4_00aa00gg + ((SrcAlpha << 16) | SrcGreen);
ULONG _D5_00rr00bb = _D4_00rr00bb + ((SrcRed << 16) | SrcBlue);
// Saturate the ARGB values.
ULONG TempMask = (AlphaMask >> AlphaShift) << 16;
if ((_D5_00aa00gg & 0xffff0000) > TempMask)
{
_D5_00aa00gg = TempMask | (_D5_00aa00gg & 0x0000ffff);
}
TempMask = GreenMask >> GreenShift;
if ((_D5_00aa00gg & 0x0000ffff) > TempMask)
{
_D5_00aa00gg = TempMask | (_D5_00aa00gg & 0x00ff0000);
}
TempMask = (RedMask >> RedShift) << 16;
if ((_D5_00rr00bb & 0xffff0000) > TempMask)
{
_D5_00rr00bb = TempMask | (_D5_00rr00bb & 0x0000ffff);
}
TempMask = BlueMask >> BlueShift;
if ((_D5_00rr00bb & 0x0000ffff) > TempMask)
{
_D5_00rr00bb = TempMask | (_D5_00rr00bb & 0x00ff0000);
}
src.Value = (_D5_00aa00gg << 8) | _D5_00rr00bb;
}
else if (AlphaType == 1)
{
// Constant Alpha Only
// red and blue
ULONG uB00rr00bb = (DstRed << 16) | DstBlue;
ULONG uF00rr00bb = (SrcRed << 16) | SrcBlue;
ULONG uMrrrrbbbb = ((uB00rr00bb << 8) - uB00rr00bb)
+ (Alpha * (uF00rr00bb - uB00rr00bb)) + 0x00800080;
ULONG uM00rr00bb = (uMrrrrbbbb & 0xff00ff00) >> 8;
ULONG uD00rr00bb = ((uMrrrrbbbb + uM00rr00bb) & 0xff00ff00) >> 8;
// alpha and green
ULONG uB00aa00gg = (DstAlpha << 16) | DstGreen;
ULONG uF00aa00gg = (SrcAlpha << 16) | SrcGreen;
ULONG uMaaaagggg = ((uB00aa00gg << 8) - uB00aa00gg)
+ (Alpha * (uF00aa00gg - uB00aa00gg)) + 0x00800080;
ULONG uM00aa00gg = (uMaaaagggg & 0xff00ff00) >> 8;
ULONG uDaa00gg00 = (uMaaaagggg + uM00aa00gg) & 0xff00ff00;
src.Value = uD00rr00bb + uDaa00gg00;
}
// Convert src.Value back to the appropriate format;
SrcBlue = (src.Value & 0x000000ff) << BlueShift;
SrcGreen = ((src.Value & 0x0000ff00) >> 8) << GreenShift;
SrcRed = ((src.Value & 0x00ff0000) >> 16) << RedShift;
SrcAlpha = ((src.Value & 0xff000000) >> 24) << AlphaShift;
src.Value = ((SrcRed & RedMask)
| (SrcGreen & GreenMask)
| (SrcBlue & BlueMask)
| (SrcAlpha & AlphaMask));
// If the destination surface has a palette, src.Value must
// be converted to a palette index.
if (BlendPalette)
{
ULONG Error = RGBError(src.Value, pPalette[0]);
ULONG Index = 0;
for (ULONG i = 1; i < PalEntries; i++)
{
ULONG TempErr = RGBError(src.Value, pPalette[i]);
if (TempErr < Error)
{
Error = TempErr;
Index = i;
}
}
src.Value = Index;
}
}
#endif /* wince 500 */
src.Value &= dst.Mask;
if( rop3 == 0xAA || ( transparentBlt && ( originalSrc == transparentColor ) ) )
{
// we won't write this pixel
if( quickWrite )
dst.Ptr += dst.BytesPerAccess;
else
{
dst.CacheState += dst.CacheStateIncrement; // leave dirty flag as-is
if( !(dst.CacheState&0x00ff00) ) // Check bits remaining in dst cache
{
if( dst.CacheState & 0x0000ff )
*(unsigned long *)dst.Ptr = dst.Cache; // flush cache
dst.CacheState = dst.CacheStateNewDWord; // clears dirty flag
dst.Ptr += dst.BytesPerAccess; // +/- 4
dst.Cache = *(unsigned long *)dst.Ptr;
}
}
continue;
}
}
// Now, we are ready to write the value from src.Value into the dst pixel
if( quickWrite )
{
switch(dst.Bpp)
{
case 8:
*(unsigned char *)dst.Ptr = (unsigned char)src.Value;
break;
case 16:
*(unsigned short *)dst.Ptr = (unsigned short)src.Value;
break;
case 32:
*(unsigned long *)dst.Ptr = (unsigned long)src.Value;
break;
case 24:
*dst.Ptr = (unsigned char)(src.Value);
*(dst.Ptr+1) = (unsigned char)(src.Value>>8);
*(dst.Ptr+2) = (unsigned char)(src.Value>>16);
}
dst.Ptr += dst.BytesPerAccess;
}
else
{
unsigned char tmpShift = (unsigned char)(( dst.CacheState >> 16 ) ^ dst.MaskShiftXor);
dst.Cache &= ~( dst.Mask << tmpShift);
dst.Cache |= src.Value << tmpShift;
dst.CacheState += dst.CacheStateIncrementDirty; // sets dirty flag
if( !(dst.CacheState&0x00ff00) ) // Check bits remaining in dst cache
{
*(UNALIGNED unsigned long *)dst.Ptr = dst.Cache; // flush cache (we know it was dirty)
dst.CacheState = dst.CacheStateNewDWord; // clears dirty flag
dst.Ptr += dst.BytesPerAccess; // +/- 4
if (x != width - 1 )
dst.Cache = *(UNALIGNED unsigned long *)dst.Ptr;
}
}
} // next column
if( dst.CacheState & 0x0000ff )
{
*(UNALIGNED unsigned long *)dst.Ptr = dst.Cache; // flush cache
}
} // next row
return S_OK;
}
#ifdef ARM
#pragma optimize("", on)
#endif
unsigned long
ProcessROP3(
unsigned long dstValue,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?