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

📄 blt.cpp

📁 SMDK2416_BSP
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	/// 4. Do HW Bitblt

	CopyRect(&rectlSrcBackup, (LPRECT)pBltParms->prclSrc);
	/// Set Source Surface Information
	/// If using PLA control for surface in virtual address, use PLA
	if((pBltParms->pSrc)->InVideoMemory() )	{
		descSrcSurface.dwBaseaddr = IMAGE_FRAMEBUFFER_DMA_BASE + pBltParms->pSrc->OffsetInVideoMemory();
		descSrcSurface.dwVertRes = (pBltParms->pSrc->ScreenHeight() != 0 ) ? pBltParms->pSrc->ScreenHeight() : pBltParms->pSrc->Height();			
	} 
	else {
		dwTopStrideStartAddr = m_dwSourceSurfacePA + pBltParms->prclSrc->top * pBltParms->pSrc->Stride();
		descSrcSurface.dwBaseaddr = dwTopStrideStartAddr;
		descSrcSurface.dwVertRes = pBltParms->prclSrc->bottom - pBltParms->prclSrc->top;

		pBltParms->prclSrc->top = 0;
		pBltParms->prclSrc->bottom = descSrcSurface.dwVertRes;
	}

	/// Set Destination Surface Information
	descDstSurface.dwBaseaddr = (IMAGE_FRAMEBUFFER_DMA_BASE + (( S3C2450Surf *)(pBltParms->pDst))->OffsetInVideoMemory());
	descDstSurface.dwColorMode = pBltParms->pDst->Format();
	descDstSurface.dwHoriRes = pBltParms->pDst->Stride()/ (EGPEFormatToBpp[pBltParms->pDst->Format()]/8);
	descDstSurface.dwVertRes = pBltParms->pDst->ScreenHeight();	

	/// Transparency does not relate with alpha blending
	m_oG2D->SetAlphaMode(G2D_NO_ALPHA_MODE);
	/// No transparecy with alphablend
	m_oG2D->SetAlphaValue(0xff);
	m_oG2D->Set3rdOperand(G2D_OPERAND3_PAT);

	/// Real Register Surface Description setting will be done in HWBitBlt
	bHWSuccess = HWBitBlt(pBltParms, &descSrcSurface, &descDstSurface);

	CopyRect((LPRECT)pBltParms->prclSrc, &rectlSrcBackup);

	 if(pBltParms->pDst->IsRotate())
	 {
		RotateRectlBack(prclDst);
		if(pBltParms->prclClip)
		{
			RotateRectlBack(pBltParms->prclClip);
		}		
	 }
	 if(pBltParms->pSrc->IsRotate())
	 {
		RotateRectlBack(prclSrc);
	 }		 
	if (pBltParms->bltFlags & BLT_TRANSPARENT)
	{
		m_oG2D->SetTransparentMode(0, pBltParms->solidColor);			// turn off Transparency
	}
	if(!bHWSuccess)
	{	
		return EmulatedBlt(pBltParms);
	}

	return	S_OK;
}
#endif
#if (BSP_TYPE == BSP_SMDK2450)
/**
*	@fn		void S3C2450Disp::HWBitBlt(GpeBltParms *pBltParms)
*	@brief	Check Further Optional processing. This is intemediate layer between display driver and 2D driver
*	@param	pBltParms	Blit Parameter Information Structure
*	@sa		GPEBltParms
*	@note	currently support only rotation
*	@note	DMDO_0	= 0, DMDO_90 = 1, DMDO_180 = 2, DMDO_270 = 4
*/
BOOL S3C2450DISP::HWBitBlt(GPEBltParms *pBltParms, PSURFACE_DESCRIPTOR pdescSrcSurface, PSURFACE_DESCRIPTOR pdescDstSurface)
{
	PRECTL prclSrc;		//< Src is already rotated.
	PRECTL prclDst;		//< Dst is already rotated.
	RECT     rectlPhySrc;		//< If screen is rotated, this value has RotateRectl(prclSrc), physically addressed coordinate.
	RECT	rectlPhyDst;		//< If screen is rotated, this value has RotateRectl(prclDst), physically addressed coordinate.
	
	prclSrc = pBltParms->prclSrc;
	prclDst = pBltParms->prclDst;

	CopyRect(&rectlPhySrc, (LPRECT)prclSrc);
	CopyRect(&rectlPhyDst, (LPRECT)prclDst);
	
	int	iRotate = DMDO_0;

#if 0 
	if(pBltParms->prclClip)
	{
	RETAILMSG(0,(TEXT("ClipWindow set, prclClip: 0x%x, Cl:%d, Ct:%d, Cr:%d, Cb:%d\r\n"), pBltParms->prclClip,
		(pBltParms->prclClip ? pBltParms->prclClip->left : 0),
		(pBltParms->prclClip ? pBltParms->prclClip->top : 0),
		(pBltParms->prclClip ? pBltParms->prclClip->right : 0),
		(pBltParms->prclClip ? pBltParms->prclClip->bottom : 0)
		));			
		m_oG2D->SetClipWindow(pBltParms->prclClip);
	}
	else
	{
	RETAILMSG(0,(TEXT("ClipWindow set, prclDst: 0x%x, Cl:%d, Ct:%d, Cr:%d, Cb:%d\r\n"), pBltParms->prclDst,
		(pBltParms->prclDst ? pBltParms->prclDst->left : 0),
		(pBltParms->prclDst ? pBltParms->prclDst->top : 0),
		(pBltParms->prclDst ? pBltParms->prclDst->right : 0),
		(pBltParms->prclDst ? pBltParms->prclDst->bottom : 0)
		));						
		m_oG2D->SetClipWindow(prclDst);
	}	
#endif
	

	/// OnScreen Case
	if(pBltParms->pSrc == pBltParms->pDst)
	{
		iRotate = DMDO_0;
	}
	/// OffScreen Case
	else		
	{
		/// this code assume that source surface is always DMDO_0
		iRotate =	pBltParms->pDst->Rotate();
	}


#define SWAP(x,y, _type)  { _type i; i = x; x = y; y = i; }		
	RETAILMSG(0,(TEXT("HWBitBlt Src(%d,%d)~(%d,%d), Dst(%d,%d)~(%d,%d)\n"),
		prclSrc->left, prclSrc->top, prclSrc->right, prclSrc->bottom,
		prclDst->left, prclDst->top, prclDst->right, prclDst->bottom));
	RotateRectlBack(prclSrc);
	RotateRectlBack(prclDst);	
	/// if Stretch option is set, run StretchBlt
	/// if StretchBlt is on, but source region and destination region are same. use BitBlt
	if(((pBltParms->bltFlags & BLT_STRETCH) == BLT_STRETCH) 
		//< If Does not need to stretch or shrink. just BitBlt is faster.
		&&	ABS(prclSrc->right - prclSrc->left) != ABS(prclDst->right - prclDst->left)		
		&&	ABS(prclSrc->bottom - prclSrc->top) != ABS(prclDst->bottom - prclDst->top)
		)
	{
		RotateRectl(prclSrc);
		RotateRectl(prclDst);		
		RECTL t_rect;
		DWORD	dwSrcWidth;
		DWORD	dwSrcHeight;
		SURFACE_DESCRIPTOR descScratch;

		dwSrcWidth = ABS(prclSrc->right - prclSrc->left);
		dwSrcHeight  = ABS(prclSrc->bottom - prclSrc->top);

		/// Set Scratch Destination Region
		t_rect.left = 0;
		t_rect.top = 0;
		t_rect.right = dwSrcWidth;
		t_rect.bottom = dwSrcHeight;
#if 1
	RETAILMSG(TEMP_DEBUG,(TEXT("t_rect,realstretch: (%d,%d)~(%d,%d), R:%d\r\n"), 
		t_rect.left,		t_rect.top,		t_rect.right,		t_rect.bottom, iRotate		));
#endif
#if TEMP_DEBUG
	if(pBltParms->pSrc)
	{
	RETAILMSG(TEMP_DEBUG,(TEXT("Src:0x%x SrcB 0x%x, Surf(W:%d,H:%d,BPP:%d,STRIDE:%d), Screen(W:%d,H:%d), rect: (%d,%d)~(%d,%d), R:%d\r\n"), 
		pBltParms->pSrc,
		pBltParms->pSrc->Buffer(),
		pBltParms->pSrc->Width(),
		pBltParms->pSrc->Height(),
		EGPEFormatToBpp[pBltParms->pSrc->Format()],
		pBltParms->pSrc->Stride(),
		pBltParms->pSrc->ScreenWidth(),
		pBltParms->pSrc->ScreenHeight(),
		pBltParms->prclSrc->left,
		pBltParms->prclSrc->top,
		pBltParms->prclSrc->right,
		pBltParms->prclSrc->bottom,
		pBltParms->pSrc->Rotate()
		));
	}
	if(pBltParms->pDst)
	{
	RETAILMSG(TEMP_DEBUG,(TEXT("Dst:0x%x DstB 0x%x,  Surf(W:%d,H:%d,BPP:%d,STRIDE:%d), Screen(W:%d,H:%d), rect: (%d,%d)~(%d,%d), R:%d\r\n"), 
		pBltParms->pDst,
		pBltParms->pDst->Buffer(),
		pBltParms->pDst->Width(),
		pBltParms->pDst->Height(),
		EGPEFormatToBpp[pBltParms->pDst->Format()],
		pBltParms->pDst->Stride(),		
		pBltParms->pDst->ScreenWidth(),
		pBltParms->pDst->ScreenHeight(),
		pBltParms->prclDst->left,
		pBltParms->prclDst->top,
		pBltParms->prclDst->right,
		pBltParms->prclDst->bottom,
		pBltParms->pDst->Rotate()
		));									
	}
	RETAILMSG(TEMP_DEBUG, (TEXT("ROP : 0x%0x\r\n"), pBltParms->rop4));				
	RETAILMSG(TEMP_DEBUG, (TEXT("xPositive : %d\r\n"),pBltParms->xPositive));
	RETAILMSG(TEMP_DEBUG, (TEXT("yPositive : %d\r\n"),pBltParms->yPositive));	
#endif			
		/// Set Source Surface Descriptor 
		m_oG2D->SetSrcSurface(pdescSrcSurface);	

		/// Check whether XY flip or not, 
		///if XY flip is requested, just Rotation 180 degree
		RotateRectlBack(prclDst);
		if( (prclDst->right < prclDst->left)  && (prclDst->bottom < prclDst->top) )
		{
			RotateRectl(prclDst);		
			switch(iRotate)
			{
				case DMDO_0:
					iRotate = DMDO_180;
					break;
				case DMDO_90:
					iRotate = DMDO_270;
					break;
				case DMDO_180:
					iRotate = DMDO_0;
					break;
				case DMDO_270:
					iRotate = DMDO_90;
					break;
			}

			/// Set Destination Surface to real Framebuffer Surface
			m_oG2D->SetDstSurface(pdescDstSurface);
			
			/// SWAP rect
			SWAP(prclDst->top, prclDst->bottom, LONG);
			SWAP(prclDst->left, prclDst->right, LONG);			
			/// Set Destination Clipping window Rect
			if(pBltParms->prclClip)
			{
				m_oG2D->SetClipWindow(pBltParms->prclClip);
			}
			else
			{
				m_oG2D->SetClipWindow(prclDst);
			}	
					
			EnterCriticalSection(&m_cs2D);	
			m_oG2D->StretchBlt( prclSrc, prclDst, m_oG2D->GetRotType(iRotate));
			LeaveCriticalSection(&m_cs2D);				
			/// Recover rect
			SWAP(prclDst->top, prclDst->bottom, LONG);
			SWAP(prclDst->left, prclDst->right, LONG);			

			RotateRectl(prclDst);
			
			return TRUE;
			
		}
		RotateRectl(prclDst);		

		
		/// Reconfigure HW to set destination framebuffer address as Scratch Framebuffer
		
		/// Check mirror case, and reset region rectangle
		/// Doing FlipBlt from Source to Sratch
		/// In mirror case, source region does not change.
		/// only destination's regions has reverse coordinate, this cannot be negative.
		if(iRotate == DMDO_90 || iRotate == DMDO_270)
		{	
			RotateRectlBack(prclDst);
		 	if(prclDst->right < prclDst->left)
			{
				RotateRectl(prclDst);
				/// Allocation Scratch Framebuffer for Flip Operation.
				DDGPESurf *ScratchSurf;
				
				AllocSurface(&ScratchSurf, dwSrcWidth, dwSrcHeight, pBltParms->pDst->Format(), EGPEFormatToEDDGPEPixelFormat[pBltParms->pDst->Format()], GPE_REQUIRE_VIDEO_MEMORY);
				if(ScratchSurf == NULL)
				{
					RETAILMSG(TRUE,(TEXT("Scratch Surface Allocation is failed. %d\n"), __LINE__));
#if 0//USE_PACSURF, To increase video memory is better than to use system memory as Video Surface
					RETAILMSG(TRUE,(TEXT("try to allocate surface usign PA Surface\r\n")));
					PACSurf *ScratchSurf;
#endif
					RETAILMSG(TRUE,(TEXT("Maybe There's no sufficient video memory. please increase video memory\r\n")));
					RETAILMSG(TRUE,(TEXT("try to redirect to SW Emulated Bitblt\r\n")));		
					return FALSE;
				}
				

				/// Set Scratch Surface Information
				descScratch.dwBaseaddr = (IMAGE_FRAMEBUFFER_DMA_BASE + ScratchSurf->OffsetInVideoMemory());
				RETAILMSG(TEMP_DEBUG,(TEXT("ScratchBaseAddr : 0x%x\n"), descScratch.dwBaseaddr));
				descScratch.dwColorMode = pBltParms->pDst->Format();
				descScratch.dwHoriRes = dwSrcWidth;
				descScratch.dwVertRes = dwSrcHeight;
			
				/// Set Destination Surface to Scratch Surface
				m_oG2D->SetDstSurface(&descScratch);
				/// Set Destination Clipping window Rect
				m_oG2D->SetClipWindow(&t_rect);
				/// Set Y-axis flip flag
				EnterCriticalSection(&m_cs2D);	
				m_oG2D->FlipBlt( prclSrc, &t_rect,  FLIP_Y );
				LeaveCriticalSection(&m_cs2D);
				/// Y-axis mirror case. left-right inversion
				/// Set Source Address to Scratch Memory
				m_oG2D->SetSrcSurface(&descScratch);
				/// Set Destination Surface to real Framebuffer Surface
				m_oG2D->SetDstSurface(pdescDstSurface);\
	
				/// Swap top, left coordinate when 90 and 270
				RETAILMSG(TEMP_DEBUG,(TEXT("S TBSWAP:%d,%d,%d,%d,%d,%d\n"),prclDst->left, prclDst->top, prclDst->right, prclDst->bottom, iRotate, m_oG2D->GetRotType(iRotate)));
				SWAP(prclDst->top, prclDst->bottom, LONG);
				/// Set Destination Clipping window Rect
				if(pBltParms->prclClip)
				{
					m_oG2D->SetClipWindow(pBltParms->prclClip);
				}
				else
				{
					m_oG2D->SetClipWindow(prclDst);
				}	
				
				EnterCriticalSection(&m_cs2D);	
				RETAILMSG(TEMP_DEBUG,(TEXT("S TASWAP:%d,%d,%d,%d,%d,%d\n"),prclDst->left, prclDst->top, prclDst->right, prclDst->bottom, iRotate, m_oG2D->GetRotType(iRotate)));				
				m_oG2D->StretchBlt( &t_rect, prclDst, m_oG2D->GetRotType(iRotate));
				LeaveCriticalSection(&m_cs2D);		
				/// recover left, right coordinate
				SWAP(prclDst->top, prclDst->bottom, LONG);				

				/// Disallocate Scratch Surface
				delete ScratchSurf;

				RETAILMSG(TEMP_DEBUG, (TEXT("Stretch Y-axis flip: R:%d\r\n"), pBltParms->pDst->Rotate()));
				
				return TRUE;
			}
			if(prclDst->bottom < prclDst->top)
			{
				RotateRectl(prclDst);			
				/// Allocation Scratch Framebuffer for Flip Operation.
				DDGPESurf *ScratchSurf;
				AllocSurface(&ScratchSurf, dwSrcWidth, dwSrcHeight, pBltParms->pDst->Format(), EGPEFormatToEDDGPEPixelFormat[pBltParms->pDst->Format()], GPE_REQUIRE_VIDEO_MEMORY);
				if(ScratchSurf == NULL)
				{
					RETAILMSG(TRUE,(TEXT("Scratch Surface Allocation is failed. %d\n"), __LINE__));
#if 0//USE_PACSURF, To increase video memory is better than to use system memory as Video Surface
					RETAILMSG(TRUE,(TEXT("try to allocate surface usign PA Surface\r\n")));
					PACSurf *ScratchSurf;
#endif
					RETAILMSG(TRUE,(TEXT("Maybe There's no sufficient video memory. please increase video memory\r\n")));
					RETAILMSG(TRUE,(TEXT("try to redirect to SW Emulated Bitblt\r\n")));		
					return FALSE;
				}
				

				/// Set Scratch Surface Information
				descScratch.dwBaseaddr = (IMAGE_FRAMEBUFFER_DMA_BASE + ScratchSurf->OffsetInVideoMemory());
				RETAILMSG(TEMP_DEBUG,(TEXT("ScratchBaseAddr : 0x%x, Offset:%d,SrcW:%d, SrcH:%d, Stride:%d, R:%d\n"), descScratch.dwBaseaddr, ScratchSurf->OffsetInVideoMemory(), dwSrcWidth, dwSrcHeight, ScratchSurf->Stride(), ScratchSurf->Rotate()));
				descScratch.dwColorMode = pBltParms->pDst->Format();
				descScratch.dwHoriRes = dwSrcWidth;
				descScratch.dwVertRes = dwSrcHeight;

				/// Set Destination Surface to Scratch Surface
				m_oG2D->SetDstSurface(&descScratch);
				/// Set Destination Clipping window Rect
				m_oG2D->SetClipWindow(&t_rect);
				/// Set X-axis flip flag
				EnterCriticalSection(&m_cs2D);
				m_oG2D->FlipBlt( prclSrc, &t_rect,  FLIP_X );
				LeaveCriticalSection(&m_cs2D);

				/// Set Source Address to Scratch Memory
				m_oG2D->SetSrcSurface(&descScratch);
				/// Set Destination Surface to real Framebuffer Surface
				m_oG2D->SetDstSurface(pdescDstSurface);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -