blt.cpp
来自「6410BSP3」· C++ 代码 · 共 1,258 行 · 第 1/4 页
CPP
1,258 行
return S_OK;
default: // unsupported ROP4 to accelerate
return S_OK;
}
return S_OK;
}
#define PFN_SHIEFT UserKInfo[KINX_PFN_SHIFT]
#define MAX_SUPPORTED_PFN (MAXDWORD>>PFN_SHIEFT)
#define PAGE_MASK (PAGE_SIZE-1)
#define DBGMSG_SRCC (FALSE)
/**
* @fn SCODE S3C6410DISP::ValidatePAContinuityOfSurf(GPESurf *pTargetSurf)
* @brief If possible, clean dcahce for Source Rectangle
* @param pTargetSurf Surface pointer of Target Surface
* @sa GPESurf
* @note for support cb to ncnb bitblt
* @note Bitmap image has top-down or bottom-up style memory region,
* we can determine that by stride as positive(top-down) or as negative(bottom-up)
* bottom-up bitmap mean buffer's start address is last addres of image buffer
* image's start address is calculated as (Buffer address + Stride(negative) * height)
* @return DWORD PhysAddressofSurface
*/
DWORD S3C6410Disp::ValidatePAContinuityOfSurf( GPESurf *pTargetSurf )
{
BOOL m_fLocked;
LPVOID m_lpvLockedAddress;
DWORD m_dwLockedSize;
DWORD dwLength = 0;
DWORD dwSrcSurfaceSize = 0;
PDWORD m_pdwPhysAddress = 0;
PDWORD m_pdwPhysLength;
PBYTE * m_ppVirtAddress;
PVOID pUseBufferPtr = 0;
PVOID pVirtualStartPtr = 0;
// Normally negative stride can be found on system memory bitmap image. or DIB
if(pTargetSurf->Stride() < 0)
{
RETAILMSG(DBGMSG_SRCC, (TEXT("Currently we cannot handle bottom-up bitmap using HW\r\n")));
return NULL;
}
// Check the start address
// Check if data is allocated across different pages
// usable macros
// VM_PAGE_OFST_MASK
// VM_PAGE_SHIFT
// VM_PAGE_SIZE
// uCount++;
ASSERT(m_pdwPhysAddress==0);
ASSERT((PAGE_MASK & PAGE_SIZE) == 0 );
dwLength = pTargetSurf->Height() * ABS(pTargetSurf->Stride());
RETAILMSG(DBGMSG_SRCC,(TEXT("TargetSurf 0x%x, Height : %d, Stride : %d\r\n"),pTargetSurf->Buffer(), pTargetSurf->Height(), pTargetSurf->Stride())); //< XPositive, yPositive
// Todo: Check the Data Size
// if size is not big to get efficiency. return false
#if (_WIN32_WCE < 600)
if(pTargetSurf->Stride() < 0)
{
pUseBufferPtr = MapPtrToProcess((PDWORD)((DWORD)pTargetSurf->Buffer() - dwLength + ABS(pTargetSurf->Stride())), (HANDLE)GetCurrentProcessId());
pVirtualStartPtr = MapPtrToProcess(pUseBufferPtr, (HANDLE)GetCurrentProcessId());
}
else
{
pUseBufferPtr = MapPtrToProcess((PDWORD)pTargetSurf->Buffer(), (HANDLE)GetCurrentProcessId());
pVirtualStartPtr = MapPtrToProcess(pUseBufferPtr, (HANDLE)GetCurrentProcessId());;
}
#else
if(pTargetSurf->Stride() < 0)
{
pUseBufferPtr = (PDWORD)((DWORD)pTargetSurf->Buffer() - dwLength + ABS(pTargetSurf->Stride()));
pVirtualStartPtr = pUseBufferPtr;
}
else
{
pUseBufferPtr = (PDWORD)pTargetSurf->Buffer();
pVirtualStartPtr = pUseBufferPtr;
}
#endif
UINT nPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES( pUseBufferPtr, dwLength );
m_pdwPhysAddress = new DWORD[3*nPages]; // It's really sturcture {m_pdwPhysAddress, m_pdwPhysLength, m_ppVirtAddress}
if (m_pdwPhysAddress) {
m_pdwPhysLength = m_pdwPhysAddress + nPages;
m_ppVirtAddress = (PBYTE *)(m_pdwPhysAddress + 2*nPages);
RETAILMSG(DBGMSG_SRCC,(TEXT("pUseBufferPtr:0x%x, dwLength:%d, m_pdwPhysAddress:0x%x.\r\n"), pUseBufferPtr, dwLength, m_pdwPhysAddress));
m_fLocked = LockPages( pUseBufferPtr, dwLength, m_pdwPhysAddress, LOCKFLAG_QUERY_ONLY); // Src to Dst
if (!m_fLocked) { // Create table for Physical Address and length.
RETAILMSG(DBGMSG_SRCC,(TEXT("LockPages is Failed : %d\r\n"), GetLastError() ));
FreePhysAddress(m_pdwPhysAddress);
return NULL;
}
m_lpvLockedAddress = pUseBufferPtr;
m_dwLockedSize = dwLength;
RETAILMSG(DBGMSG_SRCC,(TEXT("pVirtualStartPtr:0x%x.\r\n"), pVirtualStartPtr));
/// Get each Physical address pages from pagelocked information
for (DWORD dwIndex = 0; dwIndex< nPages; dwIndex++) {
if (m_pdwPhysAddress[dwIndex] > MAX_SUPPORTED_PFN) {
ASSERT(FALSE);
FreePhysAddress(m_pdwPhysAddress);
return NULL; //< NULL is FAIL
}
DWORD dwSize = min((PAGE_SIZE - ((DWORD)pUseBufferPtr & PAGE_MASK)),dwLength) ;
m_pdwPhysAddress[dwIndex] = (m_pdwPhysAddress[dwIndex]<<PFN_SHIEFT) + ((DWORD)pUseBufferPtr & PAGE_MASK);
m_pdwPhysLength[dwIndex] = dwSize;
m_ppVirtAddress[dwIndex] = (PBYTE)pUseBufferPtr;
dwLength -= dwSize;
pUseBufferPtr = (PBYTE)pUseBufferPtr+dwSize;
RETAILMSG(DBGMSG_SRCC,(TEXT("dwIndex : %d, m_pdwPhysAddress[%d]:0x%x, m_pdwPhysLength[%d]:%d, dwSize:%d, pUseBufferPtr(PageEnd):0x%x.\r\n"),
dwIndex,
dwIndex, m_pdwPhysAddress[dwIndex],
dwIndex, m_pdwPhysLength[dwIndex],
dwSize,
pUseBufferPtr
));
}
/// Check if Source Pages is contiguous in Physical memory address.
DWORD dwRead = 1;
while (dwRead < nPages) {
if (m_pdwPhysAddress[dwRead - 1] + m_pdwPhysLength[dwRead - 1] == m_pdwPhysAddress[dwRead]) {
// m_dwBlocks and m_dwBlocks+1 is contiguous.
dwRead++;
}
else { // No match, We cannot use HW
RETAILMSG(DBGMSG_SRCC,(TEXT("Source Memory Blocks is not congiuous : Go Emul path\r\n")));
FreePhysAddress(m_pdwPhysAddress);
return NULL; //< NULL is Fail
}
}
// Merge to one big contiguous memory block
if(nPages > 1)
{
for(dwRead = 1 ; dwRead < nPages; dwRead++) {
m_pdwPhysLength[0] += m_pdwPhysLength[dwRead];
}
}
}
else
{
RETAILMSG(DBGMSG_SRCC,(TEXT("Not Enough Memory for m_pdwPhysAddress\r\n")));
FreePhysAddress(m_pdwPhysAddress);
return NULL; //< NULL is Fail
}
// uPossibleCount ++;
// RETAILMSG(TRUE,(TEXT("DCache Clean , Available Flow Count : %d avail. / %d Total \r\n"),uPossibleCount, uCount));
RETAILMSG(DBGMSG_SRCC,(TEXT("CacheFlush Start : 0x%x length : %d\r\n"),
(PBYTE)pVirtualStartPtr,
pTargetSurf->Height() * ABS(pTargetSurf->Stride())));
// Just Contiguous Source Surface can use HW // Cache flush for all surface region
CacheRangeFlush( (PBYTE)pVirtualStartPtr,
pTargetSurf->Height() * ABS(pTargetSurf->Stride()),
CACHE_SYNC_WRITEBACK);
RETAILMSG(DBGMSG_SRCC,(TEXT("m_pdwPhysAddress[0] : 0x%x\r\n"), m_pdwPhysAddress[0]));
m_dwSourceSurfacePA = m_pdwPhysAddress[0]; //< Just leave for compatiblilty
FreePhysAddress(m_pdwPhysAddress);
return m_dwSourceSurfacePA;
}
void S3C6410Disp::FreePhysAddress(DWORD *m_pdwPhysAddress)
{
if(m_pdwPhysAddress)
{
delete [] m_pdwPhysAddress;
m_pdwPhysAddress=NULL;
}
}
void S3C6410Disp::ClipDestDrawRect(GPEBltParms *pBltParms)
{
if(pBltParms->pDst->InVideoMemory() )
{
if(pBltParms->prclDst->left < 0)
{
pBltParms->prclSrc->left -= pBltParms->prclDst->left;
pBltParms->prclDst->left = 0;
}
if(pBltParms->prclDst->top < 0)
{
pBltParms->prclSrc->top -= pBltParms->prclDst->top;
pBltParms->prclDst->top = 0;
}
}
}
DWORD S3C6410Disp::GetHWColorFormat(GPESurf *pSurf)
{
DWORD dw2DHWColorFormat = G2D_COLOR_UNUSED;
if(pSurf)
{
GPEFormat * pFormat;
pFormat = pSurf->FormatPtr();
if (pSurf->Format() == gpe16Bpp)
{
if (pFormat->m_pPalette)
{
if (pFormat->m_PaletteEntries == 3 &&
pFormat->m_pPalette[0] == 0x0000f800 && // R
pFormat->m_pPalette[1] == 0x000007e0 && // G
pFormat->m_pPalette[2] == 0x0000001f) // B
{
dw2DHWColorFormat = G2D_COLOR_RGB_565;
}
else if (pFormat->m_PaletteEntries == 3 &&
pFormat->m_pPalette[0] == 0x00007c00 && // R
pFormat->m_pPalette[1] == 0x000003e0 && // G
pFormat->m_pPalette[2] == 0x0000001f) // B
{
dw2DHWColorFormat = G2D_COLOR_UNUSED;//G2D_COLOR_ARGB_1555;
}
else if (pFormat->m_PaletteEntries == 4 &&
pFormat->m_pPalette[3] == 0x00008000 && // A
pFormat->m_pPalette[0] == 0x00007c00 && // R
pFormat->m_pPalette[1] == 0x000003e0 && // G
pFormat->m_pPalette[2] == 0x0000001f) // B
{
dw2DHWColorFormat = G2D_COLOR_ARGB_1555;
}
else
{
DEBUGMSG(GPE_ZONE_HW, (TEXT("pFormat->m_PaletteEntries=%08x\r\n"), pFormat->m_PaletteEntries));
for (int i=0; i<pFormat->m_PaletteEntries; i++)
{
DEBUGMSG(GPE_ZONE_HW, (TEXT("%d : 0x%08x\r\n"), i, pFormat->m_pPalette[i]));
}
dw2DHWColorFormat = G2D_COLOR_UNUSED;
}
}
else
{
DEBUGMSG(GPE_ZONE_HW, (TEXT("Surface Format HAS NO PALETTE, we assume it's RGBx555\r\n")));
dw2DHWColorFormat = G2D_COLOR_UNUSED;//G2D_COLOR_ARGB_1555;
}
}
else
if (pSurf->Format() == gpe32Bpp)
{
if (pFormat->m_pPalette)
{
if (pFormat->m_PaletteEntries == 4 &&
pFormat->m_pPalette[3] == 0xff000000 && // A
pFormat->m_pPalette[0] == 0x00ff0000 && // R
pFormat->m_pPalette[1] == 0x0000ff00 && // G
pFormat->m_pPalette[2] == 0x000000ff) // B
{
dw2DHWColorFormat = G2D_COLOR_ARGB_8888;
}
else if (//pFormat->m_PaletteEntries == 3 &&
pFormat->m_pPalette[0] == 0x00ff0000 && // R
pFormat->m_pPalette[1] == 0x0000ff00 && // G
pFormat->m_pPalette[2] == 0x000000ff) // B
{
dw2DHWColorFormat = G2D_COLOR_XRGB_8888;
}
else if (pFormat->m_PaletteEntries == 4 &&
pFormat->m_pPalette[3] == 0x000000ff && // A
pFormat->m_pPalette[0] == 0xff000000 && // R
pFormat->m_pPalette[1] == 0x00ff0000 && // G
pFormat->m_pPalette[2] == 0x0000ff00) // B
{
dw2DHWColorFormat = G2D_COLOR_RGBA_8888;
}
else if (//pFormat->m_PaletteEntries == 3 &&
pFormat->m_pPalette[0] == 0xff000000 && // R
pFormat->m_pPalette[1] == 0x00ff0000 && // G
pFormat->m_pPalette[2] == 0x0000ff00) // B
{
dw2DHWColorFormat = G2D_COLOR_RGBX_8888;
}
else
{
DEBUGMSG(GPE_ZONE_HW, (TEXT("pFormat->m_PaletteEntries=%08x\r\n"), pFormat->m_PaletteEntries));
for (int i = 0; i<pFormat->m_PaletteEntries; i++)
{
DEBUGMSG(GPE_ZONE_HW, (TEXT("%d : 0x%08x\r\n"), i, pFormat->m_pPalette[i]));
}
dw2DHWColorFormat = G2D_COLOR_UNUSED;
}
}
else
{
DEBUGMSG(GPE_ZONE_HW, (TEXT("Surface Format HAS NO PALETTE, we assume it as ABGR8888 and use ARGB8888\r\n")));
//dw2DHWColorFormat = G2D_COLOR_UNUSED;
dw2DHWColorFormat = G2D_COLOR_ARGB_8888;
}
}
DEBUGMSG(GPE_ZONE_HW, (TEXT("Surface:0x%x, GPEFormat:%d, HWColorMode:%d\n\r"), pSurf, pSurf->Format(), dw2DHWColorFormat));
return dw2DHWColorFormat;
}
RETAILMSG(DISP_ZONE_ERROR, (TEXT("Illegal Surface\n\r")));
return dw2DHWColorFormat;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?