📄 fimgse2d.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHESetColorKeyOffR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name: FIMGSE2D.cpp
Abstract: hardware control implementation for S3C6400 FIMGSE-2D
Functions:
Notes:
--*/
#include <windows.h>
#include <winddi.h>
#include <emul.h>
#include <ceddk.h>
#include "fimgse2d.h"
#include "regctrl_g2d.h"
#define HW_PROBE 0
#if HW_PROBE // For check HW consume time, insert GPIO LED triggering code.
#include <s3c6400.h>
#include <DrvLib.h>
static volatile S3C6400_GPIO_REG *g_pGPIORegs = NULL;
#endif
volatile bool bG2dDone;
volatile unsigned uIntCnt;
DWORD FillBitResidue[32] = {0x00000000, 0x80000000, 0xC0000000, 0xE0000000, 0xF0000000,
0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000,
0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000,
0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000,
0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000,
0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00,
0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0,
0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE}; // 0~31
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;
}
FIMGSE2D::~FIMGSE2D()
{
}
void FIMGSE2D::Reset(void)
{
m_pG2DReg->CONTROL = 1; //assert G2D reset
m_pG2DReg->CONTROL = 0; //deassert G2D reset
}
void FIMGSE2D::WaitForIdleStatus(void)
{
while(!(m_pG2DReg->FIFO_STATUS & G2D_DE_STATUS_FA_BIT));
}
void FIMGSE2D::CheckFifo(DWORD uEmptyFifo)
{
while( ((m_pG2DReg->FIFO_STATUS)&0x3f) > (FIFO_NUM - uEmptyFifo) );
}
// 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_eBpp == RGB24);
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_eBpp == RGB24);
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();
}
void FIMGSE2D::SetRotationOrgX(WORD usRotOrgX)
{
m_pG2DReg->ROT_OC_X = (DWORD) (usRotOrgX & 0x000007FF);
}
void FIMGSE2D::SetRotationOrgY(WORD usRotOrgY)
{
m_pG2DReg->ROT_OC_Y = (DWORD) (usRotOrgY & 0x000007FF);
}
// Clear Frame irrelevant to clipping window size
// Draw Pixel
void FIMGSE2D::SetXYIncrFormat(DWORD uDividend, DWORD uDivisor, DWORD* uResult)
{
int i;
DWORD uQuotient;
DWORD uUnderPoint=0;
Assert(uDivisor != 0);
uQuotient = (DWORD)(uDividend/uDivisor);
Assert(uQuotient <= 2048); // Quotient should be less than 2048.
uDividend-=(uQuotient*uDivisor);
for (i=0; i<12; i++)
{
uDividend <<= 1;
uUnderPoint <<= 1;
if (uDividend >= uDivisor)
{
uUnderPoint = uUnderPoint | 1;
uDividend -= uDivisor;
}
}
uUnderPoint = (uUnderPoint + 1) >> 1;
*uResult = uUnderPoint|(uQuotient<<11);
}
void FIMGSE2D::BitBlt(WORD usSrcStX, WORD usSrcStY, WORD usSrcEndX, WORD usSrcEndY,
WORD usDstStX, WORD usDstStY, WORD usDstEndX, WORD usDstEndY)
{
DWORD uCmdRegVal=0;
// Check boundary of X coordiante
Assert( (usSrcStX >= m_uCwX1)&&(usSrcEndX >= m_uCwX1) );
// Coordinate X of source image or destination image should be less than that of clipping window.
Assert( ((WORD)(usSrcEndX-1) <= m_uCwX2)&&((WORD)(usDstEndX-1) <= m_uCwX2) );
// Check boundary of Y coordinate
Assert( (usSrcStY >= m_uCwY1)&&(usSrcEndY >= m_uCwY1) );
// Coordinate Y of source image or destination image should be less than that of clipping window.
Assert( ((WORD)(usSrcEndY-1) <= m_uCwY2)&&((WORD)(usDstEndY-1) <= m_uCwY2) );
#if 0
RETAILMSG(1,(TEXT("Src:(%d,%d)~(%d,%d), Dst:(%d,%d)~(%d,%d), Boundary:(%d,%d)~(%d,%d)\r\n"), usSrcStX, usSrcStY, usSrcEndX, usSrcEndY,
usDstStX, usDstStY, usDstEndX, usDstEndY, m_uCwX1, m_uCwY1, m_uCwX2, m_uCwY2));
#endif
InterruptEnable();
SetCoordinateSrcBlock(usSrcStX, usSrcStY, usSrcEndX - 1, usSrcEndY - 1);
SetCoordinateDstBlock(usDstStX, usDstStY, usDstEndX - 1, usDstEndY - 1);
// uCmdRegVal = m_pG2DReg->CMDR1; // Write Only
// uCmdRegVal &= ~(0x3<<0);
uCmdRegVal = G2D_NORMAL_BITBLT_BIT;
CheckFifo(1);
#if HW_PROBE // For check HW consume time, insert GPIO LED triggering code.
g_pGPIORegs->GPNDAT |= (1<<13);
#endif
m_pG2DReg->CMDR1 = uCmdRegVal; // One Instruction
#ifdef PROFILE
StartTimer();
#endif
while(!WaitForFinish());
#if HW_PROBE // For check HW consume time, insert GPIO LED triggering code.
g_pGPIORegs->GPNDAT &= ~(1<<13);
#endif
InterruptDisable();
SetRopEtype(ROP_SRC_ONLY);
// InterruptPendingClear();
}
#if 1
// Support X only, Y only flipping
// Support Free scale Stretch
void FIMGSE2D::StretchBlt(WORD usSrcStX, WORD usSrcStY, WORD usSrcEndX, WORD usSrcEndY,
WORD usDstStX, WORD usDstStY, WORD usDstEndX, WORD usDstEndY)
{
WORD usSrcWidth, usSrcHeight;
WORD usDstWidth, usDstHeight;
DWORD uXYIncr;
DWORD uCmdRegVal=0;
// Check boundary of X coordiante
// Assert( (usSrcStX >= m_uCwX1)&&(usSrcEndX >= m_uCwX1) );
// Coordinate X of source image or destination image should be less than that of clipping window.
// Assert( (usSrcEndX <= m_uCwX2)&&(usDstEndX <= m_uCwX2) );
// Check boundary of Y coordinate
// Assert( (usSrcStY >= m_uCwY1)&&(usSrcEndY >= m_uCwY1) );
// Coordinate Y of source image or destination image should be less than that of clipping window.
// Assert( (usSrcEndY <= m_uCwY2)&&(usDstEndY <= m_uCwY2) );
#if 0
RETAILMSG(1,(TEXT("Src:(%d,%d)~(%d,%d), Dst:(%d,%d)~(%d,%d), Boundary:(%d,%d)~(%d,%d)\r\n"), usSrcStX, usSrcStY, usSrcEndX, usSrcEndY,
usDstStX, usDstStY, usDstEndX, usDstEndY, m_uCwX1, m_uCwY1, m_uCwX2, m_uCwY2));
#endif
if((usDstEndX < usDstStX) && (usDstEndY < usDstEndY) )
{
printf("X and Y flipping is not supported.\n");
}
// Flipping(Mirroring)
if(usDstEndX < usDstStX) // Y-axis flipping
{
RETAILMSG(1,(TEXT("y-axis flip")));
m_pG2DReg->ROT_MODE = G2D_Y_FLIP;
SetRotationOrg(usDstStX + usDstWidth/2, usDstStY + usDstHeight/2); //Org must be center position in image
}
else if(usDstEndY < usDstStY) // X-axis flipping
{
RETAILMSG(1,(TEXT("x-axis flip")));
m_pG2DReg->ROT_MODE = G2D_X_FLIP;
SetRotationOrg(usDstStX + usDstWidth/2, usDstStY + usDstHeight/2); //Org must be center position in image
}
SetCoordinateSrcBlock(usSrcStX, usSrcStY, usSrcEndX - 1, usSrcEndY - 1);
SetCoordinateDstBlock(usDstStX, usDstStY, usDstEndX - 1, usDstEndY - 1);
// Stretch ratio calculation
usSrcWidth=ABS(usSrcStX-usSrcEndX); // width and height is not include last line
usDstWidth=ABS(usDstStX-usDstEndX);
usSrcHeight=ABS(usSrcStY-usSrcEndY);
usDstHeight=ABS(usDstStY-usDstEndY);
// printf("srcWidth : %d, DstWidth : %d, SrcHeight : %d, DstHeight : %d\n", usSrcWidth, usDstWidth, usSrcHeight, usDstHeight);
SetXYIncrFormat(usSrcWidth, usDstWidth, &uXYIncr);
m_pG2DReg->X_INCR = uXYIncr;
printf("x_incr : %x\n", uXYIncr);
SetXYIncrFormat(usSrcHeight, usDstHeight, &uXYIncr);
m_pG2DReg->Y_INCR = uXYIncr;
printf("y_incr : %x\n", uXYIncr);
// uCmdRegVal = m_pG2DReg->CMDR1; // Write Only
// uCmdRegVal &= ~(0x3<<0);
uCmdRegVal = ((usSrcWidth == usDstWidth) && (usSrcHeight == usDstHeight)) ? G2D_NORMAL_BITBLT_BIT : G2D_STRETCH_BITBLT_BIT;
CheckFifo(1);
InterruptEnable();
m_pG2DReg->CMDR1 = uCmdRegVal; // One Instruction
#ifdef PROFILE
StartTimer();
#endif
while(!WaitForFinish());
InterruptDisable();
// Resource Register Clear
SetRotationOrg(0,0);
m_pG2DReg->ROT_MODE = G2D_ROTATION_0_DEG_BIT;
SetRopEtype(ROP_SRC_ONLY);
// InterruptPendingClear();
}
#endif
#if 0
void FIMGSE2D::StretchBlt(WORD usSrcStX, WORD usSrcStY, WORD usSrcEndX, WORD usSrcEndY,
WORD usDstStX, WORD usDstStY, WORD usDstEndX, WORD usDstEndY)
{
WORD usSrcWidth, usSrcHeight;
WORD usDstWidth, usDstHeight;
DWORD uXYIncr;
DWORD uCmdRegVal=0;
WORD FlipFlag=0;
// Check boundary of X coordiante
// Assert( (usSrcStX >= m_uCwX1)&&(usSrcEndX >= m_uCwX1) );
// Coordinate X of source image or destination image should be less than that of clipping window.
// Assert( (usSrcEndX <= m_uCwX2)&&(usDstEndX <= m_uCwX2) );
// Check boundary of Y coordinate
// Assert( (usSrcStY >= m_uCwY1)&&(usSrcEndY >= m_uCwY1) );
// Coordinate Y of source image or destination image should be less than that of clipping window.
// Assert( (usSrcEndY <= m_uCwY2)&&(usDstEndY <= m_uCwY2) );
#if 1
RETAILMSG(1,(TEXT("Src:(%d,%d)~(%d,%d), Dst:(%d,%d)~(%d,%d), Boundary:(%d,%d)~(%d,%d)\r\n"), usSrcStX, usSrcStY, usSrcEndX, usSrcEndY,
usDstStX, usDstStY, usDstEndX, usDstEndY, m_uCwX1, m_uCwY1, m_uCwX2, m_uCwY2));
#endif
// Flipping(Mirroring)
if(usDstEndX < usDstStX) // Y-axis flipping
{
WORD temp;
RETAILMSG(1,(TEXT("y-axis flip")));
FlipFlag |= G2D_Y_FLIP;
temp = usDstStX;
usDstStX = usDstEndX; // last line is not drawing.
usDstEndX = temp;
}
if(usDstEndY<usDstStY) // X-axis flipping
{
WORD temp;
RETAILMSG(1,(TEXT("x-axis flip")));
FlipFlag |= G2D_X_FLIP;
temp = usDstStY;
usDstStY = usDstEndY; // last line is not drawing.
usDstEndY = temp;
}
SetCoordinateSrcBlock(usSrcStX, usSrcStY, usSrcEndX - 1, usSrcEndY - 1);
SetCoordinateDstBlock(usDstStX, usDstStY, usDstEndX - 1, usDstEndY - 1);
#if 1
RETAILMSG(1,(TEXT("Src:(%d,%d)~(%d,%d), Dst:(%d,%d)~(%d,%d), Boundary:(%d,%d)~(%d,%d)\r\n"), usSrcStX, usSrcStY, usSrcEndX, usSrcEndY,
usDstStX, usDstStY, usDstEndX, usDstEndY, m_uCwX1, m_uCwY1, m_uCwX2, m_uCwY2));
#endif
// Stretch ratio calculation
usSrcWidth=ABS(usSrcStX-usSrcEndX); // width and height is not include last line
usDstWidth=ABS(usDstStX-usDstEndX);
usSrcHeight=ABS(usSrcStY-usSrcEndY);
usDstHeight=ABS(usDstStY-usDstEndY);
printf("srcWidth : %d, DstWidth : %d, SrcHeight : %d, DstHeight : %d\n", usSrcWidth, usDstWidth, usSrcHeight, usDstHeight);
SetXYIncrFormat(usSrcWidth, usDstWidth, &uXYIncr);
m_pG2DReg->X_INCR = uXYIncr;
printf("x_incr : %x\n", uXYIncr);
SetXYIncrFormat(usSrcHeight, usDstHeight, &uXYIncr);
m_pG2DReg->Y_INCR = uXYIncr;
printf("y_incr : %x\n", uXYIncr);
// uCmdRegVal = m_pG2DReg->CMDR1; // Write Only
// uCmdRegVal &= ~(0x3<<0);
uCmdRegVal = ((usSrcWidth == usDstWidth) && (usSrcHeight == usDstHeight)) ? G2D_NORMAL_BITBLT_BIT : G2D_STRETCH_BITBLT_BIT;
CheckFifo(1);
// printf("uCmdRegVal: %x",uCmdRegVal);
InterruptEnable();
m_pG2DReg->CMDR1 = uCmdRegVal; // One Instruction
#ifdef PROFILE
StartTimer();
#endif
while(!WaitForFinish());
InterruptDisable();
// Flipping(Mirroring)
if((FlipFlag & G2D_Y_FLIP)) // Y-axis flipping
{
// Filpping Original Coordinate
// x : -dcx + 2ox
// ox = (translated dest x + original dest x)/2
// y = original dest y
// oy = not used. default 0
SetRotationOrg(usDstStX + usDstWidth/2, usDstStY + usDstHeight/2); //Org must be center position in image
m_pG2DReg->ROT_MODE = G2D_Y_FLIP;
SetCoordinateSrcBlock(usDstStX, usDstStY, usDstEndX - 1, usDstEndY - 1);
SetCoordinateDstBlock(usDstStX, usDstStY, usDstEndX - 1, usDstEndY - 1);
SetRopEtype(ROP_SRC_ONLY);
CheckFifo(1);
InterruptEnable();
m_pG2DReg->CMDR1 = G2D_NORMAL_BITBLT_BIT; // One Instruction
while(!WaitForFinish());
InterruptDisable();
}
if((FlipFlag & G2D_X_FLIP)) // X-axis flipping
{
// Filpping Original Coordinate
// x : dcx
// ox = not used. default 0
// y = -dcy + 2oy
// oy = (translated dest y + original dest y)/2
SetRotationOrg(usDstStX + usDstWidth/2, usDstStY + usDstHeight/2);
m_pG2DReg->ROT_MODE = G2D_X_FLIP;
SetCoordinateSrcBlock(usDstStX, usDstStY, usDstEndX - 1, usDstEndY - 1);
SetCoordinateDstBlock(usDstStX, usDstStY, usDstEndX - 1, usDstEndY - 1);
SetRopEtype(ROP_SRC_ONLY);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -