⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fimgse2d.cpp

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 CPP
📖 第 1 页 / 共 4 页
字号:
*    @param    prclSrc    Source Rectangle
*    @param    prclDst    Destination Rectangle
*    @param    m_iRotate    Rotatation Degree. See also ROT_TYPE type
*    @note This funciton performs getting offset for stretchblt algorithm compensation
*    @sa    ROT_TYPE
*
**/
LONG FIMGSE2D::GetCompensatedOffset(DWORD usSrcValue, DWORD usDstValue)

{
    /// Calculate X,Y Offset
    float fIncrement;
    float fStretchRatio;
    float fReferPoint = 0.5;
    LONG i =0;
    
    fIncrement = (float)usSrcValue / (float)usDstValue;
    fStretchRatio = (float)usDstValue / (float)usSrcValue;
    
    do
    {
        if(fReferPoint > 1) break;    
        fReferPoint += fIncrement;
        i++;
    } while(1);

    RETAILMSG(ZONE_CHECK(ZONE_STRETCHBLT),(TEXT("\n fIncr : %5.6f, fSR: %5.6f, i : %d, Offset : %d"), fIncrement, fStretchRatio, i, (LONG)(fStretchRatio - i)));
    
    return (fStretchRatio < 1) ? 0 : (LONG)(fStretchRatio - i);
}

/**
*    @fn    FIMGSE2D::StretchBlt_Bilinear(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_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(ZONE_CHECK(ZONE_STRETCHBLT),(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(ZONE_CHECK(ZONE_STRETCHBLT), (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(ZONE_CHECK(ZONE_STRETCHBLT),(TEXT("\nXIncr : %d.%d"), (uXIncr&0x003ff800)>>11, (uXIncr & 0x000007ff)));        
    
    /// calculate vertical length
    uYIncr = CalculateXYIncrFormat(usSrcHeight  , usDstHeight );
    SetYIncr(uYIncr);
    RETAILMSG(ZONE_CHECK(ZONE_STRETCHBLT),(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(ZONE_CHECK(ZONE_STRETCHBLT),(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.
        CheckFifo(1);
        
        RETAILMSG(ZONE_CHECK(ZONE_STRETCHBLT),(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)
        CheckFifo(1);
        RETAILMSG(ZONE_CHECK(ZONE_STRETCHBLT),(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)
        CheckFifo(1);
        RETAILMSG(ZONE_CHECK(ZONE_STRETCHBLT),(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(ZONE_CHECK(ZONE_STRETCHBLT),(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)

#if    (G2D_CMDPROCESSING==G2D_FASTRETURN)
    WaitForEmptyFifo();        //< This is check fully empty command fifo.
    m_pG2DReg->CMDR1 = uCmdRegVal;        // Process Only One Instruction per bitblt request
#elif (G2D_CMDPROCESSING==G2D_INTERRUPT)
    CheckFifo(1);    
    IntEnable();    
    m_pG2DReg->CMDR1 = uCmdRegVal;        // Process Only One Instruction per bitblt request
    WaitForSingleObject(m_hInterrupt2D, INFINITE);

    IntDisable();    
    IntPendingClear();    

    InterruptDone(m_dwSysIntr2D);
#elif (G2D_CMDPROCESSING==G2D_BUSYWAITING)
    CheckFifo(1);
    IntEnable();    
    while(!WaitForFinish());                        // Polling Style    
    m_pG2DReg->CMDR1 = uCmdRegVal;        // Process Only One Instruction per bitblt request

    IntDisable();    
#else
#error "CMDPROCESSING TYPE is invalid, Please Check Header Definition"
    RETAILMSG(TRUE,(TEXT("\nCMDPROCESSING TYPE is invalid, Please Check Header Definition")));
    return FALSE;
#endif


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

}
/// This implementation has distorted stretch result.
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(ZONE_CHECK(ZONE_STRETCHBLT),(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(ZONE_CHECK(ZONE_STRETCHBLT), (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(ZONE_CHECK(ZONE_STRETCHBLT),(TEXT("\nXIncr : %d.%x"), (uXYIncr&0x003ff800)>>11, (uXYIncr & 0x000007ff)));    

    uXYIncr = CalculateXYIncrFormat(usSrcHeight -1, usDstHeight -1);
    SetYIncr(uXYIncr);
    RETAILMSG(ZONE_CHECK(ZONE_STRETCHBLT),(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(ZONE_CHECK(ZONE_STRETCHBLT),(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;

#if    (G2D_CMDPROCESSING==G2D_FASTRETURN)
    WaitForEmptyFifo();        //< This is check fully empty command fifo.
    m_pG2DReg->CMDR1 = uCmdRegVal;        // Process Only One Instruction per bitblt request

⌨️ 快捷键说明

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