blt.cpp

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

CPP
1,258
字号
        //DumpBltParms(pBltParms);
        
        if(!pBltParms->pSrc)
        {
            return S_OK;
        }
        if(!(( &pBltParms->blendFunction != 0) && ( pBltParms->blendFunction.BlendFlags == 0) ) )
        {
            RETAILMSG(DISP_ZONE_TEMP, (TEXT("AlphaBlend BitBlt with HW request is rejected.\r\n")));
            RETAILMSG(DISP_ZONE_TEMP, (TEXT("SrcFormat:%d, BlendFunction : 0x%x Op(%d), Flag(%d),SourceConstantAlpha(%d),AlphaFormat(%d)\r\n"),
                pBltParms->pSrc->Format(),
                pBltParms->blendFunction, 
                pBltParms->blendFunction.BlendOp,
                pBltParms->blendFunction.BlendFlags, 
                pBltParms->blendFunction.SourceConstantAlpha, pBltParms->blendFunction.AlphaFormat));    
            
            return S_OK;
        }
#if G2D_BYPASS_2STEP_PROCESS_PPA_AFTER_SCA
        if(pBltParms->blendFunction.SourceConstantAlpha != 0xFF && pBltParms->blendFunction.AlphaFormat == 1)
        {
            return S_OK;
        }
#endif
#if G2D_BYPASS_SOURCECONSTANT_ALPHABLEND        // 
        if(pBltParms->blendFunction.SourceConstantAlpha != 0xFF)
        {
            return S_OK;
        }
#endif
#if G2D_BYPASS_PERPIXEL_ALPHABLEND
        if(pBltParms->blendFunction.AlphaFormat == 1)
        {
            return S_OK;
        }
