Access library dependencies through a single object.

Bug 18752589

Change-Id: I93155cead50b30faa876023f9ed00f60b7c9e34e
Reviewed-on: https://swiftshader-review.googlesource.com/2831
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Greg Hartman <ghartman@google.com>
Tested-by: Greg Hartman <ghartman@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
Tested-by: Nicolas Capens <capn@google.com>
diff --git a/src/Common/SharedLibrary.hpp b/src/Common/SharedLibrary.hpp
index adaa7fc..bcddce7 100644
--- a/src/Common/SharedLibrary.hpp
+++ b/src/Common/SharedLibrary.hpp
@@ -9,6 +9,9 @@
 // or implied, including but not limited to any patent rights, are granted to you.

 //

 

+#ifndef SharedLibrary_hpp

+#define SharedLibrary_hpp

+

 #if defined(_WIN32)

 	#include <Windows.h>

 #else

@@ -102,3 +105,5 @@
 		return library ? dlsym(library, name) : 0;

 	}

 #endif

+

+#endif   // SharedLibrary_hpp

diff --git a/src/Main/FrameBufferAndroid.cpp b/src/Main/FrameBufferAndroid.cpp
index 56aa94c..daa178a 100644
--- a/src/Main/FrameBufferAndroid.cpp
+++ b/src/Main/FrameBufferAndroid.cpp
@@ -96,10 +96,7 @@
     }
 }
 
-extern "C"
+sw::FrameBuffer *createFrameBuffer(void *display, ANativeWindow* window, int width, int height)
 {
-    sw::FrameBuffer *createFrameBuffer(void *display, void* window, int width, int height)
-    {
-        return new sw::FrameBufferAndroid((ANativeWindow*)window, width, height);
-    }
+    return new sw::FrameBufferAndroid(window, width, height);
 }
diff --git a/src/Main/FrameBufferWin.cpp b/src/Main/FrameBufferWin.cpp
index 928aa55..8765171 100644
--- a/src/Main/FrameBufferWin.cpp
+++ b/src/Main/FrameBufferWin.cpp
@@ -52,27 +52,24 @@
 #include "FrameBufferGDI.hpp"

 #include "Common/Configurator.hpp"

 

-extern "C"

+sw::FrameBufferWin *createFrameBufferWin(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin)

 {

-	sw::FrameBufferWin *createFrameBufferWin(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin)

+	sw::Configurator ini("SwiftShader.ini");

+	int api = ini.getInteger("Testing", "FrameBufferAPI", 0);

+

+	if(api == 0 && topLeftOrigin)

 	{

-		sw::Configurator ini("SwiftShader.ini");

-		int api = ini.getInteger("Testing", "FrameBufferAPI", 0);

-

-		if(api == 0 && topLeftOrigin)

-		{

-			return new sw::FrameBufferDD(windowHandle, width, height, fullscreen, topLeftOrigin);

-		}

-		else

-		{

-			return new sw::FrameBufferGDI(windowHandle, width, height, fullscreen, topLeftOrigin);

-		}

-

-		return 0;

+		return new sw::FrameBufferDD(windowHandle, width, height, fullscreen, topLeftOrigin);

+	}

+	else

+	{

+		return new sw::FrameBufferGDI(windowHandle, width, height, fullscreen, topLeftOrigin);

 	}

 

-	sw::FrameBuffer *createFrameBuffer(HDC display, HWND window, int width, int height)

-	{

-		return createFrameBufferWin(window, width, height, false, false);

-	}

+	return 0;

+}

+

+sw::FrameBuffer *createFrameBuffer(HDC display, HWND window, int width, int height)

+{

+	return createFrameBufferWin(window, width, height, false, false);

 }

diff --git a/src/Main/FrameBufferWin.hpp b/src/Main/FrameBufferWin.hpp
index dfbe302..c887c67 100644
--- a/src/Main/FrameBufferWin.hpp
+++ b/src/Main/FrameBufferWin.hpp
@@ -54,9 +54,4 @@
 	};

 }

 

-extern "C"

-{

-	sw::FrameBufferWin *createFrameBufferWin(HWND windowHandle, int width, int height, bool fullscreen, bool topLeftOrigin);

-}

-

 #endif	 //	sw_FrameBufferWin_hpp

diff --git a/src/Main/FrameBufferX11.cpp b/src/Main/FrameBufferX11.cpp
index f0d3c50..c43a930 100644
--- a/src/Main/FrameBufferX11.cpp
+++ b/src/Main/FrameBufferX11.cpp
@@ -144,10 +144,7 @@
 	}

 }

 

-extern "C"

+sw::FrameBuffer *createFrameBuffer(Display *display, Window window, int width, int height)

 {

-	sw::FrameBuffer *createFrameBuffer(void *display, Window window, int width, int height)

-	{

-		return new sw::FrameBufferX11((Display*)display, window, width, height);

-	}

+	return new sw::FrameBufferX11(display, window, width, height);

 }

diff --git a/src/OpenGL/libEGL/Context.hpp b/src/OpenGL/libEGL/Context.hpp
index b48789f..bde79b5 100644
--- a/src/OpenGL/libEGL/Context.hpp
+++ b/src/OpenGL/libEGL/Context.hpp
@@ -20,7 +20,7 @@
 	virtual void bindTexImage(Surface *surface) = 0;

 	virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;

 	virtual Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) = 0;

-	virtual int getClientVersion() = 0;

+	virtual int getClientVersion() const = 0;

 

 protected:

 	virtual ~Context() {};

diff --git a/src/OpenGL/libEGL/Display.cpp b/src/OpenGL/libEGL/Display.cpp
index 8d99bc7..28042f9 100644
--- a/src/OpenGL/libEGL/Display.cpp
+++ b/src/OpenGL/libEGL/Display.cpp
@@ -420,17 +420,17 @@
 
 	if(clientVersion == 1 && config->mRenderableType & EGL_OPENGL_ES_BIT)
 	{
-		if(es1::createContext != 0)
+		if(libGLES_CM)
 		{
-			context = es1::createContext(config, shareContext);
+			context = libGLES_CM->es1CreateContext(config, shareContext);
 		}
 	}
 	else if((clientVersion == 2 && config->mRenderableType & EGL_OPENGL_ES2_BIT) ||
 	        (clientVersion == 3 && config->mRenderableType & EGL_OPENGL_ES3_BIT))
 	{
-		if(es2::createContext != 0)
+		if(libGLESv2)
 		{
-			context = es2::createContext(config, shareContext, clientVersion);
+			context = libGLESv2->es2CreateContext(config, shareContext, clientVersion);
 		}
 	}
 	else
diff --git a/src/OpenGL/libEGL/Surface.cpp b/src/OpenGL/libEGL/Surface.cpp
index 1a36a93..17e8586 100644
--- a/src/OpenGL/libEGL/Surface.cpp
+++ b/src/OpenGL/libEGL/Surface.cpp
@@ -137,8 +137,15 @@
     deleteResources();

 

     if(mWindow)

-    {

-		frameBuffer = es::createFrameBuffer(mDisplay->getNativeDisplay(), mWindow, backBufferWidth, backBufferHeight);

+    {
+		if(libGLES_CM)
+		{

+			frameBuffer = libGLES_CM->createFrameBuffer(mDisplay->getNativeDisplay(), mWindow, backBufferWidth, backBufferHeight);
+		}
+		else if(libGLESv2)
+		{

+			frameBuffer = libGLESv2->createFrameBuffer(mDisplay->getNativeDisplay(), mWindow, backBufferWidth, backBufferHeight);
+		}

 

 		if(!frameBuffer)

 		{

@@ -147,8 +154,15 @@
 			return error(EGL_BAD_ALLOC, false);

 		}

     }

-

-	backBuffer = es::createBackBuffer(backBufferWidth, backBufferHeight, mConfig);

+
+	if(libGLES_CM)
+	{

+		backBuffer = libGLES_CM->createBackBuffer(backBufferWidth, backBufferHeight, mConfig);
+	}
+	else if(libGLESv2)
+	{
+		backBuffer = libGLESv2->createBackBuffer(backBufferWidth, backBufferHeight, mConfig);
+	}

 

     if(!backBuffer)

     {

@@ -158,8 +172,16 @@
     }

 

     if(mConfig->mDepthStencilFormat != sw::FORMAT_NULL)

-    {

-        mDepthStencil = es::createDepthStencil(backBufferWidth, backBufferHeight, mConfig->mDepthStencilFormat, 1, false);

+    {
+
+		if(libGLES_CM)
+		{

+			mDepthStencil = libGLES_CM->createDepthStencil(backBufferWidth, backBufferHeight, mConfig->mDepthStencilFormat, 1, false);
+		}
+		else if(libGLESv2)
+		{
+			mDepthStencil = libGLESv2->createDepthStencil(backBufferWidth, backBufferHeight, mConfig->mDepthStencilFormat, 1, false);
+		}

 

 		if(!mDepthStencil)

 		{

diff --git a/src/OpenGL/libEGL/exports.map b/src/OpenGL/libEGL/exports.map
index 6a455e7..6ab0b00 100644
--- a/src/OpenGL/libEGL/exports.map
+++ b/src/OpenGL/libEGL/exports.map
@@ -42,9 +42,7 @@
     eglCreatePlatformWindowSurfaceEXT;

     eglCreatePlatformPixmapSurfaceEXT;

 

-	# Functions that don't change the error code, for use by client APIs

-	clientGetCurrentContext;

-	clientGetCurrentDisplay;

+	libEGLexports;

 

 local:

     *;

diff --git a/src/OpenGL/libEGL/libEGL.cbp b/src/OpenGL/libEGL/libEGL.cbp
index ee5fa97..2582c34 100644
--- a/src/OpenGL/libEGL/libEGL.cbp
+++ b/src/OpenGL/libEGL/libEGL.cbp
@@ -126,6 +126,7 @@
 		<Unit filename="Surface.h" />
 		<Unit filename="exports.map" />
 		<Unit filename="libEGL.cpp" />
+		<Unit filename="libEGL.hpp" />
 		<Unit filename="main.cpp" />
 		<Unit filename="main.h" />
 		<Extensions>
diff --git a/src/OpenGL/libEGL/libEGL.cpp b/src/OpenGL/libEGL/libEGL.cpp
index 1e2a70c..0dd14b7 100644
--- a/src/OpenGL/libEGL/libEGL.cpp
+++ b/src/OpenGL/libEGL/libEGL.cpp
@@ -26,6 +26,8 @@
 

 #include <string.h>

 

+using namespace egl;

+

 static bool validateDisplay(egl::Display *display)

 {

 	if(display == EGL_NO_DISPLAY)

@@ -630,13 +632,19 @@
 	}

 

 	egl::Display *display = static_cast<egl::Display*>(dpy);

+	egl::Context *shareContext = static_cast<egl::Context*>(share_context);

 

 	if(!validateConfig(display, config))

 	{

 		return EGL_NO_CONTEXT;

 	}

 

-	return display->createContext(config, static_cast<egl::Context*>(share_context), clientVersion);

+	if(shareContext && shareContext->getClientVersion() != clientVersion)

+	{

+		return error(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);

+	}

+

+	return display->createContext(config, shareContext, clientVersion);

 }

 

 EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)

@@ -977,15 +985,15 @@
 		}

 	}

 

-	if(es2::getProcAddress != 0)

+	if(libGLESv2)

 	{

-		__eglMustCastToProperFunctionPointerType proc = es2::getProcAddress(procname);

+		__eglMustCastToProperFunctionPointerType proc = libGLESv2->es2GetProcAddress(procname);

 		if(proc) return proc;

 	}

 

-	if(es1::getProcAddress != 0)

+	if(libGLES_CM)

 	{

-		__eglMustCastToProperFunctionPointerType proc =  es1::getProcAddress(procname);

+		__eglMustCastToProperFunctionPointerType proc =  libGLES_CM->es1GetProcAddress(procname);

 		if(proc) return proc;

 	}

 

diff --git a/src/OpenGL/libEGL/libEGL.def b/src/OpenGL/libEGL/libEGL.def
index e9293a9..df088dd 100644
--- a/src/OpenGL/libEGL/libEGL.def
+++ b/src/OpenGL/libEGL/libEGL.def
@@ -42,6 +42,4 @@
     eglCreatePlatformWindowSurfaceEXT

     eglCreatePlatformPixmapSurfaceEXT

 

-	; Functions that don't change the error code, for use by client APIs

-	clientGetCurrentContext

-	clientGetCurrentDisplay
\ No newline at end of file
+	libEGLexports
\ No newline at end of file
diff --git a/src/OpenGL/libEGL/libEGL.hpp b/src/OpenGL/libEGL/libEGL.hpp
new file mode 100644
index 0000000..2fd614d
--- /dev/null
+++ b/src/OpenGL/libEGL/libEGL.hpp
@@ -0,0 +1,108 @@
+#ifndef libEGL_hpp
+#define libEGL_hpp
+
+#define EGLAPI
+#include <EGL/egl.h>
+#define EGL_EGLEXT_PROTOTYPES
+#include <EGL/eglext.h>
+
+#include "Common/SharedLibrary.hpp"
+
+class LibEGLexports
+{
+public:
+	LibEGLexports();
+
+	EGLint (EGLAPIENTRY *eglGetError)(void);
+	EGLDisplay (EGLAPIENTRY *eglGetDisplay)(EGLNativeDisplayType display_id);
+	EGLBoolean (EGLAPIENTRY *eglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
+	EGLBoolean (EGLAPIENTRY *eglTerminate)(EGLDisplay dpy);
+	const char *(EGLAPIENTRY *eglQueryString)(EGLDisplay dpy, EGLint name);
+	EGLBoolean (EGLAPIENTRY *eglGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+	EGLBoolean (EGLAPIENTRY *eglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+	EGLBoolean (EGLAPIENTRY *eglGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+	EGLSurface (EGLAPIENTRY *eglCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list);
+	EGLSurface (EGLAPIENTRY *eglCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+	EGLSurface (EGLAPIENTRY *eglCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+	EGLBoolean (EGLAPIENTRY *eglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
+	EGLBoolean (EGLAPIENTRY *eglQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+	EGLBoolean (EGLAPIENTRY *eglBindAPI)(EGLenum api);
+	EGLenum (EGLAPIENTRY *eglQueryAPI)(void);
+	EGLBoolean (EGLAPIENTRY *eglWaitClient)(void);
+	EGLBoolean (EGLAPIENTRY *eglReleaseThread)(void);
+	EGLSurface (EGLAPIENTRY *eglCreatePbufferFromClientBuffer)(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+	EGLBoolean (EGLAPIENTRY *eglSurfaceAttrib)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+	EGLBoolean (EGLAPIENTRY *eglBindTexImage)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+	EGLBoolean (EGLAPIENTRY *eglReleaseTexImage)(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+	EGLBoolean (EGLAPIENTRY *eglSwapInterval)(EGLDisplay dpy, EGLint interval);
+	EGLContext (EGLAPIENTRY *eglCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+	EGLBoolean (EGLAPIENTRY *eglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
+	EGLBoolean (EGLAPIENTRY *eglMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+	EGLContext (EGLAPIENTRY *eglGetCurrentContext)(void);
+	EGLSurface (EGLAPIENTRY *eglGetCurrentSurface)(EGLint readdraw);
+	EGLDisplay (EGLAPIENTRY *eglGetCurrentDisplay)(void);
+	EGLBoolean (EGLAPIENTRY *eglQueryContext)(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+	EGLBoolean (EGLAPIENTRY *eglWaitGL)(void);
+	EGLBoolean (EGLAPIENTRY *eglWaitNative)(EGLint engine);
+	EGLBoolean (EGLAPIENTRY *eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
+	EGLBoolean (EGLAPIENTRY *eglCopyBuffers)(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
+	EGLImageKHR (EGLAPIENTRY *eglCreateImageKHR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+	EGLBoolean (EGLAPIENTRY *eglDestroyImageKHR)(EGLDisplay dpy, EGLImageKHR image);
+	__eglMustCastToProperFunctionPointerType (EGLAPIENTRY *eglGetProcAddress)(const char*);
+
+	// Functions that don't change the error code, for use by client APIs
+	egl::Context *(*clientGetCurrentContext)();
+	egl::Display *(*clientGetCurrentDisplay)();
+};
+
+class LibEGL
+{
+public:
+	LibEGL()
+	{
+		libEGL = nullptr;
+		libEGLexports = nullptr;
+	}
+
+	~LibEGL()
+	{
+		freeLibrary(libEGL);
+	}
+
+	LibEGLexports *operator->()
+	{
+		return loadExports();
+	}
+
+private:
+	LibEGLexports *loadExports()
+	{
+		if(!libEGL)
+		{
+			#if defined(_WIN32)
+			const char *libEGL_lib[] = {"libEGL.dll", "libEGL_translator.dll"};
+			#elif defined(__ANDROID__)
+			const char *libEGL_lib[] = {"/vendor/lib/egl/libEGL_swiftshader.so"};
+			#elif defined(__LP64__)
+			const char *libEGL_lib[] = {"lib64EGL_translator.so", "libEGL.so.1", "libEGL.so"};
+			#else
+			const char *libEGL_lib[] = {"libEGL_translator.so", "libEGL.so.1", "libEGL.so"};
+			#endif
+
+			libEGL = loadLibrary(libEGL_lib);
+
+			if(libEGL)
+			{
+				auto libEGLexportsProc = (LibEGLexports *(*)())getProcAddress(libEGL, "libEGLexports");
+				libEGLexports = libEGLexportsProc();
+			}
+		}
+
+		return libEGLexports;
+	}
+
+	void *libEGL;
+	LibEGLexports *libEGLexports;
+};
+
+#endif   // libEGL_hpp
diff --git a/src/OpenGL/libEGL/libEGL.vcxproj b/src/OpenGL/libEGL/libEGL.vcxproj
index 3211fe7..da31900 100644
--- a/src/OpenGL/libEGL/libEGL.vcxproj
+++ b/src/OpenGL/libEGL/libEGL.vcxproj
@@ -312,6 +312,7 @@
     <ClInclude Include="Context.hpp" />

     <ClInclude Include="Display.h" />

     <ClInclude Include="Image.hpp" />

+    <ClInclude Include="libEGL.hpp" />

     <ClInclude Include="main.h" />

     <ClInclude Include="resource.h" />

     <ClInclude Include="Surface.h" />

diff --git a/src/OpenGL/libEGL/libEGL.vcxproj.filters b/src/OpenGL/libEGL/libEGL.vcxproj.filters
index 5f18d2d..c41caac 100644
--- a/src/OpenGL/libEGL/libEGL.vcxproj.filters
+++ b/src/OpenGL/libEGL/libEGL.vcxproj.filters
@@ -73,6 +73,9 @@
     <ClInclude Include="..\common\Object.hpp">

       <Filter>Header Files</Filter>

     </ClInclude>

+    <ClInclude Include="libEGL.hpp">

+      <Filter>Header Files</Filter>

+    </ClInclude>

   </ItemGroup>

   <ItemGroup>

     <ResourceCompile Include="libEGL.rc" />

diff --git a/src/OpenGL/libEGL/main.cpp b/src/OpenGL/libEGL/main.cpp
index 4f9c731..04bfdd7 100644
--- a/src/OpenGL/libEGL/main.cpp
+++ b/src/OpenGL/libEGL/main.cpp
@@ -13,6 +13,7 @@
 

 #include "main.h"

 

+#include "libEGL.hpp"

 #include "Context.hpp"

 #include "Surface.h"

 

@@ -21,6 +22,9 @@
 #include "Common/SharedLibrary.hpp"

 #include "common/debug.h"

 

+#define EGL_EGLEXT_PROTOTYPES

+#include <EGL/eglext.h>

+

 static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;

 

 #if !defined(_MSC_VER)

@@ -62,7 +66,7 @@
 	}

 }

 

-CONSTRUCTOR static bool eglAttachProcess()

+CONSTRUCTOR static void eglAttachProcess()

 {

     TRACE("()");

 

@@ -81,51 +85,10 @@
 

     if(currentTLS == TLS_OUT_OF_INDEXES)

     {

-        return false;

+        return;

     }

 

 	eglAttachThread();

-

-	#if defined(_WIN32)

-	const char *libGLES_CM_lib[] = {"libGLES_CM.dll", "libGLES_CM_translator.dll"};

-	#elif defined(__ANDROID__)

-	const char *libGLES_CM_lib[] = {"/vendor/lib/egl/libGLESv1_CM_swiftshader.so"};

-	#elif defined(__LP64__)

-	const char *libGLES_CM_lib[] = {"lib64GLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};

-	#else

-	const char *libGLES_CM_lib[] = {"libGLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};

-	#endif

-

-    libGLES_CM = loadLibrary(libGLES_CM_lib);

-    es1::createContext = (egl::Context *(*)(const egl::Config*, const egl::Context*))getProcAddress(libGLES_CM, "glCreateContext");

-    es1::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLES_CM, "glGetProcAddress");

-

-	#if defined(_WIN32)

-	const char *libGLESv2_lib[] = {"libGLESv2.dll", "libGLES_V2_translator.dll"};

-	#elif defined(__ANDROID__)

-	const char *libGLESv2_lib[] = {"/vendor/lib/egl/libGLESv2_swiftshader.so"};

-	#elif defined(__LP64__)

-	const char *libGLESv2_lib[] = {"lib64GLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};

-	#else

-	const char *libGLESv2_lib[] = {"libGLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};

-	#endif

-

-    libGLESv2 = loadLibrary(libGLESv2_lib);

-    es2::createContext = (egl::Context *(*)(const egl::Config*, const egl::Context*, EGLint))getProcAddress(libGLESv2, "glCreateContext");

-    es2::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLESv2, "glGetProcAddress");

-

-	es::createBackBuffer = (egl::Image *(*)(int, int, const egl::Config*))getProcAddress(libGLES_CM, "createBackBuffer");

-	es::createDepthStencil = (egl::Image *(*)(unsigned int, unsigned int, sw::Format, int, bool))getProcAddress(libGLES_CM, "createDepthStencil");

-    es::createFrameBuffer = (sw::FrameBuffer *(*)(EGLNativeDisplayType, EGLNativeWindowType, int, int))getProcAddress(libGLES_CM, "createFrameBuffer");

-

-	if(!es::createBackBuffer)

-	{

-		es::createBackBuffer = (egl::Image *(*)(int, int, const egl::Config*))getProcAddress(libGLESv2, "createBackBuffer");

-		es::createDepthStencil = (egl::Image *(*)(unsigned int, unsigned int, sw::Format, int, bool))getProcAddress(libGLESv2, "createDepthStencil");

-		es::createFrameBuffer = (sw::FrameBuffer *(*)(EGLNativeDisplayType, EGLNativeWindowType, int, int))getProcAddress(libGLESv2, "createFrameBuffer");

-	}

-

-	return libGLES_CM != 0 || libGLESv2 != 0;

 }

 

 DESTRUCTOR static void eglDetachProcess()

@@ -134,7 +97,6 @@
 

 	eglDetachThread();

 	sw::Thread::freeLocalStorageKey(currentTLS);

-	freeLibrary(libGLESv2);

 }

 

 #if defined(_WIN32)

@@ -183,7 +145,7 @@
 		#ifndef NDEBUG

 			WaitForDebugger(instance);

 		#endif

-        return eglAttachProcess();

+        eglAttachProcess();

         break;

     case DLL_THREAD_ATTACH:

         eglAttachThread();

@@ -329,7 +291,6 @@
 

     return current->readSurface;

 }

-}

 

 void error(EGLint errorCode)

 {

@@ -357,38 +318,56 @@
 		}

 	}

 }

-

-extern "C"

-{

-EGLContext clientGetCurrentContext()

-{

-    return egl::getCurrentContext();

 }

 

-EGLContext clientGetCurrentDisplay()

+LibEGLexports::LibEGLexports()

 {

-    return egl::getCurrentDisplay();

-}

+	this->eglGetError = ::eglGetError;

+	this->eglGetDisplay = ::eglGetDisplay;

+	this->eglInitialize = ::eglInitialize;

+	this->eglTerminate = ::eglTerminate;

+	this->eglQueryString = ::eglQueryString;

+	this->eglGetConfigs = ::eglGetConfigs;

+	this->eglChooseConfig = ::eglChooseConfig;

+	this->eglGetConfigAttrib = ::eglGetConfigAttrib;

+	this->eglCreateWindowSurface = ::eglCreateWindowSurface;

+	this->eglCreatePbufferSurface = ::eglCreatePbufferSurface;

+	this->eglCreatePixmapSurface = ::eglCreatePixmapSurface;

+	this->eglDestroySurface = ::eglDestroySurface;

+	this->eglQuerySurface = ::eglQuerySurface;

+	this->eglBindAPI = ::eglBindAPI;

+	this->eglQueryAPI = ::eglQueryAPI;

+	this->eglWaitClient = ::eglWaitClient;

+	this->eglReleaseThread = ::eglReleaseThread;

+	this->eglCreatePbufferFromClientBuffer = ::eglCreatePbufferFromClientBuffer;

+	this->eglSurfaceAttrib = ::eglSurfaceAttrib;

+	this->eglBindTexImage = ::eglBindTexImage;

+	this->eglReleaseTexImage = ::eglReleaseTexImage;

+	this->eglSwapInterval = ::eglSwapInterval;

+	this->eglCreateContext = ::eglCreateContext;

+	this->eglDestroyContext = ::eglDestroyContext;

+	this->eglMakeCurrent = ::eglMakeCurrent;

+	this->eglGetCurrentContext = ::eglGetCurrentContext;

+	this->eglGetCurrentSurface = ::eglGetCurrentSurface;

+	this->eglGetCurrentDisplay = ::eglGetCurrentDisplay;

+	this->eglQueryContext = ::eglQueryContext;

+	this->eglWaitGL = ::eglWaitGL;

+	this->eglWaitNative = ::eglWaitNative;

+	this->eglSwapBuffers = ::eglSwapBuffers;

+	this->eglCopyBuffers = ::eglCopyBuffers;

+	this->eglCreateImageKHR = ::eglCreateImageKHR;

+	this->eglDestroyImageKHR = ::eglDestroyImageKHR;

+	this->eglGetProcAddress = ::eglGetProcAddress;

+

+	this->clientGetCurrentContext = egl::getCurrentContext;

+	this->clientGetCurrentDisplay = egl::getCurrentDisplay;

 }

 

-namespace es1

+extern "C" LibEGLexports *libEGLexports()

 {

-	egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext) = 0;

-	__eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;

+	static LibEGLexports libEGL;

+	return &libEGL;

 }

 

-namespace es2

-{

-	egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext, EGLint clientVersion) = 0;

-	__eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;

-}

-

-namespace es

-{

-	egl::Image *(*createBackBuffer)(int width, int height, const egl::Config *config) = 0;

-	egl::Image *(*createDepthStencil)(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard) = 0;

-	sw::FrameBuffer *(*createFrameBuffer)(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height) = 0;

-}

-

-void *libGLES_CM = 0;   // Handle to the libGLES_CM module

-void *libGLESv2 = 0;   // Handle to the libGLESv2 module

+LibGLES_CM libGLES_CM;

+LibGLESv2 libGLESv2;

diff --git a/src/OpenGL/libEGL/main.h b/src/OpenGL/libEGL/main.h
index 9758237..0f3211e 100644
--- a/src/OpenGL/libEGL/main.h
+++ b/src/OpenGL/libEGL/main.h
@@ -14,8 +14,12 @@
 #ifndef LIBEGL_MAIN_H_
 #define LIBEGL_MAIN_H_
 
+#include "libGLES_CM/libGLES_CM.hpp"
+#include "libGLESv2/libGLESv2.hpp"
+
 #define EGLAPI
 #include <EGL/egl.h>
+#define EGL_EGLEXT_PROTOTYPES
 #include <EGL/eglext.h>
 
 namespace egl
@@ -51,28 +55,25 @@
 
 	void setCurrentReadSurface(Surface *surface);
 	Surface *getCurrentReadSurface();
-}
 
-void error(EGLint errorCode);
+	void error(EGLint errorCode);
+	
+	template<class T>
+	const T &error(EGLint errorCode, const T &returnValue)
+	{
+		egl::error(errorCode);
 
-template<class T>
-const T &error(EGLint errorCode, const T &returnValue)
-{
-    error(errorCode);
+		return returnValue;
+	}
 
-    return returnValue;
-}
+	template<class T>
+	const T &success(const T &returnValue)
+	{
+		egl::setCurrentError(EGL_SUCCESS);
 
-template<class T>
-const T &success(const T &returnValue)
-{
-    egl::setCurrentError(EGL_SUCCESS);
+		return returnValue;
+	}
 
-    return returnValue;
-}
-
-namespace egl
-{
 	class Config;
 	class Surface;
 	class Display;
@@ -80,34 +81,7 @@
 	class Image;
 }
 
-namespace sw
-{
-	class FrameBuffer;
-	enum Format : unsigned char;
-}
-
-// libGLES_CM dependencies
-namespace es1
-{
-	extern egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext);
-	extern __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname);
-}
-
-// libGLESv2 dependencies
-namespace es2
-{
-	extern egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext, EGLint clientVersion);
-	extern __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname);
-}
-
-namespace es
-{
-	extern egl::Image *(*createBackBuffer)(int width, int height, const egl::Config *config);
-	extern egl::Image *(*createDepthStencil)(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
-	extern sw::FrameBuffer *(*createFrameBuffer)(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height);
-}
-
-extern void *libGLES_CM;   // Handle to the libGLES_CM module
-extern void *libGLESv2;    // Handle to the libGLESv2 module
+extern LibGLES_CM libGLES_CM;
+extern LibGLESv2 libGLESv2;
 
 #endif  // LIBEGL_MAIN_H_
diff --git a/src/OpenGL/libGL/main.h b/src/OpenGL/libGL/main.h
index 63b6fb5..ceb90ee 100644
--- a/src/OpenGL/libGL/main.h
+++ b/src/OpenGL/libGL/main.h
@@ -67,6 +67,6 @@
     return returnValue;
 }
 
-extern "C" sw::FrameBuffer *createFrameBuffer(NativeDisplayType display, NativeWindowType window, int width, int height);
+extern sw::FrameBuffer *createFrameBuffer(NativeDisplayType display, NativeWindowType window, int width, int height);
 
 #endif   // LIBGL_MAIN_H_
diff --git a/src/OpenGL/libGLES_CM/Context.cpp b/src/OpenGL/libGLES_CM/Context.cpp
index 0ca4654..337b406 100644
--- a/src/OpenGL/libGLES_CM/Context.cpp
+++ b/src/OpenGL/libGLES_CM/Context.cpp
@@ -255,7 +255,7 @@
     markAllStateDirty();

 }

 

-int Context::getClientVersion()

+int Context::getClientVersion() const

 {

 	return 1;

 }

@@ -2807,11 +2807,8 @@
 

 }

 

-// Exported functions for use by EGL

-extern "C"

+egl::Context *es1CreateContext(const egl::Config *config, const egl::Context *shareContext)

 {

-	es1::Context *glCreateContext(const egl::Config *config, const es1::Context *shareContext)

-	{

-		return new es1::Context(config, shareContext);

-	}

+	ASSERT(!shareContext || shareContext->getClientVersion() == 1);   // Should be checked by eglCreateContext

+	return new es1::Context(config, static_cast<const es1::Context*>(shareContext));

 }

diff --git a/src/OpenGL/libGLES_CM/Context.h b/src/OpenGL/libGLES_CM/Context.h
index 9d6c074..387c527 100644
--- a/src/OpenGL/libGLES_CM/Context.h
+++ b/src/OpenGL/libGLES_CM/Context.h
@@ -25,6 +25,7 @@
 

 #define GL_API

 #include <GLES/gl.h>

+#define GL_GLEXT_PROTOTYPES

 #include <GLES/glext.h>

 #define EGLAPI

 #include <EGL/egl.h>

@@ -263,7 +264,7 @@
     Context(const egl::Config *config, const Context *shareContext);

 

 	virtual void makeCurrent(egl::Surface *surface);

-	virtual int getClientVersion();

+	virtual int getClientVersion() const;

 

     void markAllStateDirty();

 

diff --git a/src/OpenGL/libGLES_CM/Texture.cpp b/src/OpenGL/libGLES_CM/Texture.cpp
index 7b767e2..cd2c35b 100644
--- a/src/OpenGL/libGLES_CM/Texture.cpp
+++ b/src/OpenGL/libGLES_CM/Texture.cpp
@@ -758,60 +758,56 @@
 

 }

 

-// Exported functions for use by EGL

-extern "C"

+egl::Image *createBackBuffer(int width, int height, const egl::Config *config)

 {

-	egl::Image *createBackBuffer(int width, int height, const egl::Config *config)

+	if(config)

 	{

-		if(config)

-		{

-			return new es1::Image(0, width, height, config->mAlphaSize ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE);

-		}

+		return new es1::Image(0, width, height, config->mAlphaSize ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE);

+	}

 

+	return 0;

+}

+

+egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)

+{

+	if(width == 0 || height == 0 || height > OUTLINE_RESOLUTION)

+	{

+		ERR("Invalid parameters");

 		return 0;

 	}

 

-	egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)

+	bool lockable = true;

+

+	switch(format)

 	{

-		if(width == 0 || height == 0 || height > OUTLINE_RESOLUTION)

-		{

-			ERR("Invalid parameters");

-			return 0;

-		}

-

-		bool lockable = true;

-

-		switch(format)

-		{

-	//	case sw::FORMAT_D15S1:

-		case sw::FORMAT_D24S8:

-		case sw::FORMAT_D24X8:

-	//	case sw::FORMAT_D24X4S4:

-		case sw::FORMAT_D24FS8:

-		case sw::FORMAT_D32:

-		case sw::FORMAT_D16:

-			lockable = false;

-			break;

-	//	case sw::FORMAT_S8_LOCKABLE:

-	//	case sw::FORMAT_D16_LOCKABLE:

-		case sw::FORMAT_D32F_LOCKABLE:

-	//	case sw::FORMAT_D32_LOCKABLE:

-		case sw::FORMAT_DF24S8:

-		case sw::FORMAT_DF16S8:

-			lockable = true;

-			break;

-		default:

-			UNREACHABLE();

-		}

-

-		es1::Image *surface = new es1::Image(0, width, height, format, multiSampleDepth, lockable, true);

-

-		if(!surface)

-		{

-			ERR("Out of memory");

-			return 0;

-		}

-

-		return surface;

+//	case sw::FORMAT_D15S1:

+	case sw::FORMAT_D24S8:

+	case sw::FORMAT_D24X8:

+//	case sw::FORMAT_D24X4S4:

+	case sw::FORMAT_D24FS8:

+	case sw::FORMAT_D32:

+	case sw::FORMAT_D16:

+		lockable = false;

+		break;

+//	case sw::FORMAT_S8_LOCKABLE:

+//	case sw::FORMAT_D16_LOCKABLE:

+	case sw::FORMAT_D32F_LOCKABLE:

+//	case sw::FORMAT_D32_LOCKABLE:

+	case sw::FORMAT_DF24S8:

+	case sw::FORMAT_DF16S8:

+		lockable = true;

+		break;

+	default:

+		UNREACHABLE();

 	}

+

+	es1::Image *surface = new es1::Image(0, width, height, format, multiSampleDepth, lockable, true);

+

+	if(!surface)

+	{

+		ERR("Out of memory");

+		return 0;

+	}

+

+	return surface;

 }

diff --git a/src/OpenGL/libGLES_CM/exports.map b/src/OpenGL/libGLES_CM/exports.map
index 565d1bc..4f05484 100644
--- a/src/OpenGL/libGLES_CM/exports.map
+++ b/src/OpenGL/libGLES_CM/exports.map
@@ -205,13 +205,7 @@
     glDrawTexfOES;
     glDrawTexfvOES;
 
-    # EGL dependencies
-    glCreateContext;
-    glGetProcAddress;
-
-	createFrameBuffer;
-	createBackBuffer;
-	createDepthStencil;
+    libGLES_CMexports;
 
 	Register;
 
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.cbp b/src/OpenGL/libGLES_CM/libGLES_CM.cbp
index 7041a83..c0cbc51 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.cbp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.cbp
@@ -286,6 +286,7 @@
 		<Unit filename="VertexDataManager.h" />
 		<Unit filename="exports.map" />
 		<Unit filename="libGLES_CM.cpp" />
+		<Unit filename="libGLES_CM.hpp" />
 		<Unit filename="main.cpp" />
 		<Unit filename="main.h" />
 		<Unit filename="mathutil.h" />
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.cpp b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
index 907030e..96323f0 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.cpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.cpp
@@ -34,6 +34,8 @@
 

 #include <limits>

 

+using namespace es1;

+

 static bool validImageSize(GLint level, GLsizei width, GLsizei height)

 {

 	if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)

@@ -84,218 +86,182 @@
 

 EGLint EGLAPIENTRY eglGetError(void)

 {

-	static auto eglGetError = (EGLint (EGLAPIENTRY*)(void))getProcAddress(libEGL, "eglGetError");

-	return eglGetError();

+	return libEGL->eglGetError();

 }

 

 EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)

 {

-	static auto eglGetDisplay = (EGLDisplay (EGLAPIENTRY*)(EGLNativeDisplayType display_id))getProcAddress(libEGL, "eglGetDisplay");

-	return eglGetDisplay(display_id);

+	return libEGL->eglGetDisplay(display_id);

 }

 

 EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)

 {

-	static auto eglInitialize = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLint *major, EGLint *minor))getProcAddress(libEGL, "eglInitialize");

-	return eglInitialize(dpy, major, minor);

+	return libEGL->eglInitialize(dpy, major, minor);

 }

 

 EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)

 {

-	static auto eglTerminate = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy))getProcAddress(libEGL, "eglTerminate");

-	return eglTerminate(dpy);

+	return libEGL->eglTerminate(dpy);

 }

 

 const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)

 {

-	static auto eglQueryString = (const char *(EGLAPIENTRY*)(EGLDisplay dpy, EGLint name))getProcAddress(libEGL, "eglQueryString");

-	return eglQueryString(dpy, name);

+	return libEGL->eglQueryString(dpy, name);

 }

 

 EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)

 {

-	static auto eglGetConfigs = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config))getProcAddress(libEGL, "eglGetConfigs");

-	return eglGetConfigs(dpy, configs, config_size, num_config);

+	return libEGL->eglGetConfigs(dpy, configs, config_size, num_config);

 }

 

 EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)

 {

-	static auto eglChooseConfig = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config))getProcAddress(libEGL, "eglChooseConfig");

-	return eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);

+	return libEGL->eglChooseConfig(dpy, attrib_list, configs, config_size, num_config);

 }

 

 EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)

 {

-	static auto eglGetConfigAttrib = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value))getProcAddress(libEGL, "eglGetConfigAttrib");

-	return eglGetConfigAttrib(dpy, config, attribute, value);

+	return libEGL->eglGetConfigAttrib(dpy, config, attribute, value);

 }

 

 EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list)

 {

-	static auto eglCreateWindowSurface = (EGLSurface (EGLAPIENTRY*)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list))getProcAddress(libEGL, "eglCreateWindowSurface");

-	return eglCreateWindowSurface(dpy, config, window, attrib_list);

+	return libEGL->eglCreateWindowSurface(dpy, config, window, attrib_list);

 }

 

 EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)

 {

-	static auto eglCreatePbufferSurface = (EGLSurface (EGLAPIENTRY*)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list))getProcAddress(libEGL, "eglCreatePbufferSurface");

-	return eglCreatePbufferSurface(dpy, config, attrib_list);

+	return libEGL->eglCreatePbufferSurface(dpy, config, attrib_list);

 }

 

 EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)

 {

-	static auto eglCreatePixmapSurface = (EGLSurface (EGLAPIENTRY*)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list))getProcAddress(libEGL, "eglCreatePixmapSurface");

-	return eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);

+	return libEGL->eglCreatePixmapSurface(dpy, config, pixmap, attrib_list);

 }

 

 EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)

 {

-	static auto eglDestroySurface = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLSurface surface))getProcAddress(libEGL, "eglDestroySurface");

-	return eglDestroySurface(dpy, surface);

+	return libEGL->eglDestroySurface(dpy, surface);

 }

 

 EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)

 {

-	static auto eglQuerySurface = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value))getProcAddress(libEGL, "eglQuerySurface");

-	return eglQuerySurface(dpy, surface, attribute, value);

+	return libEGL->eglQuerySurface(dpy, surface, attribute, value);

 }

 

 EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)

 {

-	static auto eglBindAPI = (EGLBoolean (EGLAPIENTRY*)(EGLenum api))getProcAddress(libEGL, "eglBindAPI");

-	return eglBindAPI(api);

+	return libEGL->eglBindAPI(api);

 }

 

 EGLenum EGLAPIENTRY eglQueryAPI(void)

 {

-	static auto eglQueryAPI = (EGLenum (EGLAPIENTRY*)(void))getProcAddress(libEGL, "eglQueryAPI");

-	return eglQueryAPI();

+	return libEGL->eglQueryAPI();

 }

 

 EGLBoolean EGLAPIENTRY eglWaitClient(void)

 {

-	static auto eglWaitClient = (EGLBoolean (EGLAPIENTRY*)(void))getProcAddress(libEGL, "eglWaitClient");

-	return eglWaitClient();

+	return libEGL->eglWaitClient();

 }

 

 EGLBoolean EGLAPIENTRY eglReleaseThread(void)

 {

-	static auto eglReleaseThread = (EGLBoolean (EGLAPIENTRY*)(void))getProcAddress(libEGL, "eglReleaseThread");

-	return eglReleaseThread();

+	return libEGL->eglReleaseThread();

 }

 

 EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)

 {

-	static auto eglCreatePbufferFromClientBuffer = (EGLSurface (EGLAPIENTRY*)(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list))getProcAddress(libEGL, "eglCreatePbufferFromClientBuffer");

-	return eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);

+	return libEGL->eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);

 }

 

 EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)

 {

-	static auto eglSurfaceAttrib = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value))getProcAddress(libEGL, "eglSurfaceAttrib");

-	return eglSurfaceAttrib(dpy, surface, attribute, value);

+	return libEGL->eglSurfaceAttrib(dpy, surface, attribute, value);

 }

 

 EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)

 {

-	static auto eglBindTexImage = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLSurface surface, EGLint buffer))getProcAddress(libEGL, "eglBindTexImage");

-	return eglBindTexImage(dpy, surface, buffer);

+	return libEGL->eglBindTexImage(dpy, surface, buffer);

 }

 

 EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)

 {

-	static auto eglReleaseTexImage = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLSurface surface, EGLint buffer))getProcAddress(libEGL, "eglReleaseTexImage");

-	return eglReleaseTexImage(dpy, surface, buffer);

+	return libEGL->eglReleaseTexImage(dpy, surface, buffer);

 }

 

 EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)

 {

-	static auto eglSwapInterval = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLint interval))getProcAddress(libEGL, "eglSwapInterval");

-	return eglSwapInterval(dpy, interval);

+	return libEGL->eglSwapInterval(dpy, interval);

 }

 

 EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)

 {

-	static auto eglCreateContext = (EGLContext (EGLAPIENTRY*)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list))getProcAddress(libEGL, "eglCreateContext");

-	return eglCreateContext(dpy, config, share_context, attrib_list);

+	return libEGL->eglCreateContext(dpy, config, share_context, attrib_list);

 }

 

 EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)

 {

-	static auto eglDestroyContext = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLContext ctx))getProcAddress(libEGL, "eglDestroyContext");

-	return eglDestroyContext(dpy, ctx);

+	return libEGL->eglDestroyContext(dpy, ctx);

 }

 

 EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)

 {

-	static auto eglMakeCurrent = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx))getProcAddress(libEGL, "eglMakeCurrent");

-	return eglMakeCurrent(dpy, draw, read, ctx);

+	return libEGL->eglMakeCurrent(dpy, draw, read, ctx);

 }

 

 EGLContext EGLAPIENTRY eglGetCurrentContext(void)

 {

-	static auto eglGetCurrentContext = (EGLContext (EGLAPIENTRY*)(void))getProcAddress(libEGL, "eglGetCurrentContext");

-	return eglGetCurrentContext();

+	return libEGL->eglGetCurrentContext();

 }

 

 EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)

 {

-	static auto eglGetCurrentSurface = (EGLSurface (EGLAPIENTRY*)(EGLint readdraw))getProcAddress(libEGL, "eglGetCurrentSurface");

-	return eglGetCurrentSurface(readdraw);

+	return libEGL->eglGetCurrentSurface(readdraw);

 }

 

 EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)

 {

-	static auto eglGetCurrentDisplay = (EGLDisplay (EGLAPIENTRY*)(void))getProcAddress(libEGL, "eglGetCurrentDisplay");

-	return eglGetCurrentDisplay();

+	return libEGL->eglGetCurrentDisplay();

 }

 

 EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)

 {

-	static auto eglQueryContext = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value))getProcAddress(libEGL, "eglQueryContext");

-	return eglQueryContext(dpy, ctx, attribute, value);

+	return libEGL->eglQueryContext(dpy, ctx, attribute, value);

 }

 

 EGLBoolean EGLAPIENTRY eglWaitGL(void)

 {

-	static auto eglWaitGL = (EGLBoolean (EGLAPIENTRY*)(void))getProcAddress(libEGL, "eglWaitGL");

-	return eglWaitGL();

+	return libEGL->eglWaitGL();

 }

 

 EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)

 {

-	static auto eglWaitNative = (EGLBoolean (EGLAPIENTRY*)(EGLint engine))getProcAddress(libEGL, "eglWaitNative");

-	return eglWaitNative(engine);

+	return libEGL->eglWaitNative(engine);

 }

 

 EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)

 {

-	static auto eglSwapBuffers = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLSurface surface))getProcAddress(libEGL, "eglSwapBuffers");

-	return eglSwapBuffers(dpy, surface);

+	return libEGL->eglSwapBuffers(dpy, surface);

 }

 

 EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)

 {

-	static auto eglCopyBuffers = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target))getProcAddress(libEGL, "eglCopyBuffers");

-	return eglCopyBuffers(dpy, surface, target);

+	return libEGL->eglCopyBuffers(dpy, surface, target);

 }

 

 EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)

 {

-	static auto eglCreateImageKHR = (EGLImageKHR (EGLAPIENTRY*)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list))getProcAddress(libEGL, "eglCreateImageKHR");

-	return eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);

+	return libEGL->eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);

 }

 

 EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)

 {

-	static auto eglDestroyImageKHR = (EGLBoolean (EGLAPIENTRY*)(EGLDisplay dpy, EGLImageKHR image))getProcAddress(libEGL, "eglDestroyImageKHR");

-	return eglDestroyImageKHR(dpy, image);

+	return libEGL->eglDestroyImageKHR(dpy, image);

 }

 

 __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)

 {

-	static auto eglGetProcAddress = (__eglMustCastToProperFunctionPointerType (EGLAPIENTRY*)(const char*))getProcAddress(libEGL, "eglGetProcAddress");

-	return eglGetProcAddress(procname);

+	return libEGL->eglGetProcAddress(procname);

 }

 

 void GL_APIENTRY glActiveTexture(GLenum texture)

@@ -3898,7 +3864,7 @@
 	UNIMPLEMENTED();

 }

 

-__eglMustCastToProperFunctionPointerType glGetProcAddress(const char *procname)

+__eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname)

 {

 	struct Extension

 	{

diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.def b/src/OpenGL/libGLES_CM/libGLES_CM.def
index 6ab41db..3efec4d 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.def
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.def
@@ -205,12 +205,6 @@
     glDrawTexfOES
     glDrawTexfvOES
 
-    ; EGL dependencies
-    glCreateContext
-    glGetProcAddress
-
-	createFrameBuffer
-	createBackBuffer
-	createDepthStencil
+	libGLES_CMexports
 
 	Register
\ No newline at end of file
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.hpp b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
new file mode 100644
index 0000000..dd2d23a
--- /dev/null
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
@@ -0,0 +1,95 @@
+#ifndef libGLES_CM_hpp
+#define libGLES_CM_hpp
+
+#define GL_API
+#include <GLES/gl.h>
+#define GL_GLEXT_PROTOTYPES
+#include <GLES/glext.h>
+#define EGLAPI
+#include <EGL/egl.h>
+
+#include "Common/SharedLibrary.hpp"
+
+namespace sw
+{
+class FrameBuffer;
+enum Format : unsigned char;
+}
+
+namespace egl
+{
+class Context;
+class Image;
+class Config;
+}
+
+class LibGLES_CMexports
+{
+public:
+	LibGLES_CMexports();
+
+	egl::Context *(*es1CreateContext)(const egl::Config *config, const egl::Context *shareContext);
+	__eglMustCastToProperFunctionPointerType (*es1GetProcAddress)(const char *procname);
+	egl::Image *(*createBackBuffer)(int width, int height, const egl::Config *config);
+	egl::Image *(*createDepthStencil)(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
+	sw::FrameBuffer *(*createFrameBuffer)(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height);
+
+	void (GL_APIENTRY *glEGLImageTargetTexture2DOES)(GLenum target, GLeglImageOES image);
+};
+
+class LibGLES_CM
+{
+public:
+	LibGLES_CM()
+	{
+		libGLES_CM = nullptr;
+		libGLES_CMexports = nullptr;
+	}
+
+	~LibGLES_CM()
+	{
+		freeLibrary(libGLES_CM);
+	}
+
+	operator bool()
+	{
+		return loadExports();
+	}
+
+	LibGLES_CMexports *operator->()
+	{
+		return loadExports();
+	}
+
+private:
+	LibGLES_CMexports *loadExports()
+	{
+		if(!libGLES_CM)
+		{
+			#if defined(_WIN32)
+			const char *libGLES_CM_lib[] = {"libGLES_CM.dll", "libGLES_CM_translator.dll"};
+			#elif defined(__ANDROID__)
+			const char *libGLES_CM_lib[] = {"/vendor/lib/egl/libGLESv1_CM_swiftshader.so"};
+			#elif defined(__LP64__)
+			const char *libGLES_CM_lib[] = {"lib64GLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};
+			#else
+			const char *libGLES_CM_lib[] = {"libGLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};
+			#endif
+
+			libGLES_CM = loadLibrary(libGLES_CM_lib);
+
+			if(libGLES_CM)
+			{
+				auto libGLES_CMexportsProc = (LibGLES_CMexports *(*)())getProcAddress(libGLES_CM, "libGLES_CMexports");
+				libGLES_CMexports = libGLES_CMexportsProc();
+			}
+		}
+
+		return libGLES_CMexports;
+	}
+
+	void *libGLES_CM;
+	LibGLES_CMexports *libGLES_CMexports;
+};
+
+#endif libGLES_CM_hpp
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.vcxproj b/src/OpenGL/libGLES_CM/libGLES_CM.vcxproj
index c591b19..ce35b8d 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.vcxproj
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.vcxproj
@@ -351,6 +351,7 @@
     <ClInclude Include="Framebuffer.h" />

     <ClInclude Include="Image.hpp" />

     <ClInclude Include="IndexDataManager.h" />

+    <ClInclude Include="libGLES_CM.hpp" />

     <ClInclude Include="main.h" />

     <ClInclude Include="mathutil.h" />

     <ClInclude Include="Renderbuffer.h" />

diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.vcxproj.filters b/src/OpenGL/libGLES_CM/libGLES_CM.vcxproj.filters
index 0ccb31a..47f9aaa 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.vcxproj.filters
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.vcxproj.filters
@@ -130,6 +130,9 @@
     <ClInclude Include="..\common\MatrixStack.hpp">

       <Filter>Header Files</Filter>

     </ClInclude>

+    <ClInclude Include="libGLES_CM.hpp">

+      <Filter>Header Files</Filter>

+    </ClInclude>

   </ItemGroup>

   <ItemGroup>

     <ResourceCompile Include="libGLES_CM.rc" />

diff --git a/src/OpenGL/libGLES_CM/main.cpp b/src/OpenGL/libGLES_CM/main.cpp
index 0927c65..0044dbf 100644
--- a/src/OpenGL/libGLES_CM/main.cpp
+++ b/src/OpenGL/libGLES_CM/main.cpp
@@ -13,12 +13,16 @@
 

 #include "main.h"

 

+#include "libGLES_CM.hpp"

 #include "Framebuffer.h"

 #include "libEGL/Surface.h"

 #include "Common/Thread.hpp"

 #include "Common/SharedLibrary.hpp"

 #include "common/debug.h"

 

+#define GL_GLEXT_PROTOTYPES

+#include <GLES/glext.h>

+

 #if !defined(_MSC_VER)

 #define CONSTRUCTOR __attribute__((constructor))

 #define DESTRUCTOR __attribute__((destructor))

@@ -37,27 +41,11 @@
     TRACE("()");

 }

 

-CONSTRUCTOR static bool glAttachProcess()

+CONSTRUCTOR static void glAttachProcess()

 {

     TRACE("()");

 

     glAttachThread();

-

-	#if defined(_WIN32)

-	const char *libEGL_lib[] = {"libEGL.dll", "libEGL_translator.dll"};

-	#elif defined(__ANDROID__)

-	const char *libEGL_lib[] = {"/vendor/lib/egl/libEGL_swiftshader.so"};

-	#elif defined(__LP64__)

-	const char *libEGL_lib[] = {"lib64EGL_translator.so", "libEGL.so.1", "libEGL.so"};

-	#else

-	const char *libEGL_lib[] = {"libEGL_translator.so", "libEGL.so.1", "libEGL.so"};

-	#endif

-

-	libEGL = loadLibrary(libEGL_lib);

-	egl::getCurrentContext = (egl::Context *(*)())getProcAddress(libEGL, "clientGetCurrentContext");

-	egl::getCurrentDisplay = (egl::Display *(*)())getProcAddress(libEGL, "clientGetCurrentDisplay");

-

-    return libEGL != 0;

 }

 

 DESTRUCTOR static void glDetachProcess()

@@ -65,7 +53,6 @@
     TRACE("()");

 

 	glDetachThread();

-	freeLibrary(libEGL);

 }

 

 #if defined(_WIN32)

@@ -74,7 +61,7 @@
     switch(reason)

     {

     case DLL_PROCESS_ATTACH:

-        return glAttachProcess();

+        glAttachProcess();

         break;

     case DLL_THREAD_ATTACH:

         glAttachThread();

@@ -97,7 +84,7 @@
 {

 es1::Context *getContext()

 {

-	egl::Context *context = egl::getCurrentContext();

+	egl::Context *context = libEGL->clientGetCurrentContext();

 

 	if(context && context->getClientVersion() == 1)

 	{

@@ -109,7 +96,7 @@
 

 egl::Display *getDisplay()

 {

-    return egl::getCurrentDisplay();

+    return libEGL->clientGetCurrentDisplay();

 }

 

 Device *getDevice()

@@ -118,7 +105,6 @@
 

     return context ? context->getDevice() : 0;

 }

-}

 

 // Records an error code

 void error(GLenum errorCode)

@@ -153,11 +139,28 @@
         }

     }

 }

-

-namespace egl

-{

-	egl::Context *(*getCurrentContext)() = 0;

-	egl::Display *(*getCurrentDisplay)() = 0;

 }

 

-void *libEGL = 0;   // Handle to the libEGL module

+egl::Context *es1CreateContext(const egl::Config *config, const egl::Context *shareContext);

+extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname);

+egl::Image *createBackBuffer(int width, int height, const egl::Config *config);

+egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);

+sw::FrameBuffer *createFrameBuffer(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height);

+

+LibGLES_CMexports::LibGLES_CMexports()

+{

+	this->es1CreateContext = ::es1CreateContext;

+	this->es1GetProcAddress = ::es1GetProcAddress;

+	this->createBackBuffer = ::createBackBuffer;

+	this->createDepthStencil = ::createDepthStencil;

+	this->createFrameBuffer = ::createFrameBuffer;

+	this->glEGLImageTargetTexture2DOES = ::glEGLImageTargetTexture2DOES;

+}

+

+extern "C" LibGLES_CMexports *libGLES_CMexports()

+{

+	static LibGLES_CMexports libGLES_CM;

+	return &libGLES_CM;

+}

+

+LibEGL libEGL;
\ No newline at end of file
diff --git a/src/OpenGL/libGLES_CM/main.h b/src/OpenGL/libGLES_CM/main.h
index 4b5648a..a5d1aad 100644
--- a/src/OpenGL/libGLES_CM/main.h
+++ b/src/OpenGL/libGLES_CM/main.h
@@ -17,6 +17,7 @@
 #include "Context.h"
 #include "Device.hpp"
 #include "common/debug.h"
+#include "libEGL/libEGL.hpp"
 #include "libEGL/Display.h"
 
 #define GL_API
@@ -29,25 +30,18 @@
 	Context *getContext();
 	egl::Display *getDisplay();
 	Device *getDevice();
+
+	void error(GLenum errorCode);
+
+	template<class T>
+	const T &error(GLenum errorCode, const T &returnValue)
+	{
+		error(errorCode);
+
+		return returnValue;
+	}
 }
 
-void error(GLenum errorCode);
-
-template<class T>
-const T &error(GLenum errorCode, const T &returnValue)
-{
-    error(errorCode);
-
-    return returnValue;
-}
-
-// libEGL dependencies
-namespace egl
-{
-	extern egl::Context *(*getCurrentContext)();
-	extern egl::Display *(*getCurrentDisplay)();
-}
-
-extern void *libEGL;   // Handle to the libEGL module
+extern LibEGL libEGL;
 
 #endif   // LIBGLES_CM_MAIN_H_
diff --git a/src/OpenGL/libGLESv2/Context.cpp b/src/OpenGL/libGLESv2/Context.cpp
index 983914e..e5225ce 100644
--- a/src/OpenGL/libGLESv2/Context.cpp
+++ b/src/OpenGL/libGLESv2/Context.cpp
@@ -300,7 +300,7 @@
     markAllStateDirty();

 }

 

-EGLint Context::getClientVersion()

+EGLint Context::getClientVersion() const

 {

 	return clientVersion;

 }

@@ -4125,11 +4125,8 @@
 

 }

 

-// Exported functions for use by EGL

-extern "C"

+egl::Context *es2CreateContext(const egl::Config *config, const egl::Context *shareContext, int clientVersion)

 {

-	es2::Context *glCreateContext(const egl::Config *config, const es2::Context *shareContext, int clientVersion)

-	{

-		return new es2::Context(config, shareContext, clientVersion);

-	}

+	ASSERT(!shareContext || shareContext->getClientVersion() == clientVersion);   // Should be checked by eglCreateContext

+	return new es2::Context(config, static_cast<const es2::Context*>(shareContext), clientVersion);

 }

