📄 swblt.cpp
字号:
//
// 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 + -