hostsupport/hostegl/src/EGLState.cpp
branchbug235_bringup_0
changeset 53 c2ef9095503a
child 56 40cc73c24bf8
equal deleted inserted replaced
52:39e5f73667ba 53:c2ef9095503a
       
     1 /* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2  *
       
     3  * Permission is hereby granted, free of charge, to any person obtaining a
       
     4  * copy of this software and /or associated documentation files
       
     5  * (the "Materials "), to deal in the Materials without restriction,
       
     6  * including without limitation the rights to use, copy, modify, merge,
       
     7  * publish, distribute, sublicense, and/or sell copies of the Materials,
       
     8  * and to permit persons to whom the Materials are furnished to do so,
       
     9  * subject to the following conditions:
       
    10  *
       
    11  * The above copyright notice and this permission notice shall be included
       
    12  * in all copies or substantial portions of the Materials.
       
    13  *
       
    14  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
       
    15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       
    16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
       
    17  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
       
    18  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
       
    19  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
       
    20  * THE USE OR OTHER DEALINGS IN THE MATERIALS.
       
    21  *
       
    22  * Initial Contributors:
       
    23  * Nokia Corporation - initial contribution.
       
    24  *
       
    25  * Contributors:
       
    26  *
       
    27  * Description:
       
    28  *
       
    29  */
       
    30 
       
    31 #include "EGLState.h"
       
    32 #include "EGLDisplay.h"
       
    33 #include "EGLProcess.h"
       
    34 #include "EGLThread.h"
       
    35 #include "EGLContext.h"
       
    36 #include "EGLConfig.h"
       
    37 #include "EGLOs.h"
       
    38 #include "EGLImage.h"
       
    39 #include "EGLPbufferSurface.h"
       
    40 #include "EGLWindowSurface.h"
       
    41 #include <EGL/eglext.h>
       
    42 
       
    43 #include <string.h>
       
    44 
       
    45 CEGLState::CEGLState(void) :
       
    46     m_initialized( false ),
       
    47     m_currentProcess( NULL ),
       
    48     m_VGLib( NULL ),
       
    49     m_VGInterface( NULL ),
       
    50     m_GLES1Lib( NULL ),
       
    51     m_GLES1Interface( NULL ),
       
    52     m_GLES2Lib( NULL ),
       
    53     m_GLES2Interface( NULL ),
       
    54 	m_hostGL( NULL ),
       
    55     m_supportedApis( 0 ),
       
    56 	m_defaultDisplay( NULL ),
       
    57 	m_dummyWindow( NULL )
       
    58     {
       
    59 
       
    60 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
    61     CEGLProcess* p = EGLI_NEW CEGLProcess(0);
       
    62     EGLI_ASSERT( p != NULL );
       
    63     AddObject<CEGLProcess>( m_processes, p );
       
    64     m_currentProcess = p;
       
    65 #endif
       
    66     }
       
    67 
       
    68 CEGLState::~CEGLState(void)
       
    69     {
       
    70     DestroyPointerVector<CEGLProcess>( m_processes );
       
    71     DestroyPointerVector<CEGLDisplay>( m_displays );
       
    72     DestroyPointerVector<CEGLConfig>( m_configs );
       
    73     if( m_VGLib ) EGLI_ASSERT( CEGLOs::FreeClientLibrary(m_VGLib) );
       
    74     if( m_GLES1Lib ) EGLI_ASSERT( CEGLOs::FreeClientLibrary(m_GLES1Lib) );
       
    75     if( m_GLES2Lib ) EGLI_ASSERT( CEGLOs::FreeClientLibrary(m_GLES2Lib) );
       
    76 #if defined(_WIN32)
       
    77 #   if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
    78     if( m_defaultDisplay )
       
    79         {
       
    80         // \todo If at some point EGL_DEFAULT_DISPLAY is created
       
    81         //       with CreateDC() the DC needs to be released by
       
    82         //       calling DeleteDC().
       
    83         //CEGLOs::DestroyDefaultDisplay( m_defaultDisplay );
       
    84         ReleaseDC( m_dummyWindow, m_defaultDisplay );
       
    85         }
       
    86     // \note Dummy window created in CEGLDisplay::Initialize(). See comment
       
    87     //       in CEGLOs::CreateDefaultDisplay().
       
    88     if( m_dummyWindow )
       
    89         {
       
    90         CEGLOs::DestroyNativeWindow( m_dummyWindow );
       
    91         }
       
    92 #   endif
       
    93 #endif
       
    94     }
       
    95 
       
    96 bool CEGLState::Initialize()
       
    97     {
       
    98     if( !m_initialized )
       
    99         {
       
   100         if( !(CreateConfigs()) ) return false;
       
   101         m_initialized = true;
       
   102         m_VGInterface = CEGLOs::LoadVGInterface( m_VGLib );
       
   103         if( m_VGInterface ) 
       
   104             {
       
   105             m_VGInterface->SetEGLInterface( this );
       
   106             m_supportedApis |= EGL_OPENVG_BIT;
       
   107             }
       
   108 
       
   109         m_GLES1Interface = CEGLOs::LoadGLES1Interface( m_GLES1Lib );
       
   110         if( m_GLES1Interface ) 
       
   111             {
       
   112             m_GLES1Interface->SetEGLInterface( this );
       
   113             m_supportedApis |= EGL_OPENGL_ES_BIT;
       
   114             }
       
   115 
       
   116 	    m_GLES2Interface = CEGLOs::LoadGLES2Interface( m_GLES2Lib );
       
   117         if( m_GLES2Interface ) 
       
   118             {
       
   119             m_GLES2Interface->SetEGLInterface( this );
       
   120             m_supportedApis |= EGL_OPENGL_ES2_BIT;
       
   121             }
       
   122 
       
   123         if( m_supportedApis & EGL_OPENGL_ES_BIT || (m_supportedApis & EGL_OPENGL_ES2_BIT) )
       
   124             {
       
   125             m_hostGL = CEGLOs::LoadHostGL();
       
   126             if( !m_hostGL ) m_initialized = false;
       
   127             }
       
   128         if( !m_supportedApis )
       
   129             {
       
   130             m_initialized = false;
       
   131             }
       
   132 
       
   133 		//m_defaultDisplay = CEGLOs::CreateDefaultDisplay();
       
   134         // \note Creating a dummy window to get DC from. See comment
       
   135         //       in CEGLOs::CreateDefaultDisplay().
       
   136 		m_dummyWindow = CEGLOs::CreateNativeWindow(0, 0);
       
   137         if( m_dummyWindow )
       
   138 			{
       
   139 #if defined(_WIN32)
       
   140 			m_defaultDisplay = (EGLINativeDisplayType)GetDC( (HWND)m_dummyWindow );
       
   141 #else // Linux
       
   142 			EGLI_ASSERT( false );
       
   143 #endif
       
   144 			if( !m_defaultDisplay )
       
   145 				{
       
   146 				CEGLOs::DestroyNativeWindow( m_dummyWindow );
       
   147 				m_initialized = false;
       
   148 				}
       
   149 			}
       
   150         }
       
   151     return m_initialized;
       
   152     }
       
   153 
       
   154 CEGLDisplay* CEGLState::AddDisplay( EGLINativeDisplayType nativeType, EGLint processId )
       
   155     {
       
   156 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   157     CEGLDisplay* display = EGLI_NEW CEGLDisplay( nativeType, processId );
       
   158 #else
       
   159     CEGLDisplay* display = EGLI_NEW CEGLDisplay( nativeType, m_currentProcess->Id() );
       
   160 #endif
       
   161     if( display )
       
   162         {
       
   163         AddObject<CEGLDisplay>( m_displays, display );
       
   164         }
       
   165     return display;
       
   166     }
       
   167 
       
   168 void CEGLState::RemoveDisplay( EGLDisplay display )
       
   169     {
       
   170     DeleteObjectByPointer<CEGLDisplay>( m_displays, display );
       
   171     }
       
   172 
       
   173 CEGLDisplay* CEGLState::GetDisplayByNativeType( EGLINativeDisplayType nativeType, EGLint processId ) const
       
   174     {
       
   175     CEGLDisplay* ret = NULL;
       
   176     for( std::vector<CEGLDisplay*>::const_iterator iter = m_displays.begin();
       
   177         iter != m_displays.end();
       
   178         iter++)
       
   179         {
       
   180 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   181         if( (*iter)->NativeType() == nativeType && (*iter)->ProcessId() == processId )
       
   182 #else
       
   183         if( (*iter)->NativeType() == nativeType )
       
   184 #endif
       
   185             {
       
   186             ret = (*iter);
       
   187             break;
       
   188             }
       
   189         }
       
   190     return ret;
       
   191     }
       
   192 
       
   193 CEGLDisplay* CEGLState::GetDisplay( EGLDisplay display ) const
       
   194     {
       
   195     return FindObjectByPointer<CEGLDisplay>( m_displays, display, NULL);
       
   196     }
       
   197 
       
   198 CEGLProcess* CEGLState::AddProcess( EGLint processId, bool setCurrent )
       
   199     {
       
   200 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   201     CEGLProcess* process = EGLI_NEW CEGLProcess( processId );
       
   202     if( process )
       
   203         {
       
   204         AddObject<CEGLProcess>( m_processes, process );
       
   205         if( setCurrent && process )
       
   206             {
       
   207             m_currentProcess = process;
       
   208             }
       
   209         }
       
   210     return process;
       
   211 #else
       
   212     EGLI_ASSERT( false );
       
   213     return NULL;
       
   214 #endif
       
   215     }
       
   216 
       
   217 void CEGLState::RemoveProcess( EGLint processId )
       
   218     {
       
   219 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   220     if( m_currentProcess && m_currentProcess->Id() == processId )
       
   221         {
       
   222         m_currentProcess = NULL;
       
   223         }
       
   224     DeleteObjectById<CEGLProcess>( m_processes, processId );
       
   225 #else
       
   226     EGLI_ASSERT( false );
       
   227 #endif
       
   228     }
       
   229 
       
   230 CEGLProcess* CEGLState::GetProcess( EGLint processId ) const
       
   231     {
       
   232 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   233     return FindObjectById<CEGLProcess>( m_processes, processId, NULL );
       
   234 #else
       
   235     return m_currentProcess;
       
   236 #endif
       
   237     }
       
   238 
       
   239 void CEGLState::SetCurrentProcessThread( EGLint processId, EGLI_THREAD_ID threadId )
       
   240     {
       
   241 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   242     if( m_currentProcess && m_currentProcess->Id() == processId )
       
   243         {
       
   244         m_currentProcess->SetCurrentThread( threadId );
       
   245         }
       
   246     else
       
   247         {
       
   248         CEGLProcess* process = FindObjectById<CEGLProcess>( m_processes, processId, NULL);
       
   249         // processes are created in eglPlatsimSetProcessInformation()
       
   250         EGLI_ASSERT( process != NULL );
       
   251         process->SetCurrentThread( threadId );
       
   252         m_currentProcess = process;
       
   253         }
       
   254 #else
       
   255     EGLI_ASSERT( false );
       
   256 #endif
       
   257     }
       
   258 
       
   259 void CEGLState::FillConfigs( EGLConfig* configs, EGLint size ) const
       
   260     {
       
   261     EGLI_ASSERT( size <= ConfigCount() );
       
   262     for( EGLint i=0; i < size; i++ )
       
   263         {
       
   264         configs[i] = (EGLConfig)m_configs[i];
       
   265         }
       
   266     }
       
   267 
       
   268 CEGLConfig* CEGLState::FindConfigById( EGLint id ) const
       
   269     {
       
   270     return FindObjectById<CEGLConfig>( m_configs, id, NULL );
       
   271     }
       
   272 
       
   273 EGLint CEGLState::MatchConfigs( CEGLConfig* filter, EGLConfig* configs, EGLint maxCount ) const
       
   274     {
       
   275     maxCount = EGLI_MIN( m_configs.size(), (unsigned int)maxCount );
       
   276     EGLint count = 0;
       
   277     std::vector<CEGLConfig*>::const_iterator iter = m_configs.begin();
       
   278     while( iter != m_configs.end() )
       
   279         {
       
   280         if( (*iter)->Match( *filter ) )
       
   281             {
       
   282             if( configs && count < maxCount )
       
   283                 configs[count++] = (EGLConfig)(*iter);
       
   284             else if( configs )
       
   285                 break;
       
   286             else
       
   287                 count++;
       
   288             }
       
   289         iter++;
       
   290         }
       
   291     if( configs && count > 1 )
       
   292         {
       
   293         for( int i=0; i < count-1; i++ )
       
   294             for( int j=i+1; j < count; j++ )
       
   295                 {
       
   296                 if( *((CEGLConfig*)configs[j]) > *((CEGLConfig*)configs[i]) )
       
   297                     {
       
   298                     EGLConfig tmp = configs[i];
       
   299                     configs[i] = configs[j];
       
   300                     configs[j] = tmp;
       
   301                     }
       
   302                 }
       
   303         }
       
   304     return count;
       
   305     }
       
   306 
       
   307 CEGLConfig* CEGLState::GetConfig( EGLConfig config ) const
       
   308     {
       
   309     return FindObjectByPointer<CEGLConfig>( m_configs, config, NULL );
       
   310     }
       
   311 
       
   312 void* CEGLState::GetVGContext()
       
   313     {
       
   314     CEGLOs::GetLock( &g_eglLock );
       
   315     void* ret = NULL;
       
   316     if( m_currentProcess &&
       
   317         m_currentProcess->CurrentThread() &&
       
   318         m_currentProcess->CurrentThread()->CurrentVGContext() )
       
   319         {
       
   320         ret = m_currentProcess->CurrentThread()->CurrentVGContext()->ClientContext();
       
   321         }
       
   322     CEGLOs::ReleaseLock( &g_eglLock );
       
   323     return ret;
       
   324     }
       
   325 
       
   326 void* CEGLState::GetHostProcAddress(const char* proc)
       
   327 	{
       
   328     return CEGLOs::GetGLProcAddress(m_hostGL, proc);
       
   329 	}
       
   330 
       
   331 void* CEGLState::GetGLESContext()
       
   332     {
       
   333     CEGLOs::GetLock( &g_eglLock );
       
   334     void* ret = NULL;
       
   335     if( m_currentProcess &&
       
   336         m_currentProcess->CurrentThread() &&
       
   337         m_currentProcess->CurrentThread()->CurrentGLESContext() )
       
   338         {
       
   339         ret = m_currentProcess->CurrentThread()->CurrentGLESContext()->ClientContext();
       
   340         }
       
   341     CEGLOs::ReleaseLock( &g_eglLock );
       
   342     return ret;
       
   343     }
       
   344 
       
   345 bool CEGLState::IsImageInUse( void* image )
       
   346     {
       
   347     //TODO
       
   348     return false;
       
   349     }
       
   350 
       
   351 bool CEGLState::LockVGSurface( bool read, bool write )
       
   352     {
       
   353     return LockSurface( EGL_OPENVG_API, read, write );
       
   354     }
       
   355 
       
   356 bool CEGLState::UnlockVGSurface()
       
   357     {
       
   358     return UnlockSurface( EGL_OPENVG_API );
       
   359     }
       
   360 
       
   361 void CEGLState::GetDescForImage( void* image, SurfaceDescriptor& ImageDesc )
       
   362     {
       
   363     CEGLImage* eglImage = (CEGLImage*)image;
       
   364     ImageDesc.m_stride = -1;
       
   365     ImageDesc.m_height = -1;
       
   366     ImageDesc.m_width  = -1;
       
   367     // Check that image is not null.
       
   368     if( !eglImage )
       
   369         {        
       
   370         return;
       
   371         }
       
   372 
       
   373     // Check that image is not from VGImage target. -> EGL_VG_PARENT_IMAGE_KHR
       
   374     if( eglImage->Target() == EGL_VG_PARENT_IMAGE_KHR )
       
   375         {
       
   376         return;
       
   377         }
       
   378 
       
   379 	memcpy(&ImageDesc, &eglImage->SurfaceDesc(), sizeof(ImageDesc));
       
   380     }
       
   381 
       
   382 
       
   383 void* CEGLState::GetDataForImage( void* image )
       
   384     {
       
   385     CEGLImage* eglImage = (CEGLImage*)image;
       
   386     // Check that image is not null.
       
   387     if( !eglImage )
       
   388         {
       
   389         // if null then error
       
   390         return NULL;
       
   391         }
       
   392 	return eglImage->Data();
       
   393     }
       
   394 
       
   395 void CEGLState::RegisterImageTarget( void* image, EImageTarget target, void* buffer )
       
   396 	{
       
   397 	// \todo Implement
       
   398 	}
       
   399 
       
   400 void CEGLState::UnregisterImageTarget( void* image, EImageTarget target, void* buffer )
       
   401 	{
       
   402 	// \todo Implement
       
   403 	}
       
   404 
       
   405 void CEGLState::UpdateImageSiblings( void* image, EImageTarget target, void* buffer )
       
   406 	{
       
   407 	// \todo Implement
       
   408 	}
       
   409 
       
   410 void CEGLState::ReleaseTexImage(void* surface, int name, int level)
       
   411 {
       
   412 	CEGLSurface* eglSurface = (CEGLSurface*)surface;
       
   413 	EGLITextureBinding& binding = eglSurface->TextureBinding();
       
   414 	if(binding.name == name && binding.level == level)
       
   415 	{
       
   416 		eglSurface->Unlock();
       
   417 		binding.name = 0;
       
   418 	}
       
   419 }
       
   420 
       
   421 bool CEGLState::LockGLESSurface( bool read, bool write )
       
   422     {
       
   423     return LockSurface( EGL_OPENGL_ES_API, read, write );
       
   424     }
       
   425 bool CEGLState::UnlockGLESSurface()
       
   426     {
       
   427     return UnlockSurface( EGL_OPENGL_ES_API );
       
   428     }
       
   429 
       
   430 bool CEGLState::SyncSurface( EGLenum api, EGLint apiVersion, CEGLSurface* surface, CEGLSurface* currentGLESReadSurface )
       
   431 	{
       
   432 	switch( api )
       
   433 		{
       
   434 		case EGL_OPENVG_API:
       
   435 			{
       
   436 			EGLint glesVersion = 0;
       
   437 			if( surface->IsGLES1Dirty() )
       
   438 				{
       
   439 				glesVersion = 1;
       
   440 				}
       
   441 			else if( surface->IsGLES2Dirty() )
       
   442 				{
       
   443 				glesVersion = 2;
       
   444 				}
       
   445 			if( glesVersion )
       
   446 				{
       
   447 				if( surface != currentGLESReadSurface )
       
   448 					{
       
   449 					EGLINativeContextType glesCopyContext = NULL;
       
   450                     EGLINativeDisplayType glesCopyDisplay = NULL;
       
   451                     EGLINativeGLFunctions* funcs = NULL;
       
   452 					bool pbuffer = ( surface->Type() == CEGLSurface::PBUFFER_SURFACE );
       
   453 					if( pbuffer )
       
   454 						{
       
   455 						if( !(((CEGLPbufferSurface*)surface)->BindCopyContext()) )
       
   456 							{
       
   457 							((CEGLPbufferSurface*)surface)->ReleaseCopyContext();
       
   458 							
       
   459 							return false;
       
   460 							}
       
   461 						}
       
   462 					else if( surface->Type() == CEGLSurface::WINDOW_SURFACE )
       
   463 						{
       
   464 						// \todo Remove this or handle window surface sync properly
       
   465 						/*
       
   466 						funcs = thread->CurrentGLESContext()->NativeGLFunctions();
       
   467 						glesCopyContext = thread->CurrentGLESContext()->NativeContext();
       
   468 						glesCopyDisplay = ((CEGLWindowSurface*)surface)->OsContext()->glesDisplay;
       
   469 						*/
       
   470 						}
       
   471 					if( !(GLESInterface(glesVersion)->CopyBuffers(surface->GLESColorBuffer(), surface->Descriptor())) )
       
   472 						{
       
   473 						if( pbuffer )
       
   474 							{
       
   475 							((CEGLPbufferSurface*)surface)->ReleaseCopyContext();
       
   476 							}
       
   477 						return false;
       
   478 						}
       
   479 					if( pbuffer )
       
   480 						{
       
   481 						((CEGLPbufferSurface*)surface)->ReleaseCopyContext();
       
   482 						}
       
   483 					else if( surface->Type() == CEGLSurface::WINDOW_SURFACE )
       
   484 						{
       
   485 						// \todo Remove this or handle window surface sync properly
       
   486 						//EGLI_ASSERT( false );
       
   487 						}
       
   488 					}
       
   489 				else
       
   490 					{
       
   491 					if( !(GLESInterface(glesVersion)->CopyBuffers(surface->GLESColorBuffer(), surface->Descriptor())) )
       
   492 						return false;
       
   493 					}
       
   494 
       
   495 				if( VGInterface() )
       
   496                     {
       
   497                     VGInterface()->UpdateBuffers(surface->GLESColorBuffer(), surface->Stride(), surface->Descriptor());
       
   498                     }
       
   499                 surface->SetGLES1Dirty( false );
       
   500 				surface->SetGLES2Dirty( false );
       
   501 				}
       
   502 			break;
       
   503 			}
       
   504 
       
   505 		case EGL_OPENGL_ES_API:
       
   506 			{
       
   507 			if( surface->IsVGDirty() )
       
   508                 {
       
   509 				if( !(GLESInterface(apiVersion)->UpdateBuffers(surface->VGColorBuffer(), surface->Descriptor())) )
       
   510                     {
       
   511                     return false;
       
   512                     }
       
   513                 surface->SetVGDirty( false );
       
   514                 }
       
   515 			break;
       
   516 			}
       
   517 		}
       
   518 
       
   519 	return true;
       
   520 	}
       
   521 
       
   522 bool CEGLState::LockSurface( EGLenum api, bool read, bool write )
       
   523     {
       
   524     CEGLOs::GetLock( &g_eglLock );
       
   525     CEGLSurface* readSurface = NULL;
       
   526     CEGLSurface* drawSurface = NULL;
       
   527 	CEGLSurface* glesReadSurface = NULL;
       
   528 	EGLint apiVersion;
       
   529     CEGLThread* thread = m_currentProcess->CurrentThread();
       
   530     if( !thread )
       
   531         {
       
   532         CEGLOs::ReleaseLock( &g_eglLock );
       
   533         return false;
       
   534         }
       
   535     switch( api )
       
   536         {
       
   537         case EGL_OPENVG_API:
       
   538             {
       
   539             drawSurface = thread->CurrentVGSurface();
       
   540             readSurface = drawSurface;
       
   541 			apiVersion = 0;
       
   542             break;
       
   543             }
       
   544         case EGL_OPENGL_ES_API:
       
   545             {
       
   546             thread->CurrentGLESSurfaces( &readSurface, &drawSurface );
       
   547 			apiVersion = thread->CurrentGLESContext()->ClientVersion();
       
   548             break;
       
   549             }
       
   550         }
       
   551     if( !readSurface && !drawSurface )
       
   552         {
       
   553         CEGLOs::ReleaseLock( &g_eglLock );
       
   554         return false;
       
   555         }
       
   556 
       
   557 	if( api == EGL_OPENVG_API )
       
   558 		{
       
   559 		thread->CurrentGLESSurfaces( &readSurface, NULL );
       
   560 		}
       
   561     
       
   562     if( read && readSurface )
       
   563         {
       
   564         readSurface->Lock();
       
   565 		if( !SyncSurface( api, apiVersion, readSurface, glesReadSurface ) )
       
   566 			{
       
   567 			CEGLOs::ReleaseLock( &g_eglLock );
       
   568 			return false;
       
   569 			}
       
   570         }
       
   571     if( write && drawSurface && (!read || drawSurface != readSurface) )
       
   572         {
       
   573         drawSurface->Lock();
       
   574 		if( !SyncSurface( api, apiVersion, drawSurface, glesReadSurface ) )
       
   575 			{
       
   576 			CEGLOs::ReleaseLock( &g_eglLock );
       
   577 			return false;
       
   578 			}
       
   579         }
       
   580     CEGLOs::ReleaseLock( &g_eglLock );
       
   581     return true;
       
   582     }
       
   583 
       
   584 bool CEGLState::UnlockSurface( EGLenum api )
       
   585     {
       
   586     CEGLOs::GetLock( &g_eglLock );
       
   587     CEGLSurface* drawSurface = NULL;
       
   588 	CEGLSurface* readSurface = NULL;
       
   589     CEGLThread* thread = m_currentProcess->CurrentThread();
       
   590     if( !thread )
       
   591         {
       
   592         CEGLOs::ReleaseLock( &g_eglLock );
       
   593         return false;
       
   594         }
       
   595     switch( api )
       
   596         {
       
   597         case EGL_OPENVG_API:
       
   598             {
       
   599             drawSurface = thread->CurrentVGSurface();
       
   600 			readSurface = drawSurface;
       
   601 			if( drawSurface && drawSurface->IsLocked() )
       
   602                 drawSurface->SetVGDirty( true );
       
   603             break;
       
   604             }
       
   605         case EGL_OPENGL_ES_API:
       
   606             {
       
   607             thread->CurrentGLESSurfaces( &readSurface, &drawSurface );
       
   608 			if( drawSurface && drawSurface->IsLocked() )
       
   609 				{
       
   610 				EGLint glesVersion = thread->CurrentGLESContext()->ClientVersion();
       
   611 				if(glesVersion == 1)
       
   612 					{
       
   613 					drawSurface->SetGLES1Dirty( true );
       
   614 					}
       
   615 				else
       
   616 					{
       
   617 					EGLI_ASSERT(glesVersion == 2);
       
   618 					drawSurface->SetGLES2Dirty( true );
       
   619 					}
       
   620 				}
       
   621             break;
       
   622             }
       
   623         }
       
   624     if( drawSurface && drawSurface->IsLocked() )
       
   625         {
       
   626         drawSurface->Unlock();
       
   627         }
       
   628     if( readSurface && readSurface->IsLocked() )
       
   629         {
       
   630         readSurface->Unlock();
       
   631         }
       
   632 
       
   633     CEGLOs::ReleaseLock( &g_eglLock );
       
   634     return true;
       
   635     }
       
   636 
       
   637 bool CEGLState::CreateConfigs()
       
   638     {    
       
   639     // ** Config list START **
       
   640     // Initial config count. If adding configs to the list below
       
   641     // remember to add this count too.
       
   642     int count = 21;
       
   643     for( int i=0; i < count; i++ )
       
   644         {        
       
   645         CEGLConfig* config = EGLI_NEW CEGLConfig();
       
   646         // \note AddObject destroys the object if fails to take ownership 
       
   647         AddObject<CEGLConfig>( m_configs, config );
       
   648         if( !config )
       
   649             {
       
   650             DestroyPointerVector<CEGLConfig>( m_configs );
       
   651             return false;
       
   652             }
       
   653         }
       
   654     int configId = 0;
       
   655     CEGLConfig* config = m_configs[configId];
       
   656     //                                                 r, g, b, l, a, am, s, bpp, id
       
   657     // XRGB_8888 and ARGB_8888
       
   658                                   config->SetUpConfig( 8, 8, 8, 0, 8, 0,  0, 32,  ++configId ); //  1
       
   659     config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 8, 1,  0, 32,  ++configId ); //  2
       
   660     config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 8, 4,  0, 32,  ++configId ); //  3
       
   661     config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 8, 8,  0, 32,  ++configId ); //  4    
       
   662     config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 0, 0,  0, 32,  ++configId ); //  5
       
   663     config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 0, 1,  0, 32,  ++configId ); //  6
       
   664     config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 0, 4,  0, 32,  ++configId ); //  7
       
   665     config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 0, 8,  0, 32,  ++configId ); //  8
       
   666     // RGB_565
       
   667     config = m_configs[configId]; config->SetUpConfig( 5, 6, 5, 0, 0, 0,  0, 16,  ++configId ); //  9
       
   668     config = m_configs[configId]; config->SetUpConfig( 5, 6, 5, 0, 0, 1,  0, 16,  ++configId ); // 10
       
   669     config = m_configs[configId]; config->SetUpConfig( 5, 6, 5, 0, 0, 4,  0, 16,  ++configId ); // 11
       
   670     config = m_configs[configId]; config->SetUpConfig( 5, 6, 5, 0, 0, 8,  0, 16,  ++configId ); // 12
       
   671     // LA_88
       
   672     config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 8, 0,  0, 16,  ++configId ); // 13
       
   673     config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 8, 1,  0, 16,  ++configId ); // 14
       
   674     config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 8, 4,  0, 16,  ++configId ); // 15
       
   675     config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 8, 8,  0, 16,  ++configId ); // 16
       
   676     // L_8
       
   677     config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 0, 0,  0,  8,  ++configId ); // 17
       
   678     config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 0, 1,  0,  8,  ++configId ); // 18
       
   679     config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 0, 4,  0,  8,  ++configId ); // 19
       
   680     config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 0, 8,  0,  8,  ++configId ); // 20
       
   681     // A_8
       
   682     config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 0, 8, 0,  0,  8,  ++configId ); // 21
       
   683     // ** Config list END **
       
   684     
       
   685     std::vector<CEGLConfig*> newConfigs;
       
   686 
       
   687     // stencil buffers
       
   688     std::vector<CEGLConfig*>::const_iterator iter = m_configs.begin();
       
   689     while( iter != m_configs.end() )
       
   690         {
       
   691         config = EGLI_NEW CEGLConfig();
       
   692         if( config )
       
   693             {
       
   694             *config = *(*iter);
       
   695             config->SetId( ++configId );
       
   696             config->SetAttribute( EGL_STENCIL_SIZE, 8 );
       
   697             }
       
   698         // \note AddObject destroys the object if fails to take ownership 
       
   699         AddObject<CEGLConfig>( newConfigs, config );
       
   700         if( !config )
       
   701             {
       
   702             DestroyPointerVector<CEGLConfig>( newConfigs );
       
   703             DestroyPointerVector<CEGLConfig>( m_configs );
       
   704             return false;
       
   705             }
       
   706         iter++;
       
   707         }
       
   708     try
       
   709         {
       
   710         m_configs.insert( m_configs.end(), newConfigs.begin(), newConfigs.end() );
       
   711         }
       
   712     catch( std::exception )
       
   713         {
       
   714         DestroyPointerVector<CEGLConfig>( newConfigs );
       
   715         DestroyPointerVector<CEGLConfig>( m_configs );
       
   716         return false;
       
   717         }
       
   718     newConfigs.clear();
       
   719 
       
   720     // depth buffers
       
   721     // 32bpp, 24bpp and 16bpp support
       
   722     for(int depthSize = 32; depthSize >= 16; depthSize -= 8 )
       
   723         {
       
   724         iter = m_configs.begin();
       
   725         while( iter != m_configs.end() )
       
   726             {
       
   727             config = EGLI_NEW CEGLConfig();
       
   728             if( config )
       
   729                 {
       
   730                 *config = *(*iter);
       
   731                 config->SetId( ++configId );
       
   732                 config->SetAttribute( EGL_DEPTH_SIZE, depthSize );
       
   733                 }            
       
   734             // \note AddObject destroys the object if fails to take ownership    
       
   735             AddObject<CEGLConfig>( newConfigs, config );
       
   736             if( !config )
       
   737                 {
       
   738                 DestroyPointerVector<CEGLConfig>( newConfigs );
       
   739                 DestroyPointerVector<CEGLConfig>( m_configs );
       
   740                 return false;
       
   741                 }
       
   742             iter++;
       
   743             }
       
   744         }
       
   745     try
       
   746         {
       
   747         m_configs.insert( m_configs.end(), newConfigs.begin(), newConfigs.end() );
       
   748         }
       
   749     catch( std::exception )
       
   750         {
       
   751         DestroyPointerVector<CEGLConfig>( newConfigs );
       
   752         DestroyPointerVector<CEGLConfig>( m_configs );
       
   753         return false;
       
   754         }
       
   755     newConfigs.clear();
       
   756 
       
   757     // multi sampling
       
   758     for( int samples = 16; samples >= 4; samples -= 12 )
       
   759         {
       
   760         iter = m_configs.begin();
       
   761         while( iter != m_configs.end() )
       
   762             {
       
   763             config = EGLI_NEW CEGLConfig();
       
   764             if( config )
       
   765                 {
       
   766                 *config = *(*iter);
       
   767                 config->SetId( ++configId );
       
   768                 config->SetAttribute( EGL_SAMPLES, samples );
       
   769                 config->SetAttribute( EGL_SAMPLE_BUFFERS, 1 );
       
   770                 }
       
   771             // \note AddObject destroys the object if fails to take ownership
       
   772             AddObject<CEGLConfig>( newConfigs, config );
       
   773             if( !config )
       
   774                 {
       
   775                 DestroyPointerVector<CEGLConfig>( newConfigs );
       
   776                 DestroyPointerVector<CEGLConfig>( m_configs );
       
   777                 return false;
       
   778                 }
       
   779             iter++;
       
   780             }
       
   781         }
       
   782     try
       
   783         {
       
   784         m_configs.insert( m_configs.end(), newConfigs.begin(), newConfigs.end() );
       
   785         }
       
   786     catch( std::exception )
       
   787         {
       
   788         DestroyPointerVector<CEGLConfig>( newConfigs );
       
   789         DestroyPointerVector<CEGLConfig>( m_configs );
       
   790         return false;
       
   791         }
       
   792     newConfigs.clear();  
       
   793     return true;
       
   794     }
       
   795 
       
   796 IEGLtoGLESInterface* CEGLState::GLESInterface( EGLint clientVersion ) const
       
   797 	{
       
   798 	EGLI_ASSERT(clientVersion == 1 || clientVersion == 2);
       
   799 	return clientVersion == 1 ? m_GLES1Interface : m_GLES2Interface;
       
   800 	}