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 + -
显示快捷键?