openvg/openvgrefimplementation/sfopenvg/sfopenvg/riMiniEGL.cpp
branchEGL_MERGE
changeset 216 b87045f2f5d7
parent 6 250ac10a3d98
child 217 205d3af68142
equal deleted inserted replaced
212:a8e55d78eb52 216:b87045f2f5d7
    33 			- no power management events
    33 			- no power management events
    34 			- no support for swap interval
    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?
    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.
    36  * \todo	OSDeinitMutex should be called in case getEGL fails.
    37  *//*-------------------------------------------------------------------*/
    37  *//*-------------------------------------------------------------------*/
       
    38 #include "eglapi.h"
    38 
    39 
    39 #include "egl.h"
    40 #include "egl.h"
    40 #include "openvg.h"
    41 #include "openvg.h"
    41 #include "riArray.h"
    42 #include "riArray.h"
    42 #include "riMath.h"
    43 #include "riMath.h"
    43 #include "riContext.h"
    44 #include "riContext.h"
    44 #include "riImage.h"
    45 #include "riImage.h"
       
    46 #include "riMiniEGL.h"
       
    47 #include "riDefs.h"
    45 
    48 
    46 #ifdef BUILD_WITH_PRIVATE_EGL 
    49 #ifdef BUILD_WITH_PRIVATE_EGL 
    47 #include "eglinternal.h"
    50 #include "eglinternal.h"
    48 #endif
    51 #endif
    49 
    52 
    50 #ifdef BUILD_WITH_PRIVATE_OPENVG
    53 #ifdef BUILD_WITH_PRIVATE_OPENVG
    51 #include "openvginternal.h"
    54 #include "openvginternal.h"
    52 #endif
    55 #endif
    53 
    56 
    54 //==============================================================================================
    57 #ifdef EGL_COMPOSITION
    55 
    58 #include "eglsync.h"
       
    59 //
       
    60 #include <w32std.h>
       
    61 #include <graphics/surfacemanager.h>
       
    62 #include <graphics/surfaceconfiguration.h>
       
    63 #include <graphics/suerror.h>
       
    64 #include <graphics/surface_hints.h>
       
    65 #include <graphics/surfaceupdateclient.h>
       
    66 #include <e32hashtab.h>
       
    67 #endif
       
    68 
       
    69 using namespace OpenVGRI;
       
    70 //// class EGL
       
    71 EGL::EGL() :
       
    72 	m_threads(),
       
    73 	m_currentThreads(),
       
    74 	m_displays(),
       
    75 	m_referenceCount(0)
       
    76 {
       
    77 }
       
    78 EGL::~EGL()
       
    79 {
       
    80 	for(int i=0;i<m_displays.size();i++)
       
    81 	{
       
    82 		RI_DELETE(m_displays[i]);
       
    83 	}
       
    84 	for(int i=0;i<m_threads.size();i++)
       
    85 	{
       
    86 		RI_DELETE(m_threads[i]);
       
    87 	}
       
    88 	//currentThreads contain just pointers to threads we just deleted
       
    89 }
       
    90 
       
    91 /*-------------------------------------------------------------------*//*!
       
    92 * \brief	
       
    93 * \param	
       
    94 * \return	
       
    95 * \note		
       
    96 *//*-------------------------------------------------------------------*/
    56 namespace OpenVGRI
    97 namespace OpenVGRI
    57 {
    98 {
    58 
    99 EGL* getEGL()
    59 void* OSGetCurrentThreadID(void);
   100 {
    60 void OSAcquireMutex(void);
   101 
    61 void OSReleaseMutex(void);
   102 
    62 void OSDeinitMutex(void);
   103 	//use TLS to store static global g_egl
    63 
   104 	EGL* pEgl=NULL; 
    64 EGLDisplay OSGetDisplay(EGLNativeDisplayType display_id);
   105 	if((pEgl = static_cast<EGL*>(Dll::Tls()))==NULL)
    65 void* OSCreateWindowContext(EGLNativeWindowType window);
   106 		{
    66 void OSDestroyWindowContext(void* context);
   107 		//create TLS instance
    67 bool OSIsWindow(const void* context);
   108 		pEgl = RI_NEW(EGL, ());
    68 void OSGetWindowSize(const void* context, int& width, int& height);
   109 		Dll::SetTls(pEgl);
    69 void OSBlitToWindow(void* context, const Drawable* drawable);
   110 		}
    70 EGLBoolean OSGetNativePixmapInfo(NativePixmapType pixmap, int* width, int* height, int* stride, VGImageFormat* format, int** data);
   111 	return pEgl;
    71 
   112 
    72 
   113 	
    73 /*-------------------------------------------------------------------*//*!
   114 }
    74 * \brief	
   115 static void releaseEGL()
    75 * \param	
   116 {
    76 * \return	
   117 	EGL* pEgl = static_cast<EGL*>(Dll::Tls());
    77 * \note		
   118 	if (pEgl)
    78 *//*-------------------------------------------------------------------*/
   119 		delete pEgl; 
    79 
   120 	Dll::SetTls(NULL);
    80 class RIEGLConfig
   121 
    81 {
   122 }
    82 public:
   123 //helper functions
    83 	RIEGLConfig() : m_desc(Color::formatToDescriptor(VG_sRGBA_8888)), m_configID(0)	{}
   124 RIEGLContext* CastToRIEGLContext(EGLContext aCtxId)
    84 	~RIEGLConfig()							{}
   125   {
    85 	void		set(int r, int g, int b, int a, int l, int bpp, int samples, int maskBits, int ID)
   126   return (RIEGLContext*)(aCtxId);
    86 	{
   127   }
    87 		m_desc.redBits = r;
   128 EGLContext CastFromRIEGLContext(RIEGLContext* aCtx)
    88 		m_desc.greenBits = g;
   129   {
    89 		m_desc.blueBits = b;
   130   return (EGLContext)(aCtx);
    90 		m_desc.alphaBits = a;
   131   }
    91 		m_desc.luminanceBits = l;
   132 
    92 		m_desc.alphaShift = 0;
   133 RIEGLSurface* CastToRIEGLSurface(EGLSurface aSurfaceId)
    93 		m_desc.luminanceShift = 0;
   134   {
    94 		m_desc.blueShift = b ? a : 0;
   135   return (RIEGLSurface*)(aSurfaceId);
    95 		m_desc.greenShift = g ? a + b : 0;
   136   }
    96 		m_desc.redShift = r ? a + b + g : 0;
   137 EGLSurface CastFromRIEGLSurface(RIEGLSurface* aSurface)
    97 		m_desc.format = (VGImageFormat)-1;
   138   {
    98 		m_desc.internalFormat = l ? Color::sLA : Color::sRGBA;
   139   return (EGLSurface)(aSurface);
    99 		m_desc.bitsPerPixel = bpp;
   140   }
   100 		RI_ASSERT(Color::isValidDescriptor(m_desc));
   141 
   101 		m_samples = samples;
   142 Image* CastToImage(EGLClientBuffer aBufferId)
   102         m_maskBits = maskBits;
   143   {
   103 		m_configID = ID;
   144   return (Image*)(aBufferId);
   104         m_config = (EGLConfig)ID;
   145   }
   105 	}
   146 
   106 
   147 EGLClientBuffer CastFromImage(Image* aBUffer)
   107     Color::Descriptor configToDescriptor(bool sRGB, bool premultiplied) const
   148   {
       
   149   return (EGLClientBuffer)(aBUffer);
       
   150   }
       
   151 ////
       
   152 } // namespace OpenVGRI
       
   153 /*-------------------------------------------------------------------*//*!
       
   154 * \brief	Given a display ID, return the corresponding object, or NULL
       
   155 *			if the ID hasn't been initialized.
       
   156 * \param	
       
   157 * \return	
       
   158 * \note		if egl has been initialized for this display, the display ID can
       
   159 *			be found from egl->m_displays
       
   160 *//*-------------------------------------------------------------------*/
       
   161 RIEGLDisplay* EGL::getDisplay(const EGLDisplay displayID)
       
   162 {
       
   163 	for(int i=0;i<m_displays.size();i++)
       
   164 	{
       
   165 		if(displayID == m_displays[i]->getID())
       
   166 		{
       
   167 			if (CreateDisplayInfo(displayID))
       
   168 			{
       
   169 				return m_displays[i];		
       
   170 			}
       
   171 		}
       
   172 	}
       
   173 	return NULL;		//error: the display hasn't been eglInitialized
       
   174 }
       
   175 
       
   176 /*
       
   177   Create an information object for an opened Display.
       
   178  */
       
   179 TBool EGL::CreateDisplayInfo(const EGLDisplay aDisplayID)
       
   180 {
       
   181 	TBool result = EFalse;
       
   182 	EGL_TRACE("EGL::CreateDisplayInfo begin aDisplay=%d", aDisplayID);
       
   183 	iDisplayMapLock.WriteLock();
       
   184 	
       
   185 	if (NULL != iDisplayMap.Find( aDisplayID))
       
   186 	{
       
   187 		result = ETrue;
       
   188 	}
       
   189 	else
       
   190 	{
       
   191 		TInt err = KErrNoMemory; 
       
   192 		CEglDisplayInfo* dispInfo = new CEglDisplayInfo;
       
   193 
       
   194 		if (dispInfo)
       
   195 		{
       
   196 			err = iDisplayMap.Insert(aDisplayID, dispInfo);
       
   197 			EGL_TRACE("EGL::CreateDisplayInfo - DisplayMap insert error %d", err);
       
   198 			EGLPANIC_ASSERT_DEBUG(err == KErrNone, EEglPanicDisplayMapInsertFailed);
       
   199 	
       
   200 			//added for egl sync extension benefit
       
   201 			if (iEglSyncExtension)
       
   202 			{
       
   203 				err = iEglSyncExtension->EglSyncDisplayCreate(aDisplayID);
       
   204 				EGL_TRACE("EGL::CreateDisplayInfo - EglSyncDisplayCreate error %d", err);
       
   205 				EGLPANIC_ASSERT_DEBUG(err == KErrNone, EEglPanicEglSyncDisplayCreateFailed);
       
   206 	
       
   207 				if (err)
       
   208 				{
       
   209 					iDisplayMap.Remove(aDisplayID);
       
   210 				}
       
   211 			}
       
   212 		}
       
   213 
       
   214 		if (err == KErrNone)
       
   215 		{
       
   216 			result = ETrue;
       
   217 		}
       
   218 	}
       
   219 	iDisplayMapLock.Unlock();
       
   220 
       
   221 	EGL_TRACE("EGL::CreateDisplayInfo end, result=%d", result);
       
   222 	return result;
       
   223 }
       
   224 
       
   225 /*-------------------------------------------------------------------*//*!
       
   226  * \brief   Creates the EGL sync instance
       
   227  * \ingroup eglSync
       
   228 *//*-------------------------------------------------------------------*/
       
   229 
       
   230 EGLint EGL::InitialiseExtensions()
       
   231 {
       
   232 	iEglSyncExtension = CEglSyncExtension::Create(*this);
       
   233 	return EGL_SUCCESS;
       
   234 }
       
   235 
       
   236 // API supporting EGL sync extension
       
   237 /*-------------------------------------------------------------------*//*!
       
   238  * \brief   Query and request to lock a specified display
       
   239  * \ingroup eglSync
       
   240  * \param   aEglDisplay a display identifier
       
   241  * \return  EGL_SUCCESS if successful;
       
   242  *          EGL_BAD_DISPLAY is not a name of a valid EGLDisplay
       
   243  *          EGL_NOT_INITIALIZED if the display object associated
       
   244  *          with the <aEglDisplay> has not been initialized
       
   245 *//*-------------------------------------------------------------------*/
       
   246 
       
   247 EGLint EGL::FindAndLockDisplay(EGLDisplay aDisplayID)
       
   248 {
       
   249 	EGLint result = EGL_BAD_DISPLAY;
       
   250 	EGL_TRACE("EGL::FindAndLockDisplay aDisplay=%d", aDisplayID);
       
   251 	iDisplayMapLock.ReadLock();
       
   252 	CEglDisplayInfo** pDisp = iDisplayMap.Find(aDisplayID);
       
   253 	if (pDisp && *pDisp)
       
   254 		{
       
   255 		CEglDisplayInfo* disp = *pDisp;
       
   256 		if (disp->iInitialized)
       
   257 			{
       
   258 			EGL_TRACE("EGL::FindAndLockDisplay display found");
       
   259 			result = EGL_SUCCESS;
       
   260 			}
       
   261 		else
       
   262 			{
       
   263 			EGL_TRACE("EGL::FindAndLockDisplay display not initialized");
       
   264 			result = EGL_NOT_INITIALIZED;
       
   265 			}
       
   266 		}
       
   267 	else
       
   268 		{
       
   269 		EGL_TRACE("EGL::FindAndLockDisplay cannot find display");
       
   270 		}
       
   271 	if (result != EGL_SUCCESS)
       
   272 		{
       
   273 		iDisplayMapLock.Unlock();
       
   274 		}
       
   275 	return result;
       
   276 }
       
   277 
       
   278 /*-------------------------------------------------------------------*//*!
       
   279  * \brief   Releases the lock associated with a valid EGLDisplay
       
   280  * \ingroup eglSync
       
   281  * \param   aEglDisplay a display identifier
       
   282 *//*-------------------------------------------------------------------*/
       
   283 
       
   284 void EGL::ReleaseDisplayLock(EGLDisplay aDisplayID)
       
   285 {
       
   286 	EGL_TRACE("EGL::ReleaseDisplayLock aDisplay=%d", aDisplayID);
       
   287 	iDisplayMapLock.Unlock();
       
   288 }
       
   289 
       
   290 /*-------------------------------------------------------------------*//*!
       
   291 * \brief	return EGLDisplay for the current context
       
   292 * \param	
       
   293 * \return	
       
   294 * \note		
       
   295 *//*-------------------------------------------------------------------*/
       
   296 
       
   297 EGLDisplay EGL::findDisplay(EGLContext ctx) const
       
   298 {
       
   299 	for(int i=0;i<m_displays.size();i++)
       
   300 	{
       
   301         if(m_displays[i]->contextExists(ctx))
       
   302             return m_displays[i]->getID();
       
   303 	}
       
   304     return EGL_NO_DISPLAY;
       
   305 }
       
   306 
       
   307 /*-------------------------------------------------------------------*//*!
       
   308 * \brief	return an EGL thread struct for the thread made current, or
       
   309 *            NULL if there's no current context.
       
   310 * \param	
       
   311 * \return	
       
   312 * \note		
       
   313 *//*-------------------------------------------------------------------*/
       
   314 
       
   315 RIEGLThread* EGL::getCurrentThread() const
       
   316 {
       
   317 	void* currentThreadID = OSGetCurrentThreadID();
       
   318 	for(int i=0;i<m_currentThreads.size();i++)
       
   319 	{
       
   320 		if(currentThreadID == m_currentThreads[i]->getThreadID())
       
   321 			return m_currentThreads[i];
       
   322 	}
       
   323 	return NULL;		//thread is not current
       
   324 }
       
   325 
       
   326 /*-------------------------------------------------------------------*//*!
       
   327 * \brief	return an EGL thread struct corresponding to current OS thread.
       
   328 * \param	
       
   329 * \return	
       
   330 * \note		
       
   331 *//*-------------------------------------------------------------------*/
       
   332 
       
   333 RIEGLThread* EGL::getThread()
       
   334 {
       
   335 	void* currentThreadID = OSGetCurrentThreadID();
       
   336 	for(int i=0;i<m_threads.size();i++)
       
   337 	{
       
   338 		if(currentThreadID == m_threads[i]->getThreadID())
       
   339 			return m_threads[i];
       
   340 	}
       
   341 
       
   342 	//EGL doesn't have a struct for the thread yet, add it to EGL's list
       
   343 	RIEGLThread* newThread = NULL;
       
   344 	try
       
   345 	{
       
   346 		newThread = RI_NEW(RIEGLThread, (OSGetCurrentThreadID()));	//throws bad_alloc
       
   347 		m_threads.push_back(newThread);	//throws bad_alloc
       
   348 		return newThread;
       
   349 	}
       
   350 	catch(std::bad_alloc)
       
   351 	{
       
   352 		RI_DELETE(newThread);
       
   353 		return NULL;
       
   354 	}
       
   355 }
       
   356 
       
   357 /*-------------------------------------------------------------------*//*!
       
   358 * \brief	destroy an EGL thread struct
       
   359 * \param	
       
   360 * \return	
       
   361 * \note		
       
   362 *//*-------------------------------------------------------------------*/
       
   363 
       
   364 void EGL::destroyThread()
       
   365 {
       
   366 	void* currentThreadID = OSGetCurrentThreadID();
       
   367 	for(int i=0;i<m_threads.size();i++)
       
   368 	{
       
   369 		if(currentThreadID == m_threads[i]->getThreadID())
       
   370         {
       
   371             RIEGLThread* thread = m_threads[i];
       
   372             bool res = m_threads.remove(thread);
       
   373             RI_ASSERT(res);
       
   374             RI_UNREF(res);
       
   375             RI_DELETE(thread);
       
   376             break;
       
   377         }
       
   378 	}
       
   379 }
       
   380 
       
   381 /*-------------------------------------------------------------------*//*!
       
   382 * \brief	
       
   383 * \param	
       
   384 * \return	
       
   385 * \note		
       
   386 *//*-------------------------------------------------------------------*/
       
   387 
       
   388 bool EGL::isInUse(const void* image) const
       
   389 {
       
   390     for(int i=0;i<m_currentThreads.size();i++)
   108     {
   391     {
   109         Color::Descriptor desc = m_desc;
   392         RIEGLSurface* s = m_currentThreads[i]->getCurrentSurface();
   110         unsigned int f = m_desc.luminanceBits ? Color::LUMINANCE : 0;
   393         if(s && s->getDrawable() && s->getDrawable()->isInUse((Image*)image))
   111         f |= sRGB ? Color::NONLINEAR : 0;
   394             return true;
   112         f |= premultiplied ? Color::PREMULTIPLIED : 0;
       
   113         desc.internalFormat = (Color::InternalFormat)f;
       
   114         return desc;
       
   115     }
   395     }
   116 
   396     return false;
   117 	//EGL RED SIZE bits of Red in the color buffer
   397 }
   118 	//EGL GREEN SIZE bits of Green in the color buffer
   398 //
   119 	//EGL BLUE SIZE bits of Blue in the color buffer
       
   120 	//EGL ALPHA SIZE bits of Alpha in the color buffer
       
   121 	//EGL LUMINANCE SIZE bits of Luminance in the color buffer
       
   122 	Color::Descriptor	m_desc;
       
   123 	int					m_samples;
       
   124     int                 m_maskBits;
       
   125 	EGLint				m_configID;			//EGL CONFIG ID unique EGLConfig identifier
       
   126     EGLConfig           m_config;
       
   127 	//EGL BUFFER SIZE depth of the color buffer (sum of channel bits)
       
   128 	//EGL ALPHA MASK SIZE number alpha mask bits (always 8)
       
   129 	//EGL BIND TO TEXTURE RGB boolean True if bindable to RGB textures. (always EGL_FALSE)
       
   130 	//EGL BIND TO TEXTURE RGBA boolean True if bindable to RGBA textures. (always EGL_FALSE)
       
   131 	//EGL COLOR BUFFER TYPE enum color buffer type (EGL_RGB_BUFFER, EGL_LUMINANCE_BUFFER)
       
   132 	//EGL CONFIG CAVEAT enum any caveats for the configuration (always EGL_NONE)
       
   133 	//EGL DEPTH SIZE integer bits of Z in the depth buffer (always 0)
       
   134 	//EGL LEVEL integer frame buffer level (always 0)
       
   135 	//EGL MAX PBUFFER WIDTH integer maximum width of pbuffer (always INT_MAX)
       
   136 	//EGL MAX PBUFFER HEIGHT integer maximum height of pbuffer (always INT_MAX)
       
   137 	//EGL MAX PBUFFER PIXELS integer maximum size of pbuffer (always INT_MAX)
       
   138 	//EGL MAX SWAP INTERVAL integer maximum swap interval (always 1)
       
   139 	//EGL MIN SWAP INTERVAL integer minimum swap interval (always 1)
       
   140 	//EGL NATIVE RENDERABLE boolean EGL TRUE if native rendering APIs can render to surface (always EGL_FALSE)
       
   141 	//EGL NATIVE VISUAL ID integer handle of corresponding native visual (always 0)
       
   142 	//EGL NATIVE VISUAL TYPE integer native visual type of the associated visual (always EGL_NONE)
       
   143 	//EGL RENDERABLE TYPE bitmask which client rendering APIs are supported. (always EGL_OPENVG_BIT)
       
   144 	//EGL SAMPLE BUFFERS integer number of multisample buffers (always 0)
       
   145 	//EGL SAMPLES integer number of samples per pixel (always 0)
       
   146 	//EGL STENCIL SIZE integer bits of Stencil in the stencil buffer (always 0)
       
   147 	//EGL SURFACE TYPE bitmask which types of EGL surfaces are supported. (always EGL WINDOW BIT | EGL PIXMAP BIT | EGL PBUFFER BIT)
       
   148 	//EGL TRANSPARENT TYPE enum type of transparency supported (always EGL_NONE)
       
   149 	//EGL TRANSPARENT RED VALUE integer transparent red value (undefined)
       
   150 	//EGL TRANSPARENT GREEN VALUE integer transparent green value (undefined)
       
   151 	//EGL TRANSPARENT BLUE VALUE integer transparent blue value (undefined)
       
   152 };
       
   153 
       
   154 /*-------------------------------------------------------------------*//*!
       
   155 * \brief	
       
   156 * \param	
       
   157 * \return	
       
   158 * \note		
       
   159 *//*-------------------------------------------------------------------*/
       
   160 
       
   161 class RIEGLContext
       
   162 {
       
   163 public:
       
   164 	RIEGLContext(OpenVGRI::VGContext* vgctx, const EGLConfig config);
       
   165 	~RIEGLContext();
       
   166 	void	addReference()				{ m_referenceCount++; }
       
   167 	int		removeReference()			{ m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; }
       
   168 
       
   169     VGContext*      getVGContext() const      { return m_vgContext; }
       
   170     EGLConfig getConfig() const         { return m_config; }
       
   171 private:
       
   172 	RIEGLContext(const RIEGLContext&);
       
   173 	RIEGLContext& operator=(const RIEGLContext&);
       
   174 	VGContext*		m_vgContext;
       
   175 	const EGLConfig	m_config;
       
   176 	int				m_referenceCount;
       
   177 };
       
   178 
       
   179 RIEGLContext* CastToRIEGLContext(EGLContext aCtxId);
       
   180 EGLContext CastFromRIEGLContext(RIEGLContext* aCtx);
       
   181 
       
   182 RIEGLContext::RIEGLContext(OpenVGRI::VGContext* vgctx, const EGLConfig config) :
   399 RIEGLContext::RIEGLContext(OpenVGRI::VGContext* vgctx, const EGLConfig config) :
   183 	m_vgContext(vgctx),
   400 	m_vgContext(vgctx),
   184 	m_config(config),
   401 	m_config(config),
   185 	m_referenceCount(0)
   402 	m_referenceCount(0)
   186 {
   403 {
   188 RIEGLContext::~RIEGLContext()
   405 RIEGLContext::~RIEGLContext()
   189 {
   406 {
   190 	RI_ASSERT(m_referenceCount == 0);
   407 	RI_ASSERT(m_referenceCount == 0);
   191 	RI_DELETE(m_vgContext);
   408 	RI_DELETE(m_vgContext);
   192 }
   409 }
   193 
       
   194 /*-------------------------------------------------------------------*//*!
       
   195 * \brief	
       
   196 * \param	
       
   197 * \return	
       
   198 * \note		
       
   199 *//*-------------------------------------------------------------------*/
       
   200 
       
   201 class RIEGLSurface
       
   202 {
       
   203 public:
       
   204     RIEGLSurface(void* OSWindowContext, const EGLConfig config, Drawable* drawable, bool largestPbuffer, int renderBuffer);
       
   205 	~RIEGLSurface();
       
   206 	void	addReference()				{ m_referenceCount++; }
       
   207 	int		removeReference()			{ m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; }
       
   208 
       
   209     void*           getOSWindowContext() const { return m_OSWindowContext; }
       
   210     EGLConfig       getConfig() const          { return m_config; }
       
   211     Drawable*       getDrawable() const        { return m_drawable; }
       
   212     bool            isLargestPbuffer() const   { return m_largestPbuffer; }
       
   213     int             getRenderBuffer() const    { return m_renderBuffer; }
       
   214 
       
   215 private:
       
   216 	RIEGLSurface(const RIEGLSurface&);
       
   217 	RIEGLSurface& operator=(const RIEGLSurface&);
       
   218     void*            m_OSWindowContext;
       
   219 	const EGLConfig	 m_config;
       
   220 	Drawable*        m_drawable;
       
   221 	bool			 m_largestPbuffer;
       
   222 	int				 m_renderBuffer;		//EGL_BACK_BUFFER or EGL_SINGLE_BUFFER
       
   223 	int				 m_referenceCount;
       
   224 };
       
   225 
       
   226 RIEGLSurface* CastToRIEGLSurface(EGLSurface aSurfaceId);
       
   227 EGLSurface CastFromRIEGLSurface(RIEGLSurface* aSurface);
       
   228 
   410 
   229 RIEGLSurface::RIEGLSurface(void* OSWindowContext, const EGLConfig config, Drawable* drawable, bool largestPbuffer, int renderBuffer) :
   411 RIEGLSurface::RIEGLSurface(void* OSWindowContext, const EGLConfig config, Drawable* drawable, bool largestPbuffer, int renderBuffer) :
   230     m_OSWindowContext(OSWindowContext),
   412     m_OSWindowContext(OSWindowContext),
   231 	m_config(config),
   413 	m_config(config),
   232 	m_drawable(drawable),
   414 	m_drawable(drawable),
   246 	{
   428 	{
   247 		if(!m_drawable->removeReference())
   429 		if(!m_drawable->removeReference())
   248 			RI_DELETE(m_drawable);
   430 			RI_DELETE(m_drawable);
   249 	}
   431 	}
   250 }
   432 }
   251 
       
   252 /*-------------------------------------------------------------------*//*!
       
   253 * \brief	
       
   254 * \param	
       
   255 * \return	
       
   256 * \note		
       
   257 *//*-------------------------------------------------------------------*/
       
   258 
       
   259 #define EGL_NUMCONFIGS		60
       
   260 
       
   261 class RIEGLDisplay
       
   262 {
       
   263 public:
       
   264 	RIEGLDisplay(EGLDisplay id);
       
   265 	~RIEGLDisplay();
       
   266 
       
   267 	int                getNumConfigs() const              { return EGL_NUMCONFIGS; }
       
   268     const RIEGLConfig& getConfigByIdx(int i) const             { RI_ASSERT(i >= 0 && i < EGL_NUMCONFIGS); return m_configs[i]; }
       
   269     const RIEGLConfig& getConfig(const EGLConfig config) const        { for(int i=0;i<EGL_NUMCONFIGS;i++) { if(m_configs[i].m_config == config) return m_configs[i]; } RI_ASSERT(0); return m_configs[0]; }
       
   270 
       
   271     EGLDisplay        getID() const                       { return m_id; }
       
   272 
       
   273     void              addContext(RIEGLContext* ctx)       { RI_ASSERT(ctx); m_contexts.push_back(ctx); }  //throws bad_alloc
       
   274     void              removeContext(RIEGLContext* ctx)    { RI_ASSERT(ctx); bool res = m_contexts.remove(ctx); RI_ASSERT(res); RI_UNREF(res); }
       
   275 
       
   276     void              addSurface(RIEGLSurface* srf)       { RI_ASSERT(srf); m_surfaces.push_back(srf); }  //throws bad_alloc
       
   277     void              removeSurface(RIEGLSurface* srf)    { RI_ASSERT(srf); bool res = m_surfaces.remove(srf); RI_ASSERT(res); RI_UNREF(res); }
       
   278 
       
   279     EGLBoolean        contextExists(const EGLContext ctx) const;
       
   280     EGLBoolean        surfaceExists(const EGLSurface srf) const;
       
   281     EGLBoolean        configExists(const EGLConfig cfg) const;
       
   282 
       
   283 private:
       
   284 	RIEGLDisplay(const RIEGLDisplay& t);
       
   285 	RIEGLDisplay& operator=(const RIEGLDisplay&t);
       
   286 
       
   287 	EGLDisplay              m_id;
       
   288 
       
   289 	Array<RIEGLContext*>	m_contexts;
       
   290 	Array<RIEGLSurface*>	m_surfaces;
       
   291 
       
   292 	RIEGLConfig             m_configs[EGL_NUMCONFIGS];
       
   293 };
       
   294 
   433 
   295 RIEGLDisplay::RIEGLDisplay(EGLDisplay id) :
   434 RIEGLDisplay::RIEGLDisplay(EGLDisplay id) :
   296 	m_id(id),
   435 	m_id(id),
   297 	m_contexts(),
   436 	m_contexts(),
   298 	m_surfaces()
   437 	m_surfaces()
   419 			return EGL_TRUE;
   558 			return EGL_TRUE;
   420 	}
   559 	}
   421 	return EGL_FALSE;
   560 	return EGL_FALSE;
   422 }
   561 }
   423 
   562 
       
   563 RIEGLSurface* RIEGLDisplay::getSurface(const EGLSurface surf) const
       
   564 {
       
   565 	/*
       
   566 	CEGLSurface* ret = FindObjectByPointer<CEGLSurface>( m_surfaces, surfaceId, NULL );
       
   567     if( ret && ret->IsTerminated() ) ret = NULL;
       
   568     return ret;
       
   569     */
       
   570     RIEGLSurface* ret = NULL;
       
   571     for(int i = 0; i < m_surfaces.size(); i++ )
       
   572     {
       
   573 		if( m_surfaces[i] == CastToRIEGLSurface(surf) )
       
   574         {
       
   575 			ret = m_surfaces[i];
       
   576         }
       
   577     }
       
   578     return ret;
       
   579 }
       
   580 
   424 EGLBoolean RIEGLDisplay::configExists(const EGLConfig config) const
   581 EGLBoolean RIEGLDisplay::configExists(const EGLConfig config) const
   425 {
   582 {
   426     for(int i=0;i<EGL_NUMCONFIGS;i++)
   583     for(int i=0;i<EGL_NUMCONFIGS;i++)
   427     {
   584     {
   428         if(m_configs[i].m_config == config)
   585         if(m_configs[i].m_config == config)
   429 		return EGL_TRUE;
   586 		return EGL_TRUE;
   430     }
   587     }
   431 	return EGL_FALSE;
   588 	return EGL_FALSE;
   432 }
   589 }
   433 
   590 
   434 /*-------------------------------------------------------------------*//*!
       
   435 * \brief	
       
   436 * \param	
       
   437 * \return	
       
   438 * \note		
       
   439 *//*-------------------------------------------------------------------*/
       
   440 
       
   441 class RIEGLThread
       
   442 {
       
   443 public:
       
   444 	RIEGLThread(void* currentThreadID);
       
   445 	~RIEGLThread();
       
   446 
       
   447     void*           getThreadID() const       { return m_threadID; }
       
   448 
       
   449     void            makeCurrent(RIEGLContext* c, RIEGLSurface* s)       { m_context = c; m_surface = s; }
       
   450 	RIEGLContext*	getCurrentContext() const   { return m_context; }
       
   451 	RIEGLSurface*	getCurrentSurface() const   { return m_surface; }
       
   452 
       
   453     void            setError(EGLint error)      { m_error = error; }
       
   454     EGLint          getError() const            { return m_error; }
       
   455 
       
   456     void            bindAPI(EGLint api)         { m_boundAPI = api; }
       
   457     EGLint          getBoundAPI() const         { return m_boundAPI; }
       
   458 
       
   459 private:
       
   460 	RIEGLThread(const RIEGLThread&);
       
   461 	RIEGLThread operator=(const RIEGLThread&);
       
   462 
       
   463 	RIEGLContext*		m_context;
       
   464 	RIEGLSurface*		m_surface;
       
   465 	EGLint              m_error;
       
   466 	void*               m_threadID;
       
   467 	EGLint              m_boundAPI;
       
   468 };
       
   469 
       
   470 RIEGLThread::RIEGLThread(void* currentThreadID) :
   591 RIEGLThread::RIEGLThread(void* currentThreadID) :
   471 	m_context(NULL),
   592 	m_context(NULL),
   472 	m_surface(NULL),
   593 	m_surface(NULL),
   473 	m_error(EGL_SUCCESS),
   594 	m_error(EGL_SUCCESS),
   474 	m_threadID(currentThreadID),
   595 	m_threadID(currentThreadID),
   478 
   599 
   479 RIEGLThread::~RIEGLThread()
   600 RIEGLThread::~RIEGLThread()
   480 {
   601 {
   481 }
   602 }
   482 
   603 
   483 
   604 namespace OpenVGRI
   484 
   605 {
   485 
   606 ////
   486 
       
   487 Image* CastToImage(EGLClientBuffer aBufferId);
       
   488 EGLClientBuffer CastFromImage(Image* aBUffer);
       
   489 
       
   490 /*-------------------------------------------------------------------*//*!
       
   491 * \brief	
       
   492 * \param	
       
   493 * \return	
       
   494 * \note		
       
   495 *//*-------------------------------------------------------------------*/
       
   496 
       
   497 class EGL
       
   498 {
       
   499 public:
       
   500 	EGL();
       
   501 	~EGL();
       
   502 
       
   503 	void	addReference()				{ m_referenceCount++; }
       
   504 	int		removeReference()			{ m_referenceCount--; RI_ASSERT(m_referenceCount >= 0); return m_referenceCount; }
       
   505 
       
   506     void                addDisplay(RIEGLDisplay* display)           { RI_ASSERT(display); m_displays.push_back(display); }  //throws bad alloc
       
   507     void                removeDisplay(RIEGLDisplay* display)        { RI_ASSERT(display); bool res = m_displays.remove(display); RI_ASSERT(res); RI_UNREF(res); }
       
   508     RIEGLDisplay*       getDisplay(const EGLDisplay displayID) const;
       
   509     EGLDisplay          findDisplay(const EGLContext ctx) const;
       
   510 
       
   511     void                addCurrentThread(RIEGLThread* thread)       { RI_ASSERT(thread); m_currentThreads.push_back(thread); }  //throws bad alloc
       
   512     void                removeCurrentThread(RIEGLThread* thread)    { RI_ASSERT(thread); bool res = m_currentThreads.remove(thread); RI_ASSERT(res); RI_UNREF(res); }
       
   513     RIEGLThread*        getCurrentThread() const;
       
   514 
       
   515     RIEGLThread*        getThread();
       
   516     void                destroyThread();
       
   517 
       
   518     bool                isInUse(const void* image) const;
       
   519 
       
   520 private:
       
   521 	EGL(const EGL&);						// Not allowed.
       
   522 	const EGL& operator=(const EGL&);		// Not allowed.
       
   523 
       
   524 	Array<RIEGLThread*>		m_threads;			//threads that have called EGL
       
   525 	Array<RIEGLThread*>		m_currentThreads;	//threads that have a bound context
       
   526 	Array<RIEGLDisplay*>	m_displays;
       
   527 
       
   528 	int                     m_referenceCount;
       
   529 };
       
   530 
       
   531 EGL::EGL() :
       
   532 	m_threads(),
       
   533 	m_currentThreads(),
       
   534 	m_displays(),
       
   535 	m_referenceCount(0)
       
   536 {
       
   537 }
       
   538 EGL::~EGL()
       
   539 {
       
   540 	for(int i=0;i<m_displays.size();i++)
       
   541 	{
       
   542 		RI_DELETE(m_displays[i]);
       
   543 	}
       
   544 	for(int i=0;i<m_threads.size();i++)
       
   545 	{
       
   546 		RI_DELETE(m_threads[i]);
       
   547 	}
       
   548 	//currentThreads contain just pointers to threads we just deleted
       
   549 }
       
   550 
       
   551 /*-------------------------------------------------------------------*//*!
       
   552 * \brief	
       
   553 * \param	
       
   554 * \return	
       
   555 * \note		
       
   556 *//*-------------------------------------------------------------------*/
       
   557 
       
   558 //static EGL* g_egl = NULL;	//never use this directly
       
   559 EGL* getEGL()
       
   560 {
       
   561 	/*if(!g_egl)
       
   562 	{
       
   563 		try
       
   564 		{
       
   565 			g_egl = RI_NEW(EGL, ());				//throws bad_alloc
       
   566 			g_egl->addReference();
       
   567 		}
       
   568 		catch(std::bad_alloc)
       
   569 		{
       
   570 			g_egl = NULL;
       
   571 		}
       
   572 	}
       
   573 	return g_egl;
       
   574 	*/
       
   575 
       
   576 
       
   577 	//use TLS to store static global g_egl
       
   578 	EGL* pEgl=NULL; 
       
   579 	if((pEgl = static_cast<EGL*>(Dll::Tls()))==NULL)
       
   580 		{
       
   581 		//create TLS instance
       
   582 		pEgl = RI_NEW(EGL, ());
       
   583 		Dll::SetTls(pEgl);
       
   584 		}
       
   585 	return pEgl;
       
   586 
       
   587 	
       
   588 }
       
   589 static void releaseEGL()
       
   590 {
       
   591 /*
       
   592 	if(g_egl)
       
   593 	{
       
   594 		if(!g_egl->removeReference())
       
   595 		{
       
   596 			RI_DELETE(g_egl);
       
   597 			g_egl = NULL;
       
   598 		}
       
   599 	}
       
   600 	*/
       
   601 	EGL* pEgl = static_cast<EGL*>(Dll::Tls());
       
   602 	if (pEgl)
       
   603 		delete pEgl; 
       
   604 	Dll::SetTls(NULL);
       
   605 
       
   606 }
       
   607 
       
   608 /*-------------------------------------------------------------------*//*!
       
   609 * \brief	Given a display ID, return the corresponding object, or NULL
       
   610 *			if the ID hasn't been initialized.
       
   611 * \param	
       
   612 * \return	
       
   613 * \note		if egl has been initialized for this display, the display ID can
       
   614 *			be found from egl->m_displays
       
   615 *//*-------------------------------------------------------------------*/
       
   616 
       
   617 RIEGLDisplay* EGL::getDisplay(EGLDisplay displayID) const
       
   618 {
       
   619 	for(int i=0;i<m_displays.size();i++)
       
   620 	{
       
   621 		if(displayID == m_displays[i]->getID())
       
   622 			return m_displays[i];
       
   623 	}
       
   624 	return NULL;		//error: the display hasn't been eglInitialized
       
   625 }
       
   626 
       
   627 /*-------------------------------------------------------------------*//*!
       
   628 * \brief	return EGLDisplay for the current context
       
   629 * \param	
       
   630 * \return	
       
   631 * \note		
       
   632 *//*-------------------------------------------------------------------*/
       
   633 
       
   634 EGLDisplay EGL::findDisplay(EGLContext ctx) const
       
   635 {
       
   636 	for(int i=0;i<m_displays.size();i++)
       
   637 	{
       
   638         if(m_displays[i]->contextExists(ctx))
       
   639             return m_displays[i]->getID();
       
   640 	}
       
   641     return EGL_NO_DISPLAY;
       
   642 }
       
   643 
       
   644 /*-------------------------------------------------------------------*//*!
       
   645 * \brief	return an EGL thread struct for the thread made current, or
       
   646 *            NULL if there's no current context.
       
   647 * \param	
       
   648 * \return	
       
   649 * \note		
       
   650 *//*-------------------------------------------------------------------*/
       
   651 
       
   652 RIEGLThread* EGL::getCurrentThread() const
       
   653 {
       
   654 	void* currentThreadID = OSGetCurrentThreadID();
       
   655 	for(int i=0;i<m_currentThreads.size();i++)
       
   656 	{
       
   657 		if(currentThreadID == m_currentThreads[i]->getThreadID())
       
   658 			return m_currentThreads[i];
       
   659 	}
       
   660 	return NULL;		//thread is not current
       
   661 }
       
   662 
       
   663 /*-------------------------------------------------------------------*//*!
       
   664 * \brief	return an EGL thread struct corresponding to current OS thread.
       
   665 * \param	
       
   666 * \return	
       
   667 * \note		
       
   668 *//*-------------------------------------------------------------------*/
       
   669 
       
   670 RIEGLThread* EGL::getThread()
       
   671 {
       
   672 	void* currentThreadID = OSGetCurrentThreadID();
       
   673 	for(int i=0;i<m_threads.size();i++)
       
   674 	{
       
   675 		if(currentThreadID == m_threads[i]->getThreadID())
       
   676 			return m_threads[i];
       
   677 	}
       
   678 
       
   679 	//EGL doesn't have a struct for the thread yet, add it to EGL's list
       
   680 	RIEGLThread* newThread = NULL;
       
   681 	try
       
   682 	{
       
   683 		newThread = RI_NEW(RIEGLThread, (OSGetCurrentThreadID()));	//throws bad_alloc
       
   684 		m_threads.push_back(newThread);	//throws bad_alloc
       
   685 		return newThread;
       
   686 	}
       
   687 	catch(std::bad_alloc)
       
   688 	{
       
   689 		RI_DELETE(newThread);
       
   690 		return NULL;
       
   691 	}
       
   692 }
       
   693 
       
   694 /*-------------------------------------------------------------------*//*!
       
   695 * \brief	destroy an EGL thread struct
       
   696 * \param	
       
   697 * \return	
       
   698 * \note		
       
   699 *//*-------------------------------------------------------------------*/
       
   700 
       
   701 void EGL::destroyThread()
       
   702 {
       
   703 	void* currentThreadID = OSGetCurrentThreadID();
       
   704 	for(int i=0;i<m_threads.size();i++)
       
   705 	{
       
   706 		if(currentThreadID == m_threads[i]->getThreadID())
       
   707         {
       
   708             RIEGLThread* thread = m_threads[i];
       
   709             bool res = m_threads.remove(thread);
       
   710             RI_ASSERT(res);
       
   711             RI_UNREF(res);
       
   712             RI_DELETE(thread);
       
   713             break;
       
   714         }
       
   715 	}
       
   716 }
       
   717 
       
   718 /*-------------------------------------------------------------------*//*!
       
   719 * \brief	
       
   720 * \param	
       
   721 * \return	
       
   722 * \note		
       
   723 *//*-------------------------------------------------------------------*/
       
   724 
       
   725 bool EGL::isInUse(const void* image) const
       
   726 {
       
   727     for(int i=0;i<m_currentThreads.size();i++)
       
   728     {
       
   729         RIEGLSurface* s = m_currentThreads[i]->getCurrentSurface();
       
   730         if(s && s->getDrawable() && s->getDrawable()->isInUse((Image*)image))
       
   731             return true;
       
   732     }
       
   733     return false;
       
   734 }
       
   735 
       
   736 /*-------------------------------------------------------------------*//*!
       
   737 * \brief	
       
   738 * \param	
       
   739 * \return	
       
   740 * \note		
       
   741 *//*-------------------------------------------------------------------*/
       
   742 
       
   743 #define EGL_GET_DISPLAY(DISPLAY, RETVAL) \
       
   744 	OSAcquireMutex(); \
       
   745 	EGL* egl = getEGL(); \
       
   746     if(!egl) \
       
   747     { \
       
   748 		OSReleaseMutex(); \
       
   749 		return RETVAL; \
       
   750     } \
       
   751 	RIEGLDisplay* display = egl->getDisplay(DISPLAY); \
       
   752 
       
   753 #define EGL_GET_EGL(RETVAL) \
       
   754 	OSAcquireMutex(); \
       
   755 	EGL* egl = getEGL(); \
       
   756     if(!egl) \
       
   757     { \
       
   758 		OSReleaseMutex(); \
       
   759 		return RETVAL; \
       
   760     } \
       
   761 
       
   762 #define EGL_IF_ERROR(COND, ERRORCODE, RETVAL) \
       
   763 	if(COND) { eglSetError(egl, ERRORCODE); OSReleaseMutex(); return RETVAL; } \
       
   764 
       
   765 #define EGL_RETURN(ERRORCODE, RETVAL) \
       
   766 	{ \
       
   767 		eglSetError(egl, ERRORCODE); \
       
   768 		OSReleaseMutex(); \
       
   769 		return RETVAL; \
       
   770 	}
       
   771 
       
   772 // Note: egl error handling model differs from OpenVG. The latest error is stored instead of the oldest one.
   607 // Note: egl error handling model differs from OpenVG. The latest error is stored instead of the oldest one.
   773 static void eglSetError(EGL* egl, EGLint error)
   608 //static void eglSetError(EGL* egl, EGLint error)
       
   609 void eglSetError(EGL* egl, EGLint error)
   774 {
   610 {
   775 	RIEGLThread* thread = egl->getThread();
   611 	RIEGLThread* thread = egl->getThread();
   776 	if(thread)
   612 	if(thread)
   777 		thread->setError(error);
   613 		thread->setError(error);
   778 }
   614 }
   784 * \note		This function is always called from a mutexed API function
   620 * \note		This function is always called from a mutexed API function
   785 *//*-------------------------------------------------------------------*/
   621 *//*-------------------------------------------------------------------*/
   786 
   622 
   787 void* eglvgGetCurrentVGContext(void)
   623 void* eglvgGetCurrentVGContext(void)
   788 {
   624 {
   789 	EGL* egl = getEGL();
   625 	EGL* egl = OpenVGRI::getEGL();
   790     if(egl)
   626     if(egl)
   791     {
   627     {
   792         RIEGLThread* thread = egl->getCurrentThread();
   628         RIEGLThread* thread = egl->getCurrentThread();
   793         if(thread)
   629         if(thread)
   794         {
   630         {
   806 * \note		This function is always called from a mutexed API function
   642 * \note		This function is always called from a mutexed API function
   807 *//*-------------------------------------------------------------------*/
   643 *//*-------------------------------------------------------------------*/
   808 
   644 
   809 bool eglvgIsInUse(void* image)
   645 bool eglvgIsInUse(void* image)
   810 {
   646 {
   811 	EGL* egl = getEGL();
   647 	EGL* egl = OpenVGRI::getEGL();
   812     if(egl)
   648     if(egl)
   813     {
   649     {
   814         return egl->isInUse(image);
   650         return egl->isInUse(image);
   815     }
   651     }
   816 	return false;
   652 	return false;
   817 }
   653 }
   818 
   654 
   819 //helper functions
   655 } // namespace OpenVGRI
   820 RIEGLContext* CastToRIEGLContext(EGLContext aCtxId)
   656 
   821   {
   657 
   822   return (RIEGLContext*)(aCtxId);
   658 /*-------------------------------------------------------------------*//*!
   823   }
   659 * \brief	
   824 EGLContext CastFromRIEGLContext(RIEGLContext* aCtx)
   660 * \param	
   825   {
   661 * \return	
   826   return (EGLContext)(aCtx);
   662 * \note		
   827   }
   663 *//*-------------------------------------------------------------------*/
   828 
   664 
   829 RIEGLSurface* CastToRIEGLSurface(EGLSurface aSurfaceId)
   665 #ifdef BUILD_WITH_PRIVATE_EGL
   830   {
   666 RI_APIENTRY EGLint do_eglGetError(void)
   831   return (RIEGLSurface*)(aSurfaceId);
       
   832   }
       
   833 EGLSurface CastFromRIEGLSurface(RIEGLSurface* aSurface)
       
   834   {
       
   835   return (EGLSurface)(aSurface);
       
   836   }
       
   837 
       
   838 Image* CastToImage(EGLClientBuffer aBufferId)
       
   839   {
       
   840   return (Image*)(aBufferId);
       
   841   }
       
   842 
       
   843 EGLClientBuffer CastFromImage(Image* aBUffer)
       
   844   {
       
   845   return (EGLClientBuffer)(aBUffer);
       
   846   }
       
   847 
       
   848 //==============================================================================================
       
   849 
       
   850 }	//namespace OpenVGRI
       
   851 
       
   852 using namespace OpenVGRI;
       
   853 
       
   854 
       
   855 
       
   856 
       
   857 
       
   858 /*-------------------------------------------------------------------*//*!
       
   859 * \brief	
       
   860 * \param	
       
   861 * \return	
       
   862 * \note		
       
   863 *//*-------------------------------------------------------------------*/
       
   864 
       
   865 #ifdef BUILD_WITH_PRIVATE_EGL
       
   866 RI_APIENTRY EGLint do_eglGetError()
       
   867 #else
   667 #else
   868 EGLint eglGetError()
   668 EGLint eglGetError()
   869 #endif
   669 #endif
   870 {
   670 {
   871     OSAcquireMutex();
   671     OSAcquireMutex();
   872     EGLint ret = EGL_SUCCESS;
   672     EGLint ret = EGL_SUCCESS;
   873 	EGL* egl = getEGL();
   673 	EGL* egl = OpenVGRI::getEGL();
   874     if(egl)
   674     if(egl)
   875     {
   675     {
   876         RIEGLThread* thread = egl->getThread();
   676         RIEGLThread* thread = egl->getThread();
   877         if(thread)
   677         if(thread)
   878             ret = thread->getError();	//initialized, return error code
   678             ret = thread->getError();	//initialized, return error code
   969 #endif
   769 #endif
   970 {
   770 {
   971 	EGL_GET_DISPLAY(dpy, NULL);
   771 	EGL_GET_DISPLAY(dpy, NULL);
   972 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, NULL);
   772 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, NULL);
   973 
   773 
   974 	static const char apis[] = "OpenVG";
   774 	static const char apis[] = "OpenVG OpenGL_ES OpenGL_ES2";
   975 	static const char extensions[] = "";
   775 	static const char extensions[] = "KHR_reusable_sync EGL_SYMBIAN_COMPOSITION";
   976 	static const char vendor[] = "Khronos Group";
   776 	static const char vendor[] = "Symbian Foundation";
   977 	static const char version[] = "1.3";
   777 	static const char version[] = "1.4 mergeegl";
   978 
   778 
   979 	const char* ret = NULL;
   779 	const char* ret = NULL;
   980 	switch(name)
   780 	switch(name)
   981 	{
   781 	{
   982 	case EGL_CLIENT_APIS:
   782 	case EGL_CLIENT_APIS:
  1458 	}
  1258 	}
  1459 	//we ignore the renderBuffer parameter since we can only render to double buffered surfaces
  1259 	//we ignore the renderBuffer parameter since we can only render to double buffered surfaces
  1460 
  1260 
  1461 	//TODO If the attributes of win do not correspond to config, then an EGL BAD MATCH error is generated.
  1261 	//TODO If the attributes of win do not correspond to config, then an EGL BAD MATCH error is generated.
  1462 	//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
  1262 	//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
  1463 
  1263 	// 
  1464     void* wc = NULL;
  1264 	void* wc = NULL;
  1465     Drawable* d = NULL;
  1265 	Drawable* d = NULL;
  1466 	RIEGLSurface* s = NULL;
  1266 	RIEGLSurface* s = NULL;
  1467 	try
  1267 	try
  1468 	{
  1268 	{
  1469         wc = OSCreateWindowContext(win);
  1269         wc = OSCreateWindowContext(win);
  1470 		RI_ASSERT(wc);
  1270 		RI_ASSERT(wc);
  1490         OSDestroyWindowContext(wc);
  1290         OSDestroyWindowContext(wc);
  1491         RI_DELETE(d);
  1291         RI_DELETE(d);
  1492         RI_DELETE(s);
  1292         RI_DELETE(s);
  1493 		EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_SURFACE);
  1293 		EGL_RETURN(EGL_BAD_ALLOC, EGL_NO_SURFACE);
  1494 	}
  1294 	}
       
  1295 #ifdef EGL_COMPOSITION
       
  1296 	RIEGLThread* thread = egl->getThread();
       
  1297 	RI_ASSERT(thread);
       
  1298 	
       
  1299     
       
  1300 	//egl->iDisplayMapLock.WriteLock();
       
  1301 	CEglDisplayInfo** pDispInfo;
       
  1302 	pDispInfo = egl->iDisplayMap.Find(dpy); // make sure iDisplayInfo is populated in CreateDisplay!!
       
  1303 	
       
  1304 	if (pDispInfo && *pDispInfo)
       
  1305 	{
       
  1306 		TSurfaceInfo& surfaceInfo = egl->GetSurfaceInfo();
       
  1307 		// so we don't have to pass alphaFormat to CreateSurface we set it here... not sure if needed anyway
       
  1308 		surfaceInfo.iAlphaFormat = alphaFormat;
       
  1309 		
       
  1310 		if(EGL_TRUE != egl->EglInternalFunction_CreateSurface(/*aThreadState,*/ dpy, (EGLSurface)s, config, win, surfaceInfo))
       
  1311 			EGL_RETURN(EGL_BAD_SURFACE, NULL);
       
  1312 			
       
  1313 		(*pDispInfo)->iSurfaceMap.Insert(surfaceInfo.iSurface, &surfaceInfo);		
       
  1314 		
       
  1315 		TSurfaceConfiguration surfaceConfig;
       
  1316 		surfaceConfig.SetSurfaceId(surfaceInfo.iSurfaceId);
       
  1317 			
       
  1318 		if(surfaceInfo.iNativeWindow.IsWindow())
       
  1319 		{
       
  1320 			RWindow* window = (RWindow*)(win);				
       
  1321 			RWsSession& session = *window->Session();
       
  1322 			session.RegisterSurface(surfaceInfo.iScreenNumber, surfaceInfo.iSurfaceId);
       
  1323 			window->SetBackgroundSurface(surfaceConfig, ETrue);
       
  1324 		}
       
  1325 		else
       
  1326 		{
       
  1327 			// Now what?? Nothing is good enough?
       
  1328 			// Simply no composition if not RWindow?
       
  1329 			EGL_TRACE("eglCreateWindowSurface - Native Window NOT RWindow - no composition");
       
  1330 		}
       
  1331 		
       
  1332 		TRequestStatus status = KRequestPending;
       
  1333 		TTimeStamp timestampLocalToThread;
       
  1334 		// session needs to be established... and it is in InternalFunction_CreateSurface
       
  1335 		/*
       
  1336 		 * When double-buffering is used, the client renders to one buffer (called A in this example) while the other buffer (B) is on the screen and vice versa. In order for this to work correctly and to be free of tearing artefacts, the client must use the following sequence:
       
  1337 
       
  1338 		   1. Render the graphics content to buffer A, and call NotifyWhenAvailable() followed by SubmitUpdate() for buffer A.
       
  1339 		   2. Render the graphics content to buffer B, and call NotifyWhenAvailable() followed by SubmitUpdate() for buffer B.
       
  1340 		   3. Wait for notification that buffer A is available. When it becomes available, render further content to it and call NotifyWhenAvailable() followed by SubmitUpdate() for buffer A.
       
  1341 		   4. Wait for notification that buffer B is available. When it becomes available, render further content to it and call NotifyWhenAvailable() followed by SubmitUpdate() for buffer B.
       
  1342 		   5. Repeat steps 3 and 4 for as long as required.
       
  1343 
       
  1344 		After sending the first two buffers to the composition engine, the client waits for notification before sending a further buffer. The composition engine always returns notification after receiving a new buffer even if an error condition is detected. 
       
  1345 		*/
       
  1346 		surfaceInfo.iSurfaceUpdateSession.NotifyWhenDisplayed(status, timestampLocalToThread);
       
  1347 		surfaceInfo.iSurfaceUpdateSession.SubmitUpdate(surfaceInfo.iScreenNumber,surfaceInfo.iSurfaceId, 0);
       
  1348 		surfaceInfo.iSurfaceUpdateSession.SubmitUpdate(surfaceInfo.iScreenNumber,surfaceInfo.iSurfaceId, 1);
       
  1349 		User::WaitForRequest(status);
       
  1350 	}
       
  1351 	
       
  1352 	
       
  1353 	
       
  1354 	//egl->iDisplayMapLock.Unlock();
       
  1355 		
       
  1356 	//thread->setError(EGL_SUCCESS); // done by EGL_RETURN macro?
       
  1357 #endif
  1495 	EGL_RETURN(EGL_SUCCESS, (EGLSurface)s);
  1358 	EGL_RETURN(EGL_SUCCESS, (EGLSurface)s);
  1496 }
  1359 }
       
  1360 
       
  1361 // -----------------------------------------------------------------------------
       
  1362 //
       
  1363 // -----------------------------------------------------------------------------
       
  1364 //
       
  1365 TBool EGL::EglInternalFunction_CreateSurface(/*TEglThreadState& aThreadState,*/ EGLDisplay aDisplay, EGLSurface aSurface, EGLConfig aConfig, 
       
  1366 		EGLNativeWindowType aNativeWindow, TSurfaceInfo& aSurfaceInfo)
       
  1367 {
       
  1368 	
       
  1369 	aSurfaceInfo.iNativeWindow.SetNativeWindow(aNativeWindow);    
       
  1370 	aSurfaceInfo.iSurfaceType = ESurfaceTypeWindow;
       
  1371 	aSurfaceInfo.iSize = aSurfaceInfo.iNativeWindow.SizeInPixels();
       
  1372 	
       
  1373 	aSurfaceInfo.iConfigId = aConfig;    
       
  1374 	aSurfaceInfo.iSurface = aSurface;
       
  1375 	
       
  1376 	aSurfaceInfo.iStride = 4 * aSurfaceInfo.iSize.iWidth;          // Number of bytes between start of one line and start of next   
       
  1377 	    
       
  1378 	
       
  1379 	RSurfaceManager::TSurfaceCreationAttributesBuf buf;
       
  1380 	RSurfaceManager::TSurfaceCreationAttributes& attributes = buf();
       
  1381 	// Set surafce attributes
       
  1382     attributes.iSize = aSurfaceInfo.iSize;
       
  1383     attributes.iBuffers = 2;           // double-buffering is used
       
  1384     attributes.iPixelFormat = EUidPixelFormatARGB_8888;  // this is a guess; either query or hardcode to match syborg
       
  1385     //attributes.iPixelFormat = EUidPixelFormatARGB_8888_PRE;  // this is a guess; either query or hardcode
       
  1386     /** Minimum or required number of bytes between start of one line andstart of next. */
       
  1387     attributes.iStride = aSurfaceInfo.iStride;
       
  1388     /** Minimum or required offset to the first buffer from the base of the chunk. 
       
  1389      * Typically this will be set to 0. The value specified for the offset must comply with the alignment specified in iAlignment.
       
  1390      * If iAlignment is page aligned, this value will be rounded up to a multiple of the page size when the surface is created, 
       
  1391      * therefore the surface info must be queried for the actual value used. */
       
  1392     attributes.iOffsetToFirstBuffer = 0;
       
  1393     /** Alignment applied to the base address of each buffer in the surface:
       
  1394      * 1, 2, 4, 8 ,16, 32, 64 bytes or EPageAligned. */
       
  1395     attributes.iAlignment = RSurfaceManager::EPageAligned;                      // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned
       
  1396     /** Number of hints in the array iSurfaceHints. 
       
  1397      * The number should not exceed the maximum number supported by the surface manager, 
       
  1398      * see GetSurfaceManagerAttrib(EMaxNumberOfHints). */
       
  1399     attributes.iHintCount=0;
       
  1400     /** Array of hints which should be associated with the surface. 
       
  1401      * This array must not contain duplicate hint keys. */
       
  1402      attributes.iSurfaceHints = NULL;
       
  1403     /** Minimum or required offset between the start of one buffer and the
       
  1404 	start of the next one in bytes. When set to 0 the surface manager will
       
  1405 	choose how buffers are laid out within the chunk. If it is too small
       
  1406 	and doesn't fit with the alignment, CreateSurface() will return KErrArgument. */
       
  1407     attributes.iOffsetBetweenBuffers = 0;
       
  1408     /** Require physically contiguous memory. 
       
  1409      * This value will be ignored if using a chunk which already exists. */
       
  1410     attributes.iContiguous = ETrue;
       
  1411     /** Caching attribute to create chunk memory. 
       
  1412      * This value will be ignored if using a chunk which already exists. */
       
  1413     attributes.iCacheAttrib = RSurfaceManager::ECached;      // Cache attributes
       
  1414     /** Should the surface be mappable. 
       
  1415      * If EFalse any call to MapSurface() will fail with KErrNotSupported
       
  1416      * Note, some architectures may not support mappable surfaces. */
       
  1417     attributes.iMappable = ETrue;	
       
  1418 	//
       
  1419     aSurfaceInfo.iScreenNumber = aSurfaceInfo.iNativeWindow.ScreenNumber();
       
  1420 				
       
  1421 	// Create the surface
       
  1422 	
       
  1423 	aSurfaceInfo.iSurfaceManager.Open();
       
  1424 	aSurfaceInfo.iSurfaceManager.CreateSurface(buf, aSurfaceInfo.iSurfaceId);
       
  1425 	
       
  1426 	TInt err =  aSurfaceInfo.iSurfaceManager.MapSurface(aSurfaceInfo.iSurfaceId, aSurfaceInfo.iChunk);
       
  1427 		
       
  1428 	EGL_TRACE("EGL::EglInternalFunction_CreateSurface surface manager returned chunk %x and ret val %d", aSurfaceInfo.iChunk, err);
       
  1429 				
       
  1430 
       
  1431 
       
  1432     if ( !EglInternalFunction_CallSetSurfaceParams(/*aThreadState,*/ aDisplay, aSurface, aSurfaceInfo) )
       
  1433         {
       
  1434         EGL_TRACE("CGuestEGL::EglInternalFunction_CreateSurface end failure");
       
  1435 
       
  1436         return EGL_FALSE;
       
  1437         }
       
  1438     aSurfaceInfo.iSurfaceUpdateSession.Connect();
       
  1439     EGL_TRACE("CGuestEGL::EglInternalFunction_CreateSurface end success");
       
  1440 
       
  1441     return EGL_TRUE;
       
  1442 }
       
  1443 
       
  1444 // -----------------------------------------------------------------------------
       
  1445 //
       
  1446 // -----------------------------------------------------------------------------
       
  1447 //
       
  1448 TBool EGL::EglInternalFunction_CallSetSurfaceParams(/*aThreadState,*/EGLDisplay aDisplay,EGLSurface aSurface,TSurfaceInfo& aSurfaceInfo)
       
  1449 {
       
  1450 	EGL_GET_EGL(EGL_FALSE);
       
  1451 /*
       
  1452     EGL_GET_DISPLAY(aDisplay, EGL_NO_SURFACE);
       
  1453     EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
       
  1454     //RI_ASSERT( display->ProcessId() == process->Id() );
       
  1455     RIEGLSurface* surface = display->getSurface( aSurface );
       
  1456     EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_BAD_SURFACE);
       
  1457  */
       
  1458     RI_ASSERT( aSurfaceInfo.iSurfaceType == ESurfaceTypeWindow );
       
  1459     
       
  1460     //TODO: resizing?
       
  1461     
       
  1462 #ifdef BUILD_WITH_PRIVATE_EGL
       
  1463 	if(!do_eglQuerySurface(aDisplay, aSurface, EGL_VG_ALPHA_FORMAT, &aSurfaceInfo.iAlphaFormat))
       
  1464 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1465 	if(!do_eglGetConfigAttrib(aDisplay, aSurfaceInfo.iConfigId, EGL_BUFFER_SIZE, &aSurfaceInfo.iColorBits))
       
  1466 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1467 	if(!do_eglGetConfigAttrib(aDisplay, aSurfaceInfo.iConfigId, EGL_RED_SIZE, &aSurfaceInfo.iRedBits))
       
  1468 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1469 	if(!do_eglGetConfigAttrib(aDisplay, aSurfaceInfo.iConfigId, EGL_GREEN_SIZE, &aSurfaceInfo.iGreenBits))
       
  1470 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1471 	if(!do_eglGetConfigAttrib(aDisplay, aSurfaceInfo.iConfigId, EGL_BLUE_SIZE, &aSurfaceInfo.iBlueBits))
       
  1472 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1473 	if(!do_eglGetConfigAttrib(aDisplay, aSurfaceInfo.iConfigId, EGL_ALPHA_SIZE, &aSurfaceInfo.iAlphaBits))
       
  1474 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1475 #else
       
  1476 	if(!eglQuerySurface(aDisplay, aSurface, EGL_VG_ALPHA_FORMAT, &aSurfaceInfo.iAlphaFormat))
       
  1477 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1478 	if(!eglGetConfigAttrib(aDisplay, aSurfaceInfo.iConfigId, EGL_BUFFER_SIZE, &aSurfaceInfo.iColorBits))
       
  1479 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1480 	if(!eglGetConfigAttrib(aDisplay, aSurfaceInfo.iConfigId, EGL_RED_SIZE, &aSurfaceInfo.iRedBits))
       
  1481 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1482 	if(!eglGetConfigAttrib(aDisplay, aSurfaceInfo.iConfigId, EGL_GREEN_SIZE, &aSurfaceInfo.iGreenBits))
       
  1483 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1484 	if(!eglGetConfigAttrib(aDisplay, aSurfaceInfo.iConfigId, EGL_BLUE_SIZE, &aSurfaceInfo.iBlueBits))
       
  1485 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1486 	if(!eglGetConfigAttrib(aDisplay, aSurfaceInfo.iConfigId, EGL_ALPHA_SIZE, &aSurfaceInfo.iAlphaBits))
       
  1487 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1488 #endif
       
  1489 
       
  1490     
       
  1491     EGL_TRACE("EGL::EglInternalFunction_CallSetSurfaceParams  Win surface details: width=%d height=%d colorbits=%d red=%d green=%d blue=%d alpha=%d alphaformat=0x%x",
       
  1492     		aSurfaceInfo.iSize.iWidth, aSurfaceInfo.iSize.iHeight, aSurfaceInfo.iColorBits, aSurfaceInfo.iRedBits,
       
  1493     		aSurfaceInfo.iGreenBits, aSurfaceInfo.iBlueBits, aSurfaceInfo.iAlphaBits, aSurfaceInfo.iAlphaFormat);
       
  1494     TInt err;
       
  1495     TSize size;
       
  1496 
       
  1497     TInt offsetToFirstBuffer = -1;
       
  1498     TInt offsetToSecondBuffer = -1;
       
  1499 	err = aSurfaceInfo.iSurfaceManager.GetBufferOffset(aSurfaceInfo.iSurfaceId,0,offsetToFirstBuffer);
       
  1500 	if(err!=KErrNone)
       
  1501 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1502 	err = aSurfaceInfo.iSurfaceManager.GetBufferOffset(aSurfaceInfo.iSurfaceId,1,offsetToSecondBuffer);
       
  1503 	if(err!=KErrNone)
       
  1504 		EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE );
       
  1505     EGL_TRACE("EGL::EglInternalFunction_CallSetSurfaceParams offsetToFirstBuffer=0x%x offsetToSecondBuffer=0x%x",
       
  1506     		offsetToFirstBuffer,offsetToSecondBuffer);
       
  1507 
       
  1508    
       
  1509     /* Store the pointer to the pixel data */
       
  1510     aSurfaceInfo.iBuffer0 = aSurfaceInfo.iChunk.Base() + offsetToFirstBuffer;
       
  1511     aSurfaceInfo.iBuffer1 = aSurfaceInfo.iChunk.Base() + offsetToSecondBuffer;
       
  1512     
       
  1513     aSurfaceInfo.iFrontBuffer = 0; // start rendering buffer 0 as a front buffer
       
  1514     
       
  1515     //TODO: what else? 
       
  1516     EGL_RETURN(EGL_SUCCESS,EGL_TRUE);
       
  1517 }
       
  1518 
       
  1519 // -----------------------------------------------------------------------------
       
  1520 //
       
  1521 // -----------------------------------------------------------------------------
       
  1522 //
       
  1523 TSurfaceInfo* EGL::EglInternalFunction_GetPlatformSurface( EGLDisplay display, EGLSurface surface )
       
  1524 {
       
  1525 	EGL_TRACE( "EGL::EglInternalFunction_GetPlatformSurface");
       
  1526 	TSurfaceInfo* result = NULL;
       
  1527 
       
  1528 	iDisplayMapLock.ReadLock();
       
  1529 
       
  1530 	CEglDisplayInfo** pDispInfo = iDisplayMap.Find( display );
       
  1531 	if (pDispInfo && *pDispInfo)
       
  1532 		{
       
  1533 		TSurfaceInfo** pSurfaceInfo = (*pDispInfo)->iSurfaceMap.Find( surface );
       
  1534 		if (pSurfaceInfo)
       
  1535 			{
       
  1536 			result = *pSurfaceInfo;
       
  1537 			}
       
  1538 		}
       
  1539 
       
  1540 	// TODO on success should probably Unlock() the surface in the caller
       
  1541 	iDisplayMapLock.Unlock();
       
  1542 
       
  1543 	/* TODO review calling code, to see if this suggestion makes sense
       
  1544 	if (result == NULL)
       
  1545 		{
       
  1546 		EGL_RAISE_ERROR( EGL_BAD_SURFACE, NULL); //Enable this when all surfaces are in surface map
       
  1547 		}
       
  1548 		*/
       
  1549 	return result;
       
  1550 }
       
  1551 
       
  1552 EGLBoolean EGL::EglInternalFunction_SurfaceResized(/*TEglThreadState&,*/ TSurfaceInfo&, int, int) 
       
  1553 	{
       
  1554 	return EFalse; // stub code
       
  1555 	}
  1497 
  1556 
  1498 /*-------------------------------------------------------------------*//*!
  1557 /*-------------------------------------------------------------------*//*!
  1499 * \brief	
  1558 * \brief	
  1500 * \param	
  1559 * \param	
  1501 * \return	
  1560 * \return	
  1892 #else
  1951 #else
  1893 EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
  1952 EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
  1894 #endif
  1953 #endif
  1895 {
  1954 {
  1896 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
  1955 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
       
  1956 	// From guestEGL - eglMakeCurrent
       
  1957 	if (ctx == EGL_NO_CONTEXT)
       
  1958 	{
       
  1959 		// what now??
       
  1960 		EGL_TRACE("eglMakeCurrent context NO_CONTEXT");
       
  1961 		if ( (draw != EGL_NO_SURFACE) || (read != EGL_NO_SURFACE) )
       
  1962 		{
       
  1963 			EGL_RETURN(EGL_BAD_SURFACE, EGL_FALSE);
       
  1964 		}	
       
  1965 	}
       
  1966 	else
       
  1967 	{
       
  1968 		if ( (draw == EGL_NO_SURFACE) || (read == EGL_NO_SURFACE) )
       
  1969 		{
       
  1970 			EGL_RETURN(EGL_BAD_SURFACE, EGL_FALSE);
       
  1971 		
       
  1972 		}
       
  1973 		// ToDo use new CEglContext code
       
  1974 		const TInt KMaxSurfaces( 2 );
       
  1975 		EGLSurface surfaces[KMaxSurfaces];
       
  1976 		TSurfaceInfo* surfaceInfo[KMaxSurfaces] = {NULL, NULL};
       
  1977 		surfaces[0] = draw;
       
  1978 		if (draw != read)
       
  1979 		{
       
  1980 			surfaces[1] = read;
       
  1981 		}
       
  1982 		else
       
  1983 		{
       
  1984 			surfaces[1] = EGL_NO_SURFACE;
       
  1985 		}
       
  1986 
       
  1987 		for ( TInt i = 0; i < KMaxSurfaces; i++ )
       
  1988 		{
       
  1989 			if ( EGL_NO_SURFACE != surfaces[i] )
       
  1990 			{
       
  1991 				EGL_TRACE("eglMakeCurrent check surface %d", surfaces[i] );
       
  1992 				surfaceInfo[i] = getEGL()->EglInternalFunction_GetPlatformSurface( dpy, surfaces[i] );
       
  1993 				EGL_TRACE("eglMakeCurrent surfaces[%d] is %x", i, surfaces[i]);
       
  1994 				//EGL_CHECK_ERROR( surfaceInfo, EGL_BAD_SURFACE , EGL_FALSE );
       
  1995 				if ( surfaceInfo[i] )
       
  1996 				{
       
  1997 					TSize newSize;
       
  1998 					switch (surfaceInfo[i]->iSurfaceType)
       
  1999 					{
       
  2000 						case ESurfaceTypePixmapFbsBitmap:
       
  2001 							EGLPANIC_ASSERT_DEBUG(surfaceInfo[i]->iFbsBitmap, EEglPanicTemp);
       
  2002 							newSize = surfaceInfo[i]->iFbsBitmap->SizeInPixels();
       
  2003 							break;
       
  2004 						case ESurfaceTypeWindow:
       
  2005 							EGLPANIC_ASSERT_DEBUG(surfaceInfo[i]->iNativeWindow, EEglPanicTemp);
       
  2006 							newSize = surfaceInfo[i]->iNativeWindow.SizeInPixels();
       
  2007 							break;
       
  2008 						default:
       
  2009 							// size cannot change for other surface types
       
  2010 							newSize = surfaceInfo[i]->iSize;
       
  2011 							break;
       
  2012 					}
       
  2013 					if (newSize != surfaceInfo[i]->iSize)
       
  2014 					{
       
  2015 						EGL_TRACE("eglMakeCurrent resize surface");
       
  2016 						if ( !getEGL()->EglInternalFunction_SurfaceResized(/*aThreadState,*/ *surfaceInfo[i], dpy, surfaces[i] ) )
       
  2017 						{
       
  2018 							return EGL_FALSE;
       
  2019 						}
       
  2020 						surfaceInfo[i]->iSize = newSize;
       
  2021 					}
       
  2022 				}
       
  2023 			}
       
  2024 		}
       
  2025 
       
  2026 		// adapt to only some surfaces having CEglSurfaceInfo objects so far 
       
  2027 		EGLSurface drawId = surfaceInfo[0] ? surfaceInfo[0]->iSurface : draw;
       
  2028 		EGLSurface readId = read;
       
  2029 		if ((read == draw) && surfaceInfo[0])
       
  2030 		{
       
  2031 			readId = surfaceInfo[0]->iSurface;
       
  2032 		}
       
  2033 		else if (surfaceInfo[1])
       
  2034 		{
       
  2035 			readId = surfaceInfo[1]->iSurface;
       
  2036 		}
       
  2037 
       
  2038 		EGL_TRACE("  eglMakeCurrent surfaces[0]=0x%x, surfaces[1]=0x%x", surfaces[0], surfaces[1]);
       
  2039 		EGL_TRACE("  eglMakeCurrent surfacesInfo[0]=0x%x, surfacesInfo[0].iSurface=0x%x",
       
  2040 					surfaceInfo[0], surfaceInfo[0] ? surfaceInfo[0]->iSurface : NULL);
       
  2041 		EGL_TRACE("  eglMakeCurrent surfacesInfo[1]=0x%x, surfacesInfo[1].iSurface=0x%x",
       
  2042 					surfaceInfo[1], surfaceInfo[1] ? surfaceInfo[1]->iSurface : NULL);
       
  2043 
       
  2044 		EGL_TRACE("CGuestEGL::eglMakeCurrent call host");
       
  2045 		// now we need to use readId and drawId
       
  2046 		draw = drawId;
       
  2047 		read = readId;
       
  2048 	}
       
  2049 	// end from guestEGL
       
  2050 	/* following is original EGL... very much different to hostEGL!
       
  2051 	 * is that an issue?
       
  2052 	 * Works only with one buffer... draw only used from now on?
       
  2053 	 */
  1897 	EGL_IF_ERROR(ctx != EGL_NO_CONTEXT && !display->contextExists(ctx), EGL_BAD_CONTEXT, EGL_FALSE);
  2054 	EGL_IF_ERROR(ctx != EGL_NO_CONTEXT && !display->contextExists(ctx), EGL_BAD_CONTEXT, EGL_FALSE);
  1898 	EGL_IF_ERROR(draw != EGL_NO_SURFACE && !display->surfaceExists(draw), EGL_BAD_SURFACE, EGL_FALSE);
  2055 	EGL_IF_ERROR(draw != EGL_NO_SURFACE && !display->surfaceExists(draw), EGL_BAD_SURFACE, EGL_FALSE);
  1899 	EGL_IF_ERROR(read != EGL_NO_SURFACE && !display->surfaceExists(read), EGL_BAD_SURFACE, EGL_FALSE);
  2056 	EGL_IF_ERROR(read != EGL_NO_SURFACE && !display->surfaceExists(read), EGL_BAD_SURFACE, EGL_FALSE);
  1900 	EGL_IF_ERROR(draw != read, EGL_BAD_MATCH, EGL_FALSE);	//TODO what's the proper error code?
  2057 	EGL_IF_ERROR(draw != read, EGL_BAD_MATCH, EGL_FALSE);	//TODO what's the proper error code?
  1901 	EGL_IF_ERROR((draw != EGL_NO_SURFACE && ctx == EGL_NO_CONTEXT) || (draw == EGL_NO_SURFACE && ctx != EGL_NO_CONTEXT), EGL_BAD_MATCH, EGL_FALSE);
  2058 	EGL_IF_ERROR((draw != EGL_NO_SURFACE && ctx == EGL_NO_CONTEXT) || (draw == EGL_NO_SURFACE && ctx != EGL_NO_CONTEXT), EGL_BAD_MATCH, EGL_FALSE);
  1974 		}
  2131 		}
  1975 
  2132 
  1976 		c->addReference();
  2133 		c->addReference();
  1977 		s->addReference();
  2134 		s->addReference();
  1978 	}
  2135 	}
       
  2136 	
  1979 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
  2137 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
  1980 }
  2138 }
  1981 
  2139 
  1982 /*-------------------------------------------------------------------*//*!
  2140 /*-------------------------------------------------------------------*//*!
  1983 * \brief	
  2141 * \brief	
  2180 * \brief	
  2338 * \brief	
  2181 * \param	
  2339 * \param	
  2182 * \return	
  2340 * \return	
  2183 * \note		
  2341 * \note		
  2184 *//*-------------------------------------------------------------------*/
  2342 *//*-------------------------------------------------------------------*/
  2185 
  2343 /*
       
  2344  * guestEGL swap buffers
       
  2345  * 
       
  2346 
       
  2347 	 * PSEUDO CODE
       
  2348 	 * serialization.eglSwapBuffers
       
  2349 	 * (maybe finish currently bound api)
       
  2350 	 * surfaceupdatesession.notifywhenavailable
       
  2351 	 *   .whendisplayed()  (alternative choice from above)
       
  2352 	 * surfaceupdatesession.submitupdated()
       
  2353 	 * user:waitforrequestl
       
  2354  */
  2186 #ifdef BUILD_WITH_PRIVATE_EGL
  2355 #ifdef BUILD_WITH_PRIVATE_EGL
  2187 RI_APIENTRY EGLBoolean do_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
  2356 RI_APIENTRY EGLBoolean do_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
  2188 #else
  2357 #else
  2189 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
  2358 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
  2190 #endif
  2359 #endif
  2191 {
  2360 {
  2192 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
  2361 	EGL_GET_DISPLAY(dpy, EGL_FALSE);
  2193 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
  2362 	EGL_IF_ERROR(!display, EGL_NOT_INITIALIZED, EGL_FALSE);
  2194 	EGL_IF_ERROR(!display->surfaceExists(surface), EGL_BAD_SURFACE, EGL_FALSE);
  2363 	EGL_IF_ERROR(!display->surfaceExists(surface), EGL_BAD_SURFACE, EGL_FALSE);
  2195 
  2364 
       
  2365 	
       
  2366 	TSurfaceInfo* surfaceInfo = egl->EglInternalFunction_GetPlatformSurface( dpy, surface );
       
  2367 	EGL_IF_ERROR(!surfaceInfo, EGL_BAD_SURFACE, EGL_FALSE);
       
  2368 	
  2196 	RIEGLSurface* s = (RIEGLSurface*)surface;
  2369 	RIEGLSurface* s = (RIEGLSurface*)surface;
  2197 
  2370 
  2198 	RIEGLThread* currentThread = egl->getCurrentThread();
  2371 	RIEGLThread* currentThread = egl->getCurrentThread();
  2199 	EGL_IF_ERROR(!currentThread || currentThread->getCurrentSurface() != s, EGL_BAD_SURFACE, EGL_FALSE);
  2372 	EGL_IF_ERROR(!currentThread || currentThread->getCurrentSurface() != s, EGL_BAD_SURFACE, EGL_FALSE);
  2200 	EGL_IF_ERROR(!OSIsWindow(s->getOSWindowContext()), EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
  2373 	EGL_IF_ERROR(!OSIsWindow(s->getOSWindowContext()), EGL_BAD_NATIVE_WINDOW, EGL_FALSE);
  2202 #ifdef BUILD_WITH_PRIVATE_OPENVG
  2375 #ifdef BUILD_WITH_PRIVATE_OPENVG
  2203 	/*do_vg*/vgFlush();
  2376 	/*do_vg*/vgFlush();
  2204 #else
  2377 #else
  2205 	vgFlush();
  2378 	vgFlush();
  2206 #endif
  2379 #endif
  2207 
  2380 	
       
  2381 	EGLint currentApi = currentThread->getBoundAPI();
       
  2382 	RIEGLContext* context = currentThread->getCurrentContext();
       
  2383 	switch( currentApi )
       
  2384 	{
       
  2385 		case EGL_OPENVG_API:
       
  2386 	    {
       
  2387 			//if( thread->CurrentVGContext() != surface->BoundContext() )
       
  2388 			if( currentThread->getCurrentContext()->getVGContext() != s->getOSWindowContext() ) // getOSWindowContext??
       
  2389 			{
       
  2390 				//EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
  2391 				EGL_TRACE("eglSwapBuffers EGL_BAD_SURFACE for EGL_OPENVG_API ");
       
  2392 				//EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE); // commnted out as the check against OSWindowContext seems wrong
       
  2393 			}
       
  2394 			break;
       
  2395 	    }
       
  2396 	    case EGL_OPENGL_ES_API:
       
  2397 	    {
       
  2398 			/*
       
  2399 	        if( thread->CurrentGLESContext() != surface->BoundContext() )
       
  2400 	        {
       
  2401 				 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
  2402 	        }
       
  2403 	        */
       
  2404 	        EGL_RETURN(EGL_BAD_SURFACE,EGL_FALSE);
       
  2405 	        // \todo other GLES stuff?
       
  2406 	     }
       
  2407 	}
       
  2408 	
       
  2409 	
       
  2410 	
       
  2411 	/*
       
  2412 	 * ToDo
       
  2413 	 * from hostegl
       
  2414 	 if( !(CEGLOs::IsValidNativeWindow(((CEGLWindowSurface*)surface)->NativeType())) )
       
  2415 	 */
  2208 	if(!s->getOSWindowContext())
  2416 	if(!s->getOSWindowContext())
  2209 	{	//do nothing for other than window surfaces (NOTE: single-buffered window surfaces should return immediately as well)
  2417 	{	//do nothing for other than window surfaces (NOTE: single-buffered window surfaces should return immediately as well)
  2210 		EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
  2418 		EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
  2211 	}
  2419 	}
  2212 
  2420 	if( surfaceInfo->iSurfaceType != ESurfaceTypeWindow || s->getRenderBuffer() == EGL_SINGLE_BUFFER )
       
  2421 	{
       
  2422 		EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  2423 	}
       
  2424 	
  2213 	int windowWidth = 0, windowHeight = 0;
  2425 	int windowWidth = 0, windowHeight = 0;
  2214     OSGetWindowSize(s->getOSWindowContext(), windowWidth, windowHeight);
  2426     OSGetWindowSize(s->getOSWindowContext(), windowWidth, windowHeight);
  2215 
  2427     /*
       
  2428     * TODO
       
  2429     * what we need to do for resize to work?
       
  2430     */
  2216 	if(windowWidth != s->getDrawable()->getWidth() || windowHeight != s->getDrawable()->getHeight())
  2431 	if(windowWidth != s->getDrawable()->getWidth() || windowHeight != s->getDrawable()->getHeight())
  2217 	{	//resize the back buffer
  2432 	{	//resize the back buffer
  2218 		RIEGLContext* c = currentThread->getCurrentContext();
  2433 		RIEGLContext* c = currentThread->getCurrentContext();
  2219 		RI_ASSERT(c);
  2434 		RI_ASSERT(c);
       
  2435 		/* from hostEGL
       
  2436 		if( !(surface->Resize(w, h)) )
       
  2437 		{
       
  2438 			EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ALLOC );
       
  2439 		}
       
  2440 		*/
  2220 		try
  2441 		try
  2221 		{
  2442 		{
  2222 			s->getDrawable()->resize(windowWidth, windowHeight);	//throws bad_alloc
  2443 			s->getDrawable()->resize(windowWidth, windowHeight);	//throws bad_alloc
  2223 		}
  2444 		}
  2224 		catch(std::bad_alloc)
  2445 		catch(std::bad_alloc)
  2225 		{
  2446 		{
  2226 			c->getVGContext()->setDefaultDrawable(NULL);
  2447 			c->getVGContext()->setDefaultDrawable(NULL);
  2227 			EGL_RETURN(EGL_BAD_ALLOC, EGL_FALSE);
  2448 			EGL_RETURN(EGL_BAD_ALLOC, EGL_FALSE);
  2228 		}
  2449 		}
  2229 	}
  2450 		if( windowWidth <= 0 || windowHeight <= 0 )
  2230 
  2451 		{
       
  2452 			// invisible window => do nothing
       
  2453 			EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  2454 		}
       
  2455 		/*
       
  2456 		 * what is this for? From hostEgl...
       
  2457 		 
       
  2458 		if( surface->VGClientSurface() && state->VGInterface() )
       
  2459 		{
       
  2460 			if( !(state->VGInterface()->ResizeSurface(thread->CurrentVGContext()->ClientContext(),
       
  2461 					surface->VGClientSurface(), w, h, surface->VGBuffers())) )
       
  2462 		    {
       
  2463 				EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ALLOC );
       
  2464 		    }
       
  2465 		}
       
  2466 		*/
       
  2467 	}
       
  2468 	
       
  2469 	
       
  2470 	//
       
  2471 	
       
  2472 	void* buf = NULL;
       
  2473 	if (surfaceInfo->iFrontBuffer == 0)
       
  2474 	{
       
  2475 		buf = surfaceInfo->iBuffer1;
       
  2476 	}
       
  2477 	else
       
  2478 	{
       
  2479 		buf = surfaceInfo->iBuffer0;
       
  2480 	}
       
  2481 	
       
  2482 	//
       
  2483 	switch( currentApi )
       
  2484 	{
       
  2485 		case EGL_OPENVG_API:
       
  2486 		{
       
  2487 			//VGImageFormat format = VG_sARGB_8888_PRE; // hack!!
       
  2488 			VGImageFormat format = VG_sARGB_8888; // hack!!
       
  2489 			//VGImageFormat format = VG_sRGBA_8888; // hack!!
       
  2490 			//
       
  2491 			vgReadPixels(buf,surfaceInfo->iStride,format,0,0,windowWidth,windowHeight);
       
  2492 		    break;
       
  2493 		}
       
  2494 		case EGL_OPENGL_ES_API:
       
  2495 		{
       
  2496 		/*
       
  2497 			if( surface->BoundContext() && !(state->GLESInterface(surface->BoundContext()->ClientVersion())) )
       
  2498 			{
       
  2499 				// \todo error code?
       
  2500 				EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ACCESS );
       
  2501 			}
       
  2502 			*/
       
  2503 			EGL_RETURN(EGL_BAD_ACCESS, EGL_FALSE);
       
  2504 		}
       
  2505 	}
       
  2506 	//
  2231     OSBlitToWindow(s->getOSWindowContext(), s->getDrawable());
  2507     OSBlitToWindow(s->getOSWindowContext(), s->getDrawable());
  2232 
  2508     getEGL()->EglInternalFunction_SwapBuffers(dpy, surface);
  2233 	EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
  2509     
       
  2510 	
       
  2511     EGL_RETURN(EGL_SUCCESS, EGL_TRUE);
       
  2512 }
       
  2513 
       
  2514 TBool EGL::EglInternalFunction_SwapBuffers(EGLDisplay aDisplay, EGLSurface aSurface)
       
  2515 {
       
  2516 	TSize size = iSurfaceInfo.iNativeWindow.SizeInPixels();
       
  2517 	
       
  2518 	TRequestStatus status;
       
  2519 	TTimeStamp timestampLocalToThread;
       
  2520 	// session needs to be established
       
  2521 	iSurfaceInfo.iSurfaceUpdateSession.NotifyWhenDisplayed(status, timestampLocalToThread);
       
  2522 	// what to do if native window is not RWindow???
       
  2523 	if (iSurfaceInfo.iFrontBuffer == 0)
       
  2524 	{
       
  2525 		iSurfaceInfo.iFrontBuffer = 1;
       
  2526 	}
       
  2527 	else
       
  2528 	{
       
  2529 		iSurfaceInfo.iFrontBuffer = 0;
       
  2530 	}
       
  2531 	iSurfaceInfo.iSurfaceUpdateSession.SubmitUpdate(iSurfaceInfo.iScreenNumber,iSurfaceInfo.iSurfaceId, iSurfaceInfo.iFrontBuffer);
       
  2532 	User::WaitForRequest(status);
       
  2533 	    
       
  2534 	if (size != iSurfaceInfo.iSize)
       
  2535 	{
       
  2536 		EGL_TRACE("EGL::EglInternalFunction_SwapBuffers Surface Resized size=%d,%d, iSurfaceInfo.iSize=%d,%d",
       
  2537 	    			size.iHeight, size.iWidth, iSurfaceInfo.iSize.iHeight, iSurfaceInfo.iSize.iWidth);
       
  2538 	    			
       
  2539 	    return EglInternalFunction_SurfaceResized(/*aThreadState,*/ iSurfaceInfo, aDisplay, aSurface); // TODO handling of resize
       
  2540 	}
       
  2541 	return EGL_TRUE;
  2234 }
  2542 }
  2235 
  2543 
  2236 /*-------------------------------------------------------------------*//*!
  2544 /*-------------------------------------------------------------------*//*!
  2237 * \brief	
  2545 * \brief	
  2238 * \param	
  2546 * \param