⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swblt.cpp

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*


*/
#include    "precomp.h"


//#define DDI 1
//#include <windows.h>
//#include <winddi.h>
//#include <gpe.h>
//#include <emul.h>
#include <ctblt.h>
#include <aablt.h>
//#include <memory.h>
//#include <wingdi.h>
#include "dispperf.h"

#if defined (OSV_PPC) || ( defined (_WINCEOSVER) && (_WINCEOSVER >= 500))
extern ULONG g_BilinearMasks[4];
extern ULONG g_BilinearShifts[4];
#endif

unsigned long
ProcessROP3(
    unsigned long dstValue,
    unsigned long srcValue,
    unsigned long brushValue,
    unsigned char rop3,
    unsigned char dstBitsPerPixel
    );

unsigned long
RGBError(
    unsigned long v1,
    unsigned long v2
    );

class PixelIterator
{
public:
    // Fixed upon creation:
    unsigned char * RowPtr;
    int             RowIncrement;
    unsigned long   CacheStateNewDWord;
    unsigned long   CacheStateNewRow;
    unsigned long   CacheStateIncrement;
    unsigned long   CacheStateIncrementDirty;
    int             Is24Bit;
    unsigned long   Mask;
    int             BytesPerAccess;
    int             Bpp;
    unsigned char   MaskShiftXor;

    // IteratorState
    unsigned char * Ptr;
    unsigned long   Cache;
    unsigned long   Value;
    unsigned long   CacheState;

    void
    InitPixelIterator(
        GPESurf * pSurf,
        int       xPositive,
        int       yPositive,
        RECTL   * prcl,
        int       xSkip,
        int       ySkip
        );
};

class BrushPixelIterator : public PixelIterator
{
public:
    int                 PixelsRemaining;            // Pixels still available this row of brush incl cache
    int                 PixelsPerRow;               // Width of source surface
    int                 RowInitialPixelsRemaining;  // PixelsRemaining at start of each Dst row
    int                 RowsRemaining;              // Rows (incl this) left in pattern
    int                 Rows;                       // Total rows in pattern
    int                 LeftPixelOffset;            // Byte offset from beginning of the row to LeftRowPtr;
    unsigned char       *FirstRowPtr;               // Pointer to first DWord to use in top/bottom row
    unsigned char       *LeftRowPtr;                // Ptr to *left* of pattern of current row
                                                    //      (RowPtr is *start* of next row)
    void
    InitBrushPixelIterator(
        GPESurf *pSurf,
        int     xPositive,
        int     yPositive,
        RECTL   * prcl
        );

};

void
BrushPixelIterator::InitBrushPixelIterator(
    GPESurf *pSurf,
    int xPositive,
    int yPositive,
    RECTL   * prcl
    )
{
    DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("BrushPixelIterator::InitBrushPixelIterator\r\n")));
    // This is necessary because 1 is subtracted from prcl->bottom for bottom up bitmaps.
    if (0 == prcl->bottom) prcl->bottom = pSurf->Height();
    InitPixelIterator( pSurf, xPositive, yPositive, prcl, 0, 0 );

    PixelsPerRow = pSurf->Width();
    Rows = pSurf->Height();
    RowInitialPixelsRemaining = xPositive?PixelsPerRow-prcl->left:prcl->right;
    RowsRemaining = yPositive?Rows-prcl->top:prcl->bottom;
    FirstRowPtr = RowPtr - RowIncrement * ( Rows - RowsRemaining );

    // The LeftPixelOffset member is the number of bytes between the FirstRowPtr
    // and the actual beginning of the row of pixels pointed to by FirstRowPtr.
    LeftPixelOffset = EGPEFormatToBpp[pSurf->Format()] * (PixelsPerRow - RowInitialPixelsRemaining);
    LeftPixelOffset = ((LeftPixelOffset&~31)>>3);

    if (!xPositive) LeftPixelOffset = -LeftPixelOffset;

    DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("PixelsPerRow=%d, Rows=%d, RowInitPixRem=%d, RowsRem=%d, FirstRowPtr=%08x\r\n"),
        PixelsPerRow, Rows, RowInitialPixelsRemaining, RowsRemaining, FirstRowPtr ));
}

void
PixelIterator::InitPixelIterator(
    GPESurf *pSurf,
    int xPositive,
    int yPositive,
    RECTL *prcl,
    int xSkip,
    int       ySkip
    )
{
    DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("PixelIterator::PixelIterator, prcl= l:%d,t:%d - r:%d,b:%d Bpp=%d\r\n"),
        prcl->left, prcl->top, prcl->right, prcl->bottom, EGPEFormatToBpp[pSurf->Format()]
        ));

    // Set pointer to start of first row to use
    RowPtr = (unsigned char *)(pSurf->Buffer());

    if( yPositive )
    {
        RowIncrement = pSurf->Stride();
        RowPtr += pSurf->Stride() * (prcl->top + ySkip );
    }
    else
    {
        RowIncrement = -pSurf->Stride();
        RowPtr += pSurf->Stride() *  (prcl->bottom-1-ySkip);
    }

    int StartX;
    Bpp = EGPEFormatToBpp[pSurf->Format()];

    MaskShiftXor = (Bpp<8)?(8-Bpp):0;
    CacheStateNewDWord = (32/Bpp)<<8;       // Initally 32/Bpp pixels in dword, 0 offset

    if( xPositive )
    {
        StartX = prcl->left + xSkip;
        CacheStateIncrement = ((Bpp<<8) - 1)<<8;
    }
    else
    {
        StartX = prcl->right-1-xSkip;
        CacheStateIncrement = (((-Bpp)<<8) - 1)<<8;
        CacheStateNewDWord |= (32 - Bpp)<<16;       // Initial offset points to last pixel in dword
    }

    CacheStateIncrementDirty = CacheStateIncrement+1;

    if( Is24Bit = ( pSurf->Format() == gpe24Bpp ) ) // deliberate assignment
    {
        RowPtr += 3 * StartX;
        BytesPerAccess = 3;
    }
    else
    {
        int StartBit = Bpp * StartX;

        RowPtr += (StartBit&~31) >> 3;

        // Since the first pixel on row in prcl may not be on dword alignment:
        CacheStateNewRow = CacheStateNewDWord;
        while( (( CacheStateNewRow >> 16 ) ^ StartBit ) & 31 )
        {
            CacheStateNewRow += CacheStateIncrement;
        }

        BytesPerAccess = 4;
    }

    if( !xPositive )
    {
        BytesPerAccess = -BytesPerAccess;
    }

    Mask = ( 2 << (Bpp - 1) ) - 1;

    DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("BytesPerAccess=%d,CacheStateNewRow=%06x,CacheStateIncrement=%06x\r\n"),
        BytesPerAccess, CacheStateNewRow, CacheStateIncrement ));
    DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("Mask=%08x, CacheStateNewDWord=%08x, StartX=0x%04x(%d)\r\n"),
        Mask, CacheStateNewDWord, StartX, StartX ));
    DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("Buffer=0x%08x\r\n"),
        (pSurf->Buffer()) ));
}
#undef SWAP
#define SWAP(a,b,type) { type tmp=a; a=b; b=tmp; }

