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 + -
显示快捷键?