blt_alpha.cpp

来自「6410BSP3」· C++ 代码 · 共 651 行 · 第 1/2 页

CPP
651
字号
//
// 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_alpha.cpp

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

Functions:


Notes:


--*/

#include "precomp.h"

/// 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.
/// This function will copy the source and destination surface into scratch buffer
/**
*   @fn SCODE S3C6410Disp::AcceleratedAlphaSrcCopyBlt(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::AcceleratedAlphaSrcCopyBlt(GPEBltParms *pBltParms)
{
    PRECTL prclSrc, prclDst;
    RECT rectlSrcBackup;
    RECT rectlDstBackup;
    BOOL bHWSuccess = FALSE;
    BOOL bSrcInScratch = FALSE;
    BOOL bDstInScratch = FALSE;
    
    /// Allocation Scratch Framebuffer to process Bottom-Up Image
    DDGPESurf *SrcScratchSurf = NULL;
    DDGPESurf *DstScratchSurf = NULL;
    DDGPESurf *pDstClone = NULL;    
    GPESurf *OldSrcSurf = NULL;
    GPESurf *OldDstSurf = NULL;
    
    prclSrc = pBltParms->prclSrc;
    prclDst = pBltParms->prclDst;
    
    /**
    *   Prepare Source & Destination Surface Information
    */
    SURFACE_DESCRIPTOR descSrcSurface, descDstSurface;
    DWORD   dwTopStrideStartAddr = 0;

    descSrcSurface.dwColorMode = GetHWColorFormat(pBltParms->pSrc);
    descDstSurface.dwColorMode = GetHWColorFormat(pBltParms->pDst);
    /// !!!!Surface Width may not match to Real Data format!!!!
    /// !!!!Set Width by Scan Stride Size!!!!
    descSrcSurface.dwHoriRes = ABS(SURFACE_WIDTH(pBltParms->pSrc));
    descDstSurface.dwHoriRes = ABS(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
        m_oG2D->SetRopEtype(ROP_SRC_XOR_DST);
        break;
    case    0x8888: // SRCAND
        m_oG2D->SetRopEtype(ROP_SRC_AND_DST);
        break;
    case    0xCCCC: // SRCCOPY
        m_oG2D->SetRopEtype(ROP_SRC_ONLY);
        break;
    case    0xEEEE: // SRCPAINT
        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->Stride() > 0) && (pBltParms->pSrc->Stride() > 0) && (pBltParms->pSrc == pBltParms->pDst) 
        && !(pBltParms->pSrc)->InVideoMemory() )  // OnScreen BitBlt
    {
        dwTopStrideStartAddr = m_dwPhyAddrOfSurface[0];
        descSrcSurface.dwBaseaddr = dwTopStrideStartAddr;
        descSrcSurface.dwVertRes = (pBltParms->pSrc->ScreenHeight() != 0 ) ? pBltParms->pSrc->ScreenHeight() : pBltParms->pSrc->Height();
        descDstSurface.dwBaseaddr = descSrcSurface.dwBaseaddr;
        descDstSurface.dwVertRes = descSrcSurface.dwVertRes;
        RETAILMSG(DISP_ZONE_2D,(TEXT("Onscreen CachedBitBlt:Addr:0x%x, Height:%d\r\n"), descSrcSurface.dwBaseaddr, descSrcSurface.dwVertRes));
    }
    else        // OffScreen BitBlt
    {
        if((( DDGPESurf *)(pBltParms->pSrc))->InVideoMemory() )
        {
            descSrcSurface.dwBaseaddr = (m_VideoMemoryPhysicalBase + (( DDGPESurf *)(pBltParms->pSrc))->OffsetInVideoMemory());
            /// If surface is created by user temporary, that has no screen width and height.
            descSrcSurface.dwVertRes = (pBltParms->pSrc->ScreenHeight() != 0 ) ? pBltParms->pSrc->ScreenHeight() : pBltParms->pSrc->Height();
            RETAILMSG(DISP_ZONE_2D,(TEXT("Offscreen BitBlt Src in VideoMem:Addr:0x%x, Height:%d\r\n"), descSrcSurface.dwBaseaddr, descSrcSurface.dwVertRes));
        } 
        else
        {
            // In this case, WE must copy source area
            if(pBltParms->pSrc->Stride() < 0)
            {
                bHWSuccess = CreateScratchSurface(pBltParms->pSrc, &SrcScratchSurf, pBltParms->prclSrc, &descSrcSurface, pBltParms->pSrc->Format(), TRUE);
                
                if(!bHWSuccess)
                {
                    goto PostHWBitBlt;
                }

                OldSrcSurf = pBltParms->pSrc;   
                pBltParms->pSrc = SrcScratchSurf;
                bSrcInScratch = TRUE;
                RETAILMSG(DISP_ZONE_2D,(TEXT("SBBase:0x%x, Vert:%d, Hori:%d, CM:%d\r\n"), descSrcSurface.dwBaseaddr, descSrcSurface.dwVertRes,
                descSrcSurface.dwHoriRes, descSrcSurface.dwColorMode));
            }
            else
            {
                if(m_dwPhyAddrOfSurface[0] == NULL) // Copy
                {
                    bHWSuccess = CreateScratchSurface(pBltParms->pSrc, &SrcScratchSurf, pBltParms->prclSrc, &descSrcSurface, pBltParms->pSrc->Format(),TRUE);
                    
                    if(!bHWSuccess)
                    {
                        goto PostHWBitBlt;
                    }
                    
                    OldSrcSurf = pBltParms->pSrc;   
                    pBltParms->pSrc = SrcScratchSurf;
                    bSrcInScratch = TRUE;                    
                    RETAILMSG(DISP_ZONE_2D,(TEXT("STBase:0x%x, Vert:%d, Hori:%d, CM:%d\r\n"), descSrcSurface.dwBaseaddr, descSrcSurface.dwVertRes,
                    descSrcSurface.dwHoriRes, descSrcSurface.dwColorMode));                
                }
                else
                {
                    dwTopStrideStartAddr = m_dwPhyAddrOfSurface[0] + pBltParms->prclSrc->top * pBltParms->pSrc->Stride();
                    descSrcSurface.dwBaseaddr = dwTopStrideStartAddr;
                    descSrcSurface.dwVertRes = RECT_HEIGHT(pBltParms->prclSrc);

                    pBltParms->prclSrc->top = 0;
                    pBltParms->prclSrc->bottom = descSrcSurface.dwVertRes;
                    RETAILMSG(DISP_ZONE_2D,(TEXT("STVBase:0x%x, Vert:%d, Hori:%d, CM:%d\r\n"), descSrcSurface.dwBaseaddr, descSrcSurface.dwVertRes,
                    descSrcSurface.dwHoriRes, descSrcSurface.dwColorMode));
                    
                }
            }
        }

        /// Set Destination Surface Information
        if(((DDGPESurf *)(pBltParms->pDst))->InVideoMemory() )
        {
            descDstSurface.dwBaseaddr = (m_VideoMemoryPhysicalBase + (( DDGPESurf *)(pBltParms->pDst))->OffsetInVideoMemory());
            /// If surface is created by user temporary, that has no screen width and height.
            descDstSurface.dwVertRes = (pBltParms->pDst->ScreenHeight() != 0 ) ? pBltParms->pDst->ScreenHeight() : pBltParms->pDst->Height();
            RETAILMSG(DISP_ZONE_2D,(TEXT("Offscreen BitBlt Dst in VideoMem:Addr:0x%x, Height:%d\r\n"), descDstSurface.dwBaseaddr, descDstSurface.dwVertRes));            
        }
        else
        {
            if(pBltParms->pDst->Stride() < 0)
            {
                bHWSuccess = CreateScratchSurface(pBltParms->pDst, &DstScratchSurf, pBltParms->prclDst, &descDstSurface, pBltParms->pDst->Format(), TRUE);
                
                if(!bHWSuccess)
                {
                    goto PostHWBitBlt;
                }
                
                OldDstSurf = pBltParms->pDst;   
                pBltParms->pDst = DstScratchSurf;
                bDstInScratch = TRUE;                
                RETAILMSG(DISP_ZONE_2D,(TEXT("DBBase:0x%x, Vert:%d, Hori:%d, CM:%d\r\n"), descDstSurface.dwBaseaddr, descDstSurface.dwVertRes,
                descDstSurface.dwHoriRes, descDstSurface.dwColorMode));
    /*            
                RETAILMSG(DISP_ZONE_WARNING,(TEXT("I don't know about this case\n")));
                return EmulatedBlt(pBltParms);
    */
            }
            else
            {
                if(m_dwPhyAddrOfSurface[1] == NULL) // Prepare
                {  
                    bHWSuccess = CreateScratchSurface(pBltParms->pDst, &DstScratchSurf, pBltParms->prclDst, &descDstSurface, pBltParms->pDst->Format(), TRUE);
                    
                    if(!bHWSuccess)
                    {
                        goto PostHWBitBlt;
                    }
                    
                    OldDstSurf = pBltParms->pDst;   
                    pBltParms->pDst = DstScratchSurf;
                    bDstInScratch = TRUE;                    
                    RETAILMSG(DISP_ZONE_2D,(TEXT("DTBase:0x%x, Vert:%d, Hori:%d, CM:%d\r\n"), descDstSurface.dwBaseaddr, descDstSurface.dwVertRes,
                    descDstSurface.dwHoriRes, descDstSurface.dwColorMode));
                
                }
                else
                {
                    dwTopStrideStartAddr = m_dwPhyAddrOfSurface[1] + pBltParms->prclDst->top * pBltParms->pDst->Stride();
                    descDstSurface.dwBaseaddr = dwTopStrideStartAddr;
                    descDstSurface.dwVertRes = RECT_HEIGHT(pBltParms->prclDst);
                    pBltParms->prclDst->top = 0;
                    pBltParms->prclDst->bottom = descDstSurface.dwVertRes;
                    RETAILMSG(DISP_ZONE_2D,(TEXT("DTVBase:0x%x, Vert:%d, Hori:%d, CM:%d\r\n"), descDstSurface.dwBaseaddr, descDstSurface.dwVertRes,
                    descDstSurface.dwHoriRes, descDstSurface.dwColorMode));
                }
            }
        }
    }

    m_oG2D->Set3rdOperand(G2D_OPERAND3_PAT);

    // AlphaBlending Equation, Perpixel and Perplane same.
    // Data = (Source * (ALPHA+1) + destination *(256-ALPHA)) >> 8
    // Fading
    // Data = ((Source * (ALPHA+1) ) >>8) + fading offset
    //
    
    // Check if Constant Alpha or Per-Pixel Alpha
    if(pBltParms->blendFunction.AlphaFormat != 0 && pBltParms->blendFunction.SourceConstantAlpha != 0xFF)
    {
        SURFACE_DESCRIPTOR descRealSrcSurface;
        SURFACE_DESCRIPTOR descRealDstSurface;        
        GPESurf *pDstBackup=0;
        RECT rectDstBackup;
        RECT rectSrcBackup;
        RECT rectBackupCloneDst;
        
        // Backup original source region, This can be Scratch Surface's region
        CopyRect(&rectSrcBackup, (LPRECT)pBltParms->prclSrc);            
        // Backup original destination region
        CopyRect(&rectDstBackup, (LPRECT)pBltParms->prclDst);
        // Bakcup original destination surface
        pDstBackup = pBltParms->pDst;
        
        // backup real source Surface.
        memcpy(&descRealSrcSurface, &descSrcSurface, sizeof(SURFACE_DESCRIPTOR));
    
        // if Per-Pixel Alpha with SCA then we just run 2 alphablend call
        // set destination descriptor as source descriptor.
        // prepare scratch for fading.
        if(!bSrcInScratch)
        {
            bHWSuccess = CreateScratchSurface(pBltParms->pSrc, &SrcScratchSurf, pBltParms->prclSrc, &descSrcSurface, pBltParms->pSrc->Format(), FALSE);

            OldSrcSurf = pBltParms->pSrc;
            pBltParms->pSrc = SrcScratchSurf;
            bSrcInScratch = TRUE;    
        }

        // Replace Target region as source itself
        pBltParms->prclDst = pBltParms->prclSrc;
        // Replace Target Surface as Source Surface
        pBltParms->pDst = pBltParms->pSrc;

        m_oG2D->SetAlphaMode(G2D_FADING_MODE); //< Self Fading AlphaBlend
        m_oG2D->SetAlphaValue(pBltParms->blendFunction.SourceConstantAlpha);
        // Do SCA to self(fading mode).
        bHWSuccess = HWBitBlt(pBltParms, &descRealSrcSurface, &descSrcSurface);        
        
        ///////
        // restore destination region
        pBltParms->prclDst = (LPRECTL)&rectDstBackup;
        // restore destination surface
        pBltParms->pDst = pDstBackup;

        if(!bHWSuccess)
        {
            goto PostHWBitBlt;
        }
        
#define ALPHABIT_WORKAROUND2 (TRUE)

⌨️ 快捷键说明

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