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

📄 fimgse2d.cpp

📁 SMDK2416_BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// 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 + -