📄 fimgse2d.cpp
字号:
//
// Copyright (c) Samsung Electronics. Co. LTD. All rights reserved.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
--*/
/**
* @file fimgse2d.cpp
* @brief hardware control implementation for FIMGSE-2D v2.0, This class is a kind of adapter
* @author Jiwon Kim
*
* @note This version is made for S3C2450.
*/
#include "precomp.h"
#include <nkintr.h>
#include <s3c2450.h>
#include <bsp.h>
#include "fimgse2d.h"
#include "regctrl_g2d.h"
#define HW_PROBE 0
#define ZONE_NONE (0)
#define ZONE_BITBLT (1<<0)
#define ZONE_STRETCHBLT (1<<1)
#define ZONE_LINE (1<<2)
#define ZONE_FLIPBLT (1<<3)
#define ZONE_TEMPORARY (1<<4)
#define DBG_ZONE (ZONE_NONE)//(ZONE_BITBLT)
#define ZONE_CHECK(checkedzone) (((DBG_ZONE&(checkedzone))==(checkedzone)) ? (1) :(0))
#if HW_PROBE // For check HW consume time, insert GPIO LED triggering code.
static volatile S3C2450_IOPORT_REG *g_pGPIORegs = NULL;
#define PROBE_BIT (7)
#define PROBE_TRIGGER_OFF(structure, port) {structure##->##port##DAT &= ~(1<<PROBE_BIT);}
#define PROBE_TRIGGER_ON(structure, port) {structure##->##port##DAT |= (1<<PROBE_BIT);}
#endif
FIMGSE2D::FIMGSE2D() : RegCtrlG2D()
{
// Reset();
m_iROPMapper[ROP_SRC_ONLY] = G2D_ROP_SRC_ONLY;
m_iROPMapper[ROP_PAT_ONLY] = G2D_ROP_PAT_ONLY;
m_iROPMapper[ROP_DST_ONLY] = G2D_ROP_DST_ONLY;
m_iROPMapper[ROP_SRC_OR_DST] = G2D_ROP_SRC_OR_DST;
m_iROPMapper[ROP_SRC_OR_PAT] = G2D_ROP_SRC_OR_PAT;
m_iROPMapper[ROP_DST_OR_PAT] = G2D_ROP_DST_OR_PAT;
m_iROPMapper[ROP_SRC_AND_DST] = G2D_ROP_SRC_AND_DST;
m_iROPMapper[ROP_SRC_AND_PAT] = G2D_ROP_SRC_AND_PAT;
m_iROPMapper[ROP_DST_AND_PAT] = G2D_ROP_DST_AND_PAT;
m_iROPMapper[ROP_SRC_XOR_DST] = G2D_ROP_SRC_XOR_DST;
m_iROPMapper[ROP_SRC_XOR_PAT] = G2D_ROP_SRC_XOR_PAT;
m_iROPMapper[ROP_DST_XOR_PAT] = G2D_ROP_DST_XOR_PAT;
m_iROPMapper[ROP_NOTSRCCOPY] = G2D_ROP_NOTSRCCOPY;
m_iROPMapper[ROP_DSTINVERT] = G2D_ROP_DSTINVERT;
m_iROPMapper[ROP_R2_NOTCOPYPEN] = G2D_ROP_R2_NOTCOPYPEN;
m_iColorModeMapper[gpe1Bpp] = -1;
m_iColorModeMapper[gpe2Bpp] = -1;
m_iColorModeMapper[gpe4Bpp] = -1;
m_iColorModeMapper[gpe8Bpp] = -1;
m_iColorModeMapper[gpe16Bpp] = G2D_COLOR_RGB_565;
m_iColorModeMapper[gpe24Bpp] = G2D_COLOR_XRGB_8888;
m_iColorModeMapper[gpe32Bpp] = -1;
m_iColorModeMapper[gpe16YCrCb] = -1;
m_iColorModeMapper[gpeDeviceCompatible] = -1;
m_iColorModeMapper[gpeUndefined] = G2D_COLOR_UNUSED;
}
FIMGSE2D::~FIMGSE2D()
{
}
// Set Ternary raster operation
// Support 256 raster operation
// Refer to ternary raster operation table if you know 256 ROP
// Set Alpha Value
void FIMGSE2D::SetAlphaValue(BYTE ucAlphaVal)
{
ucAlphaVal &= 0xff;
m_pG2DReg->ALPHA = (m_pG2DReg->ALPHA&(~0xff)) | ucAlphaVal;
}
// Set alpha blending mode
void FIMGSE2D::SetAlphaMode(G2D_ALPHA_BLENDING_MODE eMode)
{
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)) | uAlphaBlend;
}
// Set fade value
void FIMGSE2D::SetFadingValue(BYTE ucFadeVal)
{
ucFadeVal &= 0xff;
m_pG2DReg->ALPHA = (m_pG2DReg->ALPHA & ~(0xff<<8)) | (ucFadeVal<<8);
}
void FIMGSE2D::DisableEffect(void)
{
m_pG2DReg->ROP &= ~(0x7<<10);
}
void FIMGSE2D::EnablePlaneAlphaBlending(BYTE ucAlphaVal)
{
ucAlphaVal &= 0xff;
// Set Alpha Blending Mode
m_pG2DReg->ROP = ((m_pG2DReg->ROP) & ~(0x7<<10)) | G2D_ALPHA_BIT;
// Set Alpha Value
m_pG2DReg->ALPHA = ((m_pG2DReg->ALPHA) & ~(0xff)) | ucAlphaVal;
m_ucAlphaVal = ucAlphaVal;
m_bIsAlphaCall = true;
}
void FIMGSE2D::DisablePlaneAlphaBlending(void)
{
DisableEffect();
}
void FIMGSE2D::EnablePixelAlphaBlending(void) // Only Support 24bpp and Only used in BitBlt
{
Assert( (m_iColorModeMapper[m_descDstSurface.dwColorMode] != -1) && (m_iColorModeMapper[m_descDstSurface.dwColorMode] != gpe24Bpp) );
m_pG2DReg->ROP = ((m_pG2DReg->ROP) & ~(0x7<<10)) | G2D_PP_ALPHA_SOURCE_BIT;
}
void FIMGSE2D::DisablePixelAlphaBlending(void) // Only Support 24bpp and only used in BitBlt
{
Assert( (m_iColorModeMapper[m_descDstSurface.dwColorMode] != -1) && (m_iColorModeMapper[m_descDstSurface.dwColorMode] != gpe24Bpp) );
DisableEffect();
}
void FIMGSE2D::EnableFadding(BYTE ucFadingVal)
{
BYTE ucAlphaVal;
ucAlphaVal = (m_bIsAlphaCall == true) ? m_ucAlphaVal : 255;
ucFadingVal &= 0xff;
// Set Fadding Mode
m_pG2DReg->ROP = ((m_pG2DReg->ROP) & ~(0x7<<10)) | G2D_FADING_BIT;
// Set Fadding Value
m_pG2DReg->ALPHA = ((m_pG2DReg->ALPHA) & ~(0xff<<8)) | (ucFadingVal<<8) | (ucAlphaVal<<0);
}
void FIMGSE2D::DisableFadding(void)
{
DisableEffect();
}
/**
* @fn FIMGSE2D::GetRotType(int m_iRotate)
* @brief This function convert rotation degree value to ROT_TYPE
*
*/
ROT_TYPE FIMGSE2D::GetRotType(int m_iRotate)
{
switch(m_iRotate)
{
case DMDO_0:
return ROT_0;
case DMDO_90:
return ROT_270;
case DMDO_180:
return ROT_180;
case DMDO_270:
return ROT_90;
default:
return ROT_0;
}
return ROT_0;
}
/**
* @fn DWORD FIMGSE2D::CalculateXYIncrFormat(DWORD uDividend, DWORD uDivisor)
* @brief This function returns x_incr or y_incr vaule in register format
* @input this function accept real pixel coordinate, ex) (0,0)~(9,9) means that 10pixel by pixel image
* @return Result value
*/
DWORD FIMGSE2D::CalculateXYIncrFormat(DWORD uDividend, DWORD uDivisor)
{
int i;
DWORD uQuotient;
DWORD uUnderPoint=0;
printf("\nuDivend:%x(%d), uDivisor:%x(%d), uUnderPoint:%x(%d)", uDividend, uDividend, uDivisor, uDivisor,uUnderPoint, uUnderPoint);
Assert(uDivisor != 0);
if(uDivisor == 0)
{
uDivisor = 1; //< this will prevent data abort. but result is incorrect.
}
uQuotient = (DWORD)(uDividend/uDivisor);
Assert(uQuotient <= 2048); // Quotient should be less than 2048.
uDividend-=(uQuotient*uDivisor);
/// Now under point is calculated.
for (i=0; i<12; i++)
{
uDividend <<= 1;
uUnderPoint <<= 1;
if (uDividend >= uDivisor)
{
uUnderPoint = uUnderPoint | 1;
uDividend -= uDivisor;
}
printf("\nuDivend:%x(%d), uDivisor:%x(%d), uUnderPoint:%x(%d)", uDividend, uDividend, uDivisor, uDivisor,uUnderPoint, uUnderPoint);
}
uUnderPoint = (uUnderPoint + 1 )>> 1;
// uUnderPoint = ~uUnderPoint + 1 ;
return ( uUnderPoint|(uQuotient<<11) );
}
/**
* @fn FIMGSE2D::BitBlt(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 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
@ @sa ROT_TYPE this can be set mixed value.
*/
void FIMGSE2D::BitBlt(PRECTL prclSrc, PRECTL prclDst, ROT_TYPE m_iRotate )
{
DWORD uCmdRegVal=0;
RECT rectDst; //< If rotation case this value must be corrected.
RETAILMSG(ZONE_CHECK(ZONE_BITBLT),(TEXT("[2DHW] BitBlt Entry\r\n")));
/// Set Destination's Rotation mode
SetRotationMode(m_iRotate);
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;
}
SetRotationOrg((WORD)rectDst.left, (WORD)rectDst.top);
SetCoordinateDstBlock(rectDst.left, rectDst.top, rectDst.right, rectDst.bottom);
RETAILMSG(ZONE_CHECK(ZONE_BITBLT),(TEXT("ROT:%d, Src:(%d,%d)~(%d,%d), Dst:(%d,%d)~(%d,%d)\r\n"),
m_iRotate, prclSrc->left, prclSrc->top, prclSrc->right, prclSrc->bottom,
rectDst.left, rectDst.top, rectDst.right, rectDst.bottom));
uCmdRegVal = G2D_NORMAL_BITBLT_BIT;
// WaitForIdleStatus(); //< When only Engine is idle, 2D Engine runs.
#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
RETAILMSG(TRUE,(TEXT("CMDPROCESSING TYPE is invalid, Please Check Header Definition\n")));
return FALSE;
#endif
RETAILMSG(ZONE_CHECK(ZONE_BITBLT),(TEXT("[2DHW] BitBlt Exit\r\n")));
/// TODO: Resource Register clearing can be needed.
}
/**
* @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(ZONE_CHECK(ZONE_STRETCHBLT),(TEXT("[2DHW] StretchBlt Entry\r\n")));
/// 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) )
{
if(usSrcWidth == usDstHeight && usSrcHeight == usDstWidth)
{
RETAILMSG(TRUE, (TEXT("This is not stretch or shrink BLT, redirect to BitBlt, R:%d\n"), m_iRotate));
BitBlt(prclSrc, prclDst, m_iRotate);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -