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

📄 gapi.cpp

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	switch (m_lRotationRemap)
	{
		case 270: // Remember WinCE/PPC rotation is anticlockwise.
		{
			// GETRAWFRAMEBUFFERINFO should ALWAYS return PORTRAIT (0,0) point. 
			// In the case of Landscape VGA (270) designs this is Buffer() + size of line - one pixel
			dwFrameBufferOffset = dwBytesPerLine - dwBytesPerPixel;	//eg./ Intel Marathon 16bpp PPC case : (640*2)-2=1278
			break;
		}
		
		case 180:
		{
			dwFrameBufferOffset = dwBytesPerLine + dwVerticalHeightBytes - dwBytesPerPixel;
			break;
		}
		
		case 90:
		{
			dwFrameBufferOffset = dwVerticalHeightBytes;
			break;
		}

		case 0:
		default:
		{
			dwFrameBufferOffset = 0;
			break;
		}
	}
	#else//ROTATE_ENABLE
	dwFrameBufferOffset = 0;
	#endif//ROTATE_ENABLE

	// Add the offset to the start address
	pRawInfo->pFramePointer = (void*) ((DWORD)m_pPrimarySurface->Buffer() + dwFrameBufferOffset);

	#ifdef ROTATE_ENABLE
	#ifdef OSV_PPC
		switch(m_lRotationRemap)//PocketPC
	#else//OSV_PPC
		switch(m_lPrimaryRotation)//WinCE
	#endif//OSV_PPC
	{
		case 90:
		{
			pRawInfo->cxPixels = m_PhysDestHeight;
			pRawInfo->cyPixels = m_PhysDestWidth;
			pRawInfo->cxStride = -(int)m_ulScanLineLength;
			pRawInfo->cyStride = (int)dwBytesPerPixel;
			break;
		}

		case 180:
		{
			pRawInfo->cxPixels = m_nScreenWidth;
			pRawInfo->cyPixels = m_nScreenHeight;
			pRawInfo->cxStride = -(int)dwBytesPerPixel;
			pRawInfo->cyStride = -(int)m_ulScanLineLength;
			break;
		}

		case 270:
		{													// eg./ Intel Marathon 16bpp PPC case
			pRawInfo->cxPixels = m_PhysDestHeight;			//480
			pRawInfo->cyPixels = m_PhysDestWidth;			//640
			pRawInfo->cxStride = (int)m_ulScanLineLength;	//640*2=1280
			pRawInfo->cyStride = -(int)dwBytesPerPixel;		//-2
			break;
		}

		default:
		{
			pRawInfo->cxPixels = m_nScreenWidth;
			pRawInfo->cyPixels = m_nScreenHeight;
			pRawInfo->cxStride = (int)dwBytesPerPixel;
			pRawInfo->cyStride = (int)m_ulScanLineLength;
			break;
		}
	}
	#else//ROTATE_ENABLE
	pRawInfo->cxPixels = m_nScreenWidth;
	pRawInfo->cyPixels = m_nScreenHeight;
	pRawInfo->cxStride = (int)dwBytesPerPixel;
	pRawInfo->cyStride = (int)m_ulScanLineLength;
	#endif//ROTATE_ENABLE

}//GapiGetRawFramebuffer
#endif


