egl/sfopenvg/riMiniEGL.cpp
branchEGL_MERGE
changeset 180 f767bd5f4cfc
parent 119 5f371025658c
child 181 c1509651cd2b
equal deleted inserted replaced
119:5f371025658c 180:f767bd5f4cfc
     1 /*------------------------------------------------------------------------
       
     2  *
       
     3  * EGL 1.3
       
     4  * -------
       
     5  *
       
     6  * Copyright (c) 2007 The Khronos Group Inc.
       
     7  *
       
     8  * Permission is hereby granted, free of charge, to any person obtaining a
       
     9  * copy of this software and /or associated documentation files
       
    10  * (the "Materials "), to deal in the Materials without restriction,
       
    11  * including without limitation the rights to use, copy, modify, merge,
       
    12  * publish, distribute, sublicense, and/or sell copies of the Materials,
       
    13  * and to permit persons to whom the Materials are furnished to do so,
       
    14  * subject to the following conditions: 
       
    15  *
       
    16  * The above copyright notice and this permission notice shall be included 
       
    17  * in all copies or substantial portions of the Materials. 
       
    18  *
       
    19  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
       
    20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       
    21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
       
    22  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
       
    23  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
       
    24  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
       
    25  * THE USE OR OTHER DEALINGS IN THE MATERIALS.
       
    26  *
       
    27  *//**
       
    28  * \file
       
    29  * \brief	Simple implementation of EGL 1.3
       
    30  * \note	caveats:
       
    31 			- always renders into the backbuffer and blits it to window (no single buffered rendering)
       
    32 			- no native Windows or Mac OS X pixmap support
       
    33 			- no power management events
       
    34 			- no support for swap interval
       
    35  * \todo	what happens in egl functions when eglTerminate has been called but the context and surface are still in use?
       
    36  * \todo	OSDeinitMutex should be called in case getEGL fails.
       
    37  *//*-------------------------------------------------------------------*/
       
    38 
       
    39 //#include "riMiniEGL.h"
       
    40 #include "eglprivate.h"
       
    41 #include "riMath.h"
       
    42 #include <e32debug.h>
       
    43 
       
    44 //==============================================================================================
       
    45 
       
    46 namespace OpenVGRI
       
    47 {
       
    48 void* OSGetCurrentThreadID(void);
       
    49 void OSAcquireMutex(void);
       
    50 void OSReleaseMutex(void);
       
    51 void OSDeinitMutex(void);
       
    52 
       
    53 EGLDisplay OSGetDisplay(EGLNativeDisplayType display_id);
       
    54 void* OSCreateWindowContext(EGLNativeWindowType window);
       
    55 void OSDestroyWindowContext(void* context);
       
    56 bool OSIsWindow(const void* context);
       
    57 void OSGetWindowSize(const void* context, int& width, int& height);
       
    58 void OSBlitToWindow(void* context, const Drawable* drawable);
       
    59 EGLBoolean OSGetNativePixmapInfo(NativePixmapType pixmap, int* width, int* height, int* stride, VGImageFormat* format, int** data);
       
    60 
       
    61 
       
    62 
       
    63 /*-------------------------------------------------------------------*//*!
       
    64 * \brief	
       
    65 * \param	
       
    66 * \return	
       
    67 * \note		
       
    68 *//*-------------------------------------------------------------------*/
       
    69 
       
    70 class RIEGLContext
       
    71 {
       
    72 public:
       
    73 	RIEGLContext(OpenVGRI::VGContext* vgctx, const EGLConfig config);
       
    74 	~RIEGLContext();
       
    75 	void	addReference()				{ m_referenceCount++; }
       
    76 	int		removeReference()			{ m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; }
       
    77 
       
    78     VGContext*      getVGContext() const      { return m_vgContext; }
       
    79     EGLConfig getConfig() const         { return m_config; }
       
    80 private:
       
    81 	RIEGLContext(const RIEGLContext&);
       
    82 	RIEGLContext& operator=(const RIEGLContext&);
       
    83 	VGContext*		m_vgContext;
       
    84 	const EGLConfig	m_config;
       
    85 	int				m_referenceCount;
       
    86 };
       
    87 
       
    88 RIEGLContext* CastToRIEGLContext(EGLContext aCtxId);
       
    89 EGLContext CastFromRIEGLContext(RIEGLContext* aCtx);
       
    90 
       
    91 RIEGLContext::RIEGLContext(OpenVGRI::VGContext* vgctx, const EGLConfig config) :
       
    92 	m_vgContext(vgctx),
       
    93 	m_config(config),
       
    94 	m_referenceCount(0)
       
    95 {
       
    96 }
       
    97 RIEGLContext::~RIEGLContext()
       
    98 {
       
    99 	RI_ASSERT(m_referenceCount == 0);
       
   100 	RI_DELETE(m_vgContext);
       
   101 }
       
   102 
       
   103 /*-------------------------------------------------------------------*//*!
       
   104 * \brief	
       
   105 * \param	
       
   106 * \return	
       
   107 * \note		
       
   108 *//*-------------------------------------------------------------------*/
       
   109 
       
   110 class RIEGLSurface
       
   111 {
       
   112 public:
       
   113     RIEGLSurface(void* OSWindowContext, const EGLConfig config, Drawable* drawable, bool largestPbuffer, int renderBuffer);
       
   114 	~RIEGLSurface();
       
   115 	void	addReference()				{ m_referenceCount++; }
       
   116 	int		removeReference()			{ m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; }
       
   117 
       
   118     void*           getOSWindowContext() const { return m_OSWindowContext; }
       
   119     EGLConfig       getConfig() const          { return m_config; }
       
   120     Drawable*       getDrawable() const        { return m_drawable; }
       
   121     bool            isLargestPbuffer() const   { return m_largestPbuffer; }
       
   122     int             getRenderBuffer() const    { return m_renderBuffer; }
       
   123 
       
   124 private:
       
   125 	RIEGLSurface(const RIEGLSurface&);
       
   126 	RIEGLSurface& operator=(const RIEGLSurface&);
       
   127     void*            m_OSWindowContext;
       
   128 	const EGLConfig	 m_config;
       
   129 	Drawable*        m_drawable;
       
   130 	bool			 m_largestPbuffer;
       
   131 	int				 m_renderBuffer;		//EGL_BACK_BUFFER or EGL_SINGLE_BUFFER
       
   132 	int				 m_referenceCount;
       
   133 };
       
   134 
       
   135 RIEGLSurface* CastToRIEGLSurface(EGLSurface aSurfaceId);
       
   136 EGLSurface CastFromRIEGLSurface(RIEGLSurface* aSurface);
       
   137 
       
   138 RIEGLSurface::RIEGLSurface(void* OSWindowContext, const EGLConfig config, Drawable* drawable, bool largestPbuffer, int renderBuffer) :
       
   139     m_OSWindowContext(OSWindowContext),
       
   140 	m_config(config),
       
   141 	m_drawable(drawable),
       
   142 	m_largestPbuffer(largestPbuffer),
       
   143 	m_renderBuffer(renderBuffer),
       
   144 	m_referenceCount(0)
       
   145 {
       
   146     RI_ASSERT(m_renderBuffer == EGL_BACK_BUFFER);   //only back buffer rendering is supported
       
   147     m_drawable->addReference();
       
   148 }
       
   149 
       
   150 RIEGLSurface::~RIEGLSurface()
       
   151 {
       
   152 	RI_ASSERT(m_referenceCount == 0);
       
   153     OSDestroyWindowContext(m_OSWindowContext);
       
   154 	if(m_drawable)
       
   155 	{
       
   156 		if(!m_drawable->removeReference())
       
   157 			RI_DELETE(m_drawable);
       
   158 	}
       
   159 }
       
   160 
       
   161 RIEGLDisplay::RIEGLDisplay(EGLDisplay id) :
       
   162 	m_id(id),
       
   163 	m_contexts(),
       
   164 	m_surfaces()
       
   165 {
       
   166 	RI_ASSERT(EGL_NUMCONFIGS == 60);
       
   167 
       
   168 	//sorted by RGB/LUMINANCE (exact), larger total number of color bits (at least), buffer size (at least), config ID (exact)
       
   169 	//NOTE: 16 bit configs need to be sorted on the fly if the request ignores some channels
       
   170 	//NOTE: config IDs start from 1
       
   171 	//               R  B  G  A  L  bpp samples maskBits ID
       
   172 	m_configs[0].set(8, 8, 8, 8, 0, 32, 1, 8, 1);	//EGL_RGB_BUFFER, buffer size = 32
       
   173 	m_configs[1].set(8, 8, 8, 0, 0, 32, 1, 8, 2);	//EGL_RGB_BUFFER, buffer size = 24
       
   174 	m_configs[2].set(5, 5, 5, 1, 0, 16, 1, 4, 3);	//EGL_RGB_BUFFER, buffer size = 16
       
   175 	m_configs[3].set(5, 6, 5, 0, 0, 16, 1, 4, 4);	//EGL_RGB_BUFFER, buffer size = 16
       
   176 	m_configs[4].set(4, 4, 4, 4, 0, 16, 1, 4, 5);	//EGL_RGB_BUFFER, buffer size = 16
       
   177 	m_configs[5].set(0, 0, 0, 8, 0, 8,  1, 8, 6);	//EGL_RGB_BUFFER, buffer size = 8
       
   178 	m_configs[6].set(0, 0, 0, 4, 0, 4,  1, 4, 7);	//EGL_RGB_BUFFER, buffer size = 8
       
   179 	m_configs[7].set(0, 0, 0, 1, 0, 1,  1, 1, 8);	//EGL_RGB_BUFFER, buffer size = 8
       
   180 	m_configs[8].set(0, 0, 0, 0, 8, 8,  1, 8, 9);	//EGL_LUMINANCE_BUFFER, buffer size = 8
       
   181 	m_configs[9].set(0, 0, 0, 0, 1, 1,  1, 1, 10);	//EGL_LUMINANCE_BUFFER, buffer size = 1
       
   182 
       
   183 	m_configs[10].set(8, 8, 8, 8, 0, 32, 4, 1, 11);	//EGL_RGB_BUFFER, buffer size = 32
       
   184 	m_configs[11].set(8, 8, 8, 0, 0, 32, 4, 1, 12);	//EGL_RGB_BUFFER, buffer size = 24
       
   185 	m_configs[12].set(5, 5, 5, 1, 0, 16, 4, 1, 13);	//EGL_RGB_BUFFER, buffer size = 16
       
   186 	m_configs[13].set(5, 6, 5, 0, 0, 16, 4, 1, 14);	//EGL_RGB_BUFFER, buffer size = 16
       
   187 	m_configs[14].set(4, 4, 4, 4, 0, 16, 4, 1, 15);	//EGL_RGB_BUFFER, buffer size = 16
       
   188 	m_configs[15].set(0, 0, 0, 8, 0, 8,  4, 1, 16);	//EGL_RGB_BUFFER, buffer size = 8
       
   189 	m_configs[16].set(0, 0, 0, 4, 0, 4,  4, 1, 17);	//EGL_RGB_BUFFER, buffer size = 8
       
   190 	m_configs[17].set(0, 0, 0, 1, 0, 1,  4, 1, 18);	//EGL_RGB_BUFFER, buffer size = 8
       
   191 	m_configs[18].set(0, 0, 0, 0, 8, 8,  4, 1, 19);	//EGL_LUMINANCE_BUFFER, buffer size = 8
       
   192 	m_configs[19].set(0, 0, 0, 0, 1, 1,  4, 1, 20);	//EGL_LUMINANCE_BUFFER, buffer size = 1
       
   193 
       
   194 	m_configs[20].set(8, 8, 8, 8, 0, 32, 32, 1, 21);	//EGL_RGB_BUFFER, buffer size = 32
       
   195 	m_configs[21].set(8, 8, 8, 0, 0, 32, 32, 1, 22);	//EGL_RGB_BUFFER, buffer size = 24
       
   196 	m_configs[22].set(5, 5, 5, 1, 0, 16, 32, 1, 23);	//EGL_RGB_BUFFER, buffer size = 16
       
   197 	m_configs[23].set(5, 6, 5, 0, 0, 16, 32, 1, 24);	//EGL_RGB_BUFFER, buffer size = 16
       
   198 	m_configs[24].set(4, 4, 4, 4, 0, 16, 32, 1, 25);	//EGL_RGB_BUFFER, buffer size = 16
       
   199 	m_configs[25].set(0, 0, 0, 8, 0, 8,  32, 1, 26);	//EGL_RGB_BUFFER, buffer size = 8
       
   200 	m_configs[26].set(0, 0, 0, 4, 0, 4,  32, 1, 27);	//EGL_RGB_BUFFER, buffer size = 8
       
   201 	m_configs[27].set(0, 0, 0, 1, 0, 1,  32, 1, 28);	//EGL_RGB_BUFFER, buffer size = 8
       
   202 	m_configs[28].set(0, 0, 0, 0, 8, 8,  32, 1, 29);	//EGL_LUMINANCE_BUFFER, buffer size = 8
       
   203 	m_configs[29].set(0, 0, 0, 0, 1, 1,  32, 1, 30);	//EGL_LUMINANCE_BUFFER, buffer size = 1
       
   204 
       
   205     //configs without mask
       
   206 	m_configs[30].set(8, 8, 8, 8, 0, 32, 1, 0, 31);	//EGL_RGB_BUFFER, buffer size = 32
       
   207 	m_configs[31].set(8, 8, 8, 0, 0, 32, 1, 0, 32);	//EGL_RGB_BUFFER, buffer size = 24
       
   208 	m_configs[32].set(5, 5, 5, 1, 0, 16, 1, 0, 33);	//EGL_RGB_BUFFER, buffer size = 16
       
   209 	m_configs[33].set(5, 6, 5, 0, 0, 16, 1, 0, 34);	//EGL_RGB_BUFFER, buffer size = 16
       
   210 	m_configs[34].set(4, 4, 4, 4, 0, 16, 1, 0, 35);	//EGL_RGB_BUFFER, buffer size = 16
       
   211 	m_configs[35].set(0, 0, 0, 8, 0, 8,  1, 0, 36);	//EGL_RGB_BUFFER, buffer size = 8
       
   212 	m_configs[36].set(0, 0, 0, 4, 0, 4,  1, 0, 37);	//EGL_RGB_BUFFER, buffer size = 8
       
   213 	m_configs[37].set(0, 0, 0, 1, 0, 1,  1, 0, 38);	//EGL_RGB_BUFFER, buffer size = 8
       
   214 	m_configs[38].set(0, 0, 0, 0, 8, 8,  1, 0, 39);	//EGL_LUMINANCE_BUFFER, buffer size = 8
       
   215 	m_configs[39].set(0, 0, 0, 0, 1, 1,  1, 0, 40);	//EGL_LUMINANCE_BUFFER, buffer size = 1
       
   216 
       
   217 	m_configs[40].set(8, 8, 8, 8, 0, 32, 4, 0, 41);	//EGL_RGB_BUFFER, buffer size = 32
       
   218 	m_configs[41].set(8, 8, 8, 0, 0, 32, 4, 0, 42);	//EGL_RGB_BUFFER, buffer size = 24
       
   219 	m_configs[42].set(5, 5, 5, 1, 0, 16, 4, 0, 43);	//EGL_RGB_BUFFER, buffer size = 16
       
   220 	m_configs[43].set(5, 6, 5, 0, 0, 16, 4, 0, 44);	//EGL_RGB_BUFFER, buffer size = 16
       
   221 	m_configs[44].set(4, 4, 4, 4, 0, 16, 4, 0, 45);	//EGL_RGB_BUFFER, buffer size = 16
       
   222 	m_configs[45].set(0, 0, 0, 8, 0, 8,  4, 0, 46);	//EGL_RGB_BUFFER, buffer size = 8
       
   223 	m_configs[46].set(0, 0, 0, 4, 0, 4,  4, 0, 47);	//EGL_RGB_BUFFER, buffer size = 8
       
   224 	m_configs[47].set(0, 0, 0, 1, 0, 1,  4, 0, 48);	//EGL_RGB_BUFFER, buffer size = 8
       
   225 	m_configs[48].set(0, 0, 0, 0, 8, 8,  4, 0, 49);	//EGL_LUMINANCE_BUFFER, buffer size = 8
       
   226 	m_configs[49].set(0, 0, 0, 0, 1, 1,  4, 0, 50);	//EGL_LUMINANCE_BUFFER, buffer size = 1
       
   227 
       
   228 	m_configs[50].set(8, 8, 8, 8, 0, 32, 32, 0, 51);	//EGL_RGB_BUFFER, buffer size = 32
       
   229 	m_configs[51].set(8, 8, 8, 0, 0, 32, 32, 0, 52);	//EGL_RGB_BUFFER, buffer size = 24
       
   230 	m_configs[52].set(5, 5, 5, 1, 0, 16, 32, 0, 53);	//EGL_RGB_BUFFER, buffer size = 16
       
   231 	m_configs[53].set(5, 6, 5, 0, 0, 16, 32, 0, 54);	//EGL_RGB_BUFFER, buffer size = 16
       
   232 	m_configs[54].set(4, 4, 4, 4, 0, 16, 32, 0, 55);	//EGL_RGB_BUFFER, buffer size = 16
       
   233 	m_configs[55].set(0, 0, 0, 8, 0, 8,  32, 0, 56);	//EGL_RGB_BUFFER, buffer size = 8
       
   234 	m_configs[56].set(0, 0, 0, 4, 0, 4,  32, 0, 57);	//EGL_RGB_BUFFER, buffer size = 8
       
   235 	m_configs[57].set(0, 0, 0, 1, 0, 1,  32, 0, 58);	//EGL_RGB_BUFFER, buffer size = 8
       
   236 	m_configs[58].set(0, 0, 0, 0, 8, 8,  32, 0, 59);	//EGL_LUMINANCE_BUFFER, buffer size = 8
       
   237 	m_configs[59].set(0, 0, 0, 0, 1, 1,  32, 0, 60);	//EGL_LUMINANCE_BUFFER, buffer size = 1
       
   238 /*
       
   239 attrib                default        criteria order   priority
       
   240 --------------------------------------------------------------
       
   241 EGL_COLOR_BUFFER_TYPE EGL_RGB_BUFFER Exact    None    2 
       
   242 EGL_RED_SIZE          0              AtLeast  Special 3 
       
   243 EGL_GREEN_SIZE        0              AtLeast  Special 3 
       
   244 EGL_BLUE_SIZE         0              AtLeast  Special 3 
       
   245 EGL_LUMINANCE_SIZE    0              AtLeast  Special 3 
       
   246 EGL_ALPHA_SIZE        0              AtLeast  Special 3 
       
   247 EGL_BUFFER_SIZE       0              AtLeast  Smaller 4 
       
   248 EGL_CONFIG_ID         EGL_DONT_CARE  Exact    Smaller 11
       
   249 */
       
   250 }
       
   251 
       
   252 RIEGLDisplay::~RIEGLDisplay()
       
   253 {
       
   254 	//mark everything for deletion, but don't delete the current context and surface
       
   255 	for(int i=0;i<m_contexts.size();i++)
       
   256 	{
       
   257 		if(!m_contexts[i]->removeReference())
       
   258 			RI_DELETE(m_contexts[i]);
       
   259 	}
       
   260 	m_contexts.clear();	//remove all contexts from the list (makes further references to the current contexts invalid)
       
   261 
       
   262 	for(int i=0;i<m_surfaces.size();i++)
       
   263 	{
       
   264 		if(!m_surfaces[i]->removeReference())
       
   265 			RI_DELETE(m_surfaces[i]);
       
   266 	}
       
   267 	m_surfaces.clear();	//remove all surfaces from the list (makes further references to the current surfaces invalid)
       
   268 }
       
   269 
       
   270 EGLBoolean RIEGLDisplay::contextExists(const EGLContext ctx) const
       
   271 {
       
   272 	for(int i=0;i<m_contexts.size();i++)
       
   273 	{
       
   274 		if(m_contexts[i] == CastToRIEGLContext(ctx))
       
   275 			return EGL_TRUE;
       
   276 	}
       
   277 	return EGL_FALSE;
       
   278 }
       
   279 
       
   280 EGLBoolean RIEGLDisplay::surfaceExists(const EGLSurface surf) const
       
   281 {
       
   282 	for(int i=0;i<m_surfaces.size();i++)
       
   283 	{
       
   284 		if(m_surfaces[i] == CastToRIEGLSurface(surf))
       
   285 			return EGL_TRUE;
       
   286 	}
       
   287 	return EGL_FALSE;
       
   288 }
       
   289 
       
   290 EGLBoolean RIEGLDisplay::configExists(const EGLConfig config) const
       
   291 {
       
   292     for(int i=0;i<EGL_NUMCONFIGS;i++)
       
   293     {
       
   294         if(m_configs[i].m_config == config)
       
   295 		return EGL_TRUE;
       
   296     }
       
   297 	return EGL_FALSE;
       
   298 }
       
   299 
       
   300 /*-------------------------------------------------------------------*//*!
       
   301 * \brief	
       
   302 * \param	
       
   303 * \return	
       
   304 * \note		
       
   305 *//*-------------------------------------------------------------------*/
       
   306 
       
   307 class RIEGLThread
       
   308 {
       
   309 public:
       
   310 	RIEGLThread(void* currentThreadID);
       
   311 	~RIEGLThread();
       
   312 
       
   313     void*           getThreadID() const       { return m_threadID; }
       
   314 
       
   315     void            makeCurrent(RIEGLContext* c, RIEGLSurface* s)       { m_context = c; m_surface = s; }
       
   316 	RIEGLContext*	getCurrentContext() const   { return m_context; }
       
   317 	RIEGLSurface*	getCurrentSurface() const   { return m_surface; }
       
   318 
       
   319     void            setError(EGLint error)      { m_error = error; }
       
   320     EGLint          getError() const            { return m_error; }
       
   321 
       
   322     void            bindAPI(EGLint api)         { m_boundAPI = api; }
       
   323     EGLint          getBoundAPI() const         { return m_boundAPI; }
       
   324 
       
   325 private:
       
   326 	RIEGLThread(const RIEGLThread&);
       
   327 	RIEGLThread operator=(const RIEGLThread&);
       
   328 
       
   329 	RIEGLContext*		m_context;
       
   330 	RIEGLSurface*		m_surface;
       
   331 	EGLint              m_error;
       
   332 	void*               m_threadID;
       
   333 	EGLint              m_boundAPI;
       
   334 };
       
   335 
       
   336 RIEGLThread::RIEGLThread(void* currentThreadID) :
       
   337 	m_context(NULL),
       
   338 	m_surface(NULL),
       
   339 	m_error(EGL_SUCCESS),
       
   340 	m_threadID(currentThreadID),
       
   341 	m_boundAPI(EGL_NONE)
       
   342 {
       
   343 }
       
   344 
       
   345 RIEGLThread::~RIEGLThread()
       
   346 {
       
   347 }
       
   348 
       
   349 
       
   350 
       
   351 
       
   352 
       
   353 Image* CastToImage(EGLClientBuffer aBufferId);
       
   354 EGLClientBuffer CastFromImage(Image* aBUffer);
       
   355 
       
   356 
       
   357 
       
   358 EGL::EGL() :
       
   359 	m_threads(),
       
   360 	m_currentThreads(),
       
   361 	m_displays(),
       
   362 	m_referenceCount(0)
       
   363 {
       
   364 }
       
   365 EGL::~EGL()
       
   366 {
       
   367 	for(int i=0;i<m_displays.size();i++)
       
   368 	{
       
   369 		RI_DELETE(m_displays[i]);
       
   370 	}
       
   371 	for(int i=0;i<m_threads.size();i++)
       
   372 	{
       
   373 		RI_DELETE(m_threads[i]);
       
   374 	}
       
   375 	//currentThreads contain just pointers to threads we just deleted
       
   376 }
       
   377 
       
   378 /*-------------------------------------------------------------------*//*!
       
   379 * \brief	
       
   380 * \param	
       
   381 * \return	
       
   382 * \note		
       
   383 *//*-------------------------------------------------------------------*/
       
   384 
       
   385 //static EGL* g_egl = NULL;	//never use this directly
       
   386 EGL* getEGL()
       
   387 {
       
   388 	/*if(!g_egl)
       
   389 	{
       
   390 		try
       
   391 		{
       
   392 			g_egl = RI_NEW(EGL, ());				//throws bad_alloc
       
   393 			g_egl->addReference();
       
   394 		}
       
   395 		catch(std::bad_alloc)
       
   396 		{
       
   397 			g_egl = NULL;
       
   398 		}
       
   399 	}
       
   400 	return g_egl;
       
   401 	*/
       
   402 
       
   403 
       
   404 	//use TLS to store static global g_egl
       
   405 	EGL* pEgl = NULL;
       
   406 	
       
   407 	CEglThreadSession* es = reinterpret_cast<CEglThreadSession*>(Dll::Tls());
       
   408 	if (es)
       
   409 		{
       
   410 		return es->getEgl();
       
   411 		}
       
   412 	
       
   413 	const TInt err = CEglDriver::Open();
       
   414 	if (err != KErrNone)
       
   415 		{
       
   416 		return NULL;
       
   417 		}
       
   418 
       
   419 	// CEglDriver is reference counted. As we successfuly open the driver, pls.iDriver will be non-null
       
   420 	// and it should be safe to cache the pointer inside CEglThreadSession
       
   421 	CEglDriver* drv = CEglDriver::GetDriver();
       
   422 	__ASSERT_DEBUG(drv, User::Panic(KEglPanicCategory, EEglPanicDriverNull));
       
   423 
       
   424 	// create session object on default thread's heap
       
   425 	es = new CEglThreadSession(*drv);
       
   426 
       
   427 	if (!es || Dll::SetTls(es)!= KErrNone)
       
   428 		{
       
   429 		delete es;
       
   430 		return NULL;
       
   431 		}
       
   432 	return es->getEgl();
       
   433 }
       
   434 static void releaseEGL()
       
   435 {
       
   436 /*
       
   437 	if(g_egl)
       
   438 	{
       
   439 		if(!g_egl->removeReference())
       
   440 		{
       
   441 			RI_DELETE(g_egl);
       
   442 			g_egl = NULL;
       
   443 		}
       
   444 	}
       
   445 	*/
       
   446 	CEglThreadSession* es = reinterpret_cast<CEglThreadSession*>(Dll::Tls());
       
   447 	if (es)
       
   448 		{
       
   449 		delete es;
       
   450 		}
       
   451 	Dll::SetTls(NULL);
       
   452 }
       
   453 
       
   454 /*-------------------------------------------------------------------*//*!
       
   455 * \brief	Given a display ID, return the corresponding object, or NULL
       
   456 *			if the ID hasn't been initialized.
       
   457 * \param	
       
   458 * \return	
       
   459 * \note		if egl has been initialized for this display, the display ID can
       
   460 *			be found from egl->m_displays
       
   461 *//*-------------------------------------------------------------------*/
       
   462 
       
   463 RIEGLDisplay* EGL::getDisplay(EGLDisplay displayID) const
       
   464 {
       
   465 	for(int i=0;i<m_displays.size();i++)
       
   466 	{
       
   467 		if(displayID == m_displays[i]->getID())
       
   468 			return m_displays[i];
       
   469 	}
       
   470 	return NULL;		//error: the display hasn't been eglInitialized
       
   471 }
       
   472 
       
   473 /*-------------------------------------------------------------------*//*!
       
   474 * \brief	return EGLDisplay for the current context
       
   475 * \param	
       
   476 * \return	
       
   477 * \note		
       
   478 *//*-------------------------------------------------------------------*/
       
   479 
       
   480 EGLDisplay EGL::findDisplay(EGLContext ctx) const
       
   481 {
       
   482 	for(int i=0;i<m_displays.size();i++)
       
   483 	{
       
   484         if(m_displays[i]->contextExists(ctx))
       
   485             return m_displays[i]->getID();
       
   486 	}
       
   487     return EGL_NO_DISPLAY;
       
   488 }
       
   489 
       
   490 /*-------------------------------------------------------------------*//*!
       
   491 * \brief	return an EGL thread struct for the thread made current, or
       
   492 *            NULL if there's no current context.
       
   493 * \param	
       
   494 * \return	
       
   495 * \note		
       
   496 *//*-------------------------------------------------------------------*/
       
   497 
       
   498 RIEGLThread* EGL::getCurrentThread() const
       
   499 {
       
   500 	void* currentThreadID = OSGetCurrentThreadID();
       
   501 	for(int i=0;i<m_currentThreads.size();i++)
       
   502 	{
       
   503 		if(currentThreadID == m_currentThreads[i]->getThreadID())
       
   504 			return m_currentThreads[i];
       
   505 	}
       
   506 	return NULL;		//thread is not current
       
   507 }
       
   508 
       
   509 /*-------------------------------------------------------------------*//*!
       
   510 * \brief	return an EGL thread struct corresponding to current OS thread.
       
   511 * \param	
       
   512 * \return	
       
   513 * \note		
       
   514 *//*-------------------------------------------------------------------*/
       
   515 
       
   516 RIEGLThread* EGL::getThread()
       
   517 {
       
   518 	void* currentThreadID = OSGetCurrentThreadID();
       
   519 	for(int i=0;i<m_threads.size();i++)
       
   520 	{
       
   521 		if(currentThreadID == m_threads[i]->getThreadID())
       
   522 			return m_threads[i];
       
   523 	}
       
   524 
       
   525 	//EGL doesn't have a struct for the thread yet, add it to EGL's list
       
   526 	RIEGLThread* newThread = NULL;
       
   527 	try
       
   528 	{
       
   529 		newThread = RI_NEW(RIEGLThread, (OSGetCurrentThreadID()));	//throws bad_alloc
       
   530 		m_threads.push_back(newThread);	//throws bad_alloc
       
   531 		return newThread;
       
   532 	}
       
   533 	catch(std::bad_alloc)
       
   534 	{
       
   535 		RI_DELETE(newThread);
       
   536 		return NULL;
       
   537 	}
       
   538 }
       
   539 
       
   540 /*-------------------------------------------------------------------*//*!
       
   541 * \brief	destroy an EGL thread struct
       
   542 * \param	
       
   543 * \return	
       
   544 * \note		
       
   545 *//*-------------------------------------------------------------------*/
       
   546 
       
   547 void EGL::destroyThread()
       
   548 {
       
   549 	void* currentThreadID = OSGetCurrentThreadID();
       
   550 	for(int i=0;i<m_threads.size();i++)
       
   551 	{
       
   552 		if(currentThreadID == m_threads[i]->getThreadID())
       
   553         {
       
   554             RIEGLThread* thread = m_threads[i];
       
   555             bool res = m_threads.remove(thread);
       
   556             RI_ASSERT(res);
       
   557             RI_UNREF(res);
       
   558             RI_DELETE(thread);
       
   559             break;
       
   560         }
       
   561 	}
       
   562 }
       
   563 
       
   564 /*-------------------------------------------------------------------*//*!
       
   565 * \brief	
       
   566 * \param	
       
   567 * \return	
       
   568 * \note		
       
   569 *//*-------------------------------------------------------------------*/
       
   570 
       
   571 bool EGL::isInUse(const void* image) const
       
   572 {
       
   573     for(int i=0;i<m_currentThreads.size();i++)
       
   574     {
       
   575         RIEGLSurface* s = m_currentThreads[i]->getCurrentSurface();
       
   576         if(s && s->getDrawable() && s->getDrawable()->isInUse((Image*)image))
       
   577             return true;
       
   578     }
       
   579     return false;
       
   580 }
       
   581 
       
   582 /*-------------------------------------------------------------------*//*!
       
   583 * \brief	
       
   584 * \param	
       
   585 * \return	
       
   586 * \note		
       
   587 *//*-------------------------------------------------------------------*/
       
   588 
       
   589 #define EGL_GET_DISPLAY(DISPLAY, RETVAL) \
       
   590 	OSAcquireMutex(); \
       
   591 	EGL* egl = getEGL(); \
       
   592     if(!egl) \
       
   593     { \
       
   594 		OSReleaseMutex(); \
       
   595 		return RETVAL; \
       
   596     } \
       
   597 	RIEGLDisplay* display = egl->getDisplay(DISPLAY); \
       
   598 
       
   599 #define EGL_GET_EGL(RETVAL) \
       
   600 	OSAcquireMutex(); \
       
   601 	EGL* egl = getEGL(); \
       
   602     if(!egl) \
       
   603     { \
       
   604 		OSReleaseMutex(); \
       
   605 		return RETVAL; \
       
   606     } \
       
   607 
       
   608 #define EGL_IF_ERROR(COND, ERRORCODE, RETVAL) \
       
   609 	if(COND) { eglSetError(egl, ERRORCODE); OSReleaseMutex(); return RETVAL; } \
       
   610 
       
   611 #define EGL_RETURN(ERRORCODE, RETVAL) \
       
   612 	{ \
       
   613 		eglSetError(egl, ERRORCODE); \
       
   614 		OSReleaseMutex(); \
       
   615 		return RETVAL; \
       
   616 	}
       
   617 
       
   618 // Note: egl error handling model differs from OpenVG. The latest error is stored instead of the oldest one.
       
   619 static void eglSetError(EGL* egl, EGLint error)
       
   620 {
       
   621 	RIEGLThread* thread = egl->getThread();
       
   622 	if(thread)
       
   623 		thread->setError(error);
       
   624 }
       
   625 
       
   626 /*-------------------------------------------------------------------*//*!
       
   627 * \brief	Returns the OpenVG context current to the calling thread.
       
   628 * \param	
       
   629 * \return	
       
   630 * \note		This function is always called from a mutexed API function
       
   631 *//*-------------------------------------------------------------------*/
       
   632 
       
   633 void* eglvgGetCurrentVGContext(void)
       
   634 {
       
   635 	EGL* egl = getEGL();
       
   636     if(egl)
       
   637     {
       
   638         RIEGLThread* thread = egl->getCurrentThread();
       
   639         if(thread)
       
   640         {
       
   641             RI_ASSERT(thread->getCurrentContext() && thread->getCurrentSurface());
       
   642             return thread->getCurrentContext()->getVGContext();
       
   643         }
       
   644     }
       
   645 	return NULL;	//not initialized or made current
       
   646 }
       
   647 
       
   648 /*-------------------------------------------------------------------*//*!
       
   649 * \brief	Check if the image is current in any of the displays
       
   650 * \param	
       
   651 * \return	
       
   652 * \note		This function is always called from a mutexed API function
       
   653 *//*-------------------------------------------------------------------*/
       
   654 
       
   655 bool eglvgIsInUse(void* image)
       
   656 {
       
   657 	EGL* egl = getEGL();
       
   658     if(egl)
       
   659     {
       
   660         return egl->isInUse(image);
       
   661     }
       
   662 	return false;
       
   663 }
       
   664 
       
   665 //helper functions
       
   666 RIEGLContext* CastToRIEGLContext(EGLContext aCtxId)
       
   667   {
       
   668   return (RIEGLContext*)(aCtxId);
       
   669   }
       
   670 EGLContext CastFromRIEGLContext(RIEGLContext* aCtx)
       
   671   {
       
   672   return (EGLContext)(aCtx);
       
   673   }
       
   674 
       
   675 RIEGLSurface* CastToRIEGLSurface(EGLSurface aSurfaceId)
       
   676   {
       
   677   return (RIEGLSurface*)(aSurfaceId);
       
   678   }
       
   679 EGLSurface CastFromRIEGLSurface(RIEGLSurface* aSurface)
       
   680   {
       
   681   return (EGLSurface)(aSurface);
       
   682   }
       
   683 
       
   684 Image* CastToImage(EGLClientBuffer aBufferId)
       
   685   {
       
   686   return (Image*)(aBufferId);
       
   687   }
       
   688 
       
   689 EGLClientBuffer CastFromImage(Image* aBUffer)
       
   690   {
       
   691   return (EGLClientBuffer)(aBUffer);
       
   692   }
       
   693 
       
   694 //==============================================================================================
       
   695 
       
   696 }	//namespace OpenVGRI
       
   697 
       
   698 using namespace OpenVGRI;
       
   699 
       
   700 
       
   701 
       
   702 
       
   703 
       
   704 /*-------------------------------------------------------------------*//*!
       
   705 * \brief	
       
   706 * \param	
       
   707 * \return	
       
   708 * \note		
       
   709 *//*-------------------------------------------------------------------*/
       
   710 
       
   711 #ifdef BUILD_WITH_PRIVATE_EGL
       
   712 RI_APIENTRY EGLint do_eglGetError()
       
   713 #else
       
   714 EGLint eglGetError()
       
   715 #endif
       
   716 {
       
   717     OSAcquireMutex();
       
   718     EGLint ret = EGL_SUCCESS;
       
   719 	EGL* egl = getEGL();
       
   720     if(egl)
       
   721     {
       
   722         RIEGLThread* thread = egl->getThread();
       
   723         if(thread)
       
   724             ret = thread->getError();	//initialized, return error code
       
   725     }
       
   726     else ret = EGL_NOT_INITIALIZED;
       
   727     OSReleaseMutex();
       
   728     return ret;
       
   729 }
       
   730 
       
   731 /*-------------------------------------------------------------------*//*!
       
   732 * \brief	
       
   733 * \param	
       
   734 * \return	
       
   735 * \note		
       
   736 *//*-------------------------------------------------------------------*/
       
   737 
       
   738 #ifdef BUILD_WITH_PRIVATE_EGL
       
   739 RI_APIENTRY EGLDisplay do_eglGetDisplay(EGLNativeDisplayType display_id)
       
   740 #else
       
   741 EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
       
   742 #endif
       
   743 {
       
   744     return OSGetDisplay(display_id);
       
   745 }
       
   746 
       
   747 /*-------------------------------------------------------------------*//*!
       
   748 * \brief	
       
   749 * \param	
       
   750 * \return	
       
   751 * \note		
       
   752 *//*-------------------------------------------------------------------*/
       
   753 
       
   754 #ifdef BUILD_WITH_PRIVATE_EGL
       
   755 RI_APIENTRY EGLBoolean do_eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
       
   756 #else
       
   757 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
       
   758 #endif
       
   759 {
       
   760 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
   761 	EGL_IF_ERROR(display, EGL_SUCCESS, EGL_TRUE);	//already initialized
       
   762 
       
   763 	//create the current display
       
   764 	//if a context and a surface are bound by the time of eglTerminate, they remain bound until eglMakeCurrent is called
       
   765 	RIEGLDisplay* newDisplay = NULL;
       
   766 	try
       
   767 	{
       
   768 		newDisplay = RI_NEW(RIEGLDisplay, (dpy));	//throws bad_alloc
       
   769 		egl->addDisplay(newDisplay);	//throws bad_alloc
       
   770 		display = newDisplay;
       
   771 		RI_ASSERT(display);
       
   772 	}
       
   773 	catch(std::bad_alloc)
       
   774 	{
       
   775 		RI_DELETE(newDisplay);
       
   776 		EGL_RETURN(EGL_BAD_ALLOC, EGL_FALSE);
       
   777 	}
       
   778 
       
   779 	if(major) *major = 1;
       
   780 	if(minor) *minor = 2;
       
   781 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
   782 }
       
   783 
       
   784 /*-------------------------------------------------------------------*//*!
       
   785 * \brief	
       
   786 * \param	
       
   787 * \return	
       
   788 * \note		
       
   789 *//*-------------------------------------------------------------------*/
       
   790 
       
   791 #ifdef BUILD_WITH_PRIVATE_EGL
       
   792 RI_APIENTRY EGLBoolean do_eglTerminate(EGLDisplay dpy)
       
   793 #else
       
   794 EGLBoolean eglTerminate(EGLDisplay dpy)
       
   795 #endif
       
   796 {
       
   797 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
   798 	EGL_IF_ERROR(!display, EGL_SUCCESS, EGL_TRUE);
       
   799     egl->removeDisplay(display);
       
   800     RI_DELETE(display);
       
   801 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
   802 }
       
   803 
       
   804 /*-------------------------------------------------------------------*//*!
       
   805 * \brief	
       
   806 * \param	
       
   807 * \return	
       
   808 * \note		
       
   809 *//*-------------------------------------------------------------------*/
       
   810 
       
   811 #ifdef BUILD_WITH_PRIVATE_EGL
       
   812 RI_APIENTRY const char *do_eglQueryString(EGLDisplay dpy, EGLint name)
       
   813 #else
       
   814 const char *eglQueryString(EGLDisplay dpy, EGLint name)
       
   815 #endif
       
   816 {
       
   817 	EGL_GET_DISPLAY(dpy, NULL);
       
   818 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, NULL);
       
   819 
       
   820 	static const char apis[] = "OpenVG";
       
   821 	static const char extensions[] = "";
       
   822 	static const char vendor[] = "Khronos Group";
       
   823 	static const char version[] = "1.3";
       
   824 
       
   825 	const char* ret = NULL;
       
   826 	switch(name)
       
   827 	{
       
   828 	case EGL_CLIENT_APIS:
       
   829 		ret = apis;
       
   830 		break;
       
   831 
       
   832 	case EGL_EXTENSIONS:
       
   833 		ret = extensions;
       
   834 		break;
       
   835 
       
   836 	case EGL_VENDOR:
       
   837 		ret = vendor;
       
   838 		break;
       
   839 
       
   840 	case EGL_VERSION:
       
   841 		ret = version;
       
   842 		break;
       
   843 
       
   844 	default:
       
   845 		EGL_RETURN(EGL_BAD_PARAMETER, NULL);
       
   846 	}
       
   847 	EGL_RETURN(EGL_SUCCESS, ret);
       
   848 }
       
   849 
       
   850 /*-------------------------------------------------------------------*//*!
       
   851 * \brief	
       
   852 * \param	
       
   853 * \return	
       
   854 * \note		
       
   855 *//*-------------------------------------------------------------------*/
       
   856 
       
   857 #ifdef BUILD_WITH_PRIVATE_EGL
       
   858 RI_APIENTRY EGLBoolean do_eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
       
   859 #else
       
   860 EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
       
   861 #endif
       
   862 {
       
   863 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
   864 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
       
   865 	EGL_IF_ERROR(!num_config, EGL_BAD_PARAMETER, EGL_FALSE);
       
   866 	if(!configs)
       
   867 	{
       
   868 		*num_config = display->getNumConfigs();
       
   869 		EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
   870 	}
       
   871 	*num_config = RI_INT_MIN(config_size, display->getNumConfigs());
       
   872 	for(int i=0;i<*num_config;i++)
       
   873 		configs[i] = display->getConfigByIdx(i).m_config;
       
   874 
       
   875 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
   876 }
       
   877 
       
   878 /*-------------------------------------------------------------------*//*!
       
   879 * \brief	
       
   880 * \param	
       
   881 * \return	
       
   882 * \note		
       
   883 *//*-------------------------------------------------------------------*/
       
   884 
       
   885 static bool smaller(EGLint c, EGLint filter)
       
   886 {
       
   887 	return (filter != EGL_DONT_CARE) && (c < filter);
       
   888 }
       
   889 
       
   890 #ifdef BUILD_WITH_PRIVATE_EGL
       
   891 RI_APIENTRY EGLBoolean do_eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
       
   892 #else
       
   893 EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
       
   894 #endif
       
   895 {
       
   896 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
   897 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
       
   898 	EGL_IF_ERROR(!num_config, EGL_BAD_PARAMETER, EGL_FALSE);
       
   899 
       
   900 	if(!configs)
       
   901 	{
       
   902 		*num_config = display->getNumConfigs();
       
   903 		EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
   904 	}
       
   905 	*num_config = 0;
       
   906 	if(!config_size)
       
   907 		EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
   908 
       
   909 	int bufferSize = 0;
       
   910 	int redSize = 0;
       
   911 	int greenSize = 0;
       
   912 	int blueSize = 0;
       
   913 	int luminanceSize = 0;
       
   914 	int alphaSize = 0;
       
   915 	int colorBufferType = EGL_RGB_BUFFER;
       
   916 	int configID = EGL_DONT_CARE;
       
   917 	int sampleBuffers = 0;
       
   918 	int samples = 0;
       
   919 	if(attrib_list)
       
   920 	{
       
   921 		for(int i=0;attrib_list[i] != EGL_NONE;i+=2)
       
   922 		{
       
   923 			switch(attrib_list[i])
       
   924 			{
       
   925 			case EGL_BUFFER_SIZE:				//depth of the color buffer
       
   926 				bufferSize = attrib_list[i+1];
       
   927 				break;
       
   928 			case EGL_RED_SIZE:					//bits of Red in the color buffer
       
   929 				redSize = attrib_list[i+1];
       
   930 				break;
       
   931 			case EGL_GREEN_SIZE:				//bits of Green in the color buffer
       
   932 				greenSize = attrib_list[i+1];
       
   933 				break;
       
   934 			case EGL_BLUE_SIZE:					//bits of Blue in the color buffer
       
   935 				blueSize = attrib_list[i+1];
       
   936 				break;
       
   937 			case EGL_LUMINANCE_SIZE:			//bits of Luminance in the color buffer
       
   938 				luminanceSize = attrib_list[i+1];
       
   939 				break;
       
   940 			case EGL_ALPHA_SIZE:				//bits of Alpha in the color buffer
       
   941 				alphaSize = attrib_list[i+1];
       
   942 				break;
       
   943 			case EGL_ALPHA_MASK_SIZE:			//bits of Alpha in the alpha mask buffer
       
   944 				if(attrib_list[i+1] > 8)
       
   945 					EGL_RETURN(EGL_SUCCESS, EGL_TRUE);	//not supported
       
   946 				break;
       
   947 			case EGL_COLOR_BUFFER_TYPE:			//enum color buffer type (EGL_RGB_BUFFER, EGL_LUMINANCE_BUFFER)
       
   948 				EGL_IF_ERROR(attrib_list[i+1] != EGL_RGB_BUFFER && attrib_list[i+1] != EGL_LUMINANCE_BUFFER && attrib_list[i+1] != EGL_DONT_CARE, EGL_BAD_ATTRIBUTE, EGL_FALSE);
       
   949 				colorBufferType = attrib_list[i+1];
       
   950 				break;
       
   951 			case EGL_CONFIG_ID:					//unique EGLConfig identifier
       
   952 				configID = attrib_list[i+1];
       
   953 				break;
       
   954 
       
   955 			case EGL_SAMPLE_BUFFERS:			//integer number of multisample buffers
       
   956 				sampleBuffers = attrib_list[i+1];
       
   957 				break;
       
   958 			case EGL_SAMPLES:					//integer number of samples per pixel
       
   959 				samples = attrib_list[i+1];
       
   960 				break;
       
   961 
       
   962 			case EGL_BIND_TO_TEXTURE_RGB:		//boolean True if bindable to RGB textures. (always EGL_FALSE)
       
   963 			case EGL_BIND_TO_TEXTURE_RGBA:		//boolean True if bindable to RGBA textures. (always EGL_FALSE)
       
   964 			case EGL_DEPTH_SIZE:				//integer bits of Z in the depth buffer (always 0)
       
   965 			case EGL_LEVEL:						//integer frame buffer level (always 0)
       
   966 			case EGL_NATIVE_RENDERABLE:			//boolean EGL TRUE if native rendering APIs can render to surface (always EGL_FALSE)
       
   967 			case EGL_STENCIL_SIZE:				//integer bits of Stencil in the stencil buffer (always 0)
       
   968 				if(attrib_list[i+1])
       
   969 					EGL_RETURN(EGL_SUCCESS, EGL_TRUE);	//not supported
       
   970 				break;
       
   971 
       
   972 			case EGL_CONFIG_CAVEAT:				//enum any caveats for the configuration (always EGL_NONE)
       
   973 			case EGL_NATIVE_VISUAL_TYPE:		//integer native visual type of the associated visual (always EGL_NONE)
       
   974 				if(attrib_list[i+1] != EGL_NONE)
       
   975 					EGL_RETURN(EGL_SUCCESS, EGL_TRUE);	//not supported
       
   976 				break;
       
   977 
       
   978 			case EGL_MAX_SWAP_INTERVAL:			//integer maximum swap interval (always 1)
       
   979 			case EGL_MIN_SWAP_INTERVAL:			//integer minimum swap interval (always 1)
       
   980 				if(attrib_list[i+1] != 1)
       
   981 					EGL_RETURN(EGL_SUCCESS, EGL_TRUE);	//not supported
       
   982 				break;
       
   983 
       
   984 			case EGL_RENDERABLE_TYPE:			//bitmask which client rendering APIs are supported. (always EGL_OPENVG_BIT)
       
   985 				if(!(attrib_list[i+1] & EGL_OPENVG_BIT))
       
   986 					EGL_RETURN(EGL_SUCCESS, EGL_TRUE);	//not supported
       
   987 				break;
       
   988 
       
   989 			case EGL_SURFACE_TYPE:				//bitmask which types of EGL surfaces are supported. (always EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT | EGL_VG_COLORSPACE_LINEAR_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT)
       
   990 				break;	//all types are always supported
       
   991 
       
   992 			case EGL_TRANSPARENT_TYPE:			//enum type of transparency supported (always EGL_NONE)
       
   993 			case EGL_NATIVE_VISUAL_ID:			//integer handle of corresponding native visual (always 0)
       
   994 			case EGL_MAX_PBUFFER_WIDTH:			//integer maximum width of pbuffer (always INT_MAX)
       
   995 			case EGL_MAX_PBUFFER_HEIGHT:		//integer maximum height of pbuffer (always INT_MAX)
       
   996 			case EGL_MAX_PBUFFER_PIXELS:		//integer maximum size of pbuffer (always INT_MAX)
       
   997 			case EGL_TRANSPARENT_RED_VALUE:		//integer transparent red value (undefined)
       
   998 			case EGL_TRANSPARENT_GREEN_VALUE:	//integer transparent green value (undefined)
       
   999 			case EGL_TRANSPARENT_BLUE_VALUE:	//integer transparent blue value (undefined)
       
  1000 				break;	//ignored
       
  1001 
       
  1002 			default:
       
  1003 				EGL_RETURN(EGL_BAD_ATTRIBUTE, EGL_FALSE);	//unknown attribute
       
  1004 			}
       
  1005 		}
       
  1006 	}
       
  1007 
       
  1008 	if(configID && configID != EGL_DONT_CARE)
       
  1009 	{	//if CONFIG_ID is defined, ignore the rest of the attribs
       
  1010         for(int i=0;i<EGL_NUMCONFIGS;i++)
       
  1011         {
       
  1012             if(display->getConfigByIdx(i).m_configID == configID)
       
  1013             {
       
  1014                 *num_config = 1;
       
  1015                 *configs = display->getConfigByIdx(i).m_config;
       
  1016             }
       
  1017         }
       
  1018 		EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  1019 	}
       
  1020 
       
  1021 	//go through all configs, add passed configs to return list
       
  1022     //TODO take alpha mask size into account
       
  1023 	EGLConfig found[EGL_NUMCONFIGS];
       
  1024     int keys[EGL_NUMCONFIGS];
       
  1025 	int numFound = 0;
       
  1026 	for(int i=0;i<display->getNumConfigs();i++)
       
  1027 	{
       
  1028 		const RIEGLConfig& c = display->getConfigByIdx(i);
       
  1029 
       
  1030 		int colorBits = c.m_desc.redBits + c.m_desc.greenBits + c.m_desc.blueBits;
       
  1031 		int luminanceBits = c.m_desc.luminanceBits;
       
  1032 		int configBufferSize;
       
  1033 		if(colorBits)
       
  1034 		{
       
  1035 			RI_ASSERT(!luminanceBits);
       
  1036 			colorBits += c.m_desc.alphaBits;
       
  1037 			configBufferSize = colorBits;
       
  1038 		}
       
  1039 		else if(luminanceBits)
       
  1040 		{
       
  1041 			luminanceBits += c.m_desc.alphaBits;
       
  1042 			configBufferSize = luminanceBits;
       
  1043 		}
       
  1044 		else
       
  1045 		{	//alpha only surface
       
  1046 			colorBits = c.m_desc.alphaBits;
       
  1047 			luminanceBits = c.m_desc.alphaBits;
       
  1048 			configBufferSize = colorBits;
       
  1049 		}
       
  1050 
       
  1051 		if (smaller(configBufferSize, bufferSize))
       
  1052 			continue;
       
  1053 
       
  1054 		int configSampleBuffers = c.m_samples == 1 ? 0 : 1;
       
  1055 		if (smaller(configSampleBuffers, sampleBuffers))
       
  1056 			continue;
       
  1057 		if (smaller(c.m_samples, samples))
       
  1058 			continue;
       
  1059 
       
  1060 		if (smaller(c.m_desc.redBits, redSize)
       
  1061 			|| smaller(c.m_desc.greenBits, greenSize)
       
  1062 			|| smaller(c.m_desc.blueBits, blueSize) 
       
  1063 			|| smaller(c.m_desc.alphaBits, alphaSize) )
       
  1064 			continue;
       
  1065 
       
  1066 		if (smaller(c.m_desc.luminanceBits, luminanceSize))
       
  1067 			continue;
       
  1068 
       
  1069 		if ((colorBufferType == EGL_RGB_BUFFER && !colorBits) ||
       
  1070 			(colorBufferType == EGL_LUMINANCE_BUFFER && !luminanceBits))
       
  1071 			continue;
       
  1072 
       
  1073 		int sortKey = c.m_configID;	//sort from smaller to larger
       
  1074 		int sortBits = 0;
       
  1075 		if(redSize != 0 && redSize != EGL_DONT_CARE)
       
  1076 			sortBits += c.m_desc.redBits;
       
  1077 		if(greenSize != 0 && greenSize != EGL_DONT_CARE)
       
  1078 			sortBits += c.m_desc.greenBits;
       
  1079 		if(blueSize != 0 && blueSize != EGL_DONT_CARE)
       
  1080 			sortBits += c.m_desc.blueBits;
       
  1081 		if(alphaSize != 0 && alphaSize != EGL_DONT_CARE)
       
  1082 			sortBits += c.m_desc.alphaBits;
       
  1083 		if(luminanceSize != 0 && luminanceSize != EGL_DONT_CARE)
       
  1084 			sortBits += c.m_desc.luminanceBits;
       
  1085 		RI_ASSERT(c.m_configID <= EGL_NUMCONFIGS);	//if there are more configs, increase the shift value
       
  1086 		RI_ASSERT(sortBits <= 32);
       
  1087 		sortKey += (32-sortBits) << 4;	//sort from larger to smaller
       
  1088 
       
  1089 		found[numFound] = c.m_config;
       
  1090 		keys[numFound++] = sortKey;
       
  1091 	}
       
  1092 	if(!numFound)
       
  1093 		EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  1094 
       
  1095 	//sort return list into increasing order
       
  1096 	for(int e=0;e<numFound-1;e++)
       
  1097 	{
       
  1098 		for(int f=e+1;f<numFound;f++)
       
  1099 		{
       
  1100 			if(keys[e] > keys[f])
       
  1101 			{
       
  1102                 EGLConfig tmp = found[e];
       
  1103                 found[e] = found[f];
       
  1104                 found[f] = tmp;
       
  1105 				RI_INT_SWAP(keys[e], keys[f]);
       
  1106 			}
       
  1107 		}
       
  1108 	}
       
  1109 
       
  1110 	//write configs into return array
       
  1111 	numFound = RI_INT_MIN(numFound, config_size);
       
  1112 	for(int i=0;i<numFound;i++)
       
  1113 	{
       
  1114 		configs[i] = found[i];
       
  1115 	}
       
  1116 	*num_config = numFound;
       
  1117 
       
  1118 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  1119 }
       
  1120 
       
  1121 /*-------------------------------------------------------------------*//*!
       
  1122 * \brief	
       
  1123 * \param	
       
  1124 * \return	
       
  1125 * \note		
       
  1126 *//*-------------------------------------------------------------------*/
       
  1127 
       
  1128 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1129 RI_APIENTRY EGLBoolean do_eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
       
  1130 #else
       
  1131 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
       
  1132 #endif
       
  1133 {
       
  1134 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
  1135 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
       
  1136 	EGL_IF_ERROR(!display->configExists(config), EGL_BAD_CONFIG, EGL_FALSE);
       
  1137 	const RIEGLConfig& c = display->getConfig(config);
       
  1138 	switch(attribute)
       
  1139 	{
       
  1140 	case EGL_BUFFER_SIZE:
       
  1141 		*value = RI_INT_MAX(c.m_desc.redBits + c.m_desc.greenBits + c.m_desc.blueBits + c.m_desc.alphaBits, c.m_desc.luminanceBits + c.m_desc.alphaBits);
       
  1142 		break;
       
  1143 
       
  1144 	case EGL_RED_SIZE:
       
  1145 		*value = c.m_desc.redBits;
       
  1146 		break;
       
  1147 
       
  1148 	case EGL_GREEN_SIZE:
       
  1149 		*value = c.m_desc.greenBits;
       
  1150 		break;
       
  1151 
       
  1152 	case EGL_BLUE_SIZE:
       
  1153 		*value = c.m_desc.blueBits;
       
  1154 		break;
       
  1155 
       
  1156 	case EGL_LUMINANCE_SIZE:
       
  1157 		*value = c.m_desc.luminanceBits;
       
  1158 		break;
       
  1159 
       
  1160 	case EGL_ALPHA_SIZE:
       
  1161 		*value = c.m_desc.alphaBits;
       
  1162 		break;
       
  1163 
       
  1164 	case EGL_ALPHA_MASK_SIZE:
       
  1165 		*value = c.m_maskBits;
       
  1166 		break;
       
  1167 
       
  1168 	case EGL_BIND_TO_TEXTURE_RGB:
       
  1169 	case EGL_BIND_TO_TEXTURE_RGBA:
       
  1170 		*value = EGL_FALSE;
       
  1171 		break;
       
  1172 
       
  1173 	case EGL_COLOR_BUFFER_TYPE:
       
  1174 		if(c.m_desc.redBits)
       
  1175 			*value = EGL_RGB_BUFFER;
       
  1176 		else
       
  1177 			*value = EGL_LUMINANCE_BUFFER;
       
  1178 		break;
       
  1179 
       
  1180 	case EGL_CONFIG_CAVEAT:
       
  1181 		*value = EGL_NONE;
       
  1182 		break;
       
  1183 
       
  1184 	case EGL_CONFIG_ID:
       
  1185 		*value = c.m_configID;
       
  1186 		break;
       
  1187 
       
  1188 	case EGL_DEPTH_SIZE:
       
  1189 		*value = 0;
       
  1190 		break;
       
  1191 
       
  1192 	case EGL_LEVEL:
       
  1193 		*value = 0;
       
  1194 		break;
       
  1195 
       
  1196 	case EGL_MAX_PBUFFER_WIDTH:
       
  1197 	case EGL_MAX_PBUFFER_HEIGHT:
       
  1198 		*value = 16384;			//NOTE arbitrary maximum
       
  1199 		break;
       
  1200 		
       
  1201 	case EGL_MAX_PBUFFER_PIXELS:
       
  1202 		*value = 16384*16384;	//NOTE arbitrary maximum
       
  1203 		break;
       
  1204 
       
  1205 	case EGL_MAX_SWAP_INTERVAL:
       
  1206 	case EGL_MIN_SWAP_INTERVAL:
       
  1207 		*value = 1;
       
  1208 		break;
       
  1209 
       
  1210 	case EGL_NATIVE_RENDERABLE:
       
  1211 		*value = EGL_FALSE;
       
  1212 		break;
       
  1213 
       
  1214 	case EGL_NATIVE_VISUAL_ID:
       
  1215 		*value = 0;
       
  1216 		break;
       
  1217 
       
  1218 	case EGL_NATIVE_VISUAL_TYPE:
       
  1219 		*value = EGL_NONE;
       
  1220 		break;
       
  1221 
       
  1222 	case EGL_RENDERABLE_TYPE:
       
  1223 		*value = EGL_OPENVG_BIT;
       
  1224 		break;
       
  1225 
       
  1226 	case EGL_SAMPLE_BUFFERS:
       
  1227 		*value = c.m_samples > 1 ? 1 : 0;
       
  1228 		break;
       
  1229 
       
  1230 	case EGL_SAMPLES:
       
  1231 		*value = c.m_samples > 1 ? c.m_samples : 0;
       
  1232 		break;
       
  1233 
       
  1234 	case EGL_STENCIL_SIZE:
       
  1235 		*value = 0;
       
  1236 		break;
       
  1237 
       
  1238 	case EGL_SURFACE_TYPE:
       
  1239 		*value = EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT | EGL_VG_COLORSPACE_LINEAR_BIT | EGL_VG_ALPHA_FORMAT_PRE_BIT;
       
  1240 		break;
       
  1241 
       
  1242 	case EGL_TRANSPARENT_TYPE:
       
  1243 		*value = EGL_NONE;
       
  1244 		break;
       
  1245 
       
  1246 	case EGL_TRANSPARENT_RED_VALUE:
       
  1247 	case EGL_TRANSPARENT_GREEN_VALUE:
       
  1248 	case EGL_TRANSPARENT_BLUE_VALUE:
       
  1249 		*value = 0;
       
  1250 		break;
       
  1251 
       
  1252     case EGL_CONFORMANT:
       
  1253         *value = EGL_OPENVG_BIT;  //TODO return proper value
       
  1254         break;
       
  1255 
       
  1256 	default:
       
  1257 		EGL_RETURN(EGL_BAD_ATTRIBUTE, EGL_FALSE);
       
  1258 	}
       
  1259 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  1260 }
       
  1261 
       
  1262 /*-------------------------------------------------------------------*//*!
       
  1263 * \brief	
       
  1264 * \param	
       
  1265 * \return	
       
  1266 * \note		
       
  1267 *//*-------------------------------------------------------------------*/
       
  1268 
       
  1269 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1270 RI_APIENTRY EGLSurface do_eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
       
  1271 #else
       
  1272 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
       
  1273 #endif
       
  1274 {
       
  1275 	EGL_GET_DISPLAY(dpy, EGL_NO_SURFACE);
       
  1276 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
       
  1277 	EGL_IF_ERROR(!display->configExists(config), EGL_BAD_CONFIG, EGL_NO_SURFACE);
       
  1278 
       
  1279 	int renderBuffer = EGL_BACK_BUFFER;
       
  1280 	int colorSpace = EGL_VG_COLORSPACE_sRGB;
       
  1281 	int alphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
       
  1282 	if(attrib_list)
       
  1283 	{
       
  1284 		for(int i=0;attrib_list[i] != EGL_NONE;i+=2)
       
  1285 		{
       
  1286 			switch(attrib_list[i])
       
  1287 			{
       
  1288 			case EGL_RENDER_BUFFER:
       
  1289 				renderBuffer = attrib_list[i+1];
       
  1290 				break;
       
  1291 
       
  1292 			case EGL_VG_COLORSPACE:
       
  1293 				colorSpace = attrib_list[i+1];
       
  1294 				break;
       
  1295 
       
  1296 			case EGL_VG_ALPHA_FORMAT:
       
  1297 				alphaFormat = attrib_list[i+1];
       
  1298 				break;
       
  1299 
       
  1300 			default:
       
  1301 				EGL_RETURN(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
       
  1302 			}
       
  1303 		}
       
  1304 	}
       
  1305 	//we ignore the renderBuffer parameter since we can only render to double buffered surfaces
       
  1306 
       
  1307 	//TODO If the attributes of win do not correspond to config, then an EGL BAD MATCH error is generated.
       
  1308 	//TODO If there is already an EGLConfig associated with win (as a result of a previous eglCreateWindowSurface call), then an EGL BAD ALLOC error is generated
       
  1309 
       
  1310     void* wc = NULL;
       
  1311     Drawable* d = NULL;
       
  1312 	RIEGLSurface* s = NULL;
       
  1313 	try
       
  1314 	{
       
  1315         wc = OSCreateWindowContext(win);
       
  1316 		RI_ASSERT(wc);
       
  1317 		//TODO what should happen if window width or height is zero?
       
  1318 		int windowWidth = 0, windowHeight = 0;
       
  1319 		OSGetWindowSize(wc, windowWidth, windowHeight);
       
  1320         bool isWindow = OSIsWindow(wc);
       
  1321 		if(windowWidth <= 0 || windowHeight <= 0 || !isWindow)
       
  1322 		{
       
  1323             OSDestroyWindowContext(wc);
       
  1324             EGL_IF_ERROR(!isWindow, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
       
  1325 			EGL_IF_ERROR(windowWidth <= 0 || windowHeight <= 0, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
       
  1326 		}
       
  1327 		d = RI_NEW(Drawable, (display->getConfig(config).configToDescriptor((colorSpace == EGL_VG_COLORSPACE_LINEAR) ? false : true, (alphaFormat == EGL_VG_ALPHA_FORMAT_PRE) ? true : false), windowWidth, windowHeight, display->getConfig(config).m_samples, display->getConfig(config).m_maskBits));	//throws bad_alloc
       
  1328 		RI_ASSERT(d);
       
  1329 		s = RI_NEW(RIEGLSurface,(wc, config, d, false, renderBuffer));	//throws bad_alloc
       
  1330 		RI_ASSERT(s);
       
  1331 		s->addReference();
       
  1332 		display->addSurface(s);	//throws bad_alloc
       
  1333 	}
       
  1334 	catch(std::bad_alloc)
       
  1335 	{
       
  1336         OSDestroyWindowContext(wc);
       
  1337         RI_DELETE(d);
       
  1338         RI_DELETE(s);
       
  1339 		EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_SURFACE);
       
  1340 	}
       
  1341 	EGL_RETURN(EGL_SUCCESS, (EGLSurface)s);
       
  1342 }
       
  1343 
       
  1344 /*-------------------------------------------------------------------*//*!
       
  1345 * \brief	
       
  1346 * \param	
       
  1347 * \return	
       
  1348 * \note		
       
  1349 *//*-------------------------------------------------------------------*/
       
  1350 
       
  1351 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1352 RI_APIENTRY EGLSurface do_eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
       
  1353 #else
       
  1354 EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
       
  1355 #endif
       
  1356 {
       
  1357 	EGL_GET_DISPLAY(dpy, EGL_NO_SURFACE);
       
  1358 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
       
  1359 	EGL_IF_ERROR(!display->configExists(config), EGL_BAD_CONFIG, EGL_NO_SURFACE);
       
  1360 
       
  1361 	int width = 0, height = 0;
       
  1362 	bool largestPbuffer = false;
       
  1363 	int colorSpace = EGL_VG_COLORSPACE_sRGB;
       
  1364 	int alphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
       
  1365 	if(attrib_list)
       
  1366 	{
       
  1367 		for(int i=0;attrib_list[i] != EGL_NONE;i+=2)
       
  1368 		{
       
  1369 			switch(attrib_list[i])
       
  1370 			{
       
  1371 			case EGL_WIDTH:
       
  1372 				width = attrib_list[i+1];
       
  1373 				break;
       
  1374 
       
  1375 			case EGL_HEIGHT:
       
  1376 				height = attrib_list[i+1];
       
  1377 				break;
       
  1378 
       
  1379 			case EGL_LARGEST_PBUFFER:
       
  1380 				largestPbuffer = attrib_list[i+1] ? true : false;
       
  1381 				break;
       
  1382 
       
  1383 			case EGL_VG_COLORSPACE:
       
  1384 				colorSpace = attrib_list[i+1];
       
  1385 				break;
       
  1386 
       
  1387 			case EGL_VG_ALPHA_FORMAT:
       
  1388 				alphaFormat = attrib_list[i+1];
       
  1389 				break;
       
  1390 
       
  1391 			case EGL_TEXTURE_FORMAT:	//config doesn't support OpenGL ES
       
  1392 			case EGL_TEXTURE_TARGET:	//config doesn't support OpenGL ES
       
  1393 			case EGL_MIPMAP_TEXTURE:	//config doesn't support OpenGL ES
       
  1394 			default:
       
  1395 				EGL_RETURN(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
       
  1396 			}
       
  1397 		}
       
  1398 	}
       
  1399 	EGL_IF_ERROR(width <= 0 || height <= 0, EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
       
  1400 
       
  1401     Drawable* d = NULL;
       
  1402 	RIEGLSurface* s = NULL;
       
  1403 	try
       
  1404 	{
       
  1405 		d = RI_NEW(Drawable, (display->getConfig(config).configToDescriptor((colorSpace == EGL_VG_COLORSPACE_LINEAR) ? false : true, (alphaFormat == EGL_VG_ALPHA_FORMAT_PRE) ? true : false), width, height, display->getConfig(config).m_samples, display->getConfig(config).m_maskBits));	//throws bad_alloc
       
  1406 		RI_ASSERT(d);
       
  1407 		s = RI_NEW(RIEGLSurface,(NULL, config, d, largestPbuffer, EGL_BACK_BUFFER));	//throws bad_alloc
       
  1408 		RI_ASSERT(s);
       
  1409 		s->addReference();
       
  1410 		display->addSurface(s);	//throws bad_alloc
       
  1411 	}
       
  1412 	catch(std::bad_alloc)
       
  1413 	{
       
  1414         RI_DELETE(d);
       
  1415         RI_DELETE(s);
       
  1416 		EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_SURFACE);
       
  1417 	}
       
  1418 	EGL_RETURN(EGL_SUCCESS, (EGLSurface)s);
       
  1419 }
       
  1420 
       
  1421 /*-------------------------------------------------------------------*//*!
       
  1422 * \brief	
       
  1423 * \param	
       
  1424 * \return	
       
  1425 * \note		
       
  1426 *//*-------------------------------------------------------------------*/
       
  1427 
       
  1428 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1429 RI_APIENTRY EGLSurface do_eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
       
  1430 #else
       
  1431 EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
       
  1432 #endif
       
  1433 {
       
  1434 	EGL_GET_DISPLAY(dpy, EGL_NO_SURFACE);
       
  1435 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
       
  1436 	EGL_IF_ERROR(buftype != EGL_OPENVG_IMAGE, EGL_BAD_PARAMETER, EGL_NO_SURFACE);
       
  1437 	EGL_IF_ERROR(!buffer, EGL_BAD_PARAMETER, EGL_NO_SURFACE);	//TODO should also check if buffer really is a valid VGImage object (needs VG context for that)
       
  1438     Image* image = (Image*)buffer;
       
  1439 	EGL_IF_ERROR(image->isInUse(), EGL_BAD_ACCESS, EGL_NO_SURFACE);	//buffer is in use by OpenVG
       
  1440 	EGL_IF_ERROR(!display->configExists(config), EGL_BAD_CONFIG, EGL_NO_SURFACE);
       
  1441 	EGL_IF_ERROR(attrib_list && attrib_list[0] != EGL_NONE, EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);	//there are no valid attribs for OpenVG
       
  1442 	const Color::Descriptor& bc = ((Image*)buffer)->getDescriptor();
       
  1443 	const Color::Descriptor& cc = display->getConfig(config).m_desc;
       
  1444 	EGL_IF_ERROR(bc.redBits != cc.redBits || bc.greenBits != cc.greenBits || bc.blueBits != cc.blueBits ||
       
  1445 				 bc.alphaBits != cc.alphaBits || bc.luminanceBits != cc.luminanceBits, EGL_BAD_MATCH, EGL_NO_SURFACE);
       
  1446 
       
  1447 	//TODO If buffer is already bound to another pbuffer, an EGL BAD ACCESS error is generated.
       
  1448 
       
  1449     Drawable* d = NULL;
       
  1450 	RIEGLSurface* s = NULL;
       
  1451 	try
       
  1452 	{
       
  1453 		d = RI_NEW(Drawable, (image, display->getConfig(config).m_maskBits));
       
  1454 		RI_ASSERT(d);
       
  1455 		s = RI_NEW(RIEGLSurface,(NULL, config, d, false, EGL_BACK_BUFFER));	//throws bad_alloc
       
  1456 		RI_ASSERT(s);
       
  1457 		s->addReference();
       
  1458 		display->addSurface(s);	//throws bad_alloc
       
  1459 	}
       
  1460 	catch(std::bad_alloc)
       
  1461 	{
       
  1462         RI_DELETE(d);
       
  1463         RI_DELETE(s);
       
  1464 		EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_SURFACE);
       
  1465 	}
       
  1466 	EGL_RETURN(EGL_SUCCESS, (EGLSurface)s);
       
  1467 }
       
  1468 
       
  1469 /*-------------------------------------------------------------------*//*!
       
  1470 * \brief	
       
  1471 * \param	
       
  1472 * \return	
       
  1473 * \note		
       
  1474 *//*-------------------------------------------------------------------*/
       
  1475 
       
  1476 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1477 RI_APIENTRY EGLSurface do_eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
       
  1478 #else
       
  1479 EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
       
  1480 #endif
       
  1481 {
       
  1482     EGL_GET_DISPLAY(dpy, EGL_NO_SURFACE);
       
  1483 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
       
  1484 	EGL_IF_ERROR(!display->configExists(config), EGL_BAD_CONFIG, EGL_NO_SURFACE);
       
  1485 	//EGL_IF_ERROR(!pixmap || !isValidImageFormat(pixmap->format) || !pixmap->data || pixmap->width <= 0 || pixmap->height <= 0, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
       
  1486 
       
  1487 	RI_UNREF(attrib_list);
       
  1488 	EGL_IF_ERROR(display->getConfig(config).m_samples != 1, EGL_BAD_MATCH, EGL_NO_SURFACE);
       
  1489 
       
  1490 	//TODO If there is already an EGLSurface associated with pixmap (as a result of a previous eglCreatePixmapSurface call), then a EGL BAD ALLOC error is generated.
       
  1491 	
       
  1492 	
       
  1493 	EGLint  width  = -1;
       
  1494 	EGLint  height = -1;
       
  1495 	EGLint  stride = -1;
       
  1496 	VGImageFormat format;
       
  1497 	int* data = NULL;
       
  1498 	EGLBoolean err = OSGetNativePixmapInfo(pixmap, &width, &height, &stride,&format, &data);
       
  1499 	
       
  1500     Drawable* d = NULL;
       
  1501 	RIEGLSurface* s = NULL;
       
  1502 	try
       
  1503 	{
       
  1504 		d = RI_NEW(Drawable, (Color::formatToDescriptor(format), width, height, stride, (RIuint8*)data, display->getConfig(config).m_maskBits));	//throws bad_alloc
       
  1505 		RI_ASSERT(d);
       
  1506 		s = RI_NEW(RIEGLSurface,(NULL, config, d, false, EGL_BACK_BUFFER));	//throws bad_alloc
       
  1507 		RI_ASSERT(s);
       
  1508 		s->addReference();
       
  1509 		display->addSurface(s);	//throws bad_alloc
       
  1510 	}
       
  1511 	catch(std::bad_alloc)
       
  1512 	{
       
  1513         RI_DELETE(d);
       
  1514         RI_DELETE(s);
       
  1515 		EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_SURFACE);
       
  1516 	}
       
  1517 	EGL_RETURN(EGL_SUCCESS, (EGLSurface)s);
       
  1518 	
       
  1519 }
       
  1520 
       
  1521 /*-------------------------------------------------------------------*//*!
       
  1522 * \brief	
       
  1523 * \param	
       
  1524 * \return	
       
  1525 * \note		
       
  1526 *//*-------------------------------------------------------------------*/
       
  1527 
       
  1528 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1529 RI_APIENTRY EGLBoolean do_eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
       
  1530 #else
       
  1531 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
       
  1532 #endif
       
  1533 {
       
  1534 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
  1535 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
       
  1536 	EGL_IF_ERROR(!display->surfaceExists(surface), EGL_BAD_SURFACE, EGL_FALSE);
       
  1537 
       
  1538     display->removeSurface((RIEGLSurface*)surface);
       
  1539 	if(!((RIEGLSurface*)surface)->removeReference())
       
  1540 		RI_DELETE((RIEGLSurface*)surface);
       
  1541 
       
  1542 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  1543 }
       
  1544 
       
  1545 /*-------------------------------------------------------------------*//*!
       
  1546 * \brief	
       
  1547 * \param	
       
  1548 * \return	
       
  1549 * \note		
       
  1550 *//*-------------------------------------------------------------------*/
       
  1551 
       
  1552 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1553 RI_APIENTRY EGLBoolean do_eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
       
  1554 #else
       
  1555 EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
       
  1556 #endif
       
  1557 {
       
  1558 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
  1559 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
       
  1560 	EGL_IF_ERROR(!display->surfaceExists(surface), EGL_BAD_SURFACE, EGL_FALSE);
       
  1561 	RI_UNREF(attribute);
       
  1562 	RI_UNREF(value);
       
  1563 	//do nothing
       
  1564 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  1565 }
       
  1566 
       
  1567 /*-------------------------------------------------------------------*//*!
       
  1568 * \brief	
       
  1569 * \param	
       
  1570 * \return	
       
  1571 * \note		
       
  1572 *//*-------------------------------------------------------------------*/
       
  1573 
       
  1574 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1575 RI_APIENTRY EGLBoolean do_eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
       
  1576 #else
       
  1577 EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
       
  1578 #endif
       
  1579 {
       
  1580 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
  1581 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
       
  1582 	EGL_IF_ERROR(!display->surfaceExists(surface), EGL_BAD_SURFACE, EGL_FALSE);
       
  1583 	//TODO give an error if value is NULL?
       
  1584 
       
  1585 	RIEGLSurface* s = (RIEGLSurface*)surface;
       
  1586 	switch(attribute)
       
  1587 	{
       
  1588 	case EGL_VG_ALPHA_FORMAT:
       
  1589 		*value = (s->getDrawable()->getDescriptor().isPremultiplied()) ? EGL_VG_ALPHA_FORMAT_PRE : EGL_VG_ALPHA_FORMAT_NONPRE;
       
  1590 		break;
       
  1591 
       
  1592 	case EGL_VG_COLORSPACE:
       
  1593 		*value = (s->getDrawable()->getDescriptor().isNonlinear()) ? EGL_VG_COLORSPACE_sRGB : EGL_VG_COLORSPACE_LINEAR;
       
  1594 		break;
       
  1595 
       
  1596 	case EGL_CONFIG_ID:
       
  1597 		*value = display->getConfig(s->getConfig()).m_configID;
       
  1598 		break;
       
  1599 
       
  1600 	case EGL_HEIGHT:
       
  1601 		*value = s->getDrawable()->getHeight();
       
  1602 		break;
       
  1603 
       
  1604 	case EGL_HORIZONTAL_RESOLUTION:
       
  1605 		*value = EGL_UNKNOWN;			//TODO Horizontal dot pitch
       
  1606 		break;
       
  1607 
       
  1608 	case EGL_LARGEST_PBUFFER:
       
  1609 		if(!s->getOSWindowContext())
       
  1610 			*value = s->isLargestPbuffer() ? EGL_TRUE : EGL_FALSE;
       
  1611 		break;
       
  1612 
       
  1613 	case EGL_MIPMAP_TEXTURE:
       
  1614 		if(!s->getOSWindowContext())
       
  1615 			*value = EGL_FALSE;
       
  1616 		break;
       
  1617 
       
  1618 	case EGL_MIPMAP_LEVEL:
       
  1619 		if(!s->getOSWindowContext())
       
  1620 			*value = 0;
       
  1621 		break;
       
  1622 
       
  1623 	case EGL_PIXEL_ASPECT_RATIO:
       
  1624 		*value = EGL_UNKNOWN;			//TODO Display aspect ratio
       
  1625 		break;
       
  1626 
       
  1627 	case EGL_RENDER_BUFFER:
       
  1628 		*value = s->getRenderBuffer();
       
  1629 		break;
       
  1630 
       
  1631 	case EGL_SWAP_BEHAVIOR:
       
  1632 		*value = EGL_BUFFER_PRESERVED;
       
  1633 		break;
       
  1634 
       
  1635 	case EGL_TEXTURE_FORMAT:
       
  1636 		if(!s->getOSWindowContext())
       
  1637 			*value = EGL_NO_TEXTURE;
       
  1638 		break;
       
  1639 
       
  1640 	case EGL_TEXTURE_TARGET:
       
  1641 		if(!s->getOSWindowContext())
       
  1642 			*value = EGL_NO_TEXTURE;
       
  1643 		break;
       
  1644 
       
  1645 	case EGL_VERTICAL_RESOLUTION:
       
  1646 		*value = EGL_UNKNOWN;			//TODO Vertical dot pitch
       
  1647 		break;
       
  1648 
       
  1649 	case EGL_WIDTH:
       
  1650 		*value = s->getDrawable()->getWidth();
       
  1651 		break;
       
  1652 
       
  1653 	default:
       
  1654 		EGL_RETURN(EGL_BAD_ATTRIBUTE, EGL_FALSE);
       
  1655 	}
       
  1656 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  1657 }
       
  1658 
       
  1659 /*-------------------------------------------------------------------*//*!
       
  1660 * \brief	
       
  1661 * \param	
       
  1662 * \return	
       
  1663 * \note		
       
  1664 *//*-------------------------------------------------------------------*/
       
  1665 
       
  1666 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1667 RI_APIENTRY EGLContext do_eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
       
  1668 #else
       
  1669 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
       
  1670 #endif
       
  1671 {
       
  1672 	EGL_GET_DISPLAY(dpy, EGL_NO_CONTEXT);
       
  1673 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_NO_CONTEXT);
       
  1674 	EGL_IF_ERROR(!display->configExists(config), EGL_BAD_CONFIG, EGL_NO_CONTEXT);
       
  1675 	RI_UNREF(attrib_list);
       
  1676 
       
  1677 	RIEGLThread* thread = egl->getThread();
       
  1678 	if(!thread)
       
  1679 		EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
       
  1680 
       
  1681 	//creation of OpenGL ES contexts is not allowed in this implementation
       
  1682 	if(thread->getBoundAPI() != EGL_OPENVG_API)
       
  1683 		EGL_RETURN(EGL_BAD_MATCH, EGL_NO_CONTEXT);
       
  1684 
       
  1685     OpenVGRI::VGContext* vgctx = NULL;
       
  1686 	RIEGLContext* c = NULL;
       
  1687 	try
       
  1688 	{
       
  1689 		vgctx = RI_NEW(OpenVGRI::VGContext, (share_context ? ((RIEGLContext*)share_context)->getVGContext() : NULL));	//throws bad_alloc
       
  1690 		c = RI_NEW(RIEGLContext, (vgctx, config));	//throws bad_alloc
       
  1691 		c->addReference();
       
  1692 		display->addContext(c);	//throws bad_alloc
       
  1693 	}
       
  1694 	catch(std::bad_alloc)
       
  1695 	{
       
  1696         RI_DELETE(vgctx);
       
  1697         RI_DELETE(c);
       
  1698 		EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
       
  1699 	}
       
  1700 
       
  1701 	EGL_RETURN(EGL_SUCCESS, (EGLContext)c);
       
  1702 }
       
  1703 
       
  1704 /*-------------------------------------------------------------------*//*!
       
  1705 * \brief	
       
  1706 * \param	
       
  1707 * \return	
       
  1708 * \note		
       
  1709 *//*-------------------------------------------------------------------*/
       
  1710 
       
  1711 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1712 RI_APIENTRY EGLBoolean do_eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
       
  1713 #else
       
  1714 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
       
  1715 #endif
       
  1716 {
       
  1717 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
  1718 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
       
  1719 	EGL_IF_ERROR(!display->contextExists(ctx), EGL_BAD_CONTEXT, EGL_FALSE);
       
  1720 
       
  1721 	RIEGLContext* context = (RIEGLContext*)ctx;
       
  1722     display->removeContext(context);
       
  1723 	if(!context->removeReference() )
       
  1724 		RI_DELETE(context);
       
  1725 
       
  1726 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  1727 }
       
  1728 
       
  1729 /*-------------------------------------------------------------------*//*!
       
  1730 * \brief	
       
  1731 * \param	
       
  1732 * \return	
       
  1733 * \note		
       
  1734 *//*-------------------------------------------------------------------*/
       
  1735 
       
  1736 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1737 RI_APIENTRY EGLBoolean do_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
       
  1738 #else
       
  1739 EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
       
  1740 #endif
       
  1741 {
       
  1742 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
  1743 	EGL_IF_ERROR(ctx != EGL_NO_CONTEXT && !display->contextExists(ctx), EGL_BAD_CONTEXT, EGL_FALSE);
       
  1744 	EGL_IF_ERROR(draw != EGL_NO_SURFACE && !display->surfaceExists(draw), EGL_BAD_SURFACE, EGL_FALSE);
       
  1745 	EGL_IF_ERROR(read != EGL_NO_SURFACE && !display->surfaceExists(read), EGL_BAD_SURFACE, EGL_FALSE);
       
  1746 	EGL_IF_ERROR(draw != read, EGL_BAD_MATCH, EGL_FALSE);	//TODO what's the proper error code?
       
  1747 	EGL_IF_ERROR((draw != EGL_NO_SURFACE && ctx == EGL_NO_CONTEXT) || (draw == EGL_NO_SURFACE && ctx != EGL_NO_CONTEXT), EGL_BAD_MATCH, EGL_FALSE);
       
  1748 
       
  1749 	RIEGLSurface* s = NULL;
       
  1750 	RIEGLContext* c = NULL;
       
  1751 	if(draw != EGL_NO_SURFACE && ctx != EGL_NO_CONTEXT)
       
  1752 	{
       
  1753 		EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
       
  1754 
       
  1755 		s = (RIEGLSurface*)draw;
       
  1756 		c = (RIEGLContext*)ctx;
       
  1757 
       
  1758         //If either draw or read are pbuffers created with eglCreatePbufferFromClientBuffer, and the underlying bound client API buffers
       
  1759         //are in use by the client API that created them, an EGL BAD ACCESS error is generated.
       
  1760 		EGL_IF_ERROR(s->getDrawable()->isInUse(), EGL_BAD_ACCESS, EGL_FALSE);
       
  1761 
       
  1762 
       
  1763 		//TODO properly check compatibility of surface and context:
       
  1764 		//-both have RGB or LUMINANCE configs
       
  1765 		//-buffer bit depths match
       
  1766 		//-configs support OpenVG
       
  1767 		//-both have the same display
       
  1768 		EGL_IF_ERROR(s->getConfig() != c->getConfig(), EGL_BAD_MATCH, EGL_FALSE);
       
  1769 		//TODO check if context or surfaces are already bound to another thread
       
  1770 
       
  1771 		//If a native window underlying either draw or read is no longer valid, an EGL BAD NATIVE WINDOW error is generated.
       
  1772         EGL_IF_ERROR(s->getOSWindowContext() && !OSIsWindow(s->getOSWindowContext()), EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
       
  1773 
       
  1774 		//TODO If the previous context of the calling display has unflushed commands, and the previous surface is no longer valid, an EGL BAD CURRENT SURFACE error is generated. (can this happen?)
       
  1775 		//TODO If the ancillary buffers for draw and read cannot be allocated, an EGL BAD ALLOC error is generated. (mask buffer?)
       
  1776 	}
       
  1777 
       
  1778 	//check if the thread is current
       
  1779 	RIEGLThread* thread = egl->getCurrentThread();
       
  1780 	if(thread)
       
  1781 	{	//thread is current, release the old bindinds and remove the thread from the current thread list
       
  1782 		RIEGLContext* pc = thread->getCurrentContext();
       
  1783 		RIEGLSurface* ps = thread->getCurrentSurface();
       
  1784 		if(pc)
       
  1785 		{
       
  1786 #ifdef BUILD_WITH_PRIVATE_OPENVG
       
  1787 			do_vgFlush();
       
  1788 #else
       
  1789 			vgFlush();
       
  1790 #endif
       
  1791 			pc->getVGContext()->setDefaultDrawable(NULL);
       
  1792 			if(!pc->removeReference())
       
  1793 				RI_DELETE(pc);
       
  1794 		}
       
  1795 		if(ps)
       
  1796 		{
       
  1797 			if(!ps->removeReference())
       
  1798 				RI_DELETE(ps);
       
  1799 		}
       
  1800 
       
  1801         egl->removeCurrentThread(thread);
       
  1802 	}
       
  1803 
       
  1804 	if( c && s )
       
  1805 	{
       
  1806 		//bind context and surface to the current display
       
  1807 		RIEGLThread* newThread = egl->getThread();
       
  1808 		if(!newThread)
       
  1809 			EGL_RETURN(EGL_BAD_ALLOC, EGL_FALSE);
       
  1810         newThread->makeCurrent(c, s);
       
  1811 		c->getVGContext()->setDefaultDrawable(s->getDrawable());
       
  1812 
       
  1813 		try
       
  1814 		{
       
  1815 			egl->addCurrentThread(newThread);	//throws bad_alloc
       
  1816 		}
       
  1817 		catch(std::bad_alloc)
       
  1818 		{
       
  1819 			EGL_RETURN(EGL_BAD_ALLOC, EGL_FALSE);
       
  1820 		}
       
  1821 
       
  1822 		c->addReference();
       
  1823 		s->addReference();
       
  1824 	}
       
  1825 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  1826 }
       
  1827 
       
  1828 /*-------------------------------------------------------------------*//*!
       
  1829 * \brief	
       
  1830 * \param	
       
  1831 * \return	
       
  1832 * \note		
       
  1833 *//*-------------------------------------------------------------------*/
       
  1834 
       
  1835 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1836 RI_APIENTRY EGLContext do_eglGetCurrentContext()
       
  1837 #else
       
  1838 EGLContext eglGetCurrentContext()
       
  1839 #endif
       
  1840 {
       
  1841     EGL_GET_EGL(EGL_NO_CONTEXT);
       
  1842 	EGLContext ret = EGL_NO_CONTEXT;
       
  1843 	RIEGLThread* thread = egl->getCurrentThread();
       
  1844 	if(thread && thread->getBoundAPI() == EGL_OPENVG_API)
       
  1845     {
       
  1846         ret = CastFromRIEGLContext(thread->getCurrentContext());
       
  1847         RI_ASSERT(ret);
       
  1848     }
       
  1849 	EGL_RETURN(EGL_SUCCESS, ret);
       
  1850 }
       
  1851 
       
  1852 /*-------------------------------------------------------------------*//*!
       
  1853 * \brief	
       
  1854 * \param	
       
  1855 * \return	
       
  1856 * \note		
       
  1857 *//*-------------------------------------------------------------------*/
       
  1858 
       
  1859 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1860 RI_APIENTRY EGLSurface do_eglGetCurrentSurface(EGLint readdraw)
       
  1861 #else
       
  1862 EGLSurface eglGetCurrentSurface(EGLint readdraw)
       
  1863 #endif
       
  1864 {
       
  1865     EGL_GET_EGL(EGL_NO_SURFACE);
       
  1866 	EGL_IF_ERROR(readdraw != EGL_READ && readdraw != EGL_DRAW, EGL_BAD_PARAMETER, EGL_NO_SURFACE);
       
  1867 	EGLContext ret = EGL_NO_SURFACE;
       
  1868 	RIEGLThread* thread = egl->getCurrentThread();
       
  1869 	if(thread && thread->getBoundAPI() == EGL_OPENVG_API)
       
  1870     {
       
  1871         ret = CastFromRIEGLSurface(thread->getCurrentSurface());
       
  1872         RI_ASSERT(ret);
       
  1873     }
       
  1874 	EGL_RETURN(EGL_SUCCESS, ret);
       
  1875 }
       
  1876 
       
  1877 /*-------------------------------------------------------------------*//*!
       
  1878 * \brief	Returns the current display
       
  1879 * \param	
       
  1880 * \return	
       
  1881 * \note		
       
  1882 *//*-------------------------------------------------------------------*/
       
  1883 
       
  1884 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1885 RI_APIENTRY EGLDisplay do_eglGetCurrentDisplay(void)
       
  1886 #else
       
  1887 EGLDisplay eglGetCurrentDisplay(void)
       
  1888 #endif
       
  1889 {
       
  1890     EGL_GET_EGL(EGL_NO_DISPLAY);
       
  1891 
       
  1892 	RIEGLThread* thread = egl->getCurrentThread();
       
  1893 	if(!thread || thread->getBoundAPI() != EGL_OPENVG_API)
       
  1894 		EGL_RETURN(EGL_SUCCESS, EGL_NO_DISPLAY);
       
  1895 
       
  1896 	RIEGLContext* ctx = thread->getCurrentContext();
       
  1897     RI_ASSERT(ctx);
       
  1898     EGLDisplay ret = egl->findDisplay(CastFromRIEGLContext(ctx));
       
  1899 	EGL_RETURN(EGL_SUCCESS, ret);
       
  1900 }
       
  1901 
       
  1902 /*-------------------------------------------------------------------*//*!
       
  1903 * \brief	
       
  1904 * \param	
       
  1905 * \return	
       
  1906 * \note		
       
  1907 *//*-------------------------------------------------------------------*/
       
  1908 
       
  1909 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1910 RI_APIENTRY EGLBoolean do_eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value)
       
  1911 #else
       
  1912 EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value)
       
  1913 #endif
       
  1914 {
       
  1915 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
  1916 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
       
  1917 	EGL_IF_ERROR(!display->contextExists(ctx), EGL_BAD_CONTEXT, EGL_FALSE);
       
  1918 	EGL_IF_ERROR(attribute != EGL_CONFIG_ID && attribute != EGL_CONTEXT_CLIENT_TYPE, EGL_BAD_ATTRIBUTE, EGL_FALSE);
       
  1919 	if(attribute == EGL_CONFIG_ID)
       
  1920 		*value = display->getConfig(((RIEGLContext*)ctx)->getConfig()).m_configID;
       
  1921 	if(attribute == EGL_CONTEXT_CLIENT_TYPE)
       
  1922 		*value = EGL_OPENVG_API;
       
  1923 	// \todo [kalle 05/Jul/05] Handling of EGL_RENDER_BUFFER attribute is missing.
       
  1924 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  1925 }
       
  1926 
       
  1927 /*-------------------------------------------------------------------*//*!
       
  1928 * \brief	
       
  1929 * \param	
       
  1930 * \return	
       
  1931 * \note		
       
  1932 *//*-------------------------------------------------------------------*/
       
  1933 
       
  1934 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1935 RI_APIENTRY EGLBoolean do_eglBindAPI(EGLenum api)
       
  1936 #else
       
  1937 EGLBoolean eglBindAPI(EGLenum api)
       
  1938 #endif
       
  1939 {
       
  1940     EGL_GET_EGL(EGL_FALSE);
       
  1941 	EGL_IF_ERROR(api != EGL_OPENVG_API && api != EGL_OPENGL_ES_API, EGL_BAD_PARAMETER, EGL_FALSE);
       
  1942 	RIEGLThread* thread = egl->getThread();
       
  1943 	if(thread)
       
  1944 		thread->bindAPI(api);
       
  1945 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  1946 }
       
  1947 
       
  1948 /*-------------------------------------------------------------------*//*!
       
  1949 * \brief	
       
  1950 * \param	
       
  1951 * \return	
       
  1952 * \note		
       
  1953 *//*-------------------------------------------------------------------*/
       
  1954 
       
  1955 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1956 RI_APIENTRY EGLenum do_eglQueryAPI(void)
       
  1957 #else
       
  1958 EGLenum eglQueryAPI(void)
       
  1959 #endif
       
  1960 {
       
  1961     EGL_GET_EGL(EGL_NONE);
       
  1962 	RIEGLThread* thread = egl->getThread();
       
  1963 	if(thread)
       
  1964 		EGL_RETURN(EGL_SUCCESS, thread->getBoundAPI());
       
  1965 	EGL_RETURN(EGL_SUCCESS, EGL_NONE);
       
  1966 }
       
  1967 
       
  1968 /*-------------------------------------------------------------------*//*!
       
  1969 * \brief	
       
  1970 * \param	
       
  1971 * \return	
       
  1972 * \note		
       
  1973 *//*-------------------------------------------------------------------*/
       
  1974 
       
  1975 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1976 RI_APIENTRY EGLBoolean do_eglWaitClient()
       
  1977 #else
       
  1978 EGLBoolean eglWaitClient()
       
  1979 #endif
       
  1980 {
       
  1981     EGL_GET_EGL(EGL_FALSE);
       
  1982 	RIEGLThread* thread = egl->getCurrentThread();
       
  1983 	if(thread && thread->getBoundAPI() == EGL_OPENVG_API)
       
  1984 #ifdef BUILD_WITH_PRIVATE_OPENVG
       
  1985 		do_vgFlush();
       
  1986 #else
       
  1987 		vgFinish();
       
  1988 #endif
       
  1989 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  1990 }
       
  1991 
       
  1992 /*-------------------------------------------------------------------*//*!
       
  1993 * \brief	Waits for OpenGL ES
       
  1994 * \param	
       
  1995 * \return	
       
  1996 * \note		
       
  1997 *//*-------------------------------------------------------------------*/
       
  1998 
       
  1999 #ifdef BUILD_WITH_PRIVATE_EGL
       
  2000 RI_APIENTRY EGLBoolean do_eglWaitGL(void)
       
  2001 #else
       
  2002 EGLBoolean eglWaitGL(void)
       
  2003 #endif
       
  2004 {
       
  2005 	return EGL_TRUE;
       
  2006 }
       
  2007 
       
  2008 /*-------------------------------------------------------------------*//*!
       
  2009 * \brief	
       
  2010 * \param	
       
  2011 * \return	
       
  2012 * \note		We don't support native rendering
       
  2013 *//*-------------------------------------------------------------------*/
       
  2014 
       
  2015 #ifdef BUILD_WITH_PRIVATE_EGL
       
  2016 RI_APIENTRY EGLBoolean do_eglWaitNative(EGLint engine)
       
  2017 #else
       
  2018 EGLBoolean eglWaitNative(EGLint engine)
       
  2019 #endif
       
  2020 {
       
  2021 	RI_UNREF(engine);
       
  2022 	return EGL_TRUE;
       
  2023 }
       
  2024 
       
  2025 /*-------------------------------------------------------------------*//*!
       
  2026 * \brief	
       
  2027 * \param	
       
  2028 * \return	
       
  2029 * \note		
       
  2030 *//*-------------------------------------------------------------------*/
       
  2031 
       
  2032 #ifdef BUILD_WITH_PRIVATE_EGL
       
  2033 RI_APIENTRY EGLBoolean do_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
       
  2034 #else
       
  2035 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
       
  2036 #endif
       
  2037 {
       
  2038 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
  2039 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
       
  2040 	EGL_IF_ERROR(!display->surfaceExists(surface), EGL_BAD_SURFACE, EGL_FALSE);
       
  2041 
       
  2042 	RIEGLSurface* s = (RIEGLSurface*)surface;
       
  2043 
       
  2044 	RIEGLThread* currentThread = egl->getCurrentThread();
       
  2045 	EGL_IF_ERROR(!currentThread || currentThread->getCurrentSurface() != s, EGL_BAD_SURFACE, EGL_FALSE);
       
  2046 	EGL_IF_ERROR(!OSIsWindow(s->getOSWindowContext()), EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
       
  2047 
       
  2048 #ifdef BUILD_WITH_PRIVATE_OPENVG
       
  2049 	do_vgFlush();
       
  2050 #else
       
  2051 	vgFlush();
       
  2052 #endif
       
  2053 
       
  2054 	if(!s->getOSWindowContext())
       
  2055 	{	//do nothing for other than window surfaces (NOTE: single-buffered window surfaces should return immediately as well)
       
  2056 		EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  2057 	}
       
  2058 
       
  2059 	int windowWidth = 0, windowHeight = 0;
       
  2060     OSGetWindowSize(s->getOSWindowContext(), windowWidth, windowHeight);
       
  2061 
       
  2062 	if(windowWidth != s->getDrawable()->getWidth() || windowHeight != s->getDrawable()->getHeight())
       
  2063 	{	//resize the back buffer
       
  2064 		RIEGLContext* c = currentThread->getCurrentContext();
       
  2065 		RI_ASSERT(c);
       
  2066 		try
       
  2067 		{
       
  2068 			s->getDrawable()->resize(windowWidth, windowHeight);	//throws bad_alloc
       
  2069 		}
       
  2070 		catch(std::bad_alloc)
       
  2071 		{
       
  2072 			c->getVGContext()->setDefaultDrawable(NULL);
       
  2073 			EGL_RETURN(EGL_BAD_ALLOC, EGL_FALSE);
       
  2074 		}
       
  2075 	}
       
  2076 
       
  2077     OSBlitToWindow(s->getOSWindowContext(), s->getDrawable());
       
  2078 
       
  2079 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  2080 }
       
  2081 
       
  2082 /*-------------------------------------------------------------------*//*!
       
  2083 * \brief	
       
  2084 * \param	
       
  2085 * \return	
       
  2086 * \note		
       
  2087 *//*-------------------------------------------------------------------*/
       
  2088 
       
  2089 #ifdef BUILD_WITH_PRIVATE_EGL
       
  2090 RI_APIENTRY EGLBoolean do_eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
       
  2091 #else
       
  2092 EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
       
  2093 #endif
       
  2094 {
       
  2095 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
  2096 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
       
  2097 	EGL_IF_ERROR(!display->surfaceExists(surface), EGL_BAD_SURFACE, EGL_FALSE);
       
  2098 	//EGL_IF_ERROR(!target || !isValidImageFormat(target->format) || !target->data || target->width <= 0 || target->height <= 0, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
       
  2099 	EGLint  width  = -1;
       
  2100 	EGLint  height = -1;
       
  2101 	EGLint  stride = -1;
       
  2102 	VGImageFormat format;
       
  2103 	int* data = NULL;
       
  2104 	EGLBoolean err = OSGetNativePixmapInfo(target, &width, &height, &stride,&format, &data);
       
  2105 	
       
  2106 	TUint* fdata = (TUint*)((TUint)data + ( stride * ( height - 1  ) ) );	
       
  2107 	try
       
  2108 	{
       
  2109 		Image output(Color::formatToDescriptor(format), width, height, -stride, (RIuint8*)fdata);
       
  2110         output.addReference();
       
  2111 		output.blit(((RIEGLSurface*)surface)->getDrawable()->getColorBuffer(), 0, 0, 0, 0, width, height);	//throws bad_alloc
       
  2112         output.removeReference();
       
  2113 	}
       
  2114 	catch(std::bad_alloc)
       
  2115 	{
       
  2116 	}
       
  2117 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  2118 	
       
  2119 }
       
  2120 
       
  2121 /*-------------------------------------------------------------------*//*!
       
  2122 * \brief	
       
  2123 * \param	
       
  2124 * \return	
       
  2125 * \note		We support only swap interval one
       
  2126 *//*-------------------------------------------------------------------*/
       
  2127 
       
  2128 #ifdef BUILD_WITH_PRIVATE_EGL
       
  2129 RI_APIENTRY EGLBoolean do_eglSwapInterval(EGLDisplay dpy, EGLint interval)
       
  2130 #else
       
  2131 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
       
  2132 #endif
       
  2133 {
       
  2134 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
  2135 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
       
  2136 	RI_UNREF(interval);
       
  2137 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  2138 }
       
  2139 
       
  2140 /*-------------------------------------------------------------------*//*!
       
  2141 * \brief	
       
  2142 * \param	
       
  2143 * \return	
       
  2144 * \note		
       
  2145 *//*-------------------------------------------------------------------*/
       
  2146 
       
  2147 typedef void RI_Proc();
       
  2148 
       
  2149 //EGLAPI void (* EGLAPIENTRY      eglGetProcAddress(const char *procname))(void);
       
  2150 
       
  2151 #ifdef BUILD_WITH_PRIVATE_EGL
       
  2152 RI_APIENTRY void (*do_eglGetProcAddress(const char *procname))(...)
       
  2153 #else
       
  2154 void (*eglGetProcAddress(const char *procname))(...)
       
  2155 #endif
       
  2156 {
       
  2157 	if(!procname)
       
  2158 		return NULL;
       
  2159 	return NULL;
       
  2160 }
       
  2161 
       
  2162 
       
  2163 
       
  2164 /*-------------------------------------------------------------------*//*!
       
  2165 * \brief	
       
  2166 * \param	
       
  2167 * \return	
       
  2168 * \note		
       
  2169 *//*-------------------------------------------------------------------*/
       
  2170 
       
  2171 #ifdef BUILD_WITH_PRIVATE_EGL
       
  2172 RI_APIENTRY EGLBoolean do_eglReleaseThread(void)
       
  2173 #else
       
  2174 EGLBoolean eglReleaseThread(void)
       
  2175 #endif
       
  2176 {
       
  2177     EGL_GET_EGL(EGL_FALSE);
       
  2178 
       
  2179 	//check if the thread is current
       
  2180 	RIEGLThread* thread = egl->getCurrentThread();
       
  2181 	if(thread)
       
  2182 	{	//thread is current, release the old bindings and remove the thread from the current thread list
       
  2183 		RIEGLContext* pc = thread->getCurrentContext();
       
  2184 		RIEGLSurface* ps = thread->getCurrentSurface();
       
  2185 		if(pc)
       
  2186 		{
       
  2187 #ifdef BUILD_WITH_PRIVATE_OPENVG
       
  2188 			do_vgFlush();
       
  2189 #else
       
  2190 			vgFlush();
       
  2191 #endif
       
  2192 			pc->getVGContext()->setDefaultDrawable(NULL);
       
  2193 			if(!pc->removeReference())
       
  2194 				RI_DELETE(pc);
       
  2195 		}
       
  2196 		if(ps)
       
  2197 		{
       
  2198 			if(!ps->removeReference())
       
  2199 				RI_DELETE(ps);
       
  2200 		}
       
  2201 
       
  2202         egl->removeCurrentThread(thread);
       
  2203 	}
       
  2204 
       
  2205     //destroy EGL's thread struct
       
  2206     egl->destroyThread();
       
  2207 
       
  2208 	//destroy the EGL instance
       
  2209 	releaseEGL();
       
  2210 
       
  2211 	OSReleaseMutex();
       
  2212     OSDeinitMutex();
       
  2213 
       
  2214 	return EGL_SUCCESS;
       
  2215 }
       
  2216 
       
  2217 #ifdef BUILD_WITH_PRIVATE_EGL
       
  2218 RI_APIENTRY EGLBoolean do_eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
       
  2219 #else
       
  2220 EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
       
  2221 #endif
       
  2222 	{
       
  2223 	//not implemented
       
  2224 	RI_ASSERT(0);
       
  2225 	return false;
       
  2226 	}
       
  2227 
       
  2228 #ifdef BUILD_WITH_PRIVATE_EGL
       
  2229 RI_APIENTRY EGLBoolean do_eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
       
  2230 #else 
       
  2231 EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
       
  2232 #endif
       
  2233 	{
       
  2234 	//not implemented
       
  2235 	RI_ASSERT(0);
       
  2236 	return false;
       
  2237 	}
       
  2238 #undef EGL_NUMCONFIGS