swblt.cpp

来自「Lido PXA270平台开发板的最新BSP,包括源代码」· C++ 代码 · 共 1,766 行 · 第 1/5 页

CPP
1,766
字号
    {
        mask.RowIncrement = 0;
    }

    if( ( dst.Bpp = EGPEFormatToBpp[pParms->pDst->Format()] ) >= 8 )
    {
        quickWrite = 1;

        if( !dstYPositive )
        {
            dst.RowIncrement = -pParms->pDst->Stride();
            dst.RowPtr = (unsigned char *)pParms->pDst->Buffer() + pParms->pDst->Stride() * ( prclDst->bottom - 1 - dstYStartSkip );
        }
        else
        {
            dst.RowIncrement = pParms->pDst->Stride();
            dst.RowPtr = (unsigned char *)pParms->pDst->Buffer() + pParms->pDst->Stride() * ( dstYStartSkip + prclDst->top );
        }

        if( !dstXPositive )
        {
            dst.BytesPerAccess = -dst.Bpp/8;
            dst.RowPtr -= dst.BytesPerAccess * ( prclDst->right - 1 - dstXStartSkip );
        }
        else
        {
            dst.BytesPerAccess = dst.Bpp/8;
            dst.RowPtr += dst.BytesPerAccess * ( dstXStartSkip + prclDst->left );
        }

        dst.Mask = ( 2 << (dst.Bpp - 1) ) - 1;
        dst.CacheState=0;   // so it is not marked as dirty
    }
    else
    {
        dst.InitPixelIterator( pParms->pDst, dstXPositive, dstYPositive, prclDst,
            dstXStartSkip, dstYStartSkip );
    }

    if( yShrinkStretch )
    {
        // Back up the source and mask row increments because they will be altered dynamically
        originalMaskRowInc = mask.RowIncrement;
        originalSrcRowInc = src.RowIncrement;
        DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("yStretch:%d yShrink:%d yDMinor:%d yDMajor:%d yAccum:%d\n"),
            yStretch, yShrink, yDMinor, yDMajor, yAccum ));
    }

    if( pParms->rop4 == 0x0000 )
    {
        src.Value = 0;
    }
    else if( pParms->rop4 == 0xffff )
    {
        src.Value = dst.Mask;
    }
    else
    {
        src.Value = pParms->solidColor & dst.Mask;
        if(    ( maskedROP3 != unmaskedROP3 )
            || transparentBlt
#if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
            || alphaBlend
#endif
            || xShrinkStretch
            || ( rop3 != 0xCC && ( rop3 != 0xF0 || pParms->pBrush ) ) )
        {
            DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("Complex Blt!\r\n")));
            DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("transparent:%d,masked:%2x,unmasked:%2x,rop3:%2x,mask.RowPtr:%08x\r\n"),
                transparentBlt,maskedROP3, unmaskedROP3, rop3, mask.RowPtr ));
            complexBlt = 1;
        }
    }
    brush.Value = src.Value;

    while( height-- )
    {
        // Handle y Shrinking or stretching
        if( yShrinkStretch )
        {
            if( yShrink )
            {
                while( yAccum < 0 ) // skip source line(s) if shrinking
                {
                    DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("yShrink - skip line\r\n")));
                    src.RowPtr += src.RowIncrement;
                    mask.RowPtr += mask.RowIncrement;
                    yAccum += yDMinor;
                }
                yAccum += yDMajor;
            }
            else
            {
                if( yAccum < 0 )
                {
                    ASSERT(yStretch);

                    // repeat source line if stretching
                    DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("yStretch - Repeat. Accum=%d\r\n"), yAccum));
                    yAccum += yDMinor;      // yDMinor is a small +ve number
                        src.RowIncrement = 0;
                        mask.RowIncrement = 0;
                    }
                else
                {
                    DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("yStretch - Switch to next after this Accum=%d\r\n"), yAccum));
                    // Switch to next source line  (after this row)
                    yAccum += yDMajor;      // yDMajor is a large -ve value (i.e. |yDMajor| > |yDMinor| )
                    src.RowIncrement = originalSrcRowInc;
                    mask.RowIncrement = originalMaskRowInc;
                }
            }
        }

        // Move all iterators to next line
        if( src.RowPtr )
        {
            src.Ptr = src.RowPtr;
            src.RowPtr += src.RowIncrement;

            if( ! src.Is24Bit )
            {
                src.Cache = *(UNALIGNED unsigned long *)src.Ptr;
                src.CacheState = src.CacheStateNewRow;
            }
        }

        if( mask.RowPtr )
        {
            mask.Ptr = mask.RowPtr;
            mask.RowPtr += mask.RowIncrement;
            mask.Cache = *(UNALIGNED unsigned long *)mask.Ptr;
            mask.CacheState = mask.CacheStateNewRow;
        }

        if( brush.RowPtr )
        {
            brush.Ptr = brush.RowPtr;
            brush.LeftRowPtr = brush.Ptr - brush.LeftPixelOffset;

            if( --brush.RowsRemaining )
            {
                brush.RowPtr += brush.RowIncrement;
            }
            else
            {
                brush.RowPtr = brush.FirstRowPtr;
                brush.RowsRemaining = brush.Rows;
            }

            brush.Cache = *(unsigned long *)brush.Ptr;
            brush.CacheState = brush.CacheStateNewRow;
            brush.PixelsRemaining = brush.RowInitialPixelsRemaining;
        }

        dst.Ptr = dst.RowPtr;
        dst.RowPtr += dst.RowIncrement;

        if( !quickWrite )
        {
            dst.Cache = *(UNALIGNED unsigned long *)dst.Ptr;
            dst.CacheState = dst.CacheStateNewRow;
        }

        if( xStretch )
        {
            prevMaskPtr = mask.Ptr;
            prevMaskCache = mask.Cache;
            prevMaskCacheState = mask.CacheState;
            prevSrcPtr = src.Ptr;
            prevSrcCache = src.Cache;
            prevSrcCacheState = src.CacheState;
        }

        xAccum = rowXAccum;

        for( x=0; x<width; x++ )
        {
            if( src.Ptr )
            {
                // Read the next pixel in and convert to same depth as destination

                if( src.Is24Bit )   // Since 24-bit packed pixels cross dword boundaries:
                {
                    src.Value = ( *src.Ptr ) + ( *(src.Ptr+1) << 8 ) +  ( *(src.Ptr+2) << 16 );
                    src.Ptr += src.BytesPerAccess;
                }
                else
                {
                    if( !(src.CacheState&0x00ff00) )    // Check bits remaining in src.Cache
                    {
                        src.Ptr += src.BytesPerAccess;          // increment src.Ptr
                        src.CacheState = src.CacheStateNewDWord;
                        src.Cache = *(UNALIGNED unsigned long *)src.Ptr;    // reload src.Cache
                    }
                    src.Value = src.Cache >> ( (src.CacheState >> 16) ^ src.MaskShiftXor );
                    src.CacheState += src.CacheStateIncrement;
                }

                // Save the original source for transparency.
                originalSrc = ( src.Value &= src.Mask );
#if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
               originalSrc &= SrcRGBMask;
#endif
                if( pParms->pLookup )
                {
                    src.Value = (pParms->pLookup)[src.Value];
                }

                if( pParms->pConvert )
                {
                    src.Value = (pParms->pColorConverter->*(pParms->pConvert))( src.Value );
                }
            }

            if( complexBlt )    // brushed, masked, transparent, unusual rop3 etc
            {
                if( brush.Ptr )
                {
                    // Note that the brush will already have been converted to the same
                    // depth as the destination (if they weren't the same).
                    // The exception is if the dest is 24Bpp. In this case, the brush
                    // will have been converted to 32Bpp for simplicity.
                    // See DrvRealizeBrush for details

                    if( !(brush.PixelsRemaining--) )    // Check for wrapping off right edge of pattern
                    {
                        brush.Ptr = brush.LeftRowPtr;
                        brush.PixelsRemaining = brush.PixelsPerRow-1;
                        brush.CacheState = brush.CacheStateNewDWord;
                        brush.Cache = *(unsigned long *)brush.Ptr;  // reload brush.Cache
                    }
                    else if( !(brush.CacheState&0x00ff00) ) // Check bits remaining in brush.Cache
                    {
                        brush.Ptr += brush.BytesPerAccess;              // increment brush.Ptr
                        brush.CacheState = brush.CacheStateNewDWord;
                        brush.Cache = *(unsigned long *)brush.Ptr;  // reload brush.Cache
                    }

                    brush.Value = brush.Cache >> ( (brush.CacheState >> 16) ^ brush.MaskShiftXor );
                    brush.CacheState += brush.CacheStateIncrement;
                }
                if( mask.Ptr ) // This selects between two rop3's
                {
                    if( !(mask.CacheState&0x00ff00) )   // check bits remaining in mask cache
                    {
                        mask.Ptr += mask.BytesPerAccess;    //  == +/- 4
                        mask.CacheState = mask.CacheStateNewDWord;
                        mask.Cache = *(UNALIGNED unsigned long *)mask.Ptr;
                    }

                    rop3 = ( mask.Cache & ( 1 << ( (mask.CacheState >> 16) ^ mask.MaskShiftXor ) ) ) ? unmaskedROP3 : maskedROP3;
                    mask.CacheState += mask.CacheStateIncrement;
                }

                if( xShrinkStretch )
                {
                    // Handle x Stretching
                    if( xStretch )
                    {
                        if( xAccum < 0 )    // Repeat this pixel
                        {
                            xAccum += xDMinor;
                            mask.Ptr = prevMaskPtr;
                            mask.Cache = prevMaskCache;
                            mask.CacheState = prevMaskCacheState;
                            src.Ptr = prevSrcPtr;
                            src.Cache = prevSrcCache;
                            src.CacheState = prevSrcCacheState;
                        }
                        else                // OK to move to next source pixel after this
                        {
                            xAccum += xDMajor;
                            prevMaskPtr = mask.Ptr;
                            prevMaskCache = mask.Cache;
                            prevMaskCacheState = mask.CacheState;
                            prevSrcPtr = src.Ptr;
                            prevSrcCache = src.Cache;
                            prevSrcCacheState = src.CacheState;
                        }
                    }
                    else    // xShrink
                    {
                        while( xAccum < 0 )     // Skip pixel(s)
                        {
                            // Move to next src pixel
                            if( src.Is24Bit )   // Since 24-bit packed pixels cross dword boundaries:
                            {
                                src.Ptr += src.BytesPerAccess;
                            }
                            else
                            {
                                if( !(src.CacheState&0x00ff00) )    // Check bits remaining in src.Cache
                                {
                                    src.Ptr += src.BytesPerAccess;          // increment src.Ptr
                                    src.CacheState = src.CacheStateNewDWord;
                                    if (x != width - 1 )
                                        src.Cache = *(UNALIGNED unsigned long *)src.Ptr;    // reload src.Cache
                                }
                                src.CacheState += src.CacheStateIncrement;
                            }

                            // Move to next mask pixel
                            if( pParms->pMask )
                            {
                                if( !(mask.CacheState&0x00ff00) )   // check bits remaining in mask cache
                                {
                                    mask.Ptr += mask.BytesPerAccess;        //  == +/- 4
                                    mask.CacheState = mask.CacheStateNewDWord;
                                    mask.Cache = *(UNALIGNED unsigned long *)mask.Ptr;
                                }

                                mask.CacheState += mask.CacheStateIncrement;
                            }

                            xAccum += xDMinor;
                        }

                        xAccum += xDMajor;
                    }
                }

                if( dstMatters )        // The underlying rop4 utilizes the dst.
                {
                    // We maintain dst.Cache valid at all times if not doing quickWrite
                    if( quickWrite )
                    {
                        switch(dst.Bpp)
                        {
                        case 8:
                                *(unsigned char *)&dst.Value = *(unsigned char *)dst.Ptr;
                                break;
                        case 16:
                                *(unsigned short *)&dst.Value = *(unsigned short *)dst.Ptr;
                                break;
                        case 32:
                                *(unsigned long *)&dst.Value = *(unsigned long *)dst.Ptr;
                                break;
                        case 24:
                                dst.Value = ( *dst.Ptr ) + ( *(dst.Ptr+1) << 8 ) +  ( *(dst.Ptr+2) << 16 );
                        }
                    }
                    else
                        dst.Value = dst.Cache >> ( ( dst.CacheState >> 16 ) ^ dst.MaskShiftXor );
                }

                switch( rop3 )
                {
                    // The compiler sorts these and creates a binary search set of tests to
                    // get to an entry quickly.  Branch "prediction" helps this a lot.
                    // Remember that masked rop4s makes NOP and SRCCOPY quite a likely rop3
                    case 0xAA: break;                                          // NOP
                    case 0xCC: break;                                          // SRCCOPY
                    case 0x00: src.Value = 0;                           break; // BLACKNESS

⌨️ 快捷键说明

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