SCODE
GPE::EmulatedBlt(
    GPEBltParms * pParms
    )
{
    SCODE (GPE::*pBlt)(GPEBltParms*) = pParms->pBlt;
    SCODE sc;
    BOOL bSaveBltFunc = FALSE;

    if( pParms->pDst->InVideoMemory() ||
        ( pParms->pSrc && pParms->pSrc->InVideoMemory() ) ||
        ( pParms->pMask && pParms->pMask->InVideoMemory() ) ||
        ( pParms->pBrush && pParms->pBrush->InVideoMemory() ) )
    {
        // If we have a pending blt and now attempt a software operation using
        // video memory, the pipeline must be flushed.
        WaitForNotBusy();
    }

    // Handle improperly ordered prclDst resulting from stretch Blt
    if (pParms->pBlt != EmulatedBlt)
    {
        bSaveBltFunc = TRUE;
    }

    pParms->pBlt = EmulatedBlt_Internal;

    // Check to see if this should be handled by the ClearType(tm) or
    // AAFont libraries.
    if (pParms->rop4 == 0xAAF0)
    {
        ClearTypeBltSelect(pParms);
        AATextBltSelect(pParms);
    }

    // Check to see if this should be handled by the emul library.
    if (pParms->pBlt == EmulatedBlt_Internal)
    {
        EmulatedBltSelect02(pParms);
        EmulatedBltSelect08(pParms);
        EmulatedBltSelect16(pParms);
    }

    if (pParms->pBlt != EmulatedBlt_Internal)
    {
        DispPerfType(DISPPERF_ACCEL_EMUL);
    }

/* Bilinear is only supported in the PocketPC tree and Wince500 */
#if defined (OSV_PPC) || ( defined (_WINCEOSVER) && (_WINCEOSVER >= 500))
    // Check to see if we need to use Bilinear stretching
    if (pParms->iMode == BILINEAR)
    {
        LONG DstWidth  = pParms->prclDst->right - pParms->prclDst->left;
        LONG DstHeight = pParms->prclDst->bottom - pParms->prclDst->top;

        if (pParms->bltFlags == BLT_STRETCH
            && pParms->xPositive
            && pParms->yPositive
            && pParms->pDst->Format() > gpe8Bpp
            && (pParms->rop4 == 0xCCCC
                || pParms->rop4 == 0xEEEE
                || pParms->rop4 == 0x8888)
            && DstWidth > 0
            && DstHeight > 0
            && DstWidth >= pParms->prclSrc->right - pParms->prclSrc->left
            && DstHeight >= pParms->prclSrc->bottom - pParms->prclSrc->top)
        {
            pParms->pBlt = EmulatedBlt_Bilinear;
        }
    }

 #if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
   // Check to see if GeneratedBlts can handle this operation
    if (pParms->pBlt == EmulatedBlt_Internal)
    {
        GeneratedBltSelect(pParms);
    }
#endif /* WINCE500 */
#endif /* OSV_PPC or WINCE500*/

    sc = (this->*(pParms->pBlt))(pParms);

    if (bSaveBltFunc)
    {
        pParms->pBlt = pBlt;
    }

    return sc;
}

SCODE
GPE::EmulatedBlt_Internal(
    GPEBltParms *pParms
    )
{
    DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("New Blt. rop4=%04X\r\n"), pParms->rop4));

    unsigned char rop3 = (unsigned char)pParms->rop4;
    unsigned char maskedROP3 = (unsigned char)( pParms->rop4 >> 8 );
    unsigned char unmaskedROP3 = rop3;
    int complexBlt = 0;
    int quickWrite = 0;
    int width = pParms->prclDst->right - pParms->prclDst->left;
    int height = pParms->prclDst->bottom - pParms->prclDst->top;
    int x;
    RECTL rclBrush;
    int dstMatters = ((( pParms->rop4 >> 1 ) ^ pParms->rop4 ) & 0x5555 ) != 0;
    int dstXPositive = pParms->xPositive;    // These differ from pParms->?Positive if flipping is being performed
    int dstYPositive = pParms->yPositive;
    RECTL *prclDst = pParms->prclDst;
    RECTL tmpRclDst;
    int xShrinkStretch = 0;
    int xShrink=0;
    int xStretch=0;
    int yShrinkStretch = 0;
    int yShrink=0;
    int yStretch=0;
    int srcWidth;
    int srcHeight;
    int rowXAccum, xAccum, xDMajor, xDMinor;    // only valid if xShrinkStretch
    int yAccum, yDMajor, yDMinor;    // only valid if yShrinkStretch
    int originalMaskRowInc, originalSrcRowInc;    // Used if yShrinkStretch
    unsigned char *prevMaskPtr, *prevSrcPtr;
    unsigned long prevMaskCache, prevSrcCache;
    unsigned long prevMaskCacheState, prevSrcCacheState;
    unsigned long originalSrc;
#if defined (_WINCEOSVER) && (_WINCEOSVER >= 500)
    unsigned long SrcRGBMask;
#endif
    int dstXStartSkip = 0;    // Number of dst pixels to not write (left if dstXPositive else right)
    int dstYStartSkip = 0;    // Number of rows to ignore (top if dstYPositive)
    int srcXStartSkip = 0;
    int srcYStartSkip = 0;

⌨️ 快捷键说明

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