#endif

    }

    if(!(pBltParms->bltFlags & BLT_ALPHABLEND))
    {
        if(m_descSrcSurface.dwColorMode == G2D_COLOR_ARGB_8888) // We cannot do this
        {
#if G2D_BYPASS_ALPHADIBTEST
            return S_OK;
#else
            m_descSrcSurface.dwColorMode = G2D_COLOR_XRGB_8888; // Force to change
            RETAILMSG(DISP_ZONE_2D, (TEXT("Src change from ARGB to XRGB.\r\n")));            
#endif            
        }
        if(m_descDstSurface.dwColorMode == G2D_COLOR_ARGB_8888) // We cannot do this
        {
#if G2D_BYPASS_ALPHADIBTEST
            return S_OK;
#else            
            m_descDstSurface.dwColorMode = G2D_COLOR_XRGB_8888; // Force to change
            RETAILMSG(DISP_ZONE_2D, (TEXT("Dst change from ARGB to XRGB.\r\n")));
#endif
        }
    }

    if(pBltParms->pConvert)     //< Emulate if color conversion required
    {
        if(!pBltParms->pSrc)
        {
            return S_OK;
        }
    }

    if(pBltParms->prclClip && (pBltParms->prclClip->left == pBltParms->prclClip->right) && (pBltParms->prclClip->top == pBltParms->prclClip->bottom))
    {
        // Just skip, there is no image flushing to screen
        // SW bitblt takes this case, and it can skip more efficiently.
//        RETAILMSG(DISP_ZONE_TEMP, (TEXT("Skip, no image to bitblt\r\n")));        
//        pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::NullBlt;        
        return S_OK;
    }

    /// Odd case do nothing    
    if(pBltParms->pSrc && pBltParms->prclSrc)
    {
        if((pBltParms->prclSrc->right == pBltParms->prclSrc->left) || (pBltParms->prclSrc->bottom == pBltParms->prclSrc->top))
        {
//            RETAILMSG(DISP_ZONE_TEMP, (TEXT("Skip, no image to bitblt\r\n")));
//            pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::NullBlt;            
            return S_OK;
        }
    }

    if(pBltParms->pDst && pBltParms->prclDst)
    {
        /// Odd case do nothing
        if ((pBltParms->prclDst->right == pBltParms->prclDst->left) || (pBltParms->prclDst->bottom == pBltParms->prclDst->top))
        {
//            RETAILMSG(DISP_ZONE_TEMP, (TEXT("Skip, no image to bitblt\r\n")));
//            pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::NullBlt;            
            return S_OK;
        }    
    }

    /**
    *    Check if source and destination regions' coordinates has positive value.
    *
    *
    **/
    if ((pBltParms->bltFlags & BLT_STRETCH))            // Stretch Bllitting with X or Y axis mirroring
    {
        //DumpBltParms(pBltParms);
        
        if(!pBltParms->prclDst || !pBltParms->prclSrc)
        {
            return S_OK;
        }
        else
        {
            if ((pBltParms->prclDst->left < 0) || (pBltParms->prclDst->right <0 ) || (pBltParms->prclDst->top <0 ) || (pBltParms->prclDst->bottom <0))
            {
                return S_OK;
            }
            if ((pBltParms->prclSrc->left < 0) || (pBltParms->prclSrc->right <0 ) || (pBltParms->prclSrc->top <0 ) || (pBltParms->prclSrc->bottom <0))
            {
                return S_OK;
            }
        }
        
        if((RECT_HEIGHT(pBltParms->prclDst) > pBltParms->pDst->Height()) || (RECT_WIDTH(pBltParms->prclDst) > pBltParms->pDst->Width()))
        {
            return S_OK;
        }
    }
    
    /// Prevent Condition Check Fail Case
    m_dwPhyAddrOfSurface[0] = NULL;
    m_dwPhyAddrOfSurface[1] = NULL;

    // select accelerated function based on rop value
    switch (pBltParms->rop4)
    {
    case 0xCCCC:    // SRCCOPY
        /// There are no image to draw.
        if( pBltParms->prclDst &&
            (pBltParms->prclDst->right < 0 ||
             pBltParms->prclDst->bottom < 0 ||
             pBltParms->prclDst->top > pBltParms->pDst->Height() ||
             pBltParms->prclDst->left > SURFACE_WIDTH(pBltParms->pDst))
             )
        {
            return S_OK;
        }
      
        if( pBltParms->prclDst && pBltParms->pSrc &&
             (SURFACE_WIDTH(pBltParms->pDst) < MAX_2DHW_WIDTH) &&

             (SURFACE_WIDTH(pBltParms->pSrc) < MAX_2DHW_WIDTH) 
#if G2D_BLT_OPTIMIZE    
            &&    (ABS(RECT_WIDTH(pBltParms->prclSrc))*ABS(RECT_HEIGHT(pBltParms->prclSrc)*BYTES_PER_PIXEL(pBltParms->pSrc)) > G2D_COMPROMISE_LIMIT)
#endif
        )
        {
            if( ( (pBltParms->pSrc)->InVideoMemory()
                    || (m_G2DControlArgs.CachedBlt && (m_dwPhyAddrOfSurface[0] = ValidatePAContinuityOfSurf(pBltParms->pSrc))) )
                    &&
                    ( pBltParms->pDst->InVideoMemory()
                    || (m_G2DControlArgs.CachedBlt && (m_dwPhyAddrOfSurface[1] = ValidatePAContinuityOfSurf(pBltParms->pDst))) )
                    && (ABS(RECT_HEIGHT(pBltParms->prclSrc)) < MAX_2DHW_HEIGHT)
                    && (ABS(RECT_WIDTH(pBltParms->prclSrc)) < MAX_2DHW_WIDTH)                    
                )
                {
                // negative Stride for Alaphblend will be treated on HWBitBlt as Flip after Copy                
                if(pBltParms->bltFlags & BLT_ALPHABLEND)
                {
                    DispPerfType(DISPPERF_ACCEL_HARDWARE);
                    pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::AcceleratedAlphaSrcCopyBlt;
                }
                else if(pBltParms->pSrc->Stride() > 0)
                {
                    DispPerfType(DISPPERF_ACCEL_HARDWARE);
                    pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::AcceleratedSrcCopyBlt;
                }
                else if(pBltParms->pDst->Rotate() != DMDO_0 &&
                        pBltParms->pSrc->Rotate() != pBltParms->pDst->Rotate())  // DMDO_0=0, DMDO_90=1, DMDO_180=2, DMDO_270=4
                {
                    // Copy&Flip Whole Source Image into Temporary area
                    // BitBlt from temporary area to Screen, This can treat Negative Stride Case.
                    DispPerfType(DISPPERF_ACCEL_HARDWARE);
                    pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::AcceleratedAlphaSrcCopyBlt;
                }                
                return S_OK;
            }
            else{
                if( (pBltParms->pSrc)->InVideoMemory() ){
                    RETAILMSG(DISP_ZONE_WARNING,(TEXT("INVideo:SRCCOPY!!!!!!\r\n")));
                }
                else    // Source is not in video memory, and not contiguous
                {
                    // negative Stride for Alaphblend will be treated on HWBitBlt as Flip after Copy                
                    if(pBltParms->bltFlags & BLT_ALPHABLEND)
                    {
                        //DumpBltParms(pBltParms);
                        DispPerfType(DISPPERF_ACCEL_HARDWARE);
                        pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::AcceleratedAlphaSrcCopyBlt;
                    }
                    /// If Stretch is needed, HW is more efficient. 
                    /// so in this case, copy va to pa's scratched buffer, then use HW
                    else if(pBltParms->bltFlags & BLT_STRETCH)
                    {
                        DispPerfType(DISPPERF_ACCEL_HARDWARE);
                        pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::AcceleratedAlphaSrcCopyBlt;
                    }
                    else if(pBltParms->pDst->Rotate() != DMDO_0 &&
                        pBltParms->pSrc->Rotate() != pBltParms->pDst->Rotate())  // DMDO_0=0, DMDO_90=1, DMDO_180=2, DMDO_270=4
                    {
                        // Copy&Flip Whole Source Image into Temporary area
                        // BitBlt from temporary area to Screen, This can treat Negative Stride Case.
                        DispPerfType(DISPPERF_ACCEL_HARDWARE);
                        pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::AcceleratedAlphaSrcCopyBlt;
                    }                
                    // Other case we cannot treat, maybe that's just SRCCOPY without any rotation, alphablend, stretch
                    RETAILMSG(DISP_ZONE_WARNING,(TEXT("NotInVideo:SRCCOPY\r\n")));                

                }
            }
        }
        return S_OK;
    case 0x6666:    // SRCINVERT        
    case 0x8888:    // SRCAND
    case 0xEEEE:    // SRCPAINT
        if( pBltParms->prclDst &&
            ((pBltParms->prclDst->left >= 0) &&
            (pBltParms->prclDst->top >= 0) &&
            (pBltParms->prclDst->right >= 0 ) &&
            (pBltParms->prclDst->bottom >= 0 )) &&
            pBltParms->pSrc &&
             (SURFACE_WIDTH(pBltParms->pDst) < MAX_2DHW_WIDTH) &&

             (SURFACE_WIDTH(pBltParms->pSrc) < MAX_2DHW_WIDTH) 
#if G2D_BLT_OPTIMIZE    
            &&    (ABS(RECT_WIDTH(pBltParms->prclSrc))*ABS(RECT_HEIGHT(pBltParms->prclSrc)*BYTES_PER_PIXEL(pBltParms->pSrc)) > G2D_COMPROMISE_LIMIT)
#endif
        )    
        {
            if( ( (pBltParms->pSrc)->InVideoMemory()
                    || (m_G2DControlArgs.CachedBlt && (m_dwPhyAddrOfSurface[0] = ValidatePAContinuityOfSurf(pBltParms->pSrc))) )
                    &&
                    ( pBltParms->pDst->InVideoMemory()
                    || (m_G2DControlArgs.CachedBlt && (m_dwPhyAddrOfSurface[1] = ValidatePAContinuityOfSurf(pBltParms->pDst))) )
                    && (ABS(RECT_HEIGHT(pBltParms->prclSrc)) < MAX_2DHW_HEIGHT)
                    && (ABS(RECT_WIDTH(pBltParms->prclSrc)) < MAX_2DHW_WIDTH)                
                )
                {
                // negative Stride for Alaphblend will be treated on HWBitBlt as Flip after Copy                
                if(pBltParms->bltFlags & BLT_ALPHABLEND)
                {
                    DispPerfType(DISPPERF_ACCEL_HARDWARE);
                    pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::AcceleratedAlphaSrcCopyBlt;
                }
                else if(pBltParms->pSrc->Stride() > 0)
                {
                    DispPerfType(DISPPERF_ACCEL_HARDWARE);
                    pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::AcceleratedSrcCopyBlt;
                }
                else if(pBltParms->pDst->Rotate() != DMDO_0 &&
                        pBltParms->pSrc->Rotate() != pBltParms->pDst->Rotate())  // DMDO_0=0, DMDO_90=1, DMDO_180=2, DMDO_270=4
                {
                    // Copy&Flip Whole Source Image into Temporary area
                    // BitBlt from temporary area to Screen
                    DispPerfType(DISPPERF_ACCEL_HARDWARE);
                    pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::AcceleratedAlphaSrcCopyBlt;
                }
                return S_OK;
            }
            else{
                if( (pBltParms->pSrc)->InVideoMemory() ){
                    RETAILMSG(FALSE,(TEXT("INVideo:ROP:0x%x\r\n"), pBltParms->rop4));
                }
                else
                {
                    // negative Stride for Alaphblend will be treated on HWBitBlt as Flip after Copy                
                    if(pBltParms->bltFlags & BLT_ALPHABLEND)
                    {
                        DispPerfType(DISPPERF_ACCEL_HARDWARE);
                        pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::AcceleratedAlphaSrcCopyBlt;
                    }
                    RETAILMSG(FALSE,(TEXT("NotInVideo:ROP:0x%x\r\n"), pBltParms->rop4));
                }
            }
            
        }
        return S_OK;
    case 0xF0F0:    // PATCOPY
    case 0x5A5A:    // PATINVERT    
        if( pBltParms->solidColor != -1)    // must be a solid colored brush
        {
            if(pBltParms->prclDst &&
                ( (pBltParms->prclDst->left >= 0) && (pBltParms->prclDst->left < MAX_2DHW_XCOORD)  &&
                  (pBltParms->prclDst->top >= 0) && (pBltParms->prclDst->top < MAX_2DHW_YCOORD) &&
                  (pBltParms->prclDst->right >= 0 ) && (pBltParms->prclDst->right < MAX_2DHW_YCOORD) &&
                  (pBltParms->prclDst->bottom >= 0 ) && (pBltParms->prclDst->bottom < MAX_2DHW_YCOORD)  ) &&
                 (SURFACE_WIDTH(pBltParms->pDst) < MAX_2DHW_WIDTH) 
#if G2D_BLT_OPTIMIZE                     
            &&    (ABS(RECT_WIDTH(pBltParms->prclDst))*ABS(RECT_HEIGHT(pBltParms->prclDst)*BYTES_PER_PIXEL(pBltParms->pDst)) > G2D_COMPROMISE_LIMIT)
#endif
             )
            {
                if( ( pBltParms->pDst->InVideoMemory()
                        || (m_G2DControlArgs.CachedBlt && (m_dwPhyAddrOfSurface[1] = ValidatePAContinuityOfSurf(pBltParms->pDst))) )
                        && (ABS(RECT_HEIGHT(pBltParms->prclDst)) < MAX_2DHW_HEIGHT)
                        && (ABS(RECT_WIDTH(pBltParms->prclDst)) < MAX_2DHW_WIDTH)                    
                   )
                {
                        DumpBltParms(pBltParms);
                        DispPerfType(DISPPERF_ACCEL_HARDWARE);        
                        pBltParms->pBlt = (SCODE (GPE::*)(struct GPEBltParms *)) &S3C6410Disp::AcceleratedSolidFill;
                        return S_OK;
                }
            }
        }

⌨️ 快捷键说明

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