--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/holdingarea/libEGL/src/EGLState.cpp Thu Sep 16 09:43:14 2010 +0100
@@ -0,0 +1,800 @@
+/* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and /or associated documentation files
+ * (the "Materials "), to deal in the Materials without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Materials,
+ * and to permit persons to whom the Materials are furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
+ * THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:
+ *
+ */
+
+#include "EGLState.h"
+#include "EGLDisplay.h"
+#include "EGLProcess.h"
+#include "EGLThread.h"
+#include "EGLContext.h"
+#include "EGLConfig.h"
+#include "EGLOs.h"
+#include "EGLImage.h"
+#include "EGLPbufferSurface.h"
+#include "EGLWindowSurface.h"
+#include <EGL/eglext.h>
+
+#include <string.h>
+
+CEGLState::CEGLState(void) :
+ m_initialized( false ),
+ m_currentProcess( NULL ),
+ m_VGLib( NULL ),
+ m_VGInterface( NULL ),
+ m_GLES1Lib( NULL ),
+ m_GLES1Interface( NULL ),
+ m_GLES2Lib( NULL ),
+ m_GLES2Interface( NULL ),
+ m_hostGL( NULL ),
+ m_supportedApis( 0 ),
+ m_defaultDisplay( NULL ),
+ m_dummyWindow( NULL )
+ {
+
+#if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
+ CEGLProcess* p = EGLI_NEW CEGLProcess(0);
+ EGLI_ASSERT( p != NULL );
+ AddObject<CEGLProcess>( m_processes, p );
+ m_currentProcess = p;
+#endif
+ }
+
+CEGLState::~CEGLState(void)
+ {
+ DestroyPointerVector<CEGLProcess>( m_processes );
+ DestroyPointerVector<CEGLDisplay>( m_displays );
+ DestroyPointerVector<CEGLConfig>( m_configs );
+ if( m_VGLib ) EGLI_ASSERT( CEGLOs::FreeClientLibrary(m_VGLib) );
+ if( m_GLES1Lib ) EGLI_ASSERT( CEGLOs::FreeClientLibrary(m_GLES1Lib) );
+ if( m_GLES2Lib ) EGLI_ASSERT( CEGLOs::FreeClientLibrary(m_GLES2Lib) );
+#if defined(_WIN32)
+# if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
+ if( m_defaultDisplay )
+ {
+ // \todo If at some point EGL_DEFAULT_DISPLAY is created
+ // with CreateDC() the DC needs to be released by
+ // calling DeleteDC().
+ //CEGLOs::DestroyDefaultDisplay( m_defaultDisplay );
+ ReleaseDC( m_dummyWindow, m_defaultDisplay );
+ }
+ // \note Dummy window created in CEGLDisplay::Initialize(). See comment
+ // in CEGLOs::CreateDefaultDisplay().
+ if( m_dummyWindow )
+ {
+ CEGLOs::DestroyNativeWindow( m_dummyWindow );
+ }
+# endif
+#endif
+ }
+
+bool CEGLState::Initialize()
+ {
+ if( !m_initialized )
+ {
+ if( !(CreateConfigs()) ) return false;
+ m_initialized = true;
+ m_VGInterface = CEGLOs::LoadVGInterface( m_VGLib );
+ if( m_VGInterface )
+ {
+ m_VGInterface->SetEGLInterface( this );
+ m_supportedApis |= EGL_OPENVG_BIT;
+ }
+
+ m_GLES1Interface = CEGLOs::LoadGLES1Interface( m_GLES1Lib );
+ if( m_GLES1Interface )
+ {
+ m_GLES1Interface->SetEGLInterface( this );
+ m_supportedApis |= EGL_OPENGL_ES_BIT;
+ }
+
+ m_GLES2Interface = CEGLOs::LoadGLES2Interface( m_GLES2Lib );
+ if( m_GLES2Interface )
+ {
+ m_GLES2Interface->SetEGLInterface( this );
+ m_supportedApis |= EGL_OPENGL_ES2_BIT;
+ }
+
+ if( m_supportedApis & EGL_OPENGL_ES_BIT || (m_supportedApis & EGL_OPENGL_ES2_BIT) )
+ {
+ m_hostGL = CEGLOs::LoadHostGL();
+ if( !m_hostGL ) m_initialized = false;
+ }
+ if( !m_supportedApis )
+ {
+ m_initialized = false;
+ }
+
+ //m_defaultDisplay = CEGLOs::CreateDefaultDisplay();
+ // \note Creating a dummy window to get DC from. See comment
+ // in CEGLOs::CreateDefaultDisplay().
+ m_dummyWindow = CEGLOs::CreateNativeWindow(0, 0);
+ if( m_dummyWindow )
+ {
+#if defined(_WIN32)
+ m_defaultDisplay = (EGLINativeDisplayType)GetDC( (HWND)m_dummyWindow );
+#else // Linux
+ EGLI_ASSERT( false );
+#endif
+ if( !m_defaultDisplay )
+ {
+ CEGLOs::DestroyNativeWindow( m_dummyWindow );
+ m_initialized = false;
+ }
+ }
+ }
+ return m_initialized;
+ }
+
+CEGLDisplay* CEGLState::AddDisplay( EGLINativeDisplayType nativeType, EGLint processId )
+ {
+#if defined(EGLI_USE_PLATSIM_EXTENSIONS)
+ CEGLDisplay* display = EGLI_NEW CEGLDisplay( nativeType, processId );
+#else
+ CEGLDisplay* display = EGLI_NEW CEGLDisplay( nativeType, m_currentProcess->Id() );
+#endif
+ if( display )
+ {
+ AddObject<CEGLDisplay>( m_displays, display );
+ }
+ return display;
+ }
+
+void CEGLState::RemoveDisplay( EGLDisplay display )
+ {
+ DeleteObjectByPointer<CEGLDisplay>( m_displays, display );
+ }
+
+CEGLDisplay* CEGLState::GetDisplayByNativeType( EGLINativeDisplayType nativeType, EGLint processId ) const
+ {
+ CEGLDisplay* ret = NULL;
+ for( std::vector<CEGLDisplay*>::const_iterator iter = m_displays.begin();
+ iter != m_displays.end();
+ iter++)
+ {
+#if defined(EGLI_USE_PLATSIM_EXTENSIONS)
+ if( (*iter)->NativeType() == nativeType && (*iter)->ProcessId() == processId )
+#else
+ if( (*iter)->NativeType() == nativeType )
+#endif
+ {
+ ret = (*iter);
+ break;
+ }
+ }
+ return ret;
+ }
+
+CEGLDisplay* CEGLState::GetDisplay( EGLDisplay display ) const
+ {
+ return FindObjectByPointer<CEGLDisplay>( m_displays, display, NULL);
+ }
+
+CEGLProcess* CEGLState::AddProcess( EGLint processId, bool setCurrent )
+ {
+#if defined(EGLI_USE_PLATSIM_EXTENSIONS)
+ CEGLProcess* process = EGLI_NEW CEGLProcess( processId );
+ if( process )
+ {
+ AddObject<CEGLProcess>( m_processes, process );
+ if( setCurrent && process )
+ {
+ m_currentProcess = process;
+ }
+ }
+ return process;
+#else
+ EGLI_ASSERT( false );
+ return NULL;
+#endif
+ }
+
+void CEGLState::RemoveProcess( EGLint processId )
+ {
+#if defined(EGLI_USE_PLATSIM_EXTENSIONS)
+ if( m_currentProcess && m_currentProcess->Id() == processId )
+ {
+ m_currentProcess = NULL;
+ }
+ DeleteObjectById<CEGLProcess>( m_processes, processId );
+#else
+ EGLI_ASSERT( false );
+#endif
+ }
+
+CEGLProcess* CEGLState::GetProcess( EGLint processId ) const
+ {
+#if defined(EGLI_USE_PLATSIM_EXTENSIONS)
+ return FindObjectById<CEGLProcess>( m_processes, processId, NULL );
+#else
+ return m_currentProcess;
+#endif
+ }
+
+void CEGLState::SetCurrentProcessThread( EGLint processId, EGLI_THREAD_ID threadId )
+ {
+#if defined(EGLI_USE_PLATSIM_EXTENSIONS)
+ if( m_currentProcess && m_currentProcess->Id() == processId )
+ {
+ m_currentProcess->SetCurrentThread( threadId );
+ }
+ else
+ {
+ CEGLProcess* process = FindObjectById<CEGLProcess>( m_processes, processId, NULL);
+ // processes are created in eglPlatsimSetProcessInformation()
+ EGLI_ASSERT( process != NULL );
+ process->SetCurrentThread( threadId );
+ m_currentProcess = process;
+ }
+#else
+ EGLI_ASSERT( false );
+#endif
+ }
+
+void CEGLState::FillConfigs( EGLConfig* configs, EGLint size ) const
+ {
+ EGLI_ASSERT( size <= ConfigCount() );
+ for( EGLint i=0; i < size; i++ )
+ {
+ configs[i] = (EGLConfig)m_configs[i];
+ }
+ }
+
+CEGLConfig* CEGLState::FindConfigById( EGLint id ) const
+ {
+ return FindObjectById<CEGLConfig>( m_configs, id, NULL );
+ }
+
+EGLint CEGLState::MatchConfigs( CEGLConfig* filter, EGLConfig* configs, EGLint maxCount ) const
+ {
+ maxCount = EGLI_MIN( m_configs.size(), (unsigned int)maxCount );
+ EGLint count = 0;
+ std::vector<CEGLConfig*>::const_iterator iter = m_configs.begin();
+ while( iter != m_configs.end() )
+ {
+ if( (*iter)->Match( *filter ) )
+ {
+ if( configs && count < maxCount )
+ configs[count++] = (EGLConfig)(*iter);
+ else if( configs )
+ break;
+ else
+ count++;
+ }
+ iter++;
+ }
+ if( configs && count > 1 )
+ {
+ for( int i=0; i < count-1; i++ )
+ for( int j=i+1; j < count; j++ )
+ {
+ if( *((CEGLConfig*)configs[j]) > *((CEGLConfig*)configs[i]) )
+ {
+ EGLConfig tmp = configs[i];
+ configs[i] = configs[j];
+ configs[j] = tmp;
+ }
+ }
+ }
+ return count;
+ }
+
+CEGLConfig* CEGLState::GetConfig( EGLConfig config ) const
+ {
+ return FindObjectByPointer<CEGLConfig>( m_configs, config, NULL );
+ }
+
+void* CEGLState::GetVGContext()
+ {
+ CEGLOs::GetLock( &g_eglLock );
+ void* ret = NULL;
+ if( m_currentProcess &&
+ m_currentProcess->CurrentThread() &&
+ m_currentProcess->CurrentThread()->CurrentVGContext() )
+ {
+ ret = m_currentProcess->CurrentThread()->CurrentVGContext()->ClientContext();
+ }
+ CEGLOs::ReleaseLock( &g_eglLock );
+ return ret;
+ }
+
+void* CEGLState::GetHostProcAddress(const char* proc)
+ {
+ return CEGLOs::GetGLProcAddress(m_hostGL, proc);
+ }
+
+void* CEGLState::GetGLESContext()
+ {
+ CEGLOs::GetLock( &g_eglLock );
+ void* ret = NULL;
+ if( m_currentProcess &&
+ m_currentProcess->CurrentThread() &&
+ m_currentProcess->CurrentThread()->CurrentGLESContext() )
+ {
+ ret = m_currentProcess->CurrentThread()->CurrentGLESContext()->ClientContext();
+ }
+ CEGLOs::ReleaseLock( &g_eglLock );
+ return ret;
+ }
+
+bool CEGLState::IsImageInUse( void* image )
+ {
+ //TODO
+ return false;
+ }
+
+bool CEGLState::LockVGSurface( bool read, bool write )
+ {
+ return LockSurface( EGL_OPENVG_API, read, write );
+ }
+
+bool CEGLState::UnlockVGSurface()
+ {
+ return UnlockSurface( EGL_OPENVG_API );
+ }
+
+void CEGLState::GetDescForImage( void* image, SurfaceDescriptor& ImageDesc )
+ {
+ CEGLImage* eglImage = (CEGLImage*)image;
+ ImageDesc.m_stride = -1;
+ ImageDesc.m_height = -1;
+ ImageDesc.m_width = -1;
+ // Check that image is not null.
+ if( !eglImage )
+ {
+ return;
+ }
+
+ // Check that image is not from VGImage target. -> EGL_VG_PARENT_IMAGE_KHR
+ if( eglImage->Target() == EGL_VG_PARENT_IMAGE_KHR )
+ {
+ return;
+ }
+
+ memcpy(&ImageDesc, &eglImage->SurfaceDesc(), sizeof(ImageDesc));
+ }
+
+
+void* CEGLState::GetDataForImage( void* image )
+ {
+ CEGLImage* eglImage = (CEGLImage*)image;
+ // Check that image is not null.
+ if( !eglImage )
+ {
+ // if null then error
+ return NULL;
+ }
+ return eglImage->Data();
+ }
+
+void CEGLState::RegisterImageTarget( void* image, EImageTarget target, void* buffer )
+ {
+ // \todo Implement
+ }
+
+void CEGLState::UnregisterImageTarget( void* image, EImageTarget target, void* buffer )
+ {
+ // \todo Implement
+ }
+
+void CEGLState::UpdateImageSiblings( void* image, EImageTarget target, void* buffer )
+ {
+ // \todo Implement
+ }
+
+void CEGLState::ReleaseTexImage(void* surface, int name, int level)
+{
+ CEGLSurface* eglSurface = (CEGLSurface*)surface;
+ EGLITextureBinding& binding = eglSurface->TextureBinding();
+ if(binding.name == name && binding.level == level)
+ {
+ eglSurface->Unlock();
+ binding.name = 0;
+ }
+}
+
+bool CEGLState::LockGLESSurface( bool read, bool write )
+ {
+ return LockSurface( EGL_OPENGL_ES_API, read, write );
+ }
+bool CEGLState::UnlockGLESSurface()
+ {
+ return UnlockSurface( EGL_OPENGL_ES_API );
+ }
+
+bool CEGLState::SyncSurface( EGLenum api, EGLint apiVersion, CEGLSurface* surface, CEGLSurface* currentGLESReadSurface )
+ {
+ switch( api )
+ {
+ case EGL_OPENVG_API:
+ {
+ EGLint glesVersion = 0;
+ if( surface->IsGLES1Dirty() )
+ {
+ glesVersion = 1;
+ }
+ else if( surface->IsGLES2Dirty() )
+ {
+ glesVersion = 2;
+ }
+ if( glesVersion )
+ {
+ if( surface != currentGLESReadSurface )
+ {
+ EGLINativeContextType glesCopyContext = NULL;
+ EGLINativeDisplayType glesCopyDisplay = NULL;
+ EGLINativeGLFunctions* funcs = NULL;
+ bool pbuffer = ( surface->Type() == CEGLSurface::PBUFFER_SURFACE );
+ if( pbuffer )
+ {
+ if( !(((CEGLPbufferSurface*)surface)->BindCopyContext()) )
+ {
+ ((CEGLPbufferSurface*)surface)->ReleaseCopyContext();
+
+ return false;
+ }
+ }
+ else if( surface->Type() == CEGLSurface::WINDOW_SURFACE )
+ {
+ // \todo Remove this or handle window surface sync properly
+ /*
+ funcs = thread->CurrentGLESContext()->NativeGLFunctions();
+ glesCopyContext = thread->CurrentGLESContext()->NativeContext();
+ glesCopyDisplay = ((CEGLWindowSurface*)surface)->OsContext()->glesDisplay;
+ */
+ }
+ if( !(GLESInterface(glesVersion)->CopyBuffers(surface->GLESColorBuffer(), surface->Descriptor())) )
+ {
+ if( pbuffer )
+ {
+ ((CEGLPbufferSurface*)surface)->ReleaseCopyContext();
+ }
+ return false;
+ }
+ if( pbuffer )
+ {
+ ((CEGLPbufferSurface*)surface)->ReleaseCopyContext();
+ }
+ else if( surface->Type() == CEGLSurface::WINDOW_SURFACE )
+ {
+ // \todo Remove this or handle window surface sync properly
+ //EGLI_ASSERT( false );
+ }
+ }
+ else
+ {
+ if( !(GLESInterface(glesVersion)->CopyBuffers(surface->GLESColorBuffer(), surface->Descriptor())) )
+ return false;
+ }
+
+ if( VGInterface() )
+ {
+ VGInterface()->UpdateBuffers(surface->GLESColorBuffer(), surface->Stride(), surface->Descriptor());
+ }
+ surface->SetGLES1Dirty( false );
+ surface->SetGLES2Dirty( false );
+ }
+ break;
+ }
+
+ case EGL_OPENGL_ES_API:
+ {
+ if( surface->IsVGDirty() )
+ {
+ if( !(GLESInterface(apiVersion)->UpdateBuffers(surface->VGColorBuffer(), surface->Descriptor())) )
+ {
+ return false;
+ }
+ surface->SetVGDirty( false );
+ }
+ break;
+ }
+ }
+
+ return true;
+ }
+
+bool CEGLState::LockSurface( EGLenum api, bool read, bool write )
+ {
+ CEGLOs::GetLock( &g_eglLock );
+ CEGLSurface* readSurface = NULL;
+ CEGLSurface* drawSurface = NULL;
+ CEGLSurface* glesReadSurface = NULL;
+ EGLint apiVersion;
+ CEGLThread* thread = m_currentProcess->CurrentThread();
+ if( !thread )
+ {
+ CEGLOs::ReleaseLock( &g_eglLock );
+ return false;
+ }
+ switch( api )
+ {
+ case EGL_OPENVG_API:
+ {
+ drawSurface = thread->CurrentVGSurface();
+ readSurface = drawSurface;
+ apiVersion = 0;
+ break;
+ }
+ case EGL_OPENGL_ES_API:
+ {
+ thread->CurrentGLESSurfaces( &readSurface, &drawSurface );
+ apiVersion = thread->CurrentGLESContext()->ClientVersion();
+ break;
+ }
+ }
+ if( !readSurface && !drawSurface )
+ {
+ CEGLOs::ReleaseLock( &g_eglLock );
+ return false;
+ }
+
+ if( api == EGL_OPENVG_API )
+ {
+ thread->CurrentGLESSurfaces( &readSurface, NULL );
+ }
+
+ if( read && readSurface )
+ {
+ readSurface->Lock();
+ if( !SyncSurface( api, apiVersion, readSurface, glesReadSurface ) )
+ {
+ CEGLOs::ReleaseLock( &g_eglLock );
+ return false;
+ }
+ }
+ if( write && drawSurface && (!read || drawSurface != readSurface) )
+ {
+ drawSurface->Lock();
+ if( !SyncSurface( api, apiVersion, drawSurface, glesReadSurface ) )
+ {
+ CEGLOs::ReleaseLock( &g_eglLock );
+ return false;
+ }
+ }
+ CEGLOs::ReleaseLock( &g_eglLock );
+ return true;
+ }
+
+bool CEGLState::UnlockSurface( EGLenum api )
+ {
+ CEGLOs::GetLock( &g_eglLock );
+ CEGLSurface* drawSurface = NULL;
+ CEGLSurface* readSurface = NULL;
+ CEGLThread* thread = m_currentProcess->CurrentThread();
+ if( !thread )
+ {
+ CEGLOs::ReleaseLock( &g_eglLock );
+ return false;
+ }
+ switch( api )
+ {
+ case EGL_OPENVG_API:
+ {
+ drawSurface = thread->CurrentVGSurface();
+ readSurface = drawSurface;
+ if( drawSurface && drawSurface->IsLocked() )
+ drawSurface->SetVGDirty( true );
+ break;
+ }
+ case EGL_OPENGL_ES_API:
+ {
+ thread->CurrentGLESSurfaces( &readSurface, &drawSurface );
+ if( drawSurface && drawSurface->IsLocked() )
+ {
+ EGLint glesVersion = thread->CurrentGLESContext()->ClientVersion();
+ if(glesVersion == 1)
+ {
+ drawSurface->SetGLES1Dirty( true );
+ }
+ else
+ {
+ EGLI_ASSERT(glesVersion == 2);
+ drawSurface->SetGLES2Dirty( true );
+ }
+ }
+ break;
+ }
+ }
+ if( drawSurface && drawSurface->IsLocked() )
+ {
+ drawSurface->Unlock();
+ }
+ if( readSurface && readSurface->IsLocked() )
+ {
+ readSurface->Unlock();
+ }
+
+ CEGLOs::ReleaseLock( &g_eglLock );
+ return true;
+ }
+
+bool CEGLState::CreateConfigs()
+ {
+ // ** Config list START **
+ // Initial config count. If adding configs to the list below
+ // remember to add this count too.
+ int count = 21;
+ for( int i=0; i < count; i++ )
+ {
+ CEGLConfig* config = EGLI_NEW CEGLConfig();
+ // \note AddObject destroys the object if fails to take ownership
+ AddObject<CEGLConfig>( m_configs, config );
+ if( !config )
+ {
+ DestroyPointerVector<CEGLConfig>( m_configs );
+ return false;
+ }
+ }
+ int configId = 0;
+ CEGLConfig* config = m_configs[configId];
+ // r, g, b, l, a, am, s, bpp, id
+ // XRGB_8888 and ARGB_8888
+ config->SetUpConfig( 8, 8, 8, 0, 8, 0, 0, 32, ++configId ); // 1
+ config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 8, 1, 0, 32, ++configId ); // 2
+ config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 8, 4, 0, 32, ++configId ); // 3
+ config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 8, 8, 0, 32, ++configId ); // 4
+ config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 0, 0, 0, 32, ++configId ); // 5
+ config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 0, 1, 0, 32, ++configId ); // 6
+ config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 0, 4, 0, 32, ++configId ); // 7
+ config = m_configs[configId]; config->SetUpConfig( 8, 8, 8, 0, 0, 8, 0, 32, ++configId ); // 8
+ // RGB_565
+ config = m_configs[configId]; config->SetUpConfig( 5, 6, 5, 0, 0, 0, 0, 16, ++configId ); // 9
+ config = m_configs[configId]; config->SetUpConfig( 5, 6, 5, 0, 0, 1, 0, 16, ++configId ); // 10
+ config = m_configs[configId]; config->SetUpConfig( 5, 6, 5, 0, 0, 4, 0, 16, ++configId ); // 11
+ config = m_configs[configId]; config->SetUpConfig( 5, 6, 5, 0, 0, 8, 0, 16, ++configId ); // 12
+ // LA_88
+ config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 8, 0, 0, 16, ++configId ); // 13
+ config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 8, 1, 0, 16, ++configId ); // 14
+ config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 8, 4, 0, 16, ++configId ); // 15
+ config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 8, 8, 0, 16, ++configId ); // 16
+ // L_8
+ config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 0, 0, 0, 8, ++configId ); // 17
+ config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 0, 1, 0, 8, ++configId ); // 18
+ config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 0, 4, 0, 8, ++configId ); // 19
+ config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 8, 0, 8, 0, 8, ++configId ); // 20
+ // A_8
+ config = m_configs[configId]; config->SetUpConfig( 0, 0, 0, 0, 8, 0, 0, 8, ++configId ); // 21
+ // ** Config list END **
+
+ std::vector<CEGLConfig*> newConfigs;
+
+ // stencil buffers
+ std::vector<CEGLConfig*>::const_iterator iter = m_configs.begin();
+ while( iter != m_configs.end() )
+ {
+ config = EGLI_NEW CEGLConfig();
+ if( config )
+ {
+ *config = *(*iter);
+ config->SetId( ++configId );
+ config->SetAttribute( EGL_STENCIL_SIZE, 8 );
+ }
+ // \note AddObject destroys the object if fails to take ownership
+ AddObject<CEGLConfig>( newConfigs, config );
+ if( !config )
+ {
+ DestroyPointerVector<CEGLConfig>( newConfigs );
+ DestroyPointerVector<CEGLConfig>( m_configs );
+ return false;
+ }
+ iter++;
+ }
+ try
+ {
+ m_configs.insert( m_configs.end(), newConfigs.begin(), newConfigs.end() );
+ }
+ catch( std::exception )
+ {
+ DestroyPointerVector<CEGLConfig>( newConfigs );
+ DestroyPointerVector<CEGLConfig>( m_configs );
+ return false;
+ }
+ newConfigs.clear();
+
+ // depth buffers
+ // 32bpp, 24bpp and 16bpp support
+ for(int depthSize = 32; depthSize >= 16; depthSize -= 8 )
+ {
+ iter = m_configs.begin();
+ while( iter != m_configs.end() )
+ {
+ config = EGLI_NEW CEGLConfig();
+ if( config )
+ {
+ *config = *(*iter);
+ config->SetId( ++configId );
+ config->SetAttribute( EGL_DEPTH_SIZE, depthSize );
+ }
+ // \note AddObject destroys the object if fails to take ownership
+ AddObject<CEGLConfig>( newConfigs, config );
+ if( !config )
+ {
+ DestroyPointerVector<CEGLConfig>( newConfigs );
+ DestroyPointerVector<CEGLConfig>( m_configs );
+ return false;
+ }
+ iter++;
+ }
+ }
+ try
+ {
+ m_configs.insert( m_configs.end(), newConfigs.begin(), newConfigs.end() );
+ }
+ catch( std::exception )
+ {
+ DestroyPointerVector<CEGLConfig>( newConfigs );
+ DestroyPointerVector<CEGLConfig>( m_configs );
+ return false;
+ }
+ newConfigs.clear();
+
+ // multi sampling
+ for( int samples = 16; samples >= 4; samples -= 12 )
+ {
+ iter = m_configs.begin();
+ while( iter != m_configs.end() )
+ {
+ config = EGLI_NEW CEGLConfig();
+ if( config )
+ {
+ *config = *(*iter);
+ config->SetId( ++configId );
+ config->SetAttribute( EGL_SAMPLES, samples );
+ config->SetAttribute( EGL_SAMPLE_BUFFERS, 1 );
+ }
+ // \note AddObject destroys the object if fails to take ownership
+ AddObject<CEGLConfig>( newConfigs, config );
+ if( !config )
+ {
+ DestroyPointerVector<CEGLConfig>( newConfigs );
+ DestroyPointerVector<CEGLConfig>( m_configs );
+ return false;
+ }
+ iter++;
+ }
+ }
+ try
+ {
+ m_configs.insert( m_configs.end(), newConfigs.begin(), newConfigs.end() );
+ }
+ catch( std::exception )
+ {
+ DestroyPointerVector<CEGLConfig>( newConfigs );
+ DestroyPointerVector<CEGLConfig>( m_configs );
+ return false;
+ }
+ newConfigs.clear();
+ return true;
+ }
+
+IEGLtoGLESInterface* CEGLState::GLESInterface( EGLint clientVersion ) const
+ {
+ EGLI_ASSERT(clientVersion == 1 || clientVersion == 2);
+ return clientVersion == 1 ? m_GLES1Interface : m_GLES2Interface;
+ }