📄 blt.cpp
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995, 1996, 1997, 1998 Microsoft Corporation
Copyright (c) 1999-2000 Silicon Motion, Inc.
Module Name: blt.cpp
Abstract: bitblt/rectangle for SMI
Functions:
Notes:
--*/
#include "precomp.h"
#define DISPPERF_DECLARE
#include "dispperf.h"
#include <emul.h>
#ifdef CMDLIST
#undef CMDLISTHBLT //disable host blt cmdlist
#endif
int RotBLT_Width=9; //strip width. Copy strip by strip to work around rotationBLT garbage issue. No visible garbage if <=9, but only =1 can pass CETK4.2 so far.
extern GPESurf *g_pbuffer180;
#define GPETYPE (SCODE (GPE::*) (struct GPEBltParms*))
SCODE SMI::WrapBlt(GPEBltParms *pBltParms)
{
//WaitForNotBusy();
DispPerfType(DISPPERF_ACCEL_GPE);
WaitForNotBusy(); //in case code inside GPE does not wait sometimes.
SCODE status = EmulatedBlt(pBltParms);
return(status);
}
SCODE SMI::BltPrepare(GPEBltParms *pBltParms)
{
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("SMI::BltPrepare rop4=0x%04X\r\n"), pBltParms->rop4));
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("+Dest Format=%d Rect=%d,%d-%d,%d GPESurf=%08X\r\n"),
pBltParms->pDst->Format(), pBltParms->prclDst->left,
pBltParms->prclDst->top, pBltParms->prclDst->right,
pBltParms->prclDst->bottom, pBltParms->pDst));
// Make sure 2D Engine is on and the current power state is appropriate
POWER_HOOK(2D, VGXPowerMinimal);
if (pBltParms->prclSrc && pBltParms->pSrc)
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("+Src Format=%d Rect=%d,%d-%d,%d GPESurf=%08X\r\n"),
pBltParms->pSrc->Format(), pBltParms->prclSrc->left,
pBltParms->prclSrc->top, pBltParms->prclSrc->right,
pBltParms->prclSrc->bottom, pBltParms->pSrc));
DispPerfStart (pBltParms->rop4);
/*
if ((((DWORD)pBltParms->pDst) == 0x00121650) &&
(pBltParms->rop4 == 0xF0F0) &&
(pBltParms->prclDst->left == 0) &&
(pBltParms->prclDst->top == 0) &&
(pBltParms->prclDst->bottom == 480) &&
(pBltParms->prclDst->right == 640) &&
1)
{
DebugBreak();
//DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("SMI::BltPrepare BREAK rop4=0x%04X\r\n"), pBltParms->rop4));
}
*/
pBltParms->pBlt = GPETYPE &SMI::WrapBlt;
// return S_OK;
#ifdef ROTATION_ENABLE
if ((m_iRotate) &&
(((pBltParms->pDst) && (pBltParms->pDst->Buffer() == m_pPrimarySurface->Buffer())) || // only care if dest is main display surface
((pBltParms->pSrc) && (pBltParms->pSrc->Buffer() == m_pPrimarySurface->Buffer()))) // only care if source is main display surface
)
{
pBltParms->pBlt = GPETYPE EmulatedBltRotate;
switch( pBltParms->rop4 )
{
case 0x0000: // BLACKNESS
pBltParms->solidColor = 0x000000;
pBltParms->pBlt = GPETYPE FillRect;
break;
case 0xFFFF: // WHITENESS
pBltParms->solidColor = 0xFFFFFF;
pBltParms->pBlt = GPETYPE FillRect;
break;
case 0x5555: // DSTINVERT
case 0xAAAA: // DSTCOPY
pBltParms->pBlt = GPETYPE DestBlt;
break;
case 0xF0F0: // PATCOPY
case 0x5A5A: // PATINVERT
if (pBltParms->solidColor != -1)
{
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("+PATCOPY - solid brush\r\n")));
pBltParms->pBlt = GPETYPE FillRect;
}
break;
case 0xCCCC: // SRCCOPY
if (pBltParms->pLookup || pBltParms->pConvert)
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Color conversion not supported\r\n")));
break;
}
if (pBltParms->bltFlags & BLT_STRETCH)
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Stretch BLT flags NOT supported\r\n")));
break;
}
if ((pBltParms->pDst) && (pBltParms->pSrc))
{
if ((pBltParms->pDst->Buffer() == m_pPrimarySurface->Buffer()) &&
(pBltParms->pSrc->Buffer() == m_pPrimarySurface->Buffer())) //on-screen to on-screen
{
#if 0 //left GPE handle at this time
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("+SrcCopy\r\n")));
switch (m_iRotate)
{
LONG tmp;
case DMDO_90:
tmp = pBltParms->prclDst->left;
pBltParms->prclDst->left = pBltParms->prclDst->top;
pBltParms->prclDst->top = pBltParms->pDst->Width()-tmp;
tmp = pBltParms->prclDst->right;
pBltParms->prclDst->right = pBltParms->prclDst->bottom;
pBltParms->prclDst->bottom = pBltParms->pDst->Width()-tmp;
tmp = pBltParms->prclSrc->left;
pBltParms->prclSrc->left = pBltParms->prclSrc->top;
pBltParms->prclSrc->top = pBltParms->pSrc->Width()-tmp;
break;
case DMDO_180:
pBltParms->prclDst->left = pBltParms->pDst->Width() - pBltParms->prclDst->left;
pBltParms->prclDst->top = pBltParms->pDst->Height()- pBltParms->prclDst->top;
pBltParms->prclDst->right = pBltParms->pDst->Width() - pBltParms->prclDst->right;
pBltParms->prclDst->bottom = pBltParms->pDst->Height() - pBltParms->prclDst->bottom;
pBltParms->prclSrc->left = pBltParms->pDst->Width() - pBltParms->prclSrc->left;
pBltParms->prclSrc->top = pBltParms->pSrc->Height() - pBltParms->prclSrc->top;
break;
case DMDO_270:
tmp = pBltParms->prclDst->bottom;
pBltParms->prclDst->top = pBltParms->prclDst->left;
pBltParms->prclDst->left = pBltParms->pDst->Height()-tmp;
tmp = pBltParms->prclDst->top;
pBltParms->prclDst->bottom = pBltParms->prclDst->right;
pBltParms->prclDst->right = pBltParms->pDst->Height()-tmp;
tmp = pBltParms->prclSrc->bottom;
pBltParms->prclSrc->top = pBltParms->prclSrc->left;
pBltParms->prclSrc->left = pBltParms->pSrc->Height()-tmp;
break;
}
pBltParms->pBlt = GPETYPE SrcCopy; //Primary surface to primary surface
#endif
}
else if ((pBltParms->pDst->Buffer() == m_pPrimarySurface->Buffer()) &&
pBltParms->pSrc->InVideoMemory() &&
!(pBltParms->bltFlags & BLT_TRANSPARENT))
{
switch (m_iRotate)
{
case DMDO_90:
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("+SrcCopyRotation90\r\n")));
pBltParms->pBlt = GPETYPE SrcCopyRotation90; //off-screen surface to primary surface at 90 degree
break;
case DMDO_180:
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("+SrcCopyRotation180\r\n")));
pBltParms->pBlt = GPETYPE SrcCopyRotation180; //off-screen surface to primary surface at 180 degree
break;
case DMDO_270:
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("+SrcCopyRotation270\r\n")));
pBltParms->pBlt = GPETYPE SrcCopyRotation270; //off-screen surface to primary surface at 270 degree
break;
}
}
break;
}
default:
// CHECK IF MASK IS NOT USED
// The mask is not used if the upper byte of the rop4 equals the
// lower byte of the rop4. XOR them together and check if zero.
if ((pBltParms->rop4 & 0x00FF) == ((pBltParms->rop4 >> 8) & 0x00FF))
{
// CHECK IF PATTERN DATA ONLY (SOURCE DATA NOT USED)
// Source data is not used in the ROP if bits[1:0] equal
// bits[3:2] and bits[5:4] equal bits[7:6].
if ((pBltParms->rop4 & 0x33) == ((pBltParms->rop4 >> 2) & 0x33))
{
// CHECK IF PATTERN DATA OR SOLID COLOR
if( pBltParms->solidColor != -1 )
{
// NORMAL SOLID RECTANGLE FILL
DEBUGMSG(GPE_ZONE_BLT_LO,(TEXT("SMI::Blt - PAT with DST - solid brush\n")));
//RETAILMSG(1,(TEXT("SMI::Blt - PAT with DST - solid brush\n")));
pBltParms->pBlt = GPETYPE FillRect;
break;
}
}
}
break;
}
// see if there are any optimized software blits available
//EmulatedBltSelect02(pBltParms);
//EmulatedBltSelect08(pBltParms);
//EmulatedBltSelect16(pBltParms);
if (pBltParms->pBlt == EmulatedBltRotate) //in case some code in EmulatedBltRotate() does not waitfor hw idle
WaitForNotBusy();
return S_OK;
}
else
{
// If rotation set and not 0 degrees return.
if(m_iRotate != DMDO_0)
{
return S_OK;
}
}
#endif // ROTATION_ENABLE
if (!pBltParms->pDst->InVideoMemory())
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Destination not in video memory\r\n")));
return(S_OK);
}
//Work around some customers reported SetPixel/GetPixel issues. Let GPE to draw for small size bitmaps (ysize<2, xsize<32).
if (pBltParms->prclDst)
if ((pBltParms->prclDst->bottom-pBltParms->prclDst->top<2) && (pBltParms->prclDst->right-pBltParms->prclDst->left<32))
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Small size Blt, let CPU handle it\r\n")));
return(S_OK);
}
switch (pBltParms->rop4)
{
case 0x0000: // BLACKNESS
pBltParms->solidColor = 0x000000;
pBltParms->pBlt = GPETYPE &SMI::FillRect;
break;
case 0xFFFF: // WHITENESS
pBltParms->solidColor = 0xFFFFFFFF;
pBltParms->pBlt = GPETYPE &SMI::FillRect;
break;
case 0xF0F0: // PATCOPY
case 0x5A5A: // PATINVERT
if (pBltParms->solidColor != -1)
{
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("+PATCOPY - solid brush\r\n")));
pBltParms->pBlt = GPETYPE &SMI::FillRect;
}
else
{
if (pBltParms->pLookup || pBltParms->pConvert)
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Color conversion not supported\r\n")));
break;
}
EGPEFormat format = pBltParms->pBrush->Format();
if ( (format != pBltParms->pDst->Format())
|| (format == gpe32Bpp) //|| (format == gpe24Bpp)
)
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Brush format %d not supported\r\n"),
format));
break;
}
if ( (pBltParms->pBrush->Width() != 8)
&& (pBltParms->pBrush->Height() != 8)
)
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Brush size %d x %d not supported\r\n"),
pBltParms->pBrush->Width(),
pBltParms->pBrush->Height()));
break;
}
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("+PATCOPY - patterned brush\r\n")));
// Currently PatFill is commented out due to CreatePatternBrush problem in CETK...20030509
pBltParms->pBlt = GPETYPE &SMI::PatFill;
}
break;
// If handle 0xAAF0 in Blt, System hangs during CE TK at GDI test (DrawTextW, test ID 112). 9/19/02
case 0xAAF0: // TRANSPARENTPATCOPY
{
#ifdef UMA
if (m_SMISettings.m_bUMA)
{
break;
}
#endif
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("+IMAGEPATCOPY - image patterned mask\r\n")));
if (pBltParms->solidColor == -1)
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Patterned brush not supported\r\n")));
break;
}
EGPEFormat format = pBltParms->pMask->Format();
if (format != gpe1Bpp)
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Mask format %d not supported\r\n"), format));
break;
}
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("+TRANSPARENTPATCOPY\r\n")));
if (rev() != 0xA0)
pBltParms->pBlt = GPETYPE &SMI::MaskedImage;
break;
}
case 0x5555: // DSTINVERT
case 0xAAAA: // DSTCOPY
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("+DSTCOPY\r\n")));
pBltParms->pBlt = GPETYPE &SMI::DestBlt;
break;
case 0xCCCC: // SRCCOPY
case 0x6666: // SRCINVERT
case 0x8888: // SRCAND
case 0xEEEE: // SRCPAINT
if (!pBltParms->pSrc->InVideoMemory())
{
#if 1
#ifdef UMA
if (m_SMISettings.m_bUMA)
{
break;
}
#endif
if (pBltParms->rop4 == 0xCCCC)
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Source is not in video memory\r\n")));
if (pBltParms->pLookup || pBltParms->pConvert)
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Color conversion not supported\r\n")));
break;
}
if (pBltParms->bltFlags & BLT_STRETCH)
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Stretch BLT flags NOT supported\r\n")));
break;
}
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("+SRCCOPYHOST\r\n")));
pBltParms->pBlt = GPETYPE &SMI::SrcCopyHost;
}
#else
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Source is not in video memory\r\n")));
#endif
break;
}
if (pBltParms->pLookup || pBltParms->pConvert)
{
DEBUGMSG(GPE_ZONE_BLT_LO,
(TEXT("-Color conversion not supported\r\n")));
break;
}
if (pBltParms->bltFlags & BLT_STRETCH)
{
DEBUGMSG(GPE_ZONE_BLT_LO,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -