blt.cpp

来自「6410BSP3」· C++ 代码 · 共 1,258 行 · 第 1/4 页

CPP
1,258
字号
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//
// Copyright (c) Samsung Electronics. Co. LTD.  All rights reserved.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:    blt.cpp

Abstract:        accelerated bitblt/rectangle for S3C6410 FIMGSE-2D

Functions:


Notes:


--*/


#include "precomp.h"
#include <dispperf.h>

/// For Support Stretched Blt using HW
DDGPESurf *gpScratchSurf;
GPESurf *oldSrcSurf;

SCODE
S3C6410Disp::BltPrepare(GPEBltParms *pBltParms)
{
    RECTL rectl;
    int   iSwapTmp;
    BOOL  bRotate = FALSE;
    static bool bIsG2DReady = false;

    DEBUGMSG (GPE_ZONE_INIT, (TEXT("%s\r\n"), _T(__FUNCTION__)));

    DispPerfStart(pBltParms->rop4); //< This will be '0' when not defined DO_DISPPERF
    DispPerfParam(pBltParms);

    // default to base EmulatedBlt routine
    pBltParms->pBlt = &GPE::EmulatedBlt;        // catch all

    // see if we need to deal with cursor

    // check for destination overlap with cursor and turn off cursor if overlaps
    if (pBltParms->pDst == m_pPrimarySurface)    // only care if dest is main display surface
    {
        if (m_CursorVisible && !m_CursorDisabled)
        {
            if (pBltParms->prclDst != NULL)        // make sure there is a valid prclDst
            {
                rectl = *pBltParms->prclDst;        // if so, use it

                // There is no guarantee of a well ordered rect in blitParamters
                // due to flipping and mirroring.
                if(rectl.top > rectl.bottom)
                {
                    iSwapTmp     = rectl.top;
                    rectl.top    = rectl.bottom;
                    rectl.bottom = iSwapTmp;
                }
                if(rectl.left > rectl.right)
                {
                    iSwapTmp    = rectl.left;
                    rectl.left  = rectl.right;
                    rectl.right = iSwapTmp;
                }
            }
            else
            {
                rectl = m_CursorRect;                    // if not, use the Cursor rect - this forces the cursor to be turned off in this case
            }

            if (m_CursorRect.top <= rectl.bottom && m_CursorRect.bottom >= rectl.top &&
                m_CursorRect.left <= rectl.right && m_CursorRect.right >= rectl.left)
            {
                CursorOff();
                m_CursorForcedOff = TRUE;
            }
        }
    }

    // check for source overlap with cursor and turn off cursor if overlaps
    if (pBltParms->pSrc == m_pPrimarySurface)    // only care if source is main display surface
    {
        if (m_CursorVisible && !m_CursorDisabled)
        {
            if (pBltParms->prclSrc != NULL)        // make sure there is a valid prclSrc
            {
                rectl = *pBltParms->prclSrc;        // if so, use it
            }
            else
            {
                rectl = m_CursorRect;                    // if not, use the CUrsor rect - this forces the cursor to be turned off in this case
            }

            if (m_CursorRect.top < rectl.bottom && m_CursorRect.bottom > rectl.top &&
                m_CursorRect.left < rectl.right && m_CursorRect.right > rectl.left)
            {
                CursorOff();
                m_CursorForcedOff = TRUE;
            }
        }
    }

    // Fast Code entrance with Font Bitblt that not supported by other emulation code and acceleration hw
    // 
    if(pBltParms->rop4 == 0xAAF0)
    {
        return S_OK;
    }        
    if(pBltParms->pSrc && pBltParms->pSrc->IsRotate() ||
        pBltParms->pDst && pBltParms->pDst->IsRotate() )
    {
        bRotate = TRUE;
        pBltParms->pBlt = &GPE::EmulatedBltRotate;        // catch all
    }
// To extract 2d_accel_lib.lib totally, using preprocess statement
#if USE_SECEMUL_LIBRARY
    if( m_G2DControlArgs.UseSWAccel && !bRotate )
    {
        SECEmulatedBltSelect16(pBltParms);            //< This can be overideded by HW acceleration.            
        SECEmulatedBltSelect2416(pBltParms);
        SECEmulatedBltSelect1624(pBltParms);
   
        if(pBltParms->pBlt != (SCODE (GPE::*)(GPEBltParms *))&GPE::EmulatedBlt)
        {
            DispPerfType(DISPPERF_ACCEL_EMUL);
        }
    }
#endif
    
    if( m_VideoPowerState != VideoPowerOff && // to avoid hanging while bring up display H/W
        m_G2DControlArgs.HWOnOff)
    {
        AcceleratedBltSelect(pBltParms);

        m_oG2D->WaitForIdle();  //< Wait for Fully Empty Command Fifo for all BitBlt request to synchronize with SW BitBlt
    }
    
    DEBUGMSG(GPE_ZONE_BLT_HI, (TEXT("--%s\r\n"), _T(__FUNCTION__)));
    return S_OK;
}



// This function would be used to undo the setting of clip registers etc
SCODE
S3C6410Disp::BltComplete(GPEBltParms *pBltParms)
{
    DEBUGMSG (GPE_ZONE_BLT_HI, (TEXT("++%s()\r\n"), _T(__FUNCTION__)));

    // see if cursor was forced off because of overlap with source or destination and turn back on
    if (m_CursorForcedOff)
    {
        m_CursorForcedOff = FALSE;
        CursorOn();
    }

    if(gpScratchSurf)
    {
        pBltParms->pSrc = oldSrcSurf;
        delete gpScratchSurf;
        gpScratchSurf=NULL;
    }

    DispPerfEnd(0);

    DEBUGMSG(GPE_ZONE_BLT_HI, (TEXT("--%s()\r\n"), _T(__FUNCTION__)));
    return S_OK;
}


/**
*   @fn SCODE S3C6410Disp::AcceleratedSolidFIll(GPEBltParms *pBltParms)
*   @brief  Rectangle Solid Filling Function. Solid Fill has no Source Rectangle
*   @param  pBltParms    Blit Parameter Information Structure
*   @sa     GPEBltParms
*   @note   ROP : 0xF0F0
*   @note   Using Information : DstSurface, ROP, Solidcolor
*   @note   SW ColorFill faster than HW ColorFill x2 times for 16Bpp
*/
SCODE S3C6410Disp::AcceleratedSolidFill(GPEBltParms *pBltParms)
{
    PRECTL    prclDst         = pBltParms->prclDst;
    DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("++%s()\r\n"), _T(__FUNCTION__)));

    /**
    *    Prepare Source & DestinationSurface Information
    */

    DWORD   dwTopStrideStartAddr = 0;    

    // When Screen is rotated, ScreenHeight and ScreenWidth always has initial surface property.
    m_descDstSurface.dwHoriRes = SURFACE_WIDTH(pBltParms->pDst);

    /// 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;
    }

    m_oG2D->SetSrcSurface(&m_descDstSurface);     // Fill dummy value
    m_oG2D->SetDstSurface(&m_descDstSurface);

    if(pBltParms->prclClip)
    {
        m_oG2D->SetClipWindow(pBltParms->prclClip);
    }
    else
    {
        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;
}

/**
*   @fn SCODE S3C6410Disp::AcceleratedPatFIll(GPEBltParms *pBltParms)
*   @brief  Rectangle Pattern Filling Function. only 8x8x16bpp pattern
*   @param  pBltParms    Blit Parameter Information Structure
*   @sa     GPEBltParms
*   @note   ROP : 0xF0F0, 0x5A5A
*   @note   Using Information : DstSurface, ROP, Pattern Brush
*/
// TODO: BitBlt with Pattern memory when used with small size pattern
SCODE S3C6410Disp::AcceleratedPatFill(GPEBltParms *pBltParms)
{
    PRECTL    prclDst         = pBltParms->prclDst;
    DEBUGMSG(GPE_ZONE_BLT_LO, (TEXT("++%s()\r\n"), _T(__FUNCTION__)));

    /**
    *   Prepare Source & DestinationSurface Information
    */

    DWORD   dwTopStrideStartAddr = 0;    

    // When Screen is rotated, ScreenHeight and ScreenWidth always has initial surface property.
    m_descDstSurface.dwHoriRes = SURFACE_WIDTH(pBltParms->pDst);
    /// 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;
    }

    m_oG2D->SetSrcSurface(&m_descDstSurface);     // Fill dummy value
    m_oG2D->SetDstSurface(&m_descDstSurface);

    if(pBltParms->prclClip)
    {
        m_oG2D->SetClipWindow(pBltParms->prclClip);
    }
    else

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?