holdingarea/libEGL/src/EGLState.cpp
branchbug235_bringup_0
changeset 20 d2d6724aef32
child 24 a3f46bb01be2
--- /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;
+	}