/***********************************************************************************
 Function Name      : GapiDmaVRAMtoDRAM
 Inputs             : 
 Outputs            : 
 Returns            : 
 Description        : 

	DmaVRAMtoDRAM is called by the first invocation of GXBeginDraw, when GAPI is first used.
	Since it is called once, and before any other function, all initialisation should be in this function.
	DmaVRAMtoDRAM should copy the screen contents from VRAM to an offscreen buffer in DRAM.
	The location and dimensions of the DRAM buffer can be found by calling ExtEscape with the
	nEscape parameter equal to GETGXINFO, and the location of VRAM can be found by calling
	ExtEscape with the nEscape parameter equal to GETRAWFRAMEBUFFER.

************************************************************************************/
void MBX::GapiDmaVRAMtoDRAM(DRVESC_GXDMA *pGxDmaInfo)
{
	GAPI_BLT sBlt;

	// Blt from primary surface
	sBlt.sSrc.pvBuffer = m_pPrimarySurface->Buffer();
	sBlt.sSrc.dwPhysAddress = (DWORD)((MBXSurf*)(m_pPrimarySurface))->GetPhysAddr();
	sBlt.sSrc.dwStride = m_pPrimarySurface->Stride();
	
	// Destination is GAPI surface
	#if GAPI_SYSMEM
		sBlt.sDst.pvBuffer = pvLinearBase;
	#else
		sBlt.sDst.pvBuffer = m_pclGAPIMemNode->m_psDevMemHandle->pvLinAddr;
		sBlt.sDst.dwPhysAddress = m_pclGAPIMemNode->m_psDevMemHandle->uiDevAddr.uiAddr;
	#endif

	sBlt.sDst.dwStride = m_ui32GapiPhysStride;

#ifdef ROTATE_ENABLE
	// When we created the gapi surface we would have rotated it to match the primary.
	// We are bltting unrotated so it is the phys width that we need.
	if (m_lPrimaryRotation == 90 || m_lPrimaryRotation == 270)
	{
		sBlt.sSrc.dwWidth = m_pPrimarySurface->Height();
		sBlt.sSrc.dwHeight = m_pPrimarySurface->Width();
		sBlt.sDst.dwWidth = 320;
		sBlt.sDst.dwHeight = 240;
	}
	else
#endif
	// No rotation
	{
		sBlt.sSrc.dwWidth = m_pPrimarySurface->Width();
		sBlt.sSrc.dwHeight = m_pPrimarySurface->Height();
		sBlt.sDst.dwWidth = 240;
		sBlt.sDst.dwHeight = 320;
	}

	sBlt.dwLeft = 0;
	sBlt.dwTop = 0;
	sBlt.dwRight = sBlt.sDst.dwWidth;
	sBlt.dwBottom = sBlt.sDst.dwHeight;

	#if GAPI_SYSMEM
	// If the gapi buffer is in system memory then we will have to do a software blt.
	GapiScaleBltCPU(&sBlt);
	#else
	GapiScaleBlt (&sBlt);
	#endif

}//GapiDmaVRAMtoDRAM


/***********************************************************************************
 Function Name      : GapiDmaDRAMtoVRAM
 Inputs             : 
 Outputs            : 
 Returns            : 
 Description        : 

	DmaDRAMtoVRAM is called by GXEndDraw to copy the screen from DRAM to VRAM.
	During this time, the driver must scale the graphics display to fit the
	size of the screen on a PocketPC, or to centre the display with a blank
	margin around the edge on a Smartphone.

************************************************************************************/
void MBX::GapiDmaDRAMtoVRAM(DRVESC_GXDMA *pGxDmaInfo)
{
	GAPI_BLT sBlt;

	// Blt from GAPI surface
	#if GAPI_SYSMEM
	sBlt.sSrc.pvBuffer = pvLinearBase;
	#else
	sBlt.sSrc.pvBuffer = m_pclGAPIMemNode->m_psDevMemHandle->pvLinAddr;
	sBlt.sSrc.dwPhysAddress = m_pclGAPIMemNode->m_psDevMemHandle->uiDevAddr.uiAddr;
	#endif
	sBlt.sSrc.dwStride = m_ui32GapiPhysStride;

	// Destination is primary surface
	sBlt.sDst.pvBuffer = m_pPrimarySurface->Buffer();
	sBlt.sDst.dwPhysAddress = (DWORD)((MBXSurf*)(m_pPrimarySurface))->GetPhysAddr();
	sBlt.sDst.dwStride = m_pPrimarySurface->Stride();

#ifdef ROTATE_ENABLE
	// When we created the gapi surface we would have rotated it to match the primary.
	// We are bltting unrotated so it is the phys width that we need.
	if (m_lPrimaryRotation == 90 || m_lPrimaryRotation == 270)
	{
		sBlt.sDst.dwWidth = m_pPrimarySurface->Height();
		sBlt.sDst.dwHeight = m_pPrimarySurface->Width();
		sBlt.sSrc.dwWidth = 320;
		sBlt.sSrc.dwHeight = 240;
	}
	else
#endif
	// No rotation
	{
		sBlt.sDst.dwWidth = m_pPrimarySurface->Width();
		sBlt.sDst.dwHeight = m_pPrimarySurface->Height();
		sBlt.sSrc.dwWidth = 320;
		sBlt.sSrc.dwHeight = 240;
	}

	sBlt.dwLeft = 0;
	sBlt.dwTop = 0;
	sBlt.dwRight = sBlt.sSrc.dwWidth * 2;
	sBlt.dwBottom = sBlt.sSrc.dwHeight * 2;

	#if GAPI_SYSMEM
		// Can use slave port or stripe buffer, but stripe buffer is much faster !!
		#if GAPI_USE_STRIPE_BUFFER
			GapiScaleBltStripeBuf(&sBlt);
		#else
			GapiScaleBltSP (&sBlt); // SlavePort
		#endif
	#else
	// Src and dest both in vid mem so do a fast blt.
	GapiScaleBlt (&sBlt);
	#endif

}//GapiDmaDRAMtoVRAM


/***********************************************************************************
 Function Name      : GapiIsDMAReady
 Inputs             : 
 Outputs            : pGxDmaInfo->bStatus : TRUE if blt completed, FALSE if busy.
 Returns            : 
 Description        : 

	IsDMAReady is called by GAPI to find out if DmaVRAMtoDRAM or DmaDRAMtoVRAM is still drawing.
	It should return TRUE to indicate that DMA has finished, or FALSE if still busy.

	There is no requirement for DmaVRAMtoDRAM or DmaDRAMtoVRAM to use DMA; these functions
	can copy system memory to video memory directly, or they can set up an asynchronous DMA
	transfer. If DMA is not used, IsDMAReady can simply return TRUE.

	If the bForceWait is set to TRUE then IsDMAReady should block until the DMA operation has completed.

************************************************************************************/
void MBX::GapiIsDMAReady(DRVESC_GXDMA *pGxDmaInfo)
{
	if (pGxDmaInfo->bStatus)
	{
		// Wait for not busy
		while (*gpdwGapiOpCompleteLinAddr != gdwOpCompleteTag)
		{
			Sleep(0);// Reduce number of video mem reads.
		}

		pGxDmaInfo->bStatus = IMG_TRUE; // Ready now
	}
	else
	{
		// Report blt status.
		pGxDmaInfo->bStatus = (*gpdwGapiOpCompleteLinAddr == gdwOpCompleteTag);
	}

}//GapiIsDMAReady


/***********************************************************************************
 Function Name      : GapiScaleBlt
 Inputs             : pBlt describes the blt.
 Outputs            : 
 Returns            : Note this is synchronous.
 Description        : Blt from vid mem to vid mem
************************************************************************************/
void MBX::GapiScaleBlt (PGAPI_BLT pBlt)
{
#if !GAPI_SYSMEM

	ULONG ulScaleFactor;
	ULONG ulScaleFactorX;
	ULONG ulScaleFactorY;
	
	/* We have 10bits to represent the scale-factor */
	ulScaleFactor = ((pBlt->sSrc.dwWidth<<16)/pBlt->sDst.dwWidth) & ~0xFFE007FF;
	ulScaleFactorX = ulScaleFactor >> (16-MBX2D_STRETCH_FPSHIFT); /* = 0x10 for x2 upscale */
	
	ulScaleFactor = ((pBlt->sSrc.dwHeight<<16)/pBlt->sDst.dwHeight) & ~0xFFE007FF;
	ulScaleFactorY = ulScaleFactor >> (16-MBX2D_STRETCH_FPSHIFT);

	/* ACQUIRE SLAVE PORT */
	PVRSRVAcquireSlavePort(m_sDevData.psDevInfoKM, PVRSRV_SLAVEPORT_2D, IMG_TRUE);
	
	SlavePortInitWrites();

	/* Set Dest Surf */
	/* update DST surface attributes */
	SlavePortWrite( MBX2D_DST_CTRL_BH | EGPEFormatToDestHW[gpe16Bpp]
					| ((pBlt->sDst.dwStride<<MBX2D_DST_STRIDE_SHIFT) & MBX2D_DST_STRIDE_MASK));

	SlavePortWrite( ((pBlt->sDst.dwPhysAddress >> MBX2D_DST_ADDR_ALIGNSHIFT)
					<<	MBX2D_DST_ADDR_SHIFT) &	MBX2D_DST_ADDR_MASK);
	/* Scaling */
	SlavePortWrite( MBX2D_STRETCH_BH
					| (ulScaleFactorX<<MBX2D_X_STRETCH_SHIFT)
					| (ulScaleFactorY<<MBX2D_Y_STRETCH_SHIFT) );

	/* Set Src format and stride */
	SlavePortWrite(MBX2D_SRC_CTRL_BH
					| MBX2D_SRC_FBMEM
					| EGPEFormatToSrcHW[gpe16Bpp]
					| ((pBlt->sSrc.dwStride<<MBX2D_SRC_STRIDE_SHIFT) 
						&	MBX2D_SRC_STRIDE_MASK) );
	/* Src address */
	SlavePortWrite((( pBlt->sSrc.dwPhysAddress
					>>	MBX2D_SRC_ADDR_ALIGNSHIFT)
					<<	MBX2D_SRC_ADDR_SHIFT)
					&	MBX2D_SRC_ADDR_MASK );

	/* Specify the Src starting pixel coordinate */
	SlavePortWrite(MBX2D_SRC_OFF_BH
					| ((0<<MBX2D_SRCOFF_XSTART_SHIFT) & MBX2D_SRCOFF_XSTART_MASK)
					| ((0<<MBX2D_SRCOFF_YSTART_SHIFT) & MBX2D_SRCOFF_YSTART_MASK) );

	/* Send Blit Command */
	SlavePortWrite( MBX2D_BLIT_BH | (0xCCCC & MBX2D_ROP4_MASK) ); /* SrcCopy */

	SlavePortWrite( 0 ); /* Dummy fill colour */

	SlavePortWrite( ((SHORT)0  &  MBX2D_DST_YSTART_MASK) |
					(((SHORT)0 << MBX2D_DST_XSTART_SHIFT) & MBX2D_DST_XSTART_MASK) );

	SlavePortWrite( ((SHORT)pBlt->sDst.dwHeight & MBX2D_DST_YEND_MASK) |
					(((SHORT)pBlt->sDst.dwWidth << MBX2D_DST_XEND_SHIFT) & MBX2D_DST_XEND_MASK) );

	/*  Now do OpComplete blt. */

	/* Dest surf */
	SlavePortWrite(MBX2D_DST_CTRL_BH | MBX2D_DST_8888ARGB);
	SlavePortWrite(((gdwGapiOpCompletePhysAddr >> MBX2D_DST_ADDR_ALIGNSHIFT)
							<< MBX2D_DST_ADDR_SHIFT) & MBX2D_DST_ADDR_MASK );

	/* 1 pixel colourfill blit using gdwOpCompleteTag for colour. */
	SlavePortWrite( MBX2D_BLIT_BH | MBX2D_USE_FILL | MBX2D_ROP3_PATCOPY );
    SlavePortWrite( ++gdwOpCompleteTag );
    SlavePortWrite( 0 );
    SlavePortWrite( (1<<MBX2D_DST_XEND_SHIFT) | (1<<MBX2D_DST_YEND_SHIFT) );

	/* Insert a fence to ensure that everything is written through
	 * and write all to slaveport */
	SlavePortFencedWrites( MBX2D_FENCE_BH );

	/* RELEASE SLAVE PORT */
	PVRSRVReleaseSlavePort(	m_sDevData.psDevInfoKM, PVRSRV_SLAVEPORT_2D);

#endif /* #if !GAPI_SYSMEM */

} /* GapiScaleBlt */



/***********************************************************************************
 Function Name      : GapiScaleBltSP
 Inputs             : pBlt describes the blt.
 Outputs            : 
 Returns            : 

⌨️ 快捷键说明

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