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