fimgse2d.cpp

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

CPP
1,270
字号
*            There's predefine macro type for presenting rotation register's setting value
*            G2D_ROTATION
*    @note This function can not support Multiple Operation ex) mirrored + rotation because of HW
*    @sa    ROT_TYPE
**/
void FIMGSE2D::StretchBlt_Bilinear(PRECTL prclSrc, PRECTL prclDst, ROT_TYPE m_iRotate)
{
    POINT ptCompensatedOffset;
    WORD usSrcWidth = 0;
    WORD usSrcHeight = 0;
    WORD usDstWidth = 0;
    WORD usDstHeight = 0;
    
    DWORD uXIncr = 0;
    DWORD uYIncr = 0;
    DWORD uCmdRegVal=0;

    RECTL    rectDst;
    RECTL    rectDstRT;            //< If rotation case this value must be corrected.
    RECTL    rectDstLT;
    RECTL    rectDstRB;
    RECTL    rectDstLB;

    RETAILMSG(DISP_ZONE_ENTER,(TEXT("\n[2DHW] StretchBlt Entry")));    

    /// Always LeftTop Coordinate is less than RightBottom for Source and Destination Region
    assert( (prclSrc->left < prclSrc->right) && (prclSrc->top < prclSrc->bottom) );
    assert( (prclDst->left < prclDst->right) && (prclDst->top < prclDst->bottom) );    

    /// Set Stretch parameter
    /// most right and bottom line does not be drawn.
    usSrcWidth=(WORD) ABS( prclSrc->right  - prclSrc->left);
    usDstWidth=(WORD) ABS( prclDst->right  - prclDst->left);
    usSrcHeight=(WORD) ABS( prclSrc->bottom  - prclSrc->top);
    usDstHeight=(WORD) ABS( prclDst->bottom  - prclDst->top);

    if((m_iRotate == ROT_90) ||(m_iRotate == ROT_270) )
    {
        SWAP(usDstHeight, usDstWidth, WORD);
    }

    /// Stretch ratio calculation, width and height is include last line
    /// ex) 10x10 to 30x30
    /// Given Coordinate parameter
    /// SrcCoord. (0,0)~(10,10) :  srcwidth = 10-0 = 10, srcheight = 10-0 = 10
    /// DstCoord. (30,30)~(60,60) : dstwidth = 60-30 = 30, dstheight = 60-30 = 30
    /// Actual using coordinate
    /// src (0,0)~(9,9)
    /// Dst (30,30)~(59,59)
    /// Increment calculation : srcwidth/dstwidth = 10/30 = 0.33333...
    
    if(usSrcWidth == usDstWidth && usSrcHeight == usDstHeight)
    {
        RETAILMSG(DISP_ZONE_2D, (TEXT("\nThis is not stretch or shrink BLT, redirect to BitBlt, R:%d"), m_iRotate));
        BitBlt(prclSrc, prclDst, m_iRotate);
        return;
    }
    
    /// calculate horizontal length        
    uXIncr = CalculateXYIncrFormat(usSrcWidth , usDstWidth );    
    SetXIncr(uXIncr);
    RETAILMSG(DISP_ZONE_2D,(TEXT("\nXIncr : %d.%d"), (uXIncr&0x003ff800)>>11, (uXIncr & 0x000007ff)));        
    
    /// calculate vertical length
    uYIncr = CalculateXYIncrFormat(usSrcHeight  , usDstHeight );
    SetYIncr(uYIncr);
    RETAILMSG(DISP_ZONE_2D,(TEXT("\nYIncr : %d.%d"), (uYIncr&0x003ff800)>>11, (uYIncr & 0x000007ff)));            

    /// Set Source Region Coordinate
    SetCoordinateSrcBlock(prclSrc->left, prclSrc->top, prclSrc->right - 1, prclSrc->bottom - 1);    

    /// Now We divide destination region by 4 logically.
    /// 1. LeftTop Vertical Bar, 2. RightTop Block, 3. LeftBottom Small Block, 4.RightBottom Horizontal Bar
    
    /// 1. LeftTop Vertical Bar
    /// This region has destination's height - RightBottom Horizontal bar's height
    /// and has width value can be gotten by this fomula : 
    ///     Refered source surface's pixel coordinate = 0.5 + Increment ratio(Src/Dst) * destination's coordinate
    /// In stretchBlt, Destination's coordinate always starts from (0,0)
    /// Here, Bar's width is (max desitnation's coordinate+1) until refered source surface's pixel coordinate is not over 1.0.
    /// ex) 10x10 to 30x30
    ///    Increment ratio = 10/30 = 0.33333
    ///    Refered source surface's pixel coordinate = 0.5+0.333*0, 0.5+0.333*1, 0.5+0.333*2
    ///    0.5, 0.833  meets this condition. so max destination's coordnate is 1. width is 2
    /// then each block of destination's has this region
    /// LT = (0,0)~(1,27), LB(0,28)~(1,29), RT(2,0)~(29,27), RB(2,28)~(29,29)
    ///  real stretch ratio is 30/10 = 3. so 2 is less than 3. we need add offset 1
    /// ex) 10x10 to 50x50
    ///    Increment ratio = 10/50 = 0.2
    ///    Refered source surface's pixel coordinate = 0.5+0.2*0, 0.5+0.2*1, 0.5+0.2*2, 0.5+0.2*3
    ///   0.5, 0.7, 0.9 meets this condition. so max destination's coordinate is 2. width is 3
    /// then each block of desitnation's has this region
    /// LT = (0,0)~(2,46), LB(0,47)~(2,49), RT(3,0)~(49,47), RB(3,47)~(49,49)
    ///  real stretch ratio is 50/10 = 5. so 3 is less than 5, we need add offset 2
    ptCompensatedOffset.x = GetCompensatedOffset(usSrcWidth, usDstWidth);
    ptCompensatedOffset.y = GetCompensatedOffset(usSrcHeight, usDstHeight);

    ///    

    /// Calculate Destination Region Coordinate for each rotation degree
    if(m_iRotate == ROT_180)        //< origin set to (x2,y2)
    {
        rectDst.left = prclDst->right - 1;                        //< x2
        rectDst.top = prclDst->bottom - 1;                        //< y2
        rectDst.right = 2 * (prclDst->right - 1) - prclDst->left ;        //< x2 + (x2 - x1)
        rectDst.bottom = 2 * (prclDst->bottom -1) - prclDst->top;    //< y2 + (y2 - y1)
    }
    else     if(m_iRotate == ROT_90)        //<In this time, Height and Width are swapped.    
    {
        rectDst.left = prclDst->right - 1;                        //< x2
        rectDst.right = prclDst->right - 1 + prclDst->bottom - 1 - prclDst->top;    //< x2 + (y2 - y1)
        rectDst.top = prclDst->top;                                        //< y1
        rectDst.bottom = prclDst->top + prclDst->right - 1 - prclDst->left;        //< y1 + (x2 - x1)
    }
    else     if(m_iRotate == ROT_270)        //<In this time, Height and Width are swapped.    
    {
        rectDst.left = prclDst->left;                            //< x1
        rectDst.right = prclDst->left + prclDst->bottom - 1- prclDst->top;        //< x1 + (y2 - y1)
        rectDst.top = prclDst->bottom - 1;                                    //< y2
        rectDst.bottom = prclDst->bottom - 1 + prclDst->right - 1- prclDst->left;    //< y2 + (x2 - x1)
    }
    else        //< ROT_0
    {
        rectDst.left = prclDst->left;
        rectDst.top = prclDst->top;        
        rectDst.right = prclDst->right - 1;
        rectDst.bottom = prclDst->bottom - 1;
    }

    RETAILMSG(DISP_ZONE_2D,(TEXT("\nROT:%d, Src:(%d,%d)~(%d,%d), Dst:(%d,%d)~(%d,%d), OC:(%d,%d)"), 
        m_iRotate, prclSrc->left, prclSrc->top, prclSrc->right, prclSrc->bottom, 
        rectDst.left, rectDst.top, rectDst.right, rectDst.bottom, rectDst.left, rectDst.top));

    /// Set Destination's Rotation mode
    SetRotationMode(m_iRotate);        
    SetRotationOrg((WORD)rectDst.left, (WORD)rectDst.top);    
    uCmdRegVal = G2D_STRETCH_BITBLT_BIT;
    
    if(ptCompensatedOffset.x != 0 || ptCompensatedOffset.y != 0)
    {
        rectDstRB.left = rectDst.left + ptCompensatedOffset.x;
        rectDstRB.right = rectDst.right;
        rectDstRB.top = rectDst.top + ptCompensatedOffset.y;
        rectDstRB.bottom = rectDst.bottom;
        SetClipWindow(&rectDstRB);    //< Reconfigure clip region as Each Block's region    
        SetCoordinateDstBlock(rectDstRB.left, rectDstRB.top, rectDstRB.right + ptCompensatedOffset.x, rectDstRB.bottom + ptCompensatedOffset.y);

        /// First Issuing for Right Bottom Big Region.
        RequestEmptyFifo(1);
        
        RETAILMSG(DISP_ZONE_2D,(TEXT("\nRight Bottom Block : Dst:(%d,%d)~(%d,%d)"), 
            rectDstRB.left, rectDstRB.top, rectDstRB.right, rectDstRB.bottom));    
        
        m_pG2DReg->CMDR1 = uCmdRegVal;

        rectDstRT.left = rectDstRB.left;
        rectDstRT.right = rectDst.right;
        rectDstRT.top = rectDst.top;
        rectDstRT.bottom = rectDstRB.top - 1;
        SetClipWindow(&rectDstRT);
        SetCoordinateDstBlock(rectDstRT.left, rectDst.top, rectDst.right + ptCompensatedOffset.x, rectDst.bottom);

        /// Second Issuing for Right Top Horizontal Bar Region.(in 0, 180 degree)
        RequestEmptyFifo(1);
        RETAILMSG(DISP_ZONE_2D,(TEXT("\nRight Top Block : Dst:(%d,%d)~(%d,%d)"), 
            rectDstRT.left, rectDstRT.top, rectDstRT.right, rectDstRT.bottom));    
        
        m_pG2DReg->CMDR1 = uCmdRegVal;

        
        rectDstLB.left = rectDst.left;
        rectDstLB.right = rectDstRB.left - 1;
        rectDstLB.top = rectDstRB.top;
        rectDstLB.bottom = rectDst.bottom;
        SetClipWindow(&rectDstLB);
        SetCoordinateDstBlock(rectDst.left, rectDstLB.top, rectDst.right, rectDstLB.bottom + ptCompensatedOffset.y);    
        /// Third Issuing for Left Bottom Vertical Bar(in 0,180 degree)
        RequestEmptyFifo(1);
        RETAILMSG(DISP_ZONE_2D,(TEXT("\nLeft Bottom Block : Dst:(%d,%d)~(%d,%d)"), 
            rectDstLB.left, rectDstLB.top, rectDstLB.right, rectDstLB.bottom));    
        
        m_pG2DReg->CMDR1 = uCmdRegVal;

        
        rectDstLT.left = rectDst.left;
        rectDstLT.right = rectDstLB.right;
        rectDstLT.top = rectDst.top;
        rectDstLT.bottom = rectDstRT.bottom;
        SetClipWindow(&rectDstLT);
    RETAILMSG(DISP_ZONE_2D,(TEXT("\nLeft Top Block : Dst:(%d,%d)~(%d,%d)"), 
        rectDstLT.left, rectDstLT.top, rectDstLT.right, rectDstLT.bottom));    
        
    }
    
    SetCoordinateDstBlock(rectDst.left, rectDst.top, rectDst.right, rectDst.bottom);    
    /// Last Issuing for Left Top Small Region(in 0,180 degree)

    DoCmd(&(m_pG2DReg->CMDR1), uCmdRegVal, G2D_INTERRUPT);    

    RETAILMSG(DISP_ZONE_ENTER,(TEXT("\n[2DHW] StretchBlt Exit")));
    /// TODO: Resource Register clearing can be needed.

}
/// This implementation has distorted stretch result.
/**
*   @fn FIMGSE2D::StretchBlt(PRECTL prclSrc, PRECTL prclDst, ROT_TYPE m_iRotate)
*   @param  prclSrc Source Rectangle
*   @param  prclDst Destination Rectangle
*   @param  m_iRotate   Rotatation Degree. See also ROT_TYPE type
*   @note This funciton performs real Stretched Bit blit using 2D HW. this functio can handle rotation case.
*       There's predefine macro type for presenting rotation register's setting value
*       G2D_ROTATION
*   @note This function can not support Multiple Operation ex) mirrored + rotation because of HW
*   @sa ROT_TYPE
**/
void FIMGSE2D::StretchBlt(PRECTL prclSrc, PRECTL prclDst, ROT_TYPE m_iRotate)
{
    WORD usSrcWidth = 0;
    WORD usSrcHeight = 0;
    WORD usDstWidth = 0;
    WORD usDstHeight = 0;
    DWORD uXYIncr = 0;
    DWORD uCmdRegVal=0;

    RECTL    rectDst;            //< If rotation case this value must be corrected.

    RETAILMSG(DISP_ZONE_ENTER,(TEXT("[2DHW] StretchBlt Entry\r\n")));    

    /// Always LeftTop Coordinate is less than RightBottom for Source and Destination Region
    assert( (prclSrc->left < prclSrc->right) && (prclSrc->top < prclSrc->bottom) );
    assert( (prclDst->left < prclDst->right) && (prclDst->top < prclDst->bottom) );    

    /// Set Stretch parameter
    /// Stretch ratio calculation, width and height is not include last line
    usSrcWidth=(WORD) ABS( prclSrc->right  - prclSrc->left);
    usDstWidth=(WORD) ABS( prclDst->right  - prclDst->left);
    usSrcHeight=(WORD) ABS( prclSrc->bottom  - prclSrc->top);
    usDstHeight=(WORD) ABS( prclDst->bottom  - prclDst->top);

    if((m_iRotate == ROT_90) ||(m_iRotate == ROT_270) )
    {
        SWAP(usDstHeight, usDstWidth, WORD);
    }    

    /// When Orthogonally Rotated operation is conducted,     
    if(usSrcWidth == usDstWidth && usSrcHeight == usDstHeight)
    {
        RETAILMSG(DISP_ZONE_2D, (TEXT("This is not stretch or shrink BLT, redirect to BitBlt, R:%d\n"), m_iRotate));
        BitBlt(prclSrc, prclDst, m_iRotate);
        return;
    }
    
    uXYIncr = CalculateXYIncrFormat(usSrcWidth -1, usDstWidth -1);
    SetXIncr(uXYIncr);    
    RETAILMSG(DISP_ZONE_2D,(TEXT("\nXIncr : %d.%x"), (uXYIncr&0x003ff800)>>11, (uXYIncr & 0x000007ff)));    

    uXYIncr = CalculateXYIncrFormat(usSrcHeight -1, usDstHeight -1);
    SetYIncr(uXYIncr);
    RETAILMSG(DISP_ZONE_2D,(TEXT("\nYIncr : %d.%x"), (uXYIncr&0x003ff800)>>11, (uXYIncr & 0x000007ff)));        
    
    SetCoordinateSrcBlock(prclSrc->left, prclSrc->top, prclSrc->right - 1, prclSrc->bottom - 1);    

    if(m_iRotate == ROT_180)        //< origin set to (x2,y2)
    {
        rectDst.left = prclDst->right - 1;                        //< x2
        rectDst.top = prclDst->bottom - 1;                        //< y2
        rectDst.right = 2 * (prclDst->right - 1) - prclDst->left ;        //< x2 + (x2 - x1)
        rectDst.bottom = 2 * (prclDst->bottom -1) - prclDst->top;    //< y2 + (y2 - y1)
    }
    else     if(m_iRotate == ROT_90)        //<In this time, Height and Width are swapped.
    {
        rectDst.left = prclDst->right - 1;                        //< x2
        rectDst.right = prclDst->right - 1 + prclDst->bottom - 1 - prclDst->top;    //< x2 + (y2 - y1)
        rectDst.top = prclDst->top;                                        //< y1
        rectDst.bottom = prclDst->top + prclDst->right - 1 - prclDst->left;        //< y1 + (x2 - x1)
    }
    else     if(m_iRotate == ROT_270)        //<In this time, Height and Width are swapped.
    {
        rectDst.left = prclDst->left;                            //< x1
        rectDst.right = prclDst->left + prclDst->bottom - 1- prclDst->top;        //< x1 + (y2 - y1)
        rectDst.top = prclDst->bottom - 1;                                    //< y2
        rectDst.bottom = prclDst->bottom - 1 + prclDst->right - 1- prclDst->left;    //< y2 + (x2 - x1)
    }
    else        //< ROT_0
    {
        rectDst.left = prclDst->left;
        rectDst.top = prclDst->top;
        rectDst.right = prclDst->right - 1;
        rectDst.bottom = prclDst->bottom - 1;
    }

    /// Set Destination's Rotation mode
    SetRotationMode(m_iRotate);
    SetRotationOrg((WORD)rectDst.left, (WORD)rectDst.top);
    SetCoordinateDstBlock(rectDst.left, rectDst.top, rectDst.right, rectDst.bottom);

    RETAILMSG(DISP_ZONE_2D,(TEXT("ROT:%d, Src:(%d,%d)~(%d,%d), Dst:(%d,%d)~(%d,%d), OC:(%d,%d)\r\n"), 
        m_iRotate, prclSrc->left, prclSrc->top, prclSrc->right, prclSrc->bottom, 
        rectDst.left, rectDst.top, rectDst.right, rectDst.bottom, rectDst.left, rectDst.top));

    uCmdRegVal = G2D_STRETCH_BITBLT_BIT;

    DoCmd(&(m_pG2DReg->CMDR1), uCmdRegVal, G2D_INTERRUPT);

    RETAILMSG(DISP_ZONE_ENTER,(TEXT("[2DHW] StretchBlt Exit\r\n")));            
    /// TODO: Resource Register clearing can be needed.
}

/**
*    @fn    FIMGSE2D::FlipBlt(PRECTL prclSrc, PRECTL prclDst, ROT_TYPE m_iRotate)
*    @param    prclSrc    Source Rectangle
*    @param    prclDst    Destination Rectangle
*    @param    m_iRotate    Flip Setting. See also ROT_TYPE type
*    @note This funciton performs ONLY FLIP Bit blit using 2D HW. this function cannot handle rotation case.
*            There's predefine macro type for presenting rotation register's setting value
*            This function requires Scratch Memory for Destination.
*            This function don't support X&Y flipping
*    @sa    ROT_TYPE

⌨️ 快捷键说明

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