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 + -
显示快捷键?