📄 blt.cpp
字号:
if ((pBltParms->pDst->Format() != gpe16Bpp)
|| (pBltParms->bltFlags & BLT_ALPHABLEND) //< if AlphaBlend is required, emulate
// || (pBltParms->bltFlags & BLT_TRANSPARENT) //< Our HW support Transparent blit for 16bpp, 24bpp
#if G2D_BYPASS_HW_STRETCHBLT
|| (pBltParms->bltFlags & BLT_STRETCH) //< can support Stretch Blit for 16bpp, 24bpp
#endif
) //< Emulate if AlphaBlend is required
{
return S_OK;
}
if(pBltParms->pLookup)
{
RETAILMSG(0, (TEXT("Lookup is required\r\n")));
return S_OK;
}
if(pBltParms->pConvert) //< Emulate if color conversion required
{
RETAILMSG(0, (TEXT("Color Converting is required\r\n")));
return S_OK;
}
if(pBltParms->prclClip && (pBltParms->prclClip->left == pBltParms->prclClip->right) && (pBltParms->prclClip->top == pBltParms->prclClip->bottom))
{
// Just skip, there is no image flushing to screen
// SW bitblt takes this case, and it can skip more efficiently.
return S_OK;
}
/**
* Check if source and destination regions' coordinates has positive value.
*
*
**/
if ((pBltParms->bltFlags & BLT_STRETCH)) // Stretch Bllitting with X or Y axis mirroring
{
if(!pBltParms->prclDst)
{
// goto emulsel;
return S_OK;
}
else
{
if ((pBltParms->prclDst->left < 0) || (pBltParms->prclDst->right <0 ) || (pBltParms->prclDst->top <0 ) || (pBltParms->prclDst->bottom <0))
{
return S_OK;
// goto emulsel;
}
if ((pBltParms->prclSrc->left < 0) || (pBltParms->prclSrc->right <0 ) || (pBltParms->prclSrc->top <0 ) || (pBltParms->prclSrc->bottom <0))
{
return S_OK;
// goto emulsel;
}
/// Odd case do nothing
if ((pBltParms->prclSrc->right == pBltParms->prclSrc->left) || (pBltParms->prclSrc->bottom == pBltParms->prclSrc->top) ||
(pBltParms->prclDst->right == pBltParms->prclDst->left) || (pBltParms->prclDst->bottom == pBltParms->prclDst->top))
{
return S_OK;
}
/*
/// XY Mirrored image case
/// In this case rotation is needed so 180 rotation.
if ((pBltParms->prclDst->left > pBltParms->prclDst->right) && (pBltParms->prclDst->top > pBltParms->prclDst->bottom) )
{
/// Pick TopLeft pixel as rotation origin.
/// But rotation setting is automatically done in HWBitBlt
/// So Just Set Rotation to 180 degree
goto emulsel;
}
*/
/*
if ((pBltParms->prclDst->left > pBltParms->prclDst->right) || (pBltParms->prclDst->top > pBltParms->prclDst->bottom) )
{
/// In mirror case, source region does not change.
/// only destination's regions has reverse coordinate, this cannot be negative.
if(pBltParms->prclDst->right < pBltParms->prclDst->left)
{
/// Y-axis mirror case. left-right inversion
/// !Currently go to emul path
goto emulsel;
/// Set Y-axis flip flag
}
if(pBltParms->prclDst->bottom < pBltParms->prclDst->top)
{
/// X-axis mirror case. up-down inversion
/// ! Currently goto emul path
goto emulsel;
/// Set X-axis flip flag
}
}
*/
}
}
// select accelerated function based on rop value
switch (pBltParms->rop4)
{
case 0x0000: // BLACKNESS
pBltParms->solidColor = 0;
pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &Emulator::EmulatedBltFill16;
#if 0
// pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C2450DISP::AcceleratedBltFill;
#endif
return S_OK;
case 0xFFFF: // WHITENESS // Done have prclSrc, and pMask
pBltParms->solidColor = 0x00ffffff;
pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &Emulator::EmulatedBltFill16;
#if 0
// pBltParms->solidColor = 0x0000ffff;
// pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C2450DISP::AcceleratedBltFill;
#endif
return S_OK;
case 0x5555: // DSTINVERT
// pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &Emulator::EmulatedBltDstInvert16;
return S_OK;
// goto emulsel;
case 0xAAF0: // Special PATCOPY rop for text output -- fill where mask is set. // Not a pattern brush?
// goto emulsel;
return S_OK;
case 0x5A5A: // PATINVERT
return S_OK;
case 0xF0F0: // PATCOPY
if( pBltParms->solidColor != -1) // must be a solid colored brush
{
if( pBltParms->prclDst &&
( (pBltParms->prclDst->left >= 0) && (pBltParms->prclDst->left < 2048) &&
(pBltParms->prclDst->top >= 0) && (pBltParms->prclDst->top < 2048) &&
(pBltParms->prclDst->right >= 0 ) && (pBltParms->prclDst->top < 2048) &&
(pBltParms->prclDst->bottom >= 0 ) && (pBltParms->prclDst->top < 2048) ) &&
(pBltParms->pDst->Stride() / (EGPEFormatToBpp[pBltParms->pDst->Format()]/8) < 2048)
// (ABS(pBltParms->prclDst->right - pBltParms->prclDst->left)*ABS(pBltParms->prclDst->bottom - pBltParms->prcDst->top) > G2D_COMPROMISE_LIMIT)
)
{
#ifdef DO_DISPPERF
DispPerfType(DISPPERF_ACCEL_HARDWARE);
#endif
pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C2450DISP::AcceleratedBltFill;
return S_OK;
}
}
// goto emulsel;
return S_OK;
case 0x6666: // SRCINVERT
if( pBltParms->prclDst &&
((pBltParms->prclDst->left >= 0) &&
(pBltParms->prclDst->top >= 0) &&
(pBltParms->prclDst->right >= 0 ) &&
(pBltParms->prclDst->bottom >= 0 )) &&
pBltParms->pSrc &&
(pBltParms->pDst->Stride() / (EGPEFormatToBpp[pBltParms->pDst->Format()]/8) < 2048) &&
(pBltParms->pSrc->Stride() / (EGPEFormatToBpp[pBltParms->pSrc->Format()]/8) < 2048)
#if G2D_BLT_OPTIMIZE
&& (ABS(pBltParms->prclSrc->right - pBltParms->prclSrc->left)*ABS(pBltParms->prclSrc->bottom - pBltParms->prclSrc->top) > G2D_COMPROMISE_LIMIT)
#endif
)
{
#ifdef DO_DISPPERF
DispPerfType(DISPPERF_ACCEL_HARDWARE);
#endif
if( ( pBltParms->pSrc->InVideoMemory()
#if G2D_TRY_CBLT
|| SUCCEEDED(SourceRegionCacheClean(pBltParms))
#endif
)
&& (ABS(pBltParms->prclSrc->bottom - pBltParms->prclSrc->top) < 2048)
&& (ABS(pBltParms->prclSrc->right - pBltParms->prclSrc->left) < 2048)
) {
pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C2450DISP::AcceleratedSrcCopyBlt;
return S_OK;
}
else
{
if( (pBltParms->pSrc)->InVideoMemory() ){
RETAILMSG(FALSE,(TEXT("INVideo:SRCINVERT\r\n")));
}
else
{
RETAILMSG(FALSE,(TEXT("NotInVideo:SRCINVERT\r\n")));
}
}
}
return S_OK;
// goto emulsel;
case 0xCCCC: // SRCCOPY
if( pBltParms->prclDst &&
((pBltParms->prclDst->left >= 0) &&
(pBltParms->prclDst->top >= 0) &&
(pBltParms->prclDst->right >= 0 ) &&
(pBltParms->prclDst->bottom >= 0 )) &&
pBltParms->pSrc &&
(pBltParms->pDst->Stride() / (EGPEFormatToBpp[pBltParms->pDst->Format()]/8) < 2048) &&
(pBltParms->pSrc->Stride() / (EGPEFormatToBpp[pBltParms->pSrc->Format()]/8) < 2048)
#if G2D_BLT_OPTIMIZE
&& (ABS(pBltParms->prclSrc->right - pBltParms->prclSrc->left)*ABS(pBltParms->prclSrc->bottom - pBltParms->prclSrc->top) > G2D_COMPROMISE_LIMIT)
#endif
)
{
#ifdef DO_DISPPERF
DispPerfType(DISPPERF_ACCEL_HARDWARE);
#endif
if( ( (pBltParms->pSrc)->InVideoMemory()
#if G2D_TRY_CBLT
|| SUCCEEDED(SourceRegionCacheClean(pBltParms))
#endif
)
&& (ABS(pBltParms->prclSrc->bottom - pBltParms->prclSrc->top) < 2048)
&& (ABS(pBltParms->prclSrc->right - pBltParms->prclSrc->left) < 2048)
) {
pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C2450DISP::AcceleratedSrcCopyBlt;
return S_OK;
}
else{
if( (pBltParms->pSrc)->InVideoMemory() ){
RETAILMSG(FALSE,(TEXT("INVideo:SRCCOPY\r\n")));
}
else
{
RETAILMSG(FALSE,(TEXT("NotInVideo:SRCCOPY\r\n")));
#define DUMP_BLTPARAM (0)
#if DUMP_BLTPARAM
if(pBltParms->pSrc)
{
RETAILMSG(DUMP_BLTPARAM,(TEXT("Src 0x%x, Surf(W:%d,H:%d,BPP:%d,STRIDE:%d), Screen(W:%d,H:%d), rect: (%d,%d)~(%d,%d), R:%d\r\n"),
pBltParms->pSrc->Buffer(),
pBltParms->pSrc->Width(),
pBltParms->pSrc->Height(),
EGPEFormatToBpp[pBltParms->pSrc->Format()],
pBltParms->pSrc->Stride(),
pBltParms->pSrc->ScreenWidth(),
pBltParms->pSrc->ScreenHeight(),
pBltParms->prclSrc->left,
pBltParms->prclSrc->top,
pBltParms->prclSrc->right,
pBltParms->prclSrc->bottom,
pBltParms->pSrc->Rotate()
));
}
if(pBltParms->pDst)
{
RETAILMSG(DUMP_BLTPARAM,(TEXT("Dst 0x%x, Surf(W:%d,H:%d,BPP:%d,STRIDE:%d), Screen(W:%d,H:%d), rect: (%d,%d)~(%d,%d), R:%d\r\n"),
pBltParms->pDst->Buffer(),
pBltParms->pDst->Width(),
pBltParms->pDst->Height(),
EGPEFormatToBpp[pBltParms->pDst->Format()],
pBltParms->pDst->Stride(),
pBltParms->pDst->ScreenWidth(),
pBltParms->pDst->ScreenHeight(),
pBltParms->prclDst->left,
pBltParms->prclDst->top,
pBltParms->prclDst->right,
pBltParms->prclDst->bottom,
pBltParms->pDst->Rotate()
));
}
RETAILMSG(DUMP_BLTPARAM, (TEXT("ROP : 0x%0x\r\n"), pBltParms->rop4));
RETAILMSG(DUMP_BLTPARAM, (TEXT("xPositive : %d\r\n"),pBltParms->xPositive));
RETAILMSG(DUMP_BLTPARAM, (TEXT("yPositive : %d\r\n"),pBltParms->yPositive));
#endif
#if 0
/// If Stretch is needed, HW is more efficient.
/// so in this case, copy va to pa's scratched buffer, then use HW
if( (pBltParms->bltFlags & BLT_STRETCH) )
{
ADDRESS pSrcStart;
BOOL bBottomUp=FALSE;
AllocSurface(&gpScratchSurf, ABS(pBltParms->pSrc->Stride() / (EGPEFormatToBpp[pBltParms->pSrc->Format()]/8)), pBltParms->pSrc->Height(), pBltParms->pSrc->Format(), EGPEFormatToEDDGPEPixelFormat[pBltParms->pSrc->Format()], GPE_REQUIRE_VIDEO_MEMORY);
if(!gpScratchSurf)
{
RETAILMSG(TRUE,(TEXT("cannot create gpScratchSurf\r\n")));
return S_OK;
}
else
{
if(!gpScratchSurf->Buffer())
{
RETAILMSG(TRUE,(TEXT("Video memory is not enough to create gpScratchSurf\r\n")));
return S_OK;
}
}
if( pBltParms->pSrc->Stride() < 0) //< This is bottom-up image, need to flip. and recalculate Base Address
{
pSrcStart = (ADDRESS)pBltParms->pSrc->Buffer() + pBltParms->pSrc->Stride() * (pBltParms->pSrc->Height()-1);
bBottomUp=TRUE;
}
else
{
pSrcStart = (ADDRESS)pBltParms->pSrc->Buffer();
}
RETAILMSG(TRUE,(TEXT("copy Original Source Surface to Scratch Surface\r\n")));
memmove(gpScratchSurf->Buffer(), (LPVOID)pSrcStart, ABS(pBltParms->pSrc->Stride()*pBltParms->pSrc->Height()));
RETAILMSG(TRUE,(TEXT("Swap Original Source Surface and Scratch Surface\r\n")));
oldSrcSurf = pBltParms->pSrc;
pBltParms->pSrc = gpScratchSurf;
}
#endif
}
}
}
// goto emulsel;
return S_OK;
case 0x8888: // SRCAND
if( pBltParms->prclDst &&
((pBltParms->prclDst->left >= 0) &&
(pBltParms->prclDst->top >= 0) &&
(pBltParms->prclDst->right >= 0 ) &&
(pBltParms->prclDst->bottom >= 0 )) &&
pBltParms->pSrc &&
(pBltParms->pDst->Stride() / (EGPEFormatToBpp[pBltParms->pDst->Format()]/8) < 2048) &&
(pBltParms->pSrc->Stride() / (EGPEFormatToBpp[pBltParms->pSrc->Format()]/8) < 2048)
#if G2D_BLT_OPTIMIZE
&& (ABS(pBltParms->prclSrc->right - pBltParms->prclSrc->left)*ABS(pBltParms->prclSrc->bottom - pBltParms->prclSrc->top) > G2D_COMPROMISE_LIMIT)
#endif
) {
#ifdef DO_DISPPERF
DispPerfType(DISPPERF_ACCEL_HARDWARE);
#endif
if( ( (pBltParms->pSrc)->InVideoMemory()
#if G2D_TRY_CBLT
|| SUCCEEDED(SourceRegionCacheClean(pBltParms))
#endif
)
&& (ABS(pBltParms->prclSrc->bottom - pBltParms->prclSrc->top) < 2048)
&& (ABS(pBltParms->prclSrc->right - pBltParms->prclSrc->left) < 2048)
) {
pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C2450DISP::AcceleratedSrcCopyBlt;
return S_OK;
}
else{
if( (pBltParms->pSrc)->InVideoMemory() ){
RETAILMSG(FALSE,(TEXT("INVideo:SRCAND\r\n")));
}
else
{
RETAILMSG(FALSE,(TEXT("NotInVideo:SRCAND\r\n")));
}
}
}
return S_OK;
// goto emulsel;
case 0xEEEE: // SRCPAINT
if( pBltParms->prclDst &&
((pBltParms->prclDst->left >= 0) &&
(pBltParms->prclDst->top >= 0) &&
(pBltParms->prclDst->right >= 0 ) &&
(pBltParms->prclDst->bottom >= 0 )) &&
pBltParms->pSrc &&
(pBltParms->pDst->Stride() / (EGPEFormatToBpp[pBltParms->pDst->Format()]/8) < 2048) &&
(pBltParms->pSrc->Stride() / (EGPEFormatToBpp[pBltParms->pSrc->Format()]/8) < 2048)
#if G2D_BLT_OPTIMIZE
&& (ABS(pBltParms->prclSrc->right - pBltParms->prclSrc->left)*ABS(pBltParms->prclSrc->bottom - pBltParms->prclSrc->top) > G2D_COMPROMISE_LIMIT)
#endif
) {
#ifdef DO_DISPPERF
DispPerfType(DISPPERF_ACCEL_HARDWARE);
#endif
if( ( (pBltParms->pSrc)->InVideoMemory()
#if G2D_TRY_CBLT
|| SUCCEEDED(SourceRegionCacheClean(pBltParms))
#endif
)
&& (ABS(pBltParms->prclSrc->bottom - pBltParms->prclSrc->top) < 2048)
&& (ABS(pBltParms->prc
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -