/** * @fn void RegCtrlG2D::SetCoordinateSrcBlockEndian(DWORD uStartX, DWORD uStartY, DWORD uEndX, DWORD uEndY) * @brief Set Source Data Area that will be read * @param uStartX left X * uStartY top Y * uEndX right X * uEndY bottom Y */ void RegCtrlG2D::SetCoordinateSrcBlock(DWORD uStartX, DWORD uStartY, DWORD uEndX, DWORD uEndY) { RequestEmptyFifo(4); m_pG2DReg->COORD0_X = uStartX; m_pG2DReg->COORD0_Y = uStartY; m_pG2DReg->COORD1_X = uEndX; m_pG2DReg->COORD1_Y = uEndY; }
/** * @fn void RegCtrlG2D::SetCoordinateDstBlockEndian(DWORD uStartX, DWORD uStartY, DWORD uEndX, DWORD uEndY) * @brief Set Destination Data Area that will be written * @param uStartX left X * uStartY top Y * uEndX right X * uEndY bottom Y */ void RegCtrlG2D::SetCoordinateDstBlock(DWORD uStartX, DWORD uStartY, DWORD uEndX, DWORD uEndY) { RequestEmptyFifo(4); m_pG2DReg->COORD2_X = uStartX; m_pG2DReg->COORD2_Y = uStartY; m_pG2DReg->COORD3_X = uEndX; m_pG2DReg->COORD3_Y = uEndY; }
// else '0', Opaque Mode void FIMGSE2D::SetColorKeyOn(DWORD uBsColor) { RequestEmptyFifo(2); m_pG2DReg->ROP = m_pG2DReg->ROP | G2D_TRANSPARENT_BIT; // register Blue Screen Color m_pG2DReg->BS_COLOR = uBsColor; }
/** * @fn void RegCtrlG2D::SetClipWindow(PRECTL prtClipWindow) * @brief Set Clipping Data Area that will be not cropped. * @param uStartX left X * uStartY top Y * uEndX right X * uEndY bottom Y */ void RegCtrlG2D::SetClipWindow(PRECTL prtClipWindow) { RequestEmptyFifo(4); DEBUGMSG(DISP_ZONE_TEMP,(TEXT("cl:%d, ct:%d, cr:%d, cb:%d\r\n"), prtClipWindow->left, prtClipWindow->top, prtClipWindow->right, prtClipWindow->bottom)); m_pG2DReg->CW_LEFT_TOP_X = prtClipWindow->left; m_pG2DReg->CW_LEFT_TOP_Y = prtClipWindow->top; m_pG2DReg->CW_RIGHT_BOTTOM_X = prtClipWindow->right; m_pG2DReg->CW_RIGHT_BOTTOM_Y = prtClipWindow->bottom; }
void FIMGSE2D::SetColorKeyOff(void) { RequestEmptyFifo(2); // Blue screen off m_pG2DReg->ROP = m_pG2DReg->ROP & ~(G2D_TRANSPARENT_BIT); // color key off m_pG2DReg->COLORKEY_CNTL = (m_pG2DReg->COLORKEY_CNTL & ~(0x1U<<31)); }
void FIMGSE2D::SetDstSurface(PSURFACE_DESCRIPTOR desc_surface) { RequestEmptyFifo(4); m_pG2DReg->DST_BASE_ADDR = desc_surface->dwBaseaddr; m_pG2DReg->DST_COLOR_MODE = desc_surface->dwColorMode; m_pG2DReg->SC_HORI_RES = desc_surface->dwHoriRes; m_pG2DReg->SC_VERT_RES = desc_surface->dwVertRes; }
void FIMGSE2D::PutPixel(DWORD uPosX, DWORD uPosY, DWORD uColor) //modification { SetRotationMode(ROT_0); RequestEmptyFifo(4); m_pG2DReg->COORD0_X = uPosX; m_pG2DReg->COORD0_Y = uPosY; m_pG2DReg->FG_COLOR = uColor; DoCmd(&(m_pG2DReg->CMDR0), G2D_REND_POINT_BIT, G2D_FASTRETURN); }
void FIMGSE2D::PutLine(DWORD usPosX1, DWORD usPosY1, DWORD usPosX2, DWORD usPosY2, DWORD uColor, bool bIsDrawLastPoint) //modification { int nMajorCoordX; DWORD uHSz, uVSz; int i; int nIncr=0; DWORD uCmdRegVal; SetRotationMode(ROT_0); RequestEmptyFifo(7); RETAILMSG(DISP_ZONE_LINE,(TEXT("(%d,%d)~(%d,%d):Color:0x%x, LasT:%d\n"), usPosX1, usPosY1, usPosX2, usPosY2, uColor, bIsDrawLastPoint)); m_pG2DReg->COORD0_X = usPosX1; m_pG2DReg->COORD0_Y = usPosY1; m_pG2DReg->COORD2_X = usPosX2; m_pG2DReg->COORD2_Y = usPosY2; /// Vertical Length uVSz = ABS((WORD)usPosY1 - (WORD)usPosY2); /// Horizontal Length uHSz = ABS((WORD)usPosX1 - (WORD)usPosX2); nMajorCoordX = (uHSz>=uVSz); if(nMajorCoordX) { // X length is longer than Y length // YINCR = (EY-SY)/ABS(EX-SX) for (i=0; i<INCR_FRACTION_PART_LENGTH+1; i++) { uVSz <<= 1; nIncr <<= 1; if (uVSz >= uHSz) { nIncr = nIncr | 1; uVSz -= uHSz; } } nIncr = (nIncr + 1) >> 1; if (usPosY1 > usPosY2) { nIncr = (~nIncr) + 1; // 2's complement } RETAILMSG(DISP_ZONE_LINE, (TEXT("YINCR: %x "), nIncr )); } else { // Y length is longer than Y length // XINCR = (EX-SX)/ABS(EY-SY) for (i=0; i<INCR_FRACTION_PART_LENGTH+1; i++)
// Set alpha blending mode void FIMGSE2D::SetAlphaMode(G2D_ALPHA_BLENDING_MODE eMode) { RequestEmptyFifo(1); /* DWORD uAlphaBlend; uAlphaBlend = (eMode == G2D_NO_ALPHA_MODE) ? G2D_NO_ALPHA_BIT : (eMode == G2D_PP_ALPHA_SOURCE_MODE) ? G2D_PP_ALPHA_SOURCE_BIT : (eMode == G2D_ALPHA_MODE) ? G2D_ALPHA_BIT : (eMode == G2D_FADING_MODE) ? G2D_FADING_BIT : G2D_NO_ALPHA_BIT; */ m_pG2DReg->ROP = (m_pG2DReg->ROP & ~(0x7<<10)) | eMode;//AlphaBlend; }
/** * @fn void RegCtrlG2D::Set3rdOperand(G2D_OPERAND3 e3rdOp) * @brief Set thrid operand as Pattern or Foreground color * @param e3rdOp can be pattern or foreground color */ void RegCtrlG2D::Set3rdOperand(G2D_OPERAND3 e3rdOp) { RequestEmptyFifo(1); DWORD u3rdOpSel = (e3rdOp == G2D_OPERAND3_PAT) ? G2D_OPERAND3_PAT_BIT : (e3rdOp == G2D_OPERAND3_FG) ? G2D_OPERAND3_FG_BIT : 0xffffffff; if (u3rdOpSel == 0xffffffff) { RETAILMSG(DISP_ZONE_ERROR, (TEXT("UnSupported Third Operand!\r\n"))); } m_pG2DReg->ROP = ((m_pG2DReg->ROP) & ~(0x1<<13)) | u3rdOpSel; }
void FIMGSE2D::Init() { RequestEmptyFifo(4); /// Font Operation Related m_bIsBitBlt = true; m_bIsScr2Scr = false; DisableEffect(); // Disable per-pixel/per-plane alpha blending and fading SetColorKeyOff(); m_pG2DReg->ALPHA = (FADING_OFFSET_DISABLE | ALPHA_VALUE_DISABLE); m_pG2DReg->ROP = (G2D_OPERAND3_FG_BIT | G2D_NO_ALPHA_MODE | OPAQUE_ENABLE | G2D_ROP_SRC_ONLY); SetRotationOrg(0, 0); m_pG2DReg->ROT_MODE = ROT_0; m_pG2DReg->ALPHA = 0; }
// else '0', Opaque Mode void FIMGSE2D::SetTransparentMode(bool bIsTransparent, COLOR uBsColor) { DWORD uRopRegVal; RequestEmptyFifo(2); uRopRegVal = m_pG2DReg->ROP; uRopRegVal = (bIsTransparent == 1) ? (uRopRegVal | G2D_TRANSPARENT_BIT) : (uRopRegVal & ~(G2D_TRANSPARENT_BIT)); m_pG2DReg->ROP = uRopRegVal; // register Blue Screen Color m_pG2DReg->BS_COLOR = uBsColor; }
/* * @fn void RegCtrlG2D::SetFirstBitBLTData(DWORD uFirstData) * @brief Set First Source Data to FIMG2D HW Register using CMD register 2, Next Data must be issued by CMD Register 3 continously * @param uFirstData 32bit surface Surface data */ void RegCtrlG2D::SetFirstBitBLTData(DWORD uFirstData) { RequestEmptyFifo(1); m_pG2DReg->CMDR2 = uFirstData; }
/** * @fn void RegCtrlG2D::SetRoptype(DWORD uRopVal) * @note Set Ternary Raster Operation into G2D register directly */ void RegCtrlG2D::SetRopValue(DWORD uRopVal) { RequestEmptyFifo(1); m_pG2DReg->ROP = ((m_pG2DReg->ROP)&(~0xff)) | uRopVal; DEBUGMSG(DISP_ZONE_TEMP,(TEXT("ROPRegAddr : 0x%x, ROP : 0x%x\r\n"),&(m_pG2DReg->ROP), uRopVal)); }
void FIMGSE2D::SetBsColor(DWORD uBsColor) { RequestEmptyFifo(1); uBsColor &= 0x00ffffff; //< Remove Alpha value m_pG2DReg->BS_COLOR = uBsColor; }
void RegCtrlG2D::SetRotationOrgY(WORD usRotOrgY) { RequestEmptyFifo(1); m_pG2DReg->ROT_OC_Y = (DWORD) (usRotOrgY & 0x000007FF); }
/** * @fn void RegCtrlG2D::SetRotationMode(DWORD uRotationType) * @param uRotationType This is register value for each rotation. It can handle 0, 90, 180, 270, Xflip, Yflip * @note G2D's Rotation Register has only 1 bit as enabling. */ void RegCtrlG2D::SetRotationMode(ROT_TYPE uRotationType) { RequestEmptyFifo(1); m_pG2DReg->ROT_MODE = ((m_pG2DReg->ROT_MODE) & ~0x3f)|(uRotationType); }
/* * @fn void RegCtrlG2D::SetNextBitBLTData(DWORD uFirstData) * @brief Set Next Source Data to FIMG2D HW Register using CMD register 2, Next Data must be issued by CMD Register 3 * @param uNextData 32bit surface Surface data */ void RegCtrlG2D::SetNextBitBLTData(DWORD uNextData) { RequestEmptyFifo(1); m_pG2DReg->CMDR3 = uNextData; }
/** * @fn void RegCtrlG2D::SetEndian(bool bEndian) * @brief Set both Source and Destination data Endian * @param bEndian Endian setting 1: Big Endian, 0: Little Endian */ void RegCtrlG2D::SetEndian(bool bEndian) { RequestEmptyFifo(1); m_pG2DReg->ENDIAN = ( (bEndian<<1) | (bEndian<<0) ); }
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_DEFAULT_RETURN_TYPE); RETAILMSG(DISP_ZONE_ENTER,(TEXT("\n[2DHW] StretchBlt Exit"))); /// TODO: Resource Register clearing can be needed. }