blt.cpp
来自「6410BSP3」· C++ 代码 · 共 1,258 行 · 第 1/4 页
CPP
1,258 行
{
if(pBltParms->pDst->IsRotate())
{
RotateRectl(prclDst);
}
m_oG2D->SetClipWindow(prclDst);
}
m_oG2D->SetFgColor(pBltParms->solidColor);
m_oG2D->Set3rdOperand(G2D_OPERAND3_FG);
switch(pBltParms->rop4 & 0xFF)
{
// Pat Copy
case 0xF0:
m_oG2D->SetRopEtype(ROP_PAT_ONLY);
break;
// Pat Invert
case 0x5A:
m_oG2D->SetRopEtype(ROP_DST_XOR_PAT);
break;
}
EnterCriticalSection(&m_cs2D);
m_oG2D->BitBlt(prclDst, prclDst, ROT_0);
LeaveCriticalSection(&m_cs2D);
if(pBltParms->pDst->IsRotate())
{
RotateRectlBack(prclDst);
}
DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("--%s()\r\n"), _T(__FUNCTION__)));
return S_OK;
}
// This function will be supported in the future
SCODE S3C6410Disp::AcceleratedDestInvert(GPEBltParms *pBltParms)
{
int dstX = pBltParms->prclDst->left;
int dstY = pBltParms->prclDst->top;
int width = RECT_WIDTH(pBltParms->prclDst);
int height = RECT_HEIGHT(pBltParms->prclDst);
return S_OK;
}
// Do NOTHING.
SCODE S3C6410Disp::NullBlt(GPEBltParms *pBltParms)
{
return S_OK;
}
/// From Frame Buffer to Frame Buffer Directly
/// Constraints
/// Source Surface's width is same with Destination Surface's width.
/// Source and Dest must be in Video FrameBuffer Region
/// In Surface Format
/// ScreenHeight and ScreenWidth means logical looking aspect for application
/// Height and Width means real data format.
/**
* @fn SCODE S3C6410Disp::AcceleratedSrcCopyBlt(GPEBltParms *pBltParms)
* @brief Do Blit with SRCCOPY, SRCAND, SRCPAINT, SRCINVERT
* @param pBltParms Blit Parameter Information Structure
* @sa GPEBltParms
* @note ROP : 0xCCCC(SRCCOPY), 0x8888(SRCAND), 0x6666(SRCINVERT), 0XEEEE(SRCPAINT)
* @note Using Information : DstSurface, ROP, Solidcolor
*/
SCODE S3C6410Disp::AcceleratedSrcCopyBlt (GPEBltParms *pBltParms)
{
PRECTL prclSrc, prclDst;
RECT rectlSrcBackup;
RECT rectlDstBackup;
BOOL bHWSuccess = FALSE;
prclSrc = pBltParms->prclSrc;
prclDst = pBltParms->prclDst;
// Set Destination Offset In Video Memory, this point is Dest lefttop point
/**
* Prepare Source & Destination Surface Information
*/
DWORD dwTopStrideStartAddr = 0;
/// !!!!Surface Width may not match to Real Data format!!!!
/// !!!!Set Width by Scan Stride Size!!!!
m_descSrcSurface.dwHoriRes = SURFACE_WIDTH(pBltParms->pSrc);
m_descDstSurface.dwHoriRes = SURFACE_WIDTH(pBltParms->pDst);
if(pBltParms->pDst->IsRotate())
{
RotateRectl(prclDst); //< RotateRectl rotate rectangle with screen rotation information
if(pBltParms->prclClip)
{
RotateRectl(pBltParms->prclClip);
}
}
if(pBltParms->pSrc->IsRotate())
{
RotateRectl(prclSrc);
}
if (pBltParms->bltFlags & BLT_TRANSPARENT)
{
RETAILMSG(0,(TEXT("TransparentMode Color : %d\n"), pBltParms->solidColor));
// turn on transparency & set comparison color
m_oG2D->SetTransparentMode(1, pBltParms->solidColor);
}
switch (pBltParms->rop4)
{
case 0x6666: // SRCINVERT
RETAILMSG(DISP_ZONE_2D, (TEXT("SRCINVERT\r\n")));
m_oG2D->SetRopEtype(ROP_SRC_XOR_DST);
break;
case 0x8888: // SRCAND
RETAILMSG(DISP_ZONE_2D, (TEXT("SRCAND\r\n")));
m_oG2D->SetRopEtype(ROP_SRC_AND_DST);
break;
case 0xCCCC: // SRCCOPY
RETAILMSG(DISP_ZONE_2D, (TEXT("SRCCOPY\r\n")));
m_oG2D->SetRopEtype(ROP_SRC_ONLY);
break;
case 0xEEEE: // SRCPAINT
RETAILMSG(DISP_ZONE_2D, (TEXT("SRCPAINT\r\n")));
m_oG2D->SetRopEtype(ROP_SRC_OR_DST);
break;
}
/// Check Source Rectangle Address
/// HW Coordinate limitation is 2040
/// 1. Get the Top line Start Address
/// 2. Set the base offset to Top line Start Address
/// 3. Recalulate top,bottom rectangle
/// 4. Do HW Bitblt
CopyRect(&rectlSrcBackup, (LPRECT)pBltParms->prclSrc);
CopyRect(&rectlDstBackup, (LPRECT)pBltParms->prclDst);
/// Destination's Region can have negative coordinate, especially for left, top point
/// In this case, For both destination, source's rectangle must be clipped again to use HW.
ClipDestDrawRect(pBltParms);
/// Set Source Surface Information
if(pBltParms->pSrc == pBltParms->pDst) // OnScreen BitBlt
{
if((pBltParms->pSrc)->InVideoMemory() )
{
m_descSrcSurface.dwBaseaddr = (m_VideoMemoryPhysicalBase + pBltParms->pDst->OffsetInVideoMemory());
/// If surface is created by user temporary, that has no screen width and height.
m_descSrcSurface.dwVertRes = (pBltParms->pSrc->ScreenHeight() != 0 ) ? pBltParms->pSrc->ScreenHeight() : pBltParms->pSrc->Height();
m_descDstSurface.dwBaseaddr = m_descSrcSurface.dwBaseaddr;
m_descDstSurface.dwVertRes = m_descSrcSurface.dwVertRes;
}
else
{
dwTopStrideStartAddr = m_dwPhyAddrOfSurface[0];
m_descSrcSurface.dwBaseaddr = dwTopStrideStartAddr;
m_descSrcSurface.dwVertRes = (pBltParms->pSrc->ScreenHeight() != 0 ) ? pBltParms->pSrc->ScreenHeight() : pBltParms->pSrc->Height();
m_descDstSurface.dwBaseaddr = m_descSrcSurface.dwBaseaddr;
m_descDstSurface.dwVertRes = m_descSrcSurface.dwVertRes;
}
}
else // OffScreen BitBlt
{
if(pBltParms->pSrc->InVideoMemory() )
{
m_descSrcSurface.dwBaseaddr = (m_VideoMemoryPhysicalBase + pBltParms->pSrc->OffsetInVideoMemory());
/// If surface is created by user temporary, that has no screen width and height.
m_descSrcSurface.dwVertRes = (pBltParms->pSrc->ScreenHeight() != 0 ) ? pBltParms->pSrc->ScreenHeight() : pBltParms->pSrc->Height();
}
else
{
dwTopStrideStartAddr = m_dwPhyAddrOfSurface[0] + pBltParms->prclSrc->top * ABS(pBltParms->pSrc->Stride());
m_descSrcSurface.dwBaseaddr = dwTopStrideStartAddr;
m_descSrcSurface.dwVertRes = RECT_HEIGHT(pBltParms->prclSrc);
pBltParms->prclSrc->top = 0;
pBltParms->prclSrc->bottom = m_descSrcSurface.dwVertRes;
}
/// Set Destination Surface Information
if(pBltParms->pDst->InVideoMemory() )
{
m_descDstSurface.dwBaseaddr = (m_VideoMemoryPhysicalBase + pBltParms->pDst->OffsetInVideoMemory());
/// If surface is created by user temporary, that has no screen width and height.
m_descDstSurface.dwVertRes = (pBltParms->pDst->ScreenHeight() != 0 ) ? pBltParms->pDst->ScreenHeight() : pBltParms->pDst->Height();
}
else
{
dwTopStrideStartAddr = m_dwPhyAddrOfSurface[1] + pBltParms->prclDst->top * ABS(pBltParms->pDst->Stride());
m_descDstSurface.dwBaseaddr = dwTopStrideStartAddr;
m_descDstSurface.dwVertRes = RECT_HEIGHT(pBltParms->prclDst);
pBltParms->prclDst->top = 0;
pBltParms->prclDst->bottom = m_descDstSurface.dwVertRes;
}
}
/// Transparency does not relate with alpha blending
m_oG2D->SetAlphaMode(G2D_NO_ALPHA_MODE);
/// No transparecy with alphablend
m_oG2D->SetAlphaValue(0xff);
m_oG2D->Set3rdOperand(G2D_OPERAND3_PAT);
/// Real Register Surface Description setting will be done in HWBitBlt
bHWSuccess = HWBitBlt(pBltParms, &m_descSrcSurface, &m_descDstSurface);
CopyRect((LPRECT)pBltParms->prclSrc, &rectlSrcBackup);
CopyRect((LPRECT)pBltParms->prclDst, &rectlDstBackup);
if(pBltParms->pDst->IsRotate())
{
RotateRectlBack(prclDst);
if(pBltParms->prclClip)
{
RotateRectlBack(pBltParms->prclClip);
}
}
if(pBltParms->pSrc->IsRotate())
{
RotateRectlBack(prclSrc);
}
if (pBltParms->bltFlags & BLT_TRANSPARENT)
{
m_oG2D->SetTransparentMode(0, pBltParms->solidColor); // turn off Transparency
}
if(!bHWSuccess)
{
return EmulatedBlt(pBltParms);
}
return S_OK;
}
/**
* @fn void S3C6410Disp::AcceleratedBltSelect(GpeBltParms *pBltParms)
* @brief Select appropriate hardware acceleration function or software emulation function.
* if there's no appropriate accelerated function,
* Leave Blit funciton to intial setting, EmulatedBlt(generic Bit blit emulator)
* @param pBltParms Blit Parameter Information Structure
* @sa GPEBltParms
*/
SCODE S3C6410Disp::AcceleratedBltSelect(GPEBltParms *pBltParms)
{
if ((pBltParms->pBlt != (SCODE (GPE::*)(GPEBltParms *))&GPE::EmulatedBlt) && !m_G2DControlArgs.OverrideEmulFunc)
{
if(pBltParms->pSrc && pBltParms->pDst && (pBltParms->pSrc->Rotate() != pBltParms->pDst->Rotate()))
{
// In this case we will use HW, the rotation case
RETAILMSG(FALSE,(TEXT("AlreadySelected But Rotation:0x%x\n"),pBltParms->pBlt));
}
else
{
// Already Some Accelerated or Emulated Function is assigned.
RETAILMSG(FALSE,(TEXT("AlreadySelected:0x%x\n"),pBltParms->pBlt));
return S_OK;
}
}
if((pBltParms->rop4 != 0xCCCC)
&& (pBltParms->rop4 != 0xEEEE)
&& (pBltParms->rop4 != 0x6666)
&& (pBltParms->rop4 != 0x8888)
&& (pBltParms->rop4 != 0xF0F0)
&& (pBltParms->rop4 != 0x5A5A)
)
{
return S_OK;
}
if(pBltParms->rop4 == 0xF0F0 && !m_G2DControlArgs.UseFillRect)
{
return S_OK;
}
if(!m_G2DControlArgs.UseStretchBlt && (pBltParms->bltFlags & BLT_STRETCH)) //< can support Stretch Blit
{
return S_OK;
}
if(pBltParms->pLookup)
{
return S_OK;
}
if(!m_G2DControlArgs.UseAlphaBlend && (pBltParms->bltFlags & BLT_ALPHABLEND))
{
return S_OK;
}
if(pBltParms->pDst)
{
m_descDstSurface.dwColorMode = GetHWColorFormat(pBltParms->pDst);
if(m_descDstSurface.dwColorMode == G2D_COLOR_UNUSED)
{
RETAILMSG(DISP_ZONE_2D, (TEXT("2D HW does not support this color format\r\n")));
return S_OK;
}
}
if(pBltParms->pSrc)
{
m_descSrcSurface.dwColorMode = GetHWColorFormat(pBltParms->pSrc);
if(m_descSrcSurface.dwColorMode == G2D_COLOR_UNUSED)
{
RETAILMSG(DISP_ZONE_2D, (TEXT("2D HW does not support this color format\r\n")));
return S_OK;
}
}
if(pBltParms->bltFlags & BLT_ALPHABLEND) //< Our HW can support AlphaBlend blit for 16bpp, 32bpp
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?