📄 eglglue.c
字号:
/**************************************************************************
* Name : eglglue.c
* Author : BCB
* Created : 17/06/2003
*
* Copyright : 2003 by Imagination Technologies Limited. All rights reserved.
* : No part of this software, either material or conceptual
* : may be copied or distributed, transmitted, transcribed,
* : stored in a retrieval system or translated into any
* : human or computer language in any form by any means,
* : electronic, mechanical, manual or other-wise, or
* : disclosed to third parties without the express written
* : permission of Imagination Technologies Limited, Unit 8, HomePark
* : Industrial Estate, King's Langley, Hertfordshire,
* : WD4 8LZ, U.K.
*
* Platform : ANSI
*
* $Date: 2004/10/27 16:14:34 $ $Revision: 1.43.1.13 $
* $Log: eglglue.c $
*
* --- Revision Logs Removed ---
*
* --- Revision Logs Removed ---
**************************************************************************/
#define MODULE_ID MODID_EGL
#include "context.h"
#if defined(PDUMP)
#include "egl_internal.h"
#include "tls.h"
#endif
IMG_BOOL ValidateMemory(GLESContext *gc);
/* First stab at the interface EGL needs into the core driver below: */
/***********************************************************************************
Function Name : GLESCreateGC
Inputs : psSysContext, psMode, hShareContext, psAppHint
Outputs : phContext
Returns : Success
Description : Called to create an OpenGL-ES graphics context (GC)
************************************************************************************/
IMG_BOOL GLESCreateGC(GLESSysContext *psSysContext, GLESContextHandle *phContext, GLEScontextMode *psMode,
GLESContextHandle hShareContext, GLESAppHints *psAppHints)
{
PVRcontext *psContext = GLESCalloc(NULL, sizeof(PVRcontext));
GLESContext *gc = (GLESContext *)psContext;
GLESContext *psShareContext = (GLESContext *)hShareContext;
if(!gc)
{
DPF((DBG_ERROR,"Cannot allocate gc"));
return IMG_FALSE;
}
psContext->sMode = *psMode;
gc->psMode = &psContext->sMode;
gc->sAppHints = *psAppHints;
if(psAppHints->i32SceneAntiAlias >= 0)
{
gc->psMode->ui32AntiAliasMode = (IMG_UINT32)psAppHints->i32SceneAntiAlias;
}
switch(gc->psMode->ePixelFormat)
{
case PVRSRV_PIXEL_FORMAT_RGB565:
case PVRSRV_PIXEL_FORMAT_ARGB1555:
case PVRSRV_PIXEL_FORMAT_ARGB8888:
break;
default:
DPF((DBG_ERROR,"Unknown pixel format: %d", gc->psMode->ePixelFormat));
return IMG_FALSE;
}
gc->sHWContext.psSysContext = psSysContext;
gc->sHWContext.ps3DDevData = &psSysContext->s3D;
gc->sHWContext.psHWInfo = &psSysContext->sHWInfo;
if(!CreateTextureState(gc, psShareContext))
{
return IMG_FALSE;
}
#if (defined(SUPPORT_VGP) || defined(SUPPORT_VGP_LITE)) && !defined(PASSTHROUGH_BUILD)
if(!CreateProgramState(gc, psShareContext))
{
return IMG_FALSE;
}
#endif
*phContext = (GLESContextHandle)psContext;
#if defined (TIMING) || defined (DEBUG)
gc->pui32TimerRegister = (IMG_UINT32 *)psSysContext->sHWInfo.pvSOCRegsBase;
MetricsInitiateTiming(gc);
InitProfileData(gc);
#endif
return IMG_TRUE;
}
/***********************************************************************************
Function Name : GLESDestroyGC
Inputs : hContext
Outputs : -
Returns : Success
Description : Called to destroy an OpenGL-ES GC
************************************************************************************/
IMG_BOOL GLESDestroyGC(GLESContextHandle hContext)
{
GLESContext *gc = (GLESContext *)hContext;
IMG_BOOL bPass = IMG_TRUE;
#if DEBUG || TIMING || METRIC
MetricsOutputTotals(gc);
DebugDeinit();
#endif
FreeTextureState(gc);
FreeTransformState(gc);
FreeLightingState(gc);
#if (defined(SUPPORT_VGP) || defined(SUPPORT_VGP_LITE)) && !defined(PASSTHROUGH_BUILD)
FreeProgramState(gc);
#endif
#ifdef PDUMP
PDUMPCLOSE(gc->psPDContext);
#elif defined(OLDPDUMP)
PDUMP_CLOSE(gc);
#endif
DestroyExtensionString(gc);
GLESFree(gc, gc);
return bPass;
}
/***********************************************************************************
Function Name : ResetContext
Inputs : gc
Outputs : -
Returns : Success
Description : Resets the context to default state.
************************************************************************************/
static IMG_BOOL ResetContext(GLESContext *gc)
{
DPF((DBG_VERBOSE, "ResetContext"));
/* Misc machine state */
gc->sHWContext.ui32ISPTSPWord = MBX1_ISPTSPCTL_GOURAUD | MBX1_ISPTSPCTL_CKDISABLE;
/* This will be set dynamically on a VGP system */
#if !(defined(SUPPORT_VGP) || defined(SUPPORT_VGP_LITE)) || defined(PASSTHROUGH_BUILD)
#if defined(USE_FIXED_POINT_VERTICES)
gc->sHWContext.ui32FPControlWord = MBX1_TAFPFORMAT_TYPEFIXEDPOINT | (16 << MBX1_TAFPFORMAT_FRACTIONALBITSSHIFT);
#else
gc->sHWContext.ui32FPControlWord = MBX1_TAFPFORMAT_TYPEIEEEFLOAT;
#endif
#endif
gc->sState.sRaster.ui32ColorMask = 0xF;
gc->sState.sRaster.ui32ClearColor = 0;
gc->sState.sRaster.ui32LogicOp = MBX1_ISPTSPCTL_LO_COPY;
gc->sState.sRaster.ui32BlendSrcDst = MBX1_ISPTSPCTL_SRCBLENDONE | MBX1_ISPTSPCTL_DESTBLENDZERO;
gc->sState.sRaster.ui32AlphaFuncRef = MBX1_TSPOBJ_ACMPMODEALWAYS;
gc->sState.sPoint.pfPointSize = &gc->sState.sPoint.fAliasedSize;
gc->sState.sPoint.fSmoothSize = GLES_Half;
gc->sState.sPoint.fAliasedSize = GLES_Half;
gc->sState.sLine.pfLineWidth = &gc->sState.sLine.fAliasedWidth;
gc->sState.sLine.fSmoothWidth = GLES_Half;
gc->sState.sLine.fAliasedWidth = GLES_Half;
gc->sState.sPolygon.eCullMode = GL_BACK;
gc->sState.sPolygon.eFrontFaceDirection = GL_CCW;
gc->sState.sStencil.eTestFunc = GL_ALWAYS;
gc->sState.sStencil.ui32Mask = 0;
gc->sState.sStencil.eFail = GL_KEEP;
gc->sState.sStencil.eDepthFail = GL_KEEP;
gc->sState.sStencil.eDepthPass = GL_KEEP;
gc->sState.sStencil.ui32WriteMask = 0;
gc->sState.sDepth.ui32TestFunc = MBX1_ISPTSPCTL_DCMPMODELT;
gc->sState.sDepth.fClear = GLES_One;
gc->sClear.fClearDepth = gc->sState.sDepth.fClear;
gc->ui32FrameEnables |= GLES_FS_DITHER_ENABLE | GLES_FS_MULTISAMPLE_ENABLE;
gc->sClientPixel.ui32UnpackAlignment = 4;
gc->sClientPixel.ui32PackAlignment = 4;
/*
** Initialize larger subsystems by calling their init codes.
*/
if(!InitTransformState(gc))
{
DPF((DBG_ERROR,"Couldn't init transform state"));
return IMG_FALSE;
}
InitCurrentState(gc);
InitFogState(gc);
InitTextureState(gc);
InitVertexArrayState(gc);
if(!InitLightingState(gc))
{
DPF((DBG_ERROR,"Couldn't init lighting state"));
return IMG_FALSE;
}
#if (defined(SUPPORT_VGP) || defined(SUPPORT_VGP_LITE)) && !defined(PASSTHROUGH_BUILD)
if(!CheckVGPCodeRev())
{
DPF((DBG_ERROR,"Couldn't init fixed function TnL VGP state"));
return IMG_FALSE;
}
InitProgramState(gc);
#endif
return IMG_TRUE;
}
/***********************************************************************************
Function Name : InitContext
Inputs : gc
Outputs : -
Returns : success
Description : Called the first time a GC is made current, to do one time
initialisation of the GC.
************************************************************************************/
static IMG_BOOL InitContext(GLESContext *gc)
{
#if defined(PDUMP)
TLS pTls = EGLGetTLSValue ();
if(!PDUMPINITUM(&gc->psPDContext, pTls->servicesContext.hServices))
return IMG_FALSE;
#elif defined(OLDPDUMP)
if(!PDUMP_INIT(gc))
return IMG_FALSE;
#endif
DPF((DBG_VERBOSE, "InitContext"));
SetupTransformLightingProcs(gc);
gc->sHWContext.ui32PrimitiveHeader = MBX1_TAPRIM_ZEROOFFSETCOL;
gc->sHWContext.ui32TAControland3DState = MBX1_TAOBJTYPE_STATE;
#ifdef USE_TERMINATE_WORD
#if (defined(SUPPORT_VGP) || defined(SUPPORT_VGP_LITE)) && !defined(PASSTHROUGH_BUILD)
#error "Invalid option - no support for vgp together with use terminate word"
#else
gc->sHWContext.ui32PrimitiveHeader |= MBX1_TAPRIM_USE_TERMINATE_WORD;
#endif
#endif
if(!ResetContext(gc))
return IMG_FALSE;
BuildExtensionString(gc);
return IMG_TRUE;
}
/***********************************************************************************
Function Name : GLESMakeCurrentGC
Inputs : hDrawable, hContext
Outputs : -
Returns : Success
Description : Make a read/write Drawable current on an OpenGL-ES GC on a thread
************************************************************************************/
IMG_GLESERROR GLESMakeCurrentGC(GLESDrawableHandle hWriteDrawable, GLESDrawableHandle hReadDrawable,
GLESContextHandle hContext)
{
PVRcontext *pvrContext = (PVRcontext *)hContext;
GLESContext *gc = &pvrContext->gc;
IMG_UINT32 ui32AAFlags = 0;
DPF((DBG_VERBOSE, "GLESMakeCurrentGC"));
__GL_SET_CONTEXT(gc);
/* If no gc - we are making "uncurrent" */
if(gc)
{
GLESDrawableParams sParams;
GLESGetDrawableParameters(hWriteDrawable, &sParams);
if(sParams.ui32Width == 0 && sParams.ui32Height == 0)
{
DPF((DBG_ERROR,"Invalid drawable - what do we do?"));
goto BAD_CONTEXT;
}
if(!ValidateMemory(gc))
{
DPF((DBG_ERROR, "invalid memory"));
if(gc->psRenderSurface->bInFrame)
gc->psRenderSurface->bSceneInvalid = IMG_TRUE;
return IMG_GLES_MEMORY_INVALID_ERROR;
}
if(gc->psRenderSurface != (GLESRenderSurface *)sParams.hRenderSurface)
{
if(gc->sClear.ui32ClearFlags)
{
/* If we can't flush clears - just continue to record state. */
if(PrepareToDraw(gc))
{
GLESReleaseTA(gc, IMG_FALSE);
}
else
{
DPF((DBG_ERROR,"Can't flush clears"));
}
}
/* Save off the write render surface locally */
gc->psRenderSurface = (GLESRenderSurface *)sParams.hRenderSurface;
gc->sDrawableParams = sParams;
/* If we already have a render target, reintialise the SW registers */
if(gc->psRenderSurface->psTARenderInfo)
GLESInitRegs(gc);
}
if(!pvrContext->bHasBeenCurrent)
{
if(!InitContext(gc))
goto BAD_CONTEXT;
gc->sState.sViewport.i32X = 0;
gc->sState.sViewport.i32Y = 0;
gc->sState.sViewport.ui32Width = sParams.ui32Width;
gc->sState.sViewport.ui32Height = sParams.ui32Height;
gc->sState.sScissor.i32ScissorX = 0;
gc->sState.sScissor.i32ScissorY = 0;
gc->sState.sScissor.ui32ScissorWidth = sParams.ui32Width;
gc->sState.sScissor.ui32ScissorHeight = sParams.ui32Height;
ApplyViewport(gc);
ApplyDepthRange(gc, GLES_Zero, GLES_One);
if(sParams.ui32Width <= 50 && sParams.ui32Height <= 50)
{
/* we are in conformance mode */
gc->sAppHints.bForceExternalZBuffer = IMG_TRUE;
}
gc->bLastDrawMaskFullScreenEnable = IMG_TRUE;
gc->bFullScreenScissor = IMG_TRUE;
gc->bFullScreenViewport = IMG_TRUE;
pvrContext->bHasBeenCurrent = IMG_TRUE;
}
if(gc->psRenderSurface->bInFrame)
{
if((gc->ui32FrameEnables & GLES_FS_MULTISAMPLE_ENABLE) || (gc->sAppHints.i32SceneAntiAlias > 0))
{
#if defined(SUPPORT_MBX1_LITE)
if(gc->psMode->ui32AntiAliasMode & (GLES_ANTIALIAS_2x1|GLES_ANTIALIAS_2x2))
ui32AAFlags |= PVRSRV_ADDRENDERTARGET_AAX;
#endif
if(gc->psMode->ui32AntiAliasMode & GLES_ANTIALIAS_2x2)
ui32AAFlags |= PVRSRV_ADDRENDERTARGET_AAY;
}
if(sParams.ui32Width != gc->psRenderSurface->ui32Width ||
sParams.ui32Height != gc->psRenderSurface->ui32Height ||
ui32AAFlags != gc->psRenderSurface->ui32AAFlags ||
gc->psRenderSurface->bSceneInvalid)
{
if(!GLESDiscardScene(gc->sHWContext.psSysContext, gc->psRenderSurface))
{
DPF((DBG_ERROR,"Couldn't discard scene"));
goto BAD_PARAMS;
}
gc->psRenderSurface->bSceneInvalid = IMG_FALSE;
}
}
gc->ui32DirtyMask = 0xFFFFFFFF;
gc->ui32DirtyConstantMask = 0xFFFFFFFF;
gc->bDrawMaskInvalid = IMG_TRUE;
gc->hWriteDrawable = hWriteDrawable;
gc->hReadDrawable = hReadDrawable;
}
return IMG_GLES_NO_ERROR;
BAD_PARAMS:
/* State created by initcontext */
FreeTextureState(gc);
FreeTransformState(gc);
FreeLightingState(gc);
BAD_CONTEXT:
__GL_SET_CONTEXT(0);
return IMG_GLES_GENERIC_ERROR;
}
/***********************************************************************************
Function Name : GLESFlushBuffersGC
Inputs : hContext, bWaitForHW
Outputs : -
Returns : Sucess
Description : Indicates that the scene should be posted to the front buffer
************************************************************************************/
IMG_GLESERROR GLESFlushBuffersGC(GLESContextHandle hContext, IMG_BOOL bWaitForHW)
{
GLESContext *gc = (GLESContext *)hContext;
IMG_GLESERROR eError;
GLES_TIME_START(GLES_TIMES_SWAP_BUFFERS);
/* Make sure to flush the current write render surface */
eError = FlushHW(gc, gc->psRenderSurface, bWaitForHW);
GLES_TIME_STOP(GLES_TIMES_SWAP_BUFFERS);
return eError;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -