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

📄 khronos_egl.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/**************************************************************************
 Name         : khronos_egl.c
 Title        : Khronos EGL
 Author       : PowerVR
 Created      : December 2003

 Copyright    : 2003-2004 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.

 Description  : Khronos EGL

 Platform     : All

*******************************************************************************/
/* @todo this implementation of kegl is not thread safe.
 */
#define MODULE_ID MODID_KHRONOSEGL

#include <assert.h>
#include <string.h>

#include "drvegl.h"
#include "ogles_types.h"
#include "servicesglue.h"
#include "ws.h"
#include "wsglue.h"
#include "eglglue.h"
#include "osglue.h"
#include "egl_internal.h"
#include "cfg-core.h"
#include "cfg.h"
#include "tls.h"
#include "qsort.h"
#include "srv.h"
#include "generic-ws.h"
#include "services.h"
#include "debug.h"
#include "modid.h"
#include "misc.h"


#define ATTRIB_COUNT (_EGL_CONFIG_ATTR_LAST - _EGL_CONFIG_ATTR_FIRST + 1)
#define ATTRIB(config,n) (config)->attributes[(n)-_EGL_CONFIG_ATTR_FIRST]
  
void (* __GetProcAddress (const char *procname))(IMG_VOID);

/** @todo this currently will have everything on the same thread.... */
#define ENV_CurrentThread() 1

/** @todo GLES_ASSERT is not defined. */
#define GLES_ASSERT(a)

/* This function allows our assert to be embedded in an expression */
static INLINE int _exp_assert(int a)
{
	assert(a);
	return a;
}
#define ASSERT_EXP(a)	(_exp_assert(a))


/* Bias upwards because EGL_NO_DISPLAY is zero */
#define SLOT_INDEX_TO_EGLDISPLAY(index)	((signed int)ASSERT_EXP(EGL_NO_DISPLAY == 0),(index+1))

#define EGLDISPLAY_TO_SLOT_INDEX(egldisplay)			\
	(													\
		(signed int)ASSERT_EXP(EGL_NO_DISPLAY == 0),	\
		(signed int)ASSERT_EXP(egldisplay > 0),			\
		((signed int)egldisplay-1)						\
	)


/*
   <function>
   FUNCTION   : _TlsInit ()
   PURPOSE    : Initialise our thread local storage.
   PARAMETERS : In:  tls - Pointer to state structure.
   RETURNS    : None
   </function>
 */
static EGLint
_TlsInit (TLS pTls)
{
    EGLint i;
    
    assert (pTls!=IMG_NULL);
    pTls->lastError = EGL_NOT_INITIALIZED;
    pTls->currentReadSurface = EGL_NO_SURFACE;
    pTls->currentDrawSurface = EGL_NO_SURFACE;
    pTls->currentContext = EGL_NO_CONTEXT;
    pTls->count=1;
    pTls->dpyCount = WS_GetDisplayCount ();
    pTls->dpys = GLESMalloc (0, pTls->dpyCount * sizeof (*pTls->dpys));
    if (pTls->dpys==IMG_NULL)
        return EGL_FALSE;
    for (i=0; i<pTls->dpyCount; i++)
    {
        pTls->dpys[i].isInitialised = EGL_FALSE;
        pTls->dpys[i].nativeDisplay = (NativeDisplayType) EGL_NO_DISPLAY;
    }
    
    return EGL_TRUE;
}

/*
<function>
   FUNCTION   : _FindWindowSurface ()
   PURPOSE    : Search the surfaces associated with a specified display for
                the surface which represents a specified native window.
   PARAMETERS : In:  pDpy - Display.
                In:  window - Native window.
   RETURNS    : Surface or IMG_NULL.
</function>
 */
KEGL_SURFACE *
_FindWindowSurface (KEGL_DISPLAY *pDpy, NativeWindowType window)
{
    EGLSurface pSurface;
    assert (pDpy!=IMG_NULL);
  
    for (pSurface = pDpy->pHeadSurface; pSurface!=IMG_NULL;
         pSurface = pSurface->pNextSurface)
    {
        if (pSurface->type == EGL_SURFACE_WINDOW
            && pSurface->u.window.native == window)
            return pSurface;
    }
          
    return IMG_NULL;
}
     
/*
   <function>
   FUNCTION   : _FindPixmapSurface ()
   PURPOSE    : Search the surfaces associated with a specified display for
                the surface which represents a specified native pixmap.
   PARAMETERS : In:  pDpy - Display.
   RETURNS    : In:  pixmap = Native pixmap.
   </function>
 */
static KEGL_SURFACE *
_FindPixmapSurface (KEGL_DISPLAY *pDpy, NativePixmapType pixmap)
{
    EGLSurface pSurface;
    assert (pDpy!=IMG_NULL);
  
    for (pSurface = pDpy->pHeadSurface; pSurface!=IMG_NULL;
         pSurface = pSurface->pNextSurface)
    {
        if (pSurface->type == EGL_SURFACE_PIXMAP
            && pSurface->u.pixmap.native == pixmap)
            return pSurface;
    }
    
    return IMG_NULL;
}

/*
   <function>
   FUNCTION   : _InitialiseContextMode ()
   PURPOSE    : Initialise a GLEScontextMode from an EGLConfig.
   PARAMETERS : Out: pCtx - Context mode to initialise.
              : In:  pCfg - Configuration.
   RETURNS    : None
   
   </function>
 */
static void
_InitialiseContextMode (GLEScontextMode *pCtx,
                        KEGL_CONFIG *pCfg)
{
    assert (pCtx!=IMG_NULL);
    pCtx->bHaveDepthBuffer = IMG_FALSE;
    if (CFGC_GetAttrib (pCfg, EGL_DEPTH_SIZE))
    	 pCtx->bHaveDepthBuffer = IMG_TRUE;
    
    pCtx->ui32RedBits = CFGC_GetAttrib (pCfg, EGL_RED_SIZE);
    pCtx->ui32GreenBits = CFGC_GetAttrib (pCfg, EGL_GREEN_SIZE);
    pCtx->ui32BlueBits = CFGC_GetAttrib (pCfg, EGL_BLUE_SIZE);
    pCtx->ui32AlphaBits = CFGC_GetAttrib (pCfg, EGL_ALPHA_SIZE);

    pCtx->ui32BlueShift = 0;
    pCtx->ui32GreenShift = pCtx->ui32BlueShift + pCtx->ui32BlueBits;
    pCtx->ui32RedShift = pCtx->ui32GreenShift + pCtx->ui32GreenBits;
    pCtx->ui32AlphaShift = pCtx->ui32RedShift + pCtx->ui32RedBits;
    
    pCtx->ui32ColorBits = CFGC_GetAttrib (pCfg, EGL_BUFFER_SIZE);
    pCtx->ui32DepthBits = CFGC_GetAttrib (pCfg, EGL_DEPTH_SIZE);
	
	SRV_FindPVRPixelFormat ( pCtx->ui32AlphaBits,
							 pCtx->ui32RedBits,
						     pCtx->ui32GreenBits,
						     pCtx->ui32BlueBits,
						     &(pCtx->ePixelFormat),
								   		NULL);

	switch (CFGC_GetAttrib (pCfg, EGL_SAMPLE_BUFFERS))
	{
    case 0:
		/* No anti-aliasing */
        pCtx->ui32AntiAliasMode=0;
		break;
    case 1:
        switch (CFGC_GetAttrib (pCfg, EGL_SAMPLES))
        {
        case 0:
            pCtx->ui32AntiAliasMode=0;
            break;
        case 2:
            pCtx->ui32AntiAliasMode=GLES_ANTIALIAS_2x1;				
            break;
        case 4:
            pCtx->ui32AntiAliasMode=GLES_ANTIALIAS_2x2;
            break;
        }
		break;
	}

}

/*
   <function>
   FUNCTION   : _DpySurfaceUnlink ()
   PURPOSE    : Unlink a surface from a display.
   PARAMETERS : In:  pDpy -
                In:  pSurface -
   RETURNS    : None
   </function>
 */
static void
_DpySurfaceUnlink (KEGL_DISPLAY *pDpy, EGLSurface pSurface)
{
    EGLSurface *p;
  
    assert (pDpy!=IMG_NULL);
    assert (pSurface!=IMG_NULL);

    for (p = &pDpy->pHeadSurface; *p!=IMG_NULL; p = &((*p)->pNextSurface))
    {
        if (*p == pSurface)
        {
            *p = pSurface->pNextSurface;
            return;
        }
    }
}

/*
   <function>
   FUNCTION   : _ContextDelete
   PURPOSE    : Delete a context which is unbound.
   PARAMETERS : In:  pCtx - context to delete
   RETURNS    : None
   </function>
 */
static EGLint
_ContextDelete (EGLContext pCtx)
{
    IMG_BOOL imgResult;
    
    imgResult = GLESDestroyGC (pCtx->hOGL);
    CFGC_Unlink (pCtx->pCfg);
    GLESFree (0, pCtx);
    /* can this actually happen? If so ww don;t really have an appropriate
       error code to return, EGL_BAD_ALLOC may need to be reconsidered */
    if (!imgResult)
        return EGL_BAD_ALLOC;
        
    return EGL_SUCCESS;
}

/*
   <function>
   FUNCTION   : _SurfaceDelete
   PURPOSE    : Delete a surface which is unbound.
   PARAMETERS : In:  pSurface - surface to delete.
   RETURNS    : None.
   </function>
 */
static void
_SurfaceDelete (GLESSysContext *pvrsrv, EGLSurface pSurface)
{
    _DpySurfaceUnlink (pSurface->pDpy, pSurface);

	WS_DeleteDrawable (pSurface, pvrsrv);
    
    CFGC_Unlink (pSurface->pCfg);
    GLESFree (0, pSurface);
}

/*
   <function>
   FUNCTION   : _CompatibleContextAndSurface
   PURPOSE    :

   From k-egl specification section 2.2. A context and a surface are
   considered compatible if they:
     - have colour and ancillary buffers of the same depth
     - were created with respect to the same display.

   PARAMETERS : In:  pCtx -
                In:  pSurface -
   RETURNS    : EGL_TRUE - Compatible.
                EGL_FALSE - Not compatible.
   </function>
 */
