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