diff --git a/src/OpenGL/libGLESv2/Context.h b/src/OpenGL/libGLESv2/Context.h
index 4da5a75..995015a 100644
--- a/src/OpenGL/libGLESv2/Context.h
+++ b/src/OpenGL/libGLESv2/Context.h
@@ -353,7 +353,7 @@
     Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion);

 

 	virtual void makeCurrent(egl::Surface *surface);

-	virtual EGLint getClientVersion();

+	virtual EGLint getClientVersion() const;

 

     void markAllStateDirty();

 

diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp
index 3d84215..a9002a2 100644
--- a/src/OpenGL/libGLESv2/Texture.cpp
+++ b/src/OpenGL/libGLESv2/Texture.cpp
@@ -1797,60 +1797,57 @@
 

 }

 

-// Exported functions for use by EGL

-extern "C"

+egl::Image *createBackBuffer(int width, int height, const egl::Config *config)

 {

-	egl::Image *createBackBuffer(int width, int height, const egl::Config *config)

+	if(config)

 	{

-		if(config)

-		{

-			return new es2::Image(0, width, height, config->mAlphaSize ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE);

-		}

+		return new es2::Image(0, width, height, config->mAlphaSize ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE);

+	}

 

+	return 0;

+}

+

+egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)

+{

+	if(width == 0 || height == 0 || height > OUTLINE_RESOLUTION)

+	{

+		ERR("Invalid parameters");

+		return 0;

+	}

+		

+	bool lockable = true;

+

+	switch(format)

+	{

+//	case sw::FORMAT_D15S1:

+	case sw::FORMAT_D24S8:

+	case sw::FORMAT_D24X8:

+//	case sw::FORMAT_D24X4S4:

+	case sw::FORMAT_D24FS8:

+	case sw::FORMAT_D32:

+	case sw::FORMAT_D16:

+		lockable = false;

+		break;

+//	case sw::FORMAT_S8_LOCKABLE:

+//	case sw::FORMAT_D16_LOCKABLE:

+	case sw::FORMAT_D32F_LOCKABLE:

+//	case sw::FORMAT_D32_LOCKABLE:

+	case sw::FORMAT_DF24S8:

+	case sw::FORMAT_DF16S8:

+		lockable = true;

+		break;

+	default:

+		UNREACHABLE();

+	}

+

+	es2::Image *surface = new es2::Image(0, width, height, format, multiSampleDepth, lockable, true);

+

+	if(!surface)

+	{

+		ERR("Out of memory");

 		return 0;

 	}

 

-	egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard)

-	{

-		if(width == 0 || height == 0 || height > OUTLINE_RESOLUTION)

-		{

-			ERR("Invalid parameters");

-			return 0;

-		}

-		

-		bool lockable = true;

-

-		switch(format)

-		{

-	//	case sw::FORMAT_D15S1:

-		case sw::FORMAT_D24S8:

-		case sw::FORMAT_D24X8:

-	//	case sw::FORMAT_D24X4S4:

-		case sw::FORMAT_D24FS8:

-		case sw::FORMAT_D32:

-		case sw::FORMAT_D16:

-			lockable = false;

-			break;

-	//	case sw::FORMAT_S8_LOCKABLE:

-	//	case sw::FORMAT_D16_LOCKABLE:

-		case sw::FORMAT_D32F_LOCKABLE:

-	//	case sw::FORMAT_D32_LOCKABLE:

-		case sw::FORMAT_DF24S8:

-		case sw::FORMAT_DF16S8:

-			lockable = true;

-			break;

-		default:

-			UNREACHABLE();

-		}

-

-		es2::Image *surface = new es2::Image(0, width, height, format, multiSampleDepth, lockable, true);

-

-		if(!surface)

-		{

-			ERR("Out of memory");

-			return 0;

-		}

-

-		return surface;

-	}

+	return surface;

 }

+

diff --git a/src/OpenGL/libGLESv2/exports.map b/src/OpenGL/libGLESv2/exports.map
index cab96a0..4670a61 100644
--- a/src/OpenGL/libGLESv2/exports.map
+++ b/src/OpenGL/libGLESv2/exports.map
@@ -168,13 +168,7 @@
 	glEGLImageTargetTexture2DOES;
 	glEGLImageTargetRenderbufferStorageOES;
 
-    # EGL dependencies
-    glCreateContext;
-    glGetProcAddress;
-
-	createFrameBuffer;
-	createBackBuffer;
-	createDepthStencil;
+    libGLESv2exports;
 
 	Register;
 
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cbp b/src/OpenGL/libGLESv2/libGLESv2.cbp
index 4615472..18b8ab6 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cbp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cbp
@@ -372,6 +372,7 @@
 		<Unit filename="VertexDataManager.h" />
 		<Unit filename="exports.map" />
 		<Unit filename="libGLESv2.cpp" />
+		<Unit filename="libGLESv2.hpp" />
 		<Unit filename="main.cpp" />
 		<Unit filename="main.h" />
 		<Unit filename="mathutil.h" />
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index 13f6f6d..3277120 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -37,6 +37,8 @@
 #include <cutils/log.h>

 #endif

 

+using namespace es2;

+

 typedef std::pair<GLenum, GLenum> InternalFormatTypePair;

 typedef std::map<InternalFormatTypePair, GLenum> FormatMap;

 

@@ -6690,8 +6692,7 @@
 {

 	if(egl::getClientVersion() == 1)

 	{

-		static auto glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)es1::getProcAddress("glEGLImageTargetTexture2DOES");

-		return glEGLImageTargetTexture2DOES(target, image);

+		return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);

 	}

 

 	TRACE("(GLenum target = 0x%X, GLeglImageOES image = 0x%0.8p)", target, image);

@@ -6741,7 +6742,7 @@
 	UNIMPLEMENTED();

 }

 

-__eglMustCastToProperFunctionPointerType glGetProcAddress(const char *procname)

+__eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)

 {

 	struct Extension

 	{

diff --git a/src/OpenGL/libGLESv2/libGLESv2.def b/src/OpenGL/libGLESv2/libGLESv2.def
index 9b42766..0ce826c 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.def
+++ b/src/OpenGL/libGLESv2/libGLESv2.def
@@ -274,12 +274,6 @@
     glTexStorage3D                  @304
     glGetInternalformativ           @308
 
-    ; EGL dependencies
-    glCreateContext
-    glGetProcAddress
-
-	createFrameBuffer
-	createBackBuffer
-	createDepthStencil
+    libGLESv2exports
 
 	Register
\ No newline at end of file
diff --git a/src/OpenGL/libGLESv2/libGLESv2.hpp b/src/OpenGL/libGLESv2/libGLESv2.hpp
new file mode 100644
index 0000000..15f6528
--- /dev/null
+++ b/src/OpenGL/libGLESv2/libGLESv2.hpp
@@ -0,0 +1,93 @@
+#ifndef libGLESv2_hpp
+#define libGLESv2_hpp
+
+#define GL_API
+#include <GLES/gl.h>
+#define GL_GLEXT_PROTOTYPES
+#include <GLES/glext.h>
+#define EGLAPI
+#include <EGL/egl.h>
+
+#include "Common/SharedLibrary.hpp"
+
+namespace sw
+{
+class FrameBuffer;
+enum Format : unsigned char;
+}
+
+namespace egl
+{
+class Context;
+class Image;
+class Config;
+}
+
+class LibGLESv2exports
+{
+public:
+	LibGLESv2exports();
+
+	egl::Context *(*es2CreateContext)(const egl::Config *config, const egl::Context *shareContext, int clientVersion);
+	__eglMustCastToProperFunctionPointerType (*es2GetProcAddress)(const char *procname);
+	egl::Image *(*createBackBuffer)(int width, int height, const egl::Config *config);
+	egl::Image *(*createDepthStencil)(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);
+	sw::FrameBuffer *(*createFrameBuffer)(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height);
+};
+
+class LibGLESv2
+{
+public:
+	LibGLESv2()
+	{
+		libGLESv2 = nullptr;
+		libGLESv2exports = nullptr;
+	}
+
+	~LibGLESv2()
+	{
+		freeLibrary(libGLESv2);
+	}
+
+	operator bool()
+	{
+		return loadExports();
+	}
+
+	LibGLESv2exports *operator->()
+	{
+		return loadExports();
+	}
+
+private:
+	LibGLESv2exports *loadExports()
+	{
+		if(!libGLESv2)
+		{
+			#if defined(_WIN32)
+			const char *libGLESv2_lib[] = {"libGLESv2.dll", "libGLES_V2_translator.dll"};
+			#elif defined(__ANDROID__)
+			const char *libGLESv2_lib[] = {"/vendor/lib/egl/libGLESv2_swiftshader.so"};
+			#elif defined(__LP64__)
+			const char *libGLESv2_lib[] = {"lib64GLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};
+			#else
+			const char *libGLESv2_lib[] = {"libGLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};
+			#endif
+
+			libGLESv2 = loadLibrary(libGLESv2_lib);
+
+			if(libGLESv2)
+			{
+				auto libGLESv2exportsProc = (LibGLESv2exports *(*)())getProcAddress(libGLESv2, "libGLESv2exports");
+				libGLESv2exports = libGLESv2exportsProc();
+			}
+		}
+
+		return libGLESv2exports;
+	}
+
+	void *libGLESv2;
+	LibGLESv2exports *libGLESv2exports;
+};
+
+#endif   // libGLESv2_hpp
diff --git a/src/OpenGL/libGLESv2/libGLESv2.vcxproj b/src/OpenGL/libGLESv2/libGLESv2.vcxproj
index f47b891..7bba1e6 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.vcxproj
+++ b/src/OpenGL/libGLESv2/libGLESv2.vcxproj
@@ -355,6 +355,7 @@
     <ClInclude Include="Framebuffer.h" />

     <ClInclude Include="Image.hpp" />

     <ClInclude Include="IndexDataManager.h" />

+    <ClInclude Include="libGLESv2.hpp" />

     <ClInclude Include="main.h" />

     <ClInclude Include="mathutil.h" />

     <ClInclude Include="Program.h" />

diff --git a/src/OpenGL/libGLESv2/libGLESv2.vcxproj.filters b/src/OpenGL/libGLESv2/libGLESv2.vcxproj.filters
index 683b67a..fa96948 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.vcxproj.filters
+++ b/src/OpenGL/libGLESv2/libGLESv2.vcxproj.filters
@@ -160,6 +160,9 @@
     <ClInclude Include="VertexArray.h">

       <Filter>Header Files</Filter>

     </ClInclude>

+    <ClInclude Include="libGLESv2.hpp">

+      <Filter>Header Files</Filter>

+    </ClInclude>

   </ItemGroup>

   <ItemGroup>

     <ResourceCompile Include="libGLESv2.rc" />

diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index 469bbe4..05f2468 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -23,6 +23,8 @@
 #include <GLES3/gl3.h>

 #include <GLES2/gl2ext.h>

 

+using namespace es2;

+

 typedef std::pair<GLenum, GLenum> InternalFormatTypePair;

 typedef std::map<InternalFormatTypePair, GLenum> FormatMap;

 

diff --git a/src/OpenGL/libGLESv2/main.cpp b/src/OpenGL/libGLESv2/main.cpp
index f185bee..d77b784 100644
--- a/src/OpenGL/libGLESv2/main.cpp
+++ b/src/OpenGL/libGLESv2/main.cpp
@@ -13,7 +13,9 @@
 

 #include "main.h"

 

+#include "libGLESv2.hpp"

 #include "Framebuffer.h"

+#include "libEGL/main.h"

 #include "libEGL/Surface.h"

 #include "Common/Thread.hpp"

 #include "Common/SharedLibrary.hpp"

@@ -37,40 +39,11 @@
     TRACE("()");

 }

 

-CONSTRUCTOR static bool glAttachProcess()

+CONSTRUCTOR static void glAttachProcess()

 {

     TRACE("()");

 

     glAttachThread();

-

-	#if defined(_WIN32)

-	const char *libEGL_lib[] = {"libEGL.dll", "libEGL_translator.dll"};

-	#elif defined(__ANDROID__)

-	const char *libEGL_lib[] = {"/vendor/lib/egl/libEGL_swiftshader.so"};

-	#elif defined(__LP64__)

-	const char *libEGL_lib[] = {"lib64EGL_translator.so", "libEGL.so.1", "libEGL.so"};

-	#else

-	const char *libEGL_lib[] = {"libEGL_translator.so", "libEGL.so.1", "libEGL.so"};

-	#endif

-

-	libEGL = loadLibrary(libEGL_lib);

-	egl::getCurrentContext = (egl::Context *(*)())getProcAddress(libEGL, "clientGetCurrentContext");

-	egl::getCurrentDisplay = (egl::Display *(*)())getProcAddress(libEGL, "clientGetCurrentDisplay");

-

-	#if defined(_WIN32)

-	const char *libGLES_CM_lib[] = {"libGLES_CM.dll", "libGLES_CM_translator.dll"};

-	#elif defined(__ANDROID__)

-	const char *libGLES_CM_lib[] = {"/vendor/lib/egl/libGLESv1_CM_swiftshader.so"};

-	#elif defined(__LP64__)

-	const char *libGLES_CM_lib[] = {"lib64GLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};

-	#else

-	const char *libGLES_CM_lib[] = {"libGLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};

-	#endif

-

-	libGLES_CM = loadLibrary(libGLES_CM_lib);

-	es1::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLES_CM, "glGetProcAddress");

-

-    return libEGL != 0;

 }

 

 DESTRUCTOR static void glDetachProcess()

@@ -78,8 +51,6 @@
     TRACE("()");

 

 	glDetachThread();

-	freeLibrary(libEGL);

-	freeLibrary(libGLES_CM);

 }

 

 #if defined(_WIN32)

@@ -88,7 +59,7 @@
     switch(reason)

     {

     case DLL_PROCESS_ATTACH:

-        return glAttachProcess();

+        glAttachProcess();

         break;

     case DLL_THREAD_ATTACH:

         glAttachThread();

@@ -111,7 +82,7 @@
 {

 es2::Context *getContext()

 {

-	egl::Context *context = egl::getCurrentContext();

+	egl::Context *context = libEGL->clientGetCurrentContext();

 

 	if(context && (context->getClientVersion() == 2 ||

 	               context->getClientVersion() == 3))

@@ -124,7 +95,7 @@
 

 egl::Display *getDisplay()

 {

-    return egl::getCurrentDisplay();

+    return libEGL->clientGetCurrentDisplay();

 }

 

 Device *getDevice()

@@ -133,17 +104,6 @@
 

     return context ? context->getDevice() : 0;

 }

-}

-

-namespace egl

-{

-GLint getClientVersion()

-{

-	Context *context = egl::getCurrentContext();

-

-    return context ? context->getClientVersion() : 0;

-}

-}

 

 // Records an error code

 void error(GLenum errorCode)

@@ -178,17 +138,38 @@
         }

     }

 }

+}

 

 namespace egl

 {

-	egl::Context *(*getCurrentContext)() = 0;

-	egl::Display *(*getCurrentDisplay)() = 0;

-}

-

-namespace es1

+GLint getClientVersion()

 {

-	__eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;

+	Context *context = libEGL->clientGetCurrentContext();

+

+    return context ? context->getClientVersion() : 0;

+}

 }

 

-void *libEGL = 0;   // Handle to the libEGL module

-void *libGLES_CM = 0;   // Handle to the libGLES_CM module

+egl::Context *es2CreateContext(const egl::Config *config, const egl::Context *shareContext, int clientVersion);

+extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname);

+egl::Image *createBackBuffer(int width, int height, const egl::Config *config);

+egl::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);

+sw::FrameBuffer *createFrameBuffer(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height);

+

+LibGLESv2exports::LibGLESv2exports()

+{

+	this->es2CreateContext = ::es2CreateContext;

+	this->es2GetProcAddress = ::es2GetProcAddress;

+	this->createBackBuffer = ::createBackBuffer;

+	this->createDepthStencil = ::createDepthStencil;

+	this->createFrameBuffer = ::createFrameBuffer;

+}

+

+extern "C" LibGLESv2exports *libGLESv2exports()

+{

+	static LibGLESv2exports libGLESv2;

+	return &libGLESv2;

+}

+

+LibEGL libEGL;

+LibGLES_CM libGLES_CM;
\ No newline at end of file
diff --git a/src/OpenGL/libGLESv2/main.h b/src/OpenGL/libGLESv2/main.h
index 09ffb88..de5a2c4 100644
--- a/src/OpenGL/libGLESv2/main.h
+++ b/src/OpenGL/libGLESv2/main.h
@@ -17,7 +17,9 @@
 #include "Context.h"
 #include "Device.hpp"
 #include "common/debug.h"
+#include "libEGL/libEGL.hpp"
 #include "libEGL/Display.h"
+#include "libGLES_CM/libGLES_CM.hpp"
 
 #define GL_APICALL
 #include <GLES2/gl2.h>
@@ -29,6 +31,16 @@
 	Context *getContext();
 	egl::Display *getDisplay();
 	Device *getDevice();
+
+	void error(GLenum errorCode);
+
+	template<class T>
+	const T &error(GLenum errorCode, const T &returnValue)
+	{
+		error(errorCode);
+
+		return returnValue;
+	}
 }
 
 namespace egl
@@ -36,30 +48,7 @@
 	GLint getClientVersion();
 }
 
-void error(GLenum errorCode);
-
-template<class T>
-const T &error(GLenum errorCode, const T &returnValue)
-{
-    error(errorCode);
-
-    return returnValue;
-}
-
-// libEGL dependencies
-namespace egl
-{
-	extern egl::Context *(*getCurrentContext)();
-	extern egl::Display *(*getCurrentDisplay)();
-}
-
-// libGLES_CM dependencies
-namespace es1
-{
-	extern __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname);
-}
-
-extern void *libEGL;       // Handle to the libEGL module
-extern void *libGLES_CM;   // Handle to the libGLES_CM module
+extern LibEGL libEGL;
+extern LibGLES_CM libGLES_CM;
 
 #endif   // LIBGLESV2_MAIN_H_
diff --git a/src/Radiance/libRAD/Surface.cpp b/src/Radiance/libRAD/Surface.cpp
index 9573183..2db50dd 100644
--- a/src/Radiance/libRAD/Surface.cpp
+++ b/src/Radiance/libRAD/Surface.cpp
@@ -33,12 +33,13 @@
 {

 	es2::Image *createBackBuffer(int width, int height, const egl::Config *config);

 	es2::Image *createDepthStencil(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard);

-	#if defined(_WIN32)

-	sw::FrameBuffer *createFrameBuffer(HDC display, HWND window, int width, int height);

-	#else

-	sw::FrameBuffer *createFrameBuffer(void *display, Window window, int width, int height);

-	#endif

-}

+}
+
+#if defined(_WIN32)

+sw::FrameBuffer *createFrameBuffer(HDC display, HWND window, int width, int height);

+#else

+sw::FrameBuffer *createFrameBuffer(Display *display, Window window, int width, int height);

+#endif

 

 namespace egl

 {

diff --git a/src/Radiance/libRAD/libRAD.cbp b/src/Radiance/libRAD/libRAD.cbp
index 4017d4e..23f82a7 100644
--- a/src/Radiance/libRAD/libRAD.cbp
+++ b/src/Radiance/libRAD/libRAD.cbp
@@ -108,6 +108,7 @@
 			<Add directory="./../../Shader/" />
 			<Add directory="./../../Main/" />
 			<Add directory="./../../OpenGL/" />
+			<Add directory="./../../OpenGL/include" />
 		</Compiler>
 		<Linker>
 			<Add option="-Wl,--version-script=./exports.map" />