static EGLBoolean
_CompatibleContextAndSurface (EGLContext pCtx, EGLSurface pSurface)
{
    assert (pCtx!=IMG_NULL);
    assert (pSurface!=IMG_NULL);
  
    if (pCtx->pDpy != pSurface->pDpy)
        return EGL_FALSE;

    return CFG_CompatibleConfigs (pCtx->pCfg, pSurface->pCfg);
}

/*
   <function>
   FUNCTION   : _SurfaceUnbind
   PURPOSE    : Unbind a surface. A surface which is marked as 'isDeleting'
                which becomes completely unbound is deleted.
   PARAMETERS : In:  pvrsrv - system context
                In:  pSurface - Surface to delete.
   RETURNS    : None
   </function>
 */
static void
_SurfaceUnbind (GLESSysContext *pvrsrv, EGLSurface pSurface)
{
    pSurface->currentCount--;
    if (pSurface->currentCount==0)
        if (pSurface->isDeleting)
            _SurfaceDelete (pvrsrv, pSurface);
}

/*
   <function>
   FUNCTION   : _ContextBoundToOtherThread
   PURPOSE    : Test is a context is currently bound to another thread.
   PARAMETERS : In:  pCtx - Context to test.
   RETURNS    : EGL_TRUE - Context is bound to another thread.
                EGL_FALSE - Context is not bound to another thread.
   </function>
 */
static EGLBoolean
_ContextBoundToOtherThread (EGLContext pCtx)
{
    if (pCtx != EGL_NO_CONTEXT
        && pCtx->isCurrent
        && pCtx->boundThread != ENV_CurrentThread ())
        return EGL_TRUE;
        
    return EGL_FALSE;
}

/*
   <function>
   FUNCTION   : _SurfaceBoundToOtherThread
   PURPOSE    : Test if a surface is currently bound to another thread.
   PARAMETERS : In:  pSurface - Surface to test.
   RETURNS    : EGL_TRUE - Surface is bound to another thread.
                EGL_FALSE - Surface is not bound to another thread.
   </function>
 */
static EGLBoolean
_SurfaceBoundToOtherThread (EGLSurface pSurface)
{
    if (pSurface != EGL_NO_SURFACE
        && pSurface->currentCount > 0
        && pSurface->boundThread != ENV_CurrentThread ())
        return EGL_TRUE;
        
    return EGL_FALSE;
}

/*
   <function>
   FUNCTION   : _ValidateAttribList
   PURPOSE    : Ensure that an attribute list contains only recognised
                attributes.
   PARAMETERS : In:  pAttribList - attribute list to validate.
   RETURNS    : EGL_SUCCESS or EGL_BAD_PARAMETER
   </function>
 */



#define _EGL_CONFIG_ATTR_FIRST      0x3020
#define _EGL_CONFIG_ATTR_LAST       0x3037


static EGLint
_ValidateAttribList (const EGLint *pAttribList)
{
    /* All attributes have consecutive numbers, therefore we only need to
       range check for valid attribute identifiers. */
    if (pAttribList!=IMG_NULL)
    {
        while (*pAttribList!=EGL_NONE)
        {
            if (*pAttribList<_EGL_CONFIG_ATTR_FIRST
                || *pAttribList > _EGL_CONFIG_ATTR_LAST)
                return EGL_BAD_PARAMETER;
            pAttribList += 2;
        }
    }
    return EGL_SUCCESS;
}

/*
   <function>
   FUNCTION   : eglGetError
   PURPOSE    : Khronos EGL API
                Request the last error code.
   PARAMETERS : None.
   RETURNS    : The last error code returned from a Khronos EGL API call made
                by the current thread.
   </function>
 */
IMG_EXPORT EGLint
eglGetError (void)
{
    TLS pTls = EGLGetTLSValue ();
	if (pTls==IMG_NULL)
	{
        return EGL_SUCCESS;
	}
    DPF((DBG_VERBOSE, "egl (app->egl): eglGetError()"));
    return pTls->lastError;
}

/*
   <function>
   FUNCTION   : eglGetDisplay
   PURPOSE    : Retrieve the EGLDisplay for the specified native display.
                This API entry point operates outside of the eglInitialise,
                eglTerminate region and therefore does not set any error
                code for retrieval by eglGetError.
   PARAMETERS : In:  nativeDisplay
   RETURNS    : EGLDisplay or EGL_NO_DISPLAY
   </function>
 */
IMG_EXPORT EGLDisplay
eglGetDisplay (NativeDisplayType nativeDisplay)
{
    TLS pTls;
    EGLDisplay  eglDpy = EGL_NO_DISPLAY;
    IMG_BOOL bValidDisplay = IMG_FALSE;
	IMG_INT iSlot = 0;
	IMG_INT iFirstFreeSlot = -1;

    	pTls = TLS_Open (_TlsInit);
	    if (pTls==IMG_NULL)
		{
			return EGL_FALSE;
		}

⌨️ 快捷键说明

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