📄 gapi.cpp
字号:
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 + -