Bug 732865 - Clean up the GLContext* classes. r=bgirard,joe
💩💩 backed out by 372f90787ec8 💩 💩
authorGeorge Wright <gwright@mozilla.com>
Fri, 16 Mar 2012 14:30:09 -0400
changeset 89588 aad5bc8b3433
parent 89587 cfd17c20d8e9
child 89589 381ed2d35c2f
push id7224
push usergwright@mozilla.com
push date2012-03-16 18:31 +0000
treeherdermozilla-inbound@aad5bc8b3433 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgirard, joe
bugs732865
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 732865 - Clean up the GLContext* classes. r=bgirard,joe
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLContextProviderGLX.cpp
gfx/gl/GLContextProviderOSMesa.cpp
gfx/gl/GLContextProviderWGL.cpp
gfx/gl/GLDefs.h
gfx/gl/GLLibraryEGL.cpp
gfx/gl/GLLibraryEGL.h
gfx/gl/GLLibraryLoader.cpp
gfx/gl/GLLibraryLoader.h
gfx/gl/Makefile.in
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -105,104 +105,16 @@ static const char *sExtensionNames[] = {
     "GL_EXT_framebuffer_multisample",
     "GL_ANGLE_framebuffer_multisample",
     "GL_OES_rgb8_rgba8",
     "GL_ARB_robustness",
     "GL_EXT_robustness",
     NULL
 };
 
-bool
-LibrarySymbolLoader::OpenLibrary(const char *library)
-{
-    PRLibSpec lspec;
-    lspec.type = PR_LibSpec_Pathname;
-    lspec.value.pathname = library;
-
-    mLibrary = PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_LOCAL);
-    if (!mLibrary)
-        return false;
-
-    return true;
-}
-
-bool
-LibrarySymbolLoader::LoadSymbols(SymLoadStruct *firstStruct, bool tryplatform, const char *prefix)
-{
-    return LoadSymbols(mLibrary, firstStruct, tryplatform ? mLookupFunc : nsnull, prefix);
-}
-
-PRFuncPtr
-LibrarySymbolLoader::LookupSymbol(PRLibrary *lib,
-                                  const char *sym,
-                                  PlatformLookupFunction lookupFunction)
-{
-    PRFuncPtr res = 0;
-
-    // try finding it in the library directly, if we have one
-    if (lib) {
-        res = PR_FindFunctionSymbol(lib, sym);
-    }
-
-    // then try looking it up via the lookup symbol
-    if (!res && lookupFunction) {
-        res = lookupFunction(sym);
-    }
-
-    // finally just try finding it in the process
-    if (!res) {
-        PRLibrary *leakedLibRef;
-        res = PR_FindFunctionSymbolAndLibrary(sym, &leakedLibRef);
-    }
-
-    return res;
-}
-
-bool
-LibrarySymbolLoader::LoadSymbols(PRLibrary *lib,
-                                 SymLoadStruct *firstStruct,
-                                 PlatformLookupFunction lookupFunction,
-                                 const char *prefix)
-{
-    char sbuf[MAX_SYMBOL_LENGTH * 2];
-    int failCount = 0;
-
-    SymLoadStruct *ss = firstStruct;
-    while (ss->symPointer) {
-        *ss->symPointer = 0;
-
-        for (int i = 0; i < MAX_SYMBOL_NAMES; i++) {
-            if (ss->symNames[i] == nsnull)
-                break;
-
-            const char *s = ss->symNames[i];
-            if (prefix && *prefix != 0) {
-                strcpy(sbuf, prefix);
-                strcat(sbuf, ss->symNames[i]);
-                s = sbuf;
-            }
-
-            PRFuncPtr p = LookupSymbol(lib, s, lookupFunction);
-            if (p) {
-                *ss->symPointer = p;
-                break;
-            }
-        }
-
-        if (*ss->symPointer == 0) {
-            fprintf (stderr, "Can't find symbol '%s'\n", ss->symNames[0]);
-            failCount++;
-        }
-
-        ss++;
-    }
-
-    return failCount == 0 ? true : false;
-}
-
 /*
  * XXX - we should really know the ARB/EXT variants of these
  * instead of only handling the symbol if it's exposed directly.
  */
 
 bool
 GLContext::InitWithPrefix(const char *prefix, bool trygl)
 {
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -49,16 +49,17 @@
 #include <string.h>
 #include <ctype.h>
 
 #ifdef WIN32
 #include <windows.h>
 #endif
 
 #include "GLDefs.h"
+#include "GLLibraryLoader.h"
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
 #include "gfxContext.h"
 #include "gfxRect.h"
 #include "nsISupportsImpl.h"
 #include "prlink.h"
 
 #include "nsDataHashtable.h"
@@ -79,56 +80,16 @@ namespace mozilla {
   namespace layers {
     class LayerManagerOGL;
     class ColorTextureLayerProgram;
   }
 
 namespace gl {
 class GLContext;
 
-class LibrarySymbolLoader
-{
-public:
-    bool OpenLibrary(const char *library);
-
-    typedef PRFuncPtr (GLAPIENTRY * PlatformLookupFunction) (const char *);
-
-    enum {
-        MAX_SYMBOL_NAMES = 5,
-        MAX_SYMBOL_LENGTH = 128
-    };
-
-    typedef struct {
-        PRFuncPtr *symPointer;
-        const char *symNames[MAX_SYMBOL_NAMES];
-    } SymLoadStruct;
-
-    bool LoadSymbols(SymLoadStruct *firstStruct,
-                       bool tryplatform = false,
-                       const char *prefix = nsnull);
-
-    /*
-     * Static version of the functions in this class
-     */
-    static PRFuncPtr LookupSymbol(PRLibrary *lib,
-                                  const char *symname,
-                                  PlatformLookupFunction lookupFunction = nsnull);
-    static bool LoadSymbols(PRLibrary *lib,
-                              SymLoadStruct *firstStruct,
-                              PlatformLookupFunction lookupFunction = nsnull,
-                              const char *prefix = nsnull);
-protected:
-    LibrarySymbolLoader() {
-        mLibrary = nsnull;
-        mLookupFunc = nsnull;
-    }
-
-    PRLibrary *mLibrary;
-    PlatformLookupFunction mLookupFunc;
-};
 
 enum ShaderProgramType {
     RGBALayerProgramType,
     BGRALayerProgramType,
     RGBXLayerProgramType,
     BGRXLayerProgramType,
     RGBARectLayerProgramType,
     ColorLayerProgramType,
@@ -529,17 +490,17 @@ struct THEBES_API ContextFormat
     int blue, minBlue;
     int alpha, minAlpha;
     int samples;
 
     int colorBits() const { return red + green + blue; }
 };
 
 class GLContext
-    : public LibrarySymbolLoader
+    : public GLLibraryLoader
 {
     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GLContext)
 public:
     GLContext(const ContextFormat& aFormat,
               bool aIsOffscreen = false,
               GLContext *aSharedContext = nsnull)
       : mFlushGuaranteesResolve(false),
         mUserBoundDrawFBO(0),
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -65,52 +65,33 @@
 #endif
 
 #if defined(ANDROID)
 /* from widget */
 #if defined(MOZ_WIDGET_ANDROID)
 #include "AndroidBridge.h"
 #endif
 #include <android/log.h>
-
-// We only need to explicitly dlopen egltrace
-// on android as we can use LD_PRELOAD or other tricks
-// on other platforms. We look for it in /data/local
-// as that's writeable by all users
-#define APITRACE_LIB "/data/local/egltrace.so"
 #endif
 
-#define EGL_LIB "libEGL.so"
 #define GLES2_LIB "libGLESv2.so"
-#define EGL_LIB1 "libEGL.so.1"
 #define GLES2_LIB2 "libGLESv2.so.2"
 
-typedef void *EGLNativeDisplayType;
-typedef void *EGLNativePixmapType;
-typedef void *EGLNativeWindowType;
-
 #elif defined(XP_WIN)
 
 #include "nsILocalFile.h"
 
+#define GLES2_LIB "libGLESv2.dll"
+
 #ifndef WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN 1
 #endif
 
 #include <windows.h>
 
-typedef HDC EGLNativeDisplayType;
-typedef HBITMAP EGLNativePixmapType;
-typedef HWND EGLNativeWindowType;
-
-#define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
-
-#define EGL_LIB "libEGL.dll"
-#define GLES2_LIB "libGLESv2.dll"
-
 // a little helper
 class AutoDestroyHWND {
 public:
     AutoDestroyHWND(HWND aWnd = NULL)
         : mWnd(aWnd)
     {
     }
 
@@ -151,16 +132,17 @@ public:
 #include "nsIScreen.h"
 #include "nsIScreenManager.h"
 #include "gfxUtils.h"
 #include "gfxFailure.h"
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
 #include "gfxPlatform.h"
 #include "GLContextProvider.h"
+#include "GLLibraryEGL.h"
 #include "nsDebug.h"
 #include "nsThreadUtils.h"
 #include "EGLUtils.h"
 
 #include "nsIWidget.h"
 
 #include "gfxCrashReporterUtils.h"
 
@@ -172,38 +154,17 @@ static bool gUseBackingSurface = false;
 
 #ifdef MOZ_WIDGET_GONK
 extern nsIntRect gScreenBounds;
 #endif
 
 namespace mozilla {
 namespace gl {
 
-typedef int EGLint;
-typedef unsigned int EGLBoolean;
-typedef unsigned int EGLenum;
-typedef void *EGLConfig;
-typedef void *EGLContext;
-typedef void *EGLDisplay;
-typedef void *EGLSurface;
-typedef void *EGLClientBuffer;
-typedef void *EGLCastToRelevantPtr;
-typedef void *EGLImageKHR;
-typedef void *GLeglImageOES;
-
-#ifdef MOZ_WIDGET_QT
-#define EGL_DEFAULT_DISPLAY  ((EGLNativeDisplayType)QX11Info::display())
-#else
-#define EGL_DEFAULT_DISPLAY  ((EGLNativeDisplayType)0)
-#endif
-#define EGL_NO_CONTEXT       ((EGLContext)0)
-#define EGL_NO_DISPLAY       ((EGLDisplay)0)
-#define EGL_NO_SURFACE       ((EGLSurface)0)
-
-#define EGL_DISPLAY()        sEGLLibrary.Display()
+static GLLibraryEGL sEGLLibrary;
 
 #define ADD_ATTR_2(_array, _k, _v) do {         \
     (_array).AppendElement(_k);                 \
     (_array).AppendElement(_v);                 \
 } while (0)
 
 #define ADD_ATTR_1(_array, _k) do {             \
     (_array).AppendElement(_k);                 \
@@ -231,48 +192,16 @@ static EGLint gContextAttribs[] = {
 
 static EGLint gContextAttribsRobustness[] = {
     LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
     //LOCAL_EGL_CONTEXT_ROBUST_ACCESS_EXT, LOCAL_EGL_TRUE,
     LOCAL_EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT, LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT,
     LOCAL_EGL_NONE
 };
 
-static PRLibrary* LoadApitraceLibrary()
-{
-    static PRLibrary* sApitraceLibrary = NULL;
-
-    if (sApitraceLibrary)
-        return sApitraceLibrary;
-
-#if defined(ANDROID)
-    nsCString logFile = Preferences::GetCString("gfx.apitrace.logfile");
-
-    if (logFile.IsEmpty()) {
-        logFile = "firefox.trace";
-    }
-
-    // The firefox process can't write to /data/local, but it can write
-    // to $GRE_HOME/
-    nsCAutoString logPath;
-    logPath.AppendPrintf("%s/%s", getenv("GRE_HOME"), logFile.get());
-
-    // apitrace uses the TRACE_FILE environment variable to determine where
-    // to log trace output to
-    printf_stderr("Logging GL tracing output to %s", logPath.get());
-    setenv("TRACE_FILE", logPath.get(), false);
-
-    printf_stderr("Attempting load of %s\n", APITRACE_LIB);
-
-    sApitraceLibrary = PR_LoadLibrary(APITRACE_LIB);
-#endif
-
-    return sApitraceLibrary;
-}
-
 static int
 next_power_of_two(int v)
 {
     v--;
     v |= v >> 1;
     v |= v >> 2;
     v |= v >> 4;
     v |= v >> 8;
@@ -288,694 +217,16 @@ is_power_of_two(int v)
     NS_ASSERTION(v >= 0, "bad value");
 
     if (v == 0)
         return true;
 
     return (v & (v-1)) == 0;
 }
 
-#ifdef DEBUG
-#undef BEFORE_GL_CALL
-#undef AFTER_GL_CALL
-
-#define BEFORE_GL_CALL do {          \
-    BeforeGLCall(MOZ_FUNCTION_NAME); \
-} while (0)
-
-#define AFTER_GL_CALL do {           \
-    AfterGLCall(MOZ_FUNCTION_NAME);  \
-} while (0)
-
-static void BeforeGLCall(const char* glFunction)
-{
-    if (GLContext::DebugMode()) {
-        if (GLContext::DebugMode() & GLContext::DebugTrace)
-            printf_stderr("[egl] > %s\n", glFunction);
-    }
-}
-
-static void AfterGLCall(const char* glFunction)
-{
-    if (GLContext::DebugMode() & GLContext::DebugTrace) {
-        printf_stderr("[egl] < %s\n", glFunction);
-    }
-}
-
-// We rely on the fact that GLContext.h #defines BEFORE_GL_CALL and
-// AFTER_GL_CALL to nothing if !defined(DEBUG).
-#endif
-
-static class EGLLibrary
-{
-public:
-    EGLLibrary() 
-        : mInitialized(false),
-          mEGLLibrary(nsnull),
-          mHasRobustness(false)
-    {
-        mIsANGLE = false;
-        mHave_EGL_KHR_image_base = false;
-        mHave_EGL_KHR_image_pixmap = false;
-        mHave_EGL_KHR_gl_texture_2D_image = false;
-        mHave_EGL_KHR_lock_surface = false;
-        mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle = false;
-    }
-
-    struct {
-        typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void *display_id);
-        pfnGetDisplay fGetDisplay;
-        typedef EGLSurface (GLAPIENTRY * pfnGetCurrentSurface)(EGLint);
-        pfnGetCurrentSurface fGetCurrentSurface;
-        typedef EGLContext (GLAPIENTRY * pfnGetCurrentContext)(void);
-        pfnGetCurrentContext fGetCurrentContext;
-        typedef EGLBoolean (GLAPIENTRY * pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
-        pfnMakeCurrent fMakeCurrent;
-        typedef EGLBoolean (GLAPIENTRY * pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx);
-        pfnDestroyContext fDestroyContext;
-        typedef EGLContext (GLAPIENTRY * pfnCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
-        pfnCreateContext fCreateContext;
-        typedef EGLBoolean (GLAPIENTRY * pfnDestroySurface)(EGLDisplay dpy, EGLSurface surface);
-        pfnDestroySurface fDestroySurface;
-        typedef EGLSurface (GLAPIENTRY * pfnCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
-        pfnCreateWindowSurface fCreateWindowSurface;
-        typedef EGLSurface (GLAPIENTRY * pfnCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-        pfnCreatePbufferSurface fCreatePbufferSurface;
-        typedef EGLSurface (GLAPIENTRY * pfnCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
-        pfnCreatePixmapSurface fCreatePixmapSurface;
-        typedef EGLBoolean (GLAPIENTRY * pfnBindAPI)(EGLenum api);
-        pfnBindAPI fBindAPI;
-        typedef EGLBoolean (GLAPIENTRY * pfnInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
-        pfnInitialize fInitialize;
-        typedef EGLBoolean (GLAPIENTRY * pfnChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
-        pfnChooseConfig fChooseConfig;
-        typedef EGLint (GLAPIENTRY * pfnGetError)(void);
-        pfnGetError fGetError;
-        typedef EGLBoolean (GLAPIENTRY * pfnGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
-        pfnGetConfigAttrib fGetConfigAttrib;
-        typedef EGLBoolean (GLAPIENTRY * pfnGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
-        pfnGetConfigs fGetConfigs;
-        typedef EGLBoolean (GLAPIENTRY * pfnWaitNative)(EGLint engine);
-        pfnWaitNative fWaitNative;
-        typedef EGLCastToRelevantPtr (GLAPIENTRY * pfnGetProcAddress)(const char *procname);
-        pfnGetProcAddress fGetProcAddress;
-        typedef EGLBoolean (GLAPIENTRY * pfnSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
-        pfnSwapBuffers fSwapBuffers;
-        typedef EGLBoolean (GLAPIENTRY * pfnCopyBuffers)(EGLDisplay dpy, EGLSurface surface,
-                                                         EGLNativePixmapType target);
-        pfnCopyBuffers fCopyBuffers;
-        typedef const GLubyte* (GLAPIENTRY * pfnQueryString)(EGLDisplay, EGLint name);
-        pfnQueryString fQueryString;
-        typedef EGLBoolean (GLAPIENTRY * pfnQueryContext)(EGLDisplay dpy, EGLContext ctx,
-                                                          EGLint attribute, EGLint *value);
-        pfnQueryContext fQueryContext;
-        typedef EGLBoolean (GLAPIENTRY * pfnBindTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
-        pfnBindTexImage fBindTexImage;
-        typedef EGLBoolean (GLAPIENTRY * pfnReleaseTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
-        pfnReleaseTexImage fReleaseTexImage;
-        typedef EGLImageKHR (GLAPIENTRY * pfnCreateImageKHR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
-        pfnCreateImageKHR fCreateImageKHR;
-        typedef EGLBoolean (GLAPIENTRY * pfnDestroyImageKHR)(EGLDisplay dpy, EGLImageKHR image);
-        pfnDestroyImageKHR fDestroyImageKHR;
-#ifdef MOZ_WIDGET_GONK
-        typedef EGLBoolean (GLAPIENTRY * pfnSetSwapRectangleANDROID)(EGLDisplay dpy, EGLSurface surface, EGLint left, EGLint top, EGLint width, EGLint height);
-        pfnSetSwapRectangleANDROID fSetSwapRectangleANDROID;
-#endif
-
-        // New extension which allow us to lock texture and get raw image pointer
-        typedef EGLBoolean (GLAPIENTRY * pfnLockSurfaceKHR)(EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
-        pfnLockSurfaceKHR fLockSurfaceKHR;
-        typedef EGLBoolean (GLAPIENTRY * pfnUnlockSurfaceKHR)(EGLDisplay dpy, EGLSurface surface);
-        pfnUnlockSurfaceKHR fUnlockSurfaceKHR;
-        typedef EGLBoolean (GLAPIENTRY * pfnQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
-        pfnQuerySurface fQuerySurface;
-
-        typedef EGLBoolean (GLAPIENTRY * pfnQuerySurfacePointerANGLE)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
-        pfnQuerySurfacePointerANGLE fQuerySurfacePointerANGLE;
-
-        // This is EGL specific GL ext symbol "glEGLImageTargetTexture2DOES"
-        // Lets keep it here for now.
-        typedef void (GLAPIENTRY * pfnImageTargetTexture2DOES)(GLenum target, GLeglImageOES image);
-        pfnImageTargetTexture2DOES fImageTargetTexture2DOES;
-    } mSymbols;
-
-    EGLDisplay fGetDisplay(void* display_id)
-    {
-        BEFORE_GL_CALL;
-        EGLDisplay disp = mSymbols.fGetDisplay(display_id);
-        AFTER_GL_CALL;
-        return disp;
-    }
-    EGLSurface fGetCurrentSurface(EGLint id)
-    {
-        BEFORE_GL_CALL;
-        EGLSurface surf = mSymbols.fGetCurrentSurface(id);
-        AFTER_GL_CALL;
-        return surf;
-    }
-    EGLContext fGetCurrentContext()
-    {
-        BEFORE_GL_CALL;
-        EGLContext context = mSymbols.fGetCurrentContext();
-        AFTER_GL_CALL;
-        return context;
-    }
-    EGLBoolean fMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fMakeCurrent(dpy, draw, read, ctx);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLBoolean fDestroyContext(EGLDisplay dpy, EGLContext ctx)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fDestroyContext(dpy, ctx);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLContext fCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
-    {
-        BEFORE_GL_CALL;
-        EGLContext ctx = mSymbols.fCreateContext(dpy, config, share_context, attrib_list);
-        AFTER_GL_CALL;
-        return ctx;
-    }
-    EGLBoolean fDestroySurface(EGLDisplay dpy, EGLSurface surface)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fDestroySurface(dpy, surface);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLSurface fCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
-    {
-        BEFORE_GL_CALL;
-        EGLSurface surf = mSymbols.fCreateWindowSurface(dpy, config, win, attrib_list);
-        AFTER_GL_CALL;
-        return surf;
-    }
-    EGLSurface fCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
-    {
-        BEFORE_GL_CALL;
-        EGLSurface surf = mSymbols.fCreatePbufferSurface(dpy, config, attrib_list);
-        AFTER_GL_CALL;
-        return surf;
-    }
-    EGLSurface fCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
-    {
-        BEFORE_GL_CALL;
-        EGLSurface surf = mSymbols.fCreatePixmapSurface(dpy, config, pixmap, attrib_list);
-        AFTER_GL_CALL;
-        return surf;
-    }
-    EGLBoolean fBindAPI(EGLenum api)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fBindAPI(api);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLBoolean fInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fInitialize(dpy, major, minor);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLBoolean fChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fChooseConfig(dpy, attrib_list, configs, config_size, num_config);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLint fGetError()
-    {
-        BEFORE_GL_CALL;
-        EGLint i = mSymbols.fGetError();
-        AFTER_GL_CALL;
-        return i;
-    }
-    EGLBoolean fGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fGetConfigAttrib(dpy, config, attribute, value);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLBoolean fGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fGetConfigs(dpy, configs, config_size, num_config);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLBoolean fWaitNative(EGLint engine)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fWaitNative(engine);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLCastToRelevantPtr fGetProcAddress(const char *procname)
-    {
-        BEFORE_GL_CALL;
-        EGLCastToRelevantPtr p = mSymbols.fGetProcAddress(procname);
-        AFTER_GL_CALL;
-        return p;
-    }
-    EGLBoolean fSwapBuffers(EGLDisplay dpy, EGLSurface surface)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fSwapBuffers(dpy, surface);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLBoolean fCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fCopyBuffers(dpy, surface, target);
-        AFTER_GL_CALL;
-        return b;
-    }
-    const GLubyte* fQueryString(EGLDisplay dpy, EGLint name)
-    {
-        BEFORE_GL_CALL;
-        const GLubyte* b = mSymbols.fQueryString(dpy, name);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLBoolean fQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fQueryContext(dpy, ctx, attribute, value);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLBoolean fBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fBindTexImage(dpy, surface, buffer);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLBoolean fReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fReleaseTexImage(dpy, surface, buffer);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLImageKHR fCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
-    {
-         BEFORE_GL_CALL;
-         EGLImageKHR i = mSymbols.fCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
-         AFTER_GL_CALL;
-         return i;
-    }
-    EGLBoolean fDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fDestroyImageKHR(dpy, image);
-        AFTER_GL_CALL;
-        return b;
-    }
-#ifdef MOZ_WIDGET_GONK
-    EGLBoolean fSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface surface, EGLint left, EGLint top, EGLint width, EGLint height)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fSetSwapRectangleANDROID(dpy, surface, left, top, width, height);
-        AFTER_GL_CALL;
-        return b;
-    }
-#endif
-
-    // New extension which allow us to lock texture and get raw image pointer
-    EGLBoolean fLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fLockSurfaceKHR(dpy, surface, attrib_list);
-        AFTER_GL_CALL;
-        return b;
-    }
-
-    EGLBoolean fUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fUnlockSurfaceKHR(dpy, surface);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLBoolean fQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fQuerySurface(dpy, surface, attribute, value);
-        AFTER_GL_CALL;
-        return b;
-    }
-    EGLBoolean fQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
-    {
-        BEFORE_GL_CALL;
-        EGLBoolean b = mSymbols.fQuerySurfacePointerANGLE(dpy, surface, attribute, value);
-        AFTER_GL_CALL;
-        return b;
-    }
-
-    // This is EGL specific GL ext symbol "glEGLImageTargetTexture2DOES"
-    // Lets keep it here for now.
-    void fImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
-    {
-        BEFORE_GL_CALL;
-        mSymbols.fImageTargetTexture2DOES(target, image);
-        AFTER_GL_CALL;
-    }
-
-    bool EnsureInitialized()
-    {
-        if (mInitialized) {
-            return true;
-        }
-
-        mozilla::ScopedGfxFeatureReporter reporter("EGL");
-
-#ifdef XP_WIN
-        // Allow for explicitly specifying the location of libEGL.dll and
-        // libGLESv2.dll.
-        do {
-            nsCOMPtr<nsILocalFile> eglFile, glesv2File;
-            nsresult rv = Preferences::GetComplex("gfx.angle.egl.path",
-                                                  NS_GET_IID(nsILocalFile),
-                                                  getter_AddRefs(eglFile));
-            if (NS_FAILED(rv) || !eglFile)
-                break;
-
-            nsCAutoString s;
-
-            // note that we have to load the libs in this order, because libEGL.dll
-            // depends on libGLESv2.dll, but is not/may not be in our search path.
-            nsCOMPtr<nsIFile> f;
-            eglFile->Clone(getter_AddRefs(f));
-            glesv2File = do_QueryInterface(f);
-            if (!glesv2File)
-                break;
-
-            glesv2File->Append(NS_LITERAL_STRING("libGLESv2.dll"));
-
-            PRLibrary *glesv2lib = nsnull; // this will be leaked on purpose
-            glesv2File->Load(&glesv2lib);
-            if (!glesv2lib)
-                break;
-
-            eglFile->Append(NS_LITERAL_STRING("libEGL.dll"));
-            eglFile->Load(&mEGLLibrary);
-        } while (false);
-#endif
-
-        if (!mEGLLibrary) {
-            mEGLLibrary = LoadApitraceLibrary();
-
-            if (!mEGLLibrary) {
-                printf_stderr("Attempting load of %s\n", EGL_LIB);
-                mEGLLibrary = PR_LoadLibrary(EGL_LIB);
-#if defined(XP_UNIX)
-                if (!mEGLLibrary) {
-                    mEGLLibrary = PR_LoadLibrary(EGL_LIB1);
-                }
-#endif
-            }
-        }
-
-        if (!mEGLLibrary) {
-            NS_WARNING("Couldn't load EGL LIB.");
-            return false;
-        }
-
-#define SYMBOL(name) \
-    { (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, NULL } }
-
-        LibrarySymbolLoader::SymLoadStruct earlySymbols[] = {
-            SYMBOL(GetDisplay),
-            SYMBOL(GetCurrentSurface),
-            SYMBOL(GetCurrentContext),
-            SYMBOL(MakeCurrent),
-            SYMBOL(DestroyContext),
-            SYMBOL(CreateContext),
-            SYMBOL(DestroySurface),
-            SYMBOL(CreateWindowSurface),
-            SYMBOL(CreatePbufferSurface),
-            SYMBOL(CreatePixmapSurface),
-            SYMBOL(BindAPI),
-            SYMBOL(Initialize),
-            SYMBOL(ChooseConfig),
-            SYMBOL(GetError),
-            SYMBOL(GetConfigs),
-            SYMBOL(GetConfigAttrib),
-            SYMBOL(WaitNative),
-            SYMBOL(GetProcAddress),
-            SYMBOL(SwapBuffers),
-            SYMBOL(CopyBuffers),
-            SYMBOL(QueryString),
-            SYMBOL(QueryContext),
-            SYMBOL(BindTexImage),
-            SYMBOL(ReleaseTexImage),
-            SYMBOL(QuerySurface),
-#ifdef MOZ_WIDGET_GONK
-            SYMBOL(SetSwapRectangleANDROID),
-#endif
-            { NULL, { NULL } }
-        };
-
-        if (!LibrarySymbolLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
-            NS_WARNING("Couldn't find required entry points in EGL library (early init)");
-            return false;
-        }
-
-#if defined(MOZ_X11) && defined(MOZ_EGL_XRENDER_COMPOSITE)
-        mEGLDisplay = fGetDisplay((EGLNativeDisplayType) gdk_x11_get_default_xdisplay());
-#else
-        mEGLDisplay = fGetDisplay(EGL_DEFAULT_DISPLAY);
-#endif
-        if (!fInitialize(mEGLDisplay, NULL, NULL))
-            return false;
-
-        const char *vendor = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
-        if (vendor && (strstr(vendor, "TransGaming") != 0 || strstr(vendor, "Google Inc.") != 0)) {
-            mIsANGLE = true;
-        }
-        
-        const char *extensions = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS);
-        if (!extensions)
-            extensions = "";
-
-        printf_stderr("Extensions: %s 0x%02x\n", extensions, extensions[0]);
-        printf_stderr("Extensions length: %d\n", strlen(extensions));
-
-        // note the extra space -- this ugliness tries to match
-        // EGL_KHR_image in the middle of the string, or right at the
-        // end.  It's a prefix for other extensions, so we have to do
-        // this...
-        bool hasKHRImage = false;
-        if (strstr(extensions, "EGL_KHR_image ") ||
-            (strlen(extensions) >= strlen("EGL_KHR_image") &&
-             strcmp(extensions+(strlen(extensions)-strlen("EGL_KHR_image")), "EGL_KHR_image")))
-        {
-            hasKHRImage = true;
-        }
-
-        if (strstr(extensions, "EGL_KHR_image_base")) {
-            mHave_EGL_KHR_image_base = true;
-        }
-            
-        if (strstr(extensions, "EGL_KHR_image_pixmap")) {
-            mHave_EGL_KHR_image_pixmap = true;
-            
-        }
-
-        if (strstr(extensions, "EGL_KHR_gl_texture_2D_image")) {
-            mHave_EGL_KHR_gl_texture_2D_image = true;
-        }
-
-        if (strstr(extensions, "EGL_KHR_lock_surface")) {
-            mHave_EGL_KHR_lock_surface = true;
-        }
-
-        if (hasKHRImage) {
-            LibrarySymbolLoader::SymLoadStruct khrSymbols[] = {
-                { (PRFuncPtr*) &mSymbols.fCreateImageKHR, { "eglCreateImageKHR", NULL } },
-                { (PRFuncPtr*) &mSymbols.fDestroyImageKHR, { "eglDestroyImageKHR", NULL } },
-                { (PRFuncPtr*) &mSymbols.fImageTargetTexture2DOES, { "glEGLImageTargetTexture2DOES", NULL } },
-                { NULL, { NULL } }
-            };
-
-            LibrarySymbolLoader::LoadSymbols(mEGLLibrary, &khrSymbols[0],
-                                             (LibrarySymbolLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
-        }
-
-        if (mHave_EGL_KHR_lock_surface) {
-            LibrarySymbolLoader::SymLoadStruct lockSymbols[] = {
-                { (PRFuncPtr*) &mSymbols.fLockSurfaceKHR, { "eglLockSurfaceKHR", NULL } },
-                { (PRFuncPtr*) &mSymbols.fUnlockSurfaceKHR, { "eglUnlockSurfaceKHR", NULL } },
-                { NULL, { NULL } }
-            };
-
-            LibrarySymbolLoader::LoadSymbols(mEGLLibrary, &lockSymbols[0],
-                                             (LibrarySymbolLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
-            if (!mSymbols.fLockSurfaceKHR) {
-                mHave_EGL_KHR_lock_surface = false;
-            }
-        }
-
-        if (!mSymbols.fCreateImageKHR) {
-            mHave_EGL_KHR_image_base = false;
-            mHave_EGL_KHR_image_pixmap = false;
-            mHave_EGL_KHR_gl_texture_2D_image = false;
-        }
-
-        if (!mSymbols.fImageTargetTexture2DOES) {
-            mHave_EGL_KHR_gl_texture_2D_image = false;
-        }
-
-        if (strstr(extensions, "EGL_ANGLE_surface_d3d_texture_2d_share_handle")) {
-            LibrarySymbolLoader::SymLoadStruct d3dSymbols[] = {
-                { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", NULL } },
-                { NULL, { NULL } }
-            };
-
-            LibrarySymbolLoader::LoadSymbols(mEGLLibrary, &d3dSymbols[0],
-                                             (LibrarySymbolLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
-            if (mSymbols.fQuerySurfacePointerANGLE) {
-                mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle = true;
-            }
-        }
-
-        if (strstr(extensions, "EGL_EXT_create_context_robustness")) {
-            mHasRobustness = true;
-        }
-
-        mInitialized = true;
-        reporter.SetSuccessful();
-        return true;
-    }
-
-    EGLDisplay Display() {
-        return mEGLDisplay;
-    }
-
-    bool IsANGLE() {
-        return mIsANGLE;
-    }
-
-    bool HasKHRImageBase() {
-        return mHave_EGL_KHR_image_base;
-    }
-
-    bool HasKHRImagePixmap() {
-        return mHave_EGL_KHR_image_pixmap;
-    }
-
-    bool HasKHRImageTexture2D() {
-        return mHave_EGL_KHR_gl_texture_2D_image;
-    }
-
-    bool HasKHRLockSurface() {
-        return mHave_EGL_KHR_lock_surface;
-    }
-
-    bool HasANGLESurfaceD3DTexture2DShareHandle() {
-        return mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle;
-    }
-
-    bool HasRobustness() {
-        return mHasRobustness;
-    }
-
-    void
-    DumpEGLConfig(EGLConfig cfg)
-    {
-        int attrval;
-        int err;
-
-#define ATTR(_x) do {                                                   \
-            fGetConfigAttrib(mEGLDisplay, cfg, LOCAL_EGL_##_x, &attrval);  \
-            if ((err = fGetError()) != 0x3000) {                        \
-                printf_stderr("  %s: ERROR (0x%04x)\n", #_x, err);        \
-            } else {                                                    \
-                printf_stderr("  %s: %d (0x%04x)\n", #_x, attrval, attrval); \
-            }                                                           \
-        } while(0)
-
-        printf_stderr("EGL Config: %d [%p]\n", (int)(intptr_t)cfg, cfg);
-
-        ATTR(BUFFER_SIZE);
-        ATTR(ALPHA_SIZE);
-        ATTR(BLUE_SIZE);
-        ATTR(GREEN_SIZE);
-        ATTR(RED_SIZE);
-        ATTR(DEPTH_SIZE);
-        ATTR(STENCIL_SIZE);
-        ATTR(CONFIG_CAVEAT);
-        ATTR(CONFIG_ID);
-        ATTR(LEVEL);
-        ATTR(MAX_PBUFFER_HEIGHT);
-        ATTR(MAX_PBUFFER_PIXELS);
-        ATTR(MAX_PBUFFER_WIDTH);
-        ATTR(NATIVE_RENDERABLE);
-        ATTR(NATIVE_VISUAL_ID);
-        ATTR(NATIVE_VISUAL_TYPE);
-        ATTR(PRESERVED_RESOURCES);
-        ATTR(SAMPLES);
-        ATTR(SAMPLE_BUFFERS);
-        ATTR(SURFACE_TYPE);
-        ATTR(TRANSPARENT_TYPE);
-        ATTR(TRANSPARENT_RED_VALUE);
-        ATTR(TRANSPARENT_GREEN_VALUE);
-        ATTR(TRANSPARENT_BLUE_VALUE);
-        ATTR(BIND_TO_TEXTURE_RGB);
-        ATTR(BIND_TO_TEXTURE_RGBA);
-        ATTR(MIN_SWAP_INTERVAL);
-        ATTR(MAX_SWAP_INTERVAL);
-        ATTR(LUMINANCE_SIZE);
-        ATTR(ALPHA_MASK_SIZE);
-        ATTR(COLOR_BUFFER_TYPE);
-        ATTR(RENDERABLE_TYPE);
-        ATTR(CONFORMANT);
-
-#undef ATTR
-    }
-
-    void DumpEGLConfigs() {
-        int nc = 0;
-        fGetConfigs(mEGLDisplay, NULL, 0, &nc);
-        EGLConfig *ec = new EGLConfig[nc];
-        fGetConfigs(mEGLDisplay, ec, nc, &nc);
-
-        for (int i = 0; i < nc; ++i) {
-            printf_stderr ("========= EGL Config %d ========\n", i);
-            DumpEGLConfig(ec[i]);
-        }
-
-        delete [] ec;
-    }
-
-private:
-    bool mInitialized;
-    PRLibrary *mEGLLibrary;
-    EGLDisplay mEGLDisplay;
-
-    bool mIsANGLE;
-    bool mHasRobustness;
-
-    bool mHave_EGL_KHR_image_base;
-    bool mHave_EGL_KHR_image_pixmap;
-    bool mHave_EGL_KHR_gl_texture_2D_image;
-    bool mHave_EGL_KHR_lock_surface;
-    bool mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle;
-} sEGLLibrary;
-
 class GLContextEGL : public GLContext
 {
     friend class TextureImageEGL;
 
     static already_AddRefed<GLContextEGL>
     CreateGLContext(const ContextFormat& format,
                     EGLSurface surface,
                     EGLConfig config,
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -46,16 +46,17 @@
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
 #include "mozilla/X11Util.h"
 
 #include "prenv.h"
 #include "GLContextProvider.h"
+#include "GLLibraryLoader.h"
 #include "nsDebug.h"
 #include "nsIWidget.h"
 #include "GLXLibrary.h"
 #include "gfxXlibSurface.h"
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
 #include "gfxPlatform.h"
 #include "GLContext.h"
@@ -115,85 +116,85 @@ GLXLibrary::EnsureInitialized()
         }
         reporter.SetSuccessful();
     }
 
     if (PR_GetEnv("MOZ_GLX_DEBUG")) {
         mDebug = true;
     }
 
-    LibrarySymbolLoader::SymLoadStruct symbols[] = {
+    GLLibraryLoader::SymLoadStruct symbols[] = {
         /* functions that were in GLX 1.0 */
         { (PRFuncPtr*) &xDestroyContextInternal, { "glXDestroyContext", NULL } },
         { (PRFuncPtr*) &xMakeCurrentInternal, { "glXMakeCurrent", NULL } },
         { (PRFuncPtr*) &xSwapBuffersInternal, { "glXSwapBuffers", NULL } },
         { (PRFuncPtr*) &xQueryVersionInternal, { "glXQueryVersion", NULL } },
         { (PRFuncPtr*) &xGetCurrentContextInternal, { "glXGetCurrentContext", NULL } },
         { (PRFuncPtr*) &xWaitGLInternal, { "glXWaitGL", NULL } },
         { (PRFuncPtr*) &xWaitXInternal, { "glXWaitX", NULL } },
         /* functions introduced in GLX 1.1 */
         { (PRFuncPtr*) &xQueryExtensionsStringInternal, { "glXQueryExtensionsString", NULL } },
         { (PRFuncPtr*) &xGetClientStringInternal, { "glXGetClientString", NULL } },
         { (PRFuncPtr*) &xQueryServerStringInternal, { "glXQueryServerString", NULL } },
         { NULL, { NULL } }
     };
 
-    LibrarySymbolLoader::SymLoadStruct symbols13[] = {
+    GLLibraryLoader::SymLoadStruct symbols13[] = {
         /* functions introduced in GLX 1.3 */
         { (PRFuncPtr*) &xChooseFBConfigInternal, { "glXChooseFBConfig", NULL } },
         { (PRFuncPtr*) &xGetFBConfigAttribInternal, { "glXGetFBConfigAttrib", NULL } },
         // WARNING: xGetFBConfigs not set in symbols13_ext
         { (PRFuncPtr*) &xGetFBConfigsInternal, { "glXGetFBConfigs", NULL } },
         { (PRFuncPtr*) &xGetVisualFromFBConfigInternal, { "glXGetVisualFromFBConfig", NULL } },
         // WARNING: symbols13_ext sets xCreateGLXPixmapWithConfig instead
         { (PRFuncPtr*) &xCreatePixmapInternal, { "glXCreatePixmap", NULL } },
         { (PRFuncPtr*) &xDestroyPixmapInternal, { "glXDestroyPixmap", NULL } },
         { (PRFuncPtr*) &xCreateNewContextInternal, { "glXCreateNewContext", NULL } },
         { NULL, { NULL } }
     };
 
-    LibrarySymbolLoader::SymLoadStruct symbols13_ext[] = {
+    GLLibraryLoader::SymLoadStruct symbols13_ext[] = {
         /* extension equivalents for functions introduced in GLX 1.3 */
         // GLX_SGIX_fbconfig extension
         { (PRFuncPtr*) &xChooseFBConfigInternal, { "glXChooseFBConfigSGIX", NULL } },
         { (PRFuncPtr*) &xGetFBConfigAttribInternal, { "glXGetFBConfigAttribSGIX", NULL } },
         // WARNING: no xGetFBConfigs equivalent in extensions
         { (PRFuncPtr*) &xGetVisualFromFBConfigInternal, { "glXGetVisualFromFBConfig", NULL } },
         // WARNING: different from symbols13:
         { (PRFuncPtr*) &xCreateGLXPixmapWithConfigInternal, { "glXCreateGLXPixmapWithConfigSGIX", NULL } },
         { (PRFuncPtr*) &xDestroyPixmapInternal, { "glXDestroyGLXPixmap", NULL } }, // not from ext
         { (PRFuncPtr*) &xCreateNewContextInternal, { "glXCreateContextWithConfigSGIX", NULL } },
         { NULL, { NULL } }
     };
 
-    LibrarySymbolLoader::SymLoadStruct symbols14[] = {
+    GLLibraryLoader::SymLoadStruct symbols14[] = {
         /* functions introduced in GLX 1.4 */
         { (PRFuncPtr*) &xGetProcAddressInternal, { "glXGetProcAddress", NULL } },
         { NULL, { NULL } }
     };
 
-    LibrarySymbolLoader::SymLoadStruct symbols14_ext[] = {
+    GLLibraryLoader::SymLoadStruct symbols14_ext[] = {
         /* extension equivalents for functions introduced in GLX 1.4 */
         // GLX_ARB_get_proc_address extension
         { (PRFuncPtr*) &xGetProcAddressInternal, { "glXGetProcAddressARB", NULL } },
         { NULL, { NULL } }
     };
 
-    LibrarySymbolLoader::SymLoadStruct symbols_texturefrompixmap[] = {
+    GLLibraryLoader::SymLoadStruct symbols_texturefrompixmap[] = {
         { (PRFuncPtr*) &xBindTexImageInternal, { "glXBindTexImageEXT", NULL } },
         { (PRFuncPtr*) &xReleaseTexImageInternal, { "glXReleaseTexImageEXT", NULL } },
         { NULL, { NULL } }
     };
 
-    LibrarySymbolLoader::SymLoadStruct symbols_robustness[] = {
+    GLLibraryLoader::SymLoadStruct symbols_robustness[] = {
         { (PRFuncPtr*) &xCreateContextAttribsInternal, { "glXCreateContextAttribsARB", NULL } },
         { NULL, { NULL } }
     };
 
-    if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
+    if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
         NS_WARNING("Couldn't find required entry point in OpenGL shared library");
         return false;
     }
 
     Display *display = DefaultXDisplay();
 
     int screen = DefaultScreen(display);
     const char *serverVendor = NULL;
@@ -210,59 +211,59 @@ GLXLibrary::EnsureInitialized()
     serverVersionStr = xQueryServerString(display, screen, GLX_VERSION);
 
     if (!GLXVersionCheck(1, 1))
         // Not possible to query for extensions.
         return false;
 
     extensionsStr = xQueryExtensionsString(display, screen);
 
-    LibrarySymbolLoader::SymLoadStruct *sym13;
+    GLLibraryLoader::SymLoadStruct *sym13;
     if (!GLXVersionCheck(1, 3)) {
         // Even if we don't have 1.3, we might have equivalent extensions
         // (as on the Intel X server).
         if (!HasExtension(extensionsStr, "GLX_SGIX_fbconfig")) {
             return false;
         }
         sym13 = symbols13_ext;
     } else {
         sym13 = symbols13;
     }
-    if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, sym13)) {
+    if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, sym13)) {
         NS_WARNING("Couldn't find required entry point in OpenGL shared library");
         return false;
     }
 
-    LibrarySymbolLoader::SymLoadStruct *sym14;
+    GLLibraryLoader::SymLoadStruct *sym14;
     if (!GLXVersionCheck(1, 4)) {
         // Even if we don't have 1.4, we might have equivalent extensions
         // (as on the Intel X server).
         if (!HasExtension(extensionsStr, "GLX_ARB_get_proc_address")) {
             return false;
         }
         sym14 = symbols14_ext;
     } else {
         sym14 = symbols14;
     }
-    if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, sym14)) {
+    if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, sym14)) {
         NS_WARNING("Couldn't find required entry point in OpenGL shared library");
         return false;
     }
 
     if (HasExtension(extensionsStr, "GLX_EXT_texture_from_pixmap") &&
-        LibrarySymbolLoader::LoadSymbols(mOGLLibrary, symbols_texturefrompixmap, 
-                                         (LibrarySymbolLoader::PlatformLookupFunction)&xGetProcAddress))
+        GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_texturefrompixmap, 
+                                         (GLLibraryLoader::PlatformLookupFunction)&xGetProcAddress))
     {
         mHasTextureFromPixmap = true;
     } else {
         NS_WARNING("Texture from pixmap disabled");
     }
 
     if (HasExtension(extensionsStr, "GLX_ARB_create_context_robustness") &&
-        LibrarySymbolLoader::LoadSymbols(mOGLLibrary, symbols_robustness)) {
+        GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_robustness)) {
         mHasRobustness = true;
     }
 
     gIsATI = serverVendor && DoesStringMatch(serverVendor, "ATI");
     gIsChromium = (serverVendor &&
                    DoesStringMatch(serverVendor, "Chromium")) ||
         (serverVersionStr &&
          DoesStringMatch(serverVersionStr, "Chromium"));
--- a/gfx/gl/GLContextProviderOSMesa.cpp
+++ b/gfx/gl/GLContextProviderOSMesa.cpp
@@ -32,16 +32,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "GLContextProvider.h"
 #include "GLContext.h"
+#include "GLLibraryLoader.h"
 #include "nsDebug.h"
 #include "nsString.h"
 #include "nsIWidget.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsIConsoleService.h"
 #include "mozilla/Preferences.h"
 #include "gfxASurface.h"
@@ -113,28 +114,28 @@ OSMesaLibrary::EnsureInitialized()
 
     mOSMesaLibrary = PR_LoadLibrary(osmesalib.get());
 
     if (!mOSMesaLibrary) {
         LogMessage("Couldn't open OSMesa lib for software rendering -- webgl.osmesalib path is incorrect, or not a valid shared library");
         return false;
     }
 
-    LibrarySymbolLoader::SymLoadStruct symbols[] = {
+    GLLibraryLoader::SymLoadStruct symbols[] = {
         { (PRFuncPtr*) &fCreateContextExt, { "OSMesaCreateContextExt", NULL } },
         { (PRFuncPtr*) &fMakeCurrent, { "OSMesaMakeCurrent", NULL } },
         { (PRFuncPtr*) &fPixelStore, { "OSMesaPixelStore", NULL } },
         { (PRFuncPtr*) &fDestroyContext, { "OSMesaDestroyContext", NULL } },
         { (PRFuncPtr*) &fGetCurrentContext, { "OSMesaGetCurrentContext", NULL } },
         { (PRFuncPtr*) &fMakeCurrent, { "OSMesaMakeCurrent", NULL } },
         { (PRFuncPtr*) &fGetProcAddress, { "OSMesaGetProcAddress", NULL } },
         { NULL, { NULL } }
     };
 
-    if (!LibrarySymbolLoader::LoadSymbols(mOSMesaLibrary, &symbols[0])) {
+    if (!GLLibraryLoader::LoadSymbols(mOSMesaLibrary, &symbols[0])) {
         LogMessage("Couldn't find required entry points in OSMesa libary");
         return false;
     }
 
     mInitialized = true;
     return true;
 }
 
--- a/gfx/gl/GLContextProviderWGL.cpp
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -31,16 +31,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "GLContextProvider.h"
 #include "GLContext.h"
+#include "GLLibraryLoader.h"
 #include "nsDebug.h"
 #include "nsIWidget.h"
 #include "WGLLibrary.h"
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
 #include "gfxPlatform.h"
 #include "gfxWindowsSurface.h"
 
@@ -142,28 +143,28 @@ WGLLibrary::EnsureInitialized()
         if (!mOGLLibrary) {
             NS_WARNING("Couldn't load OpenGL DLL.");
             return false;
         }
     }
 
     gUseDoubleBufferedWindows = PR_GetEnv("MOZ_WGL_DB") != nsnull;
 
-    LibrarySymbolLoader::SymLoadStruct earlySymbols[] = {
+    GLLibraryLoader::SymLoadStruct earlySymbols[] = {
         { (PRFuncPtr*) &fCreateContext, { "wglCreateContext", NULL } },
         { (PRFuncPtr*) &fMakeCurrent, { "wglMakeCurrent", NULL } },
         { (PRFuncPtr*) &fGetProcAddress, { "wglGetProcAddress", NULL } },
         { (PRFuncPtr*) &fDeleteContext, { "wglDeleteContext", NULL } },
         { (PRFuncPtr*) &fGetCurrentContext, { "wglGetCurrentContext", NULL } },
         { (PRFuncPtr*) &fGetCurrentDC, { "wglGetCurrentDC", NULL } },
         { (PRFuncPtr*) &fShareLists, { "wglShareLists", NULL } },
         { NULL, { NULL } }
     };
 
-    if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &earlySymbols[0])) {
+    if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &earlySymbols[0])) {
         NS_WARNING("Couldn't find required entry points in OpenGL DLL (early init)");
         return false;
     }
 
     // This is ridiculous -- we have to actually create a context to
     // get the OpenGL ICD to load.
     gSharedWindow = CreateDummyWindow(&gSharedWindowDC);
     NS_ENSURE_TRUE(gSharedWindow, false);
@@ -178,61 +179,61 @@ WGLLibrary::EnsureInitialized()
     if (!fMakeCurrent((HDC)gSharedWindowDC, (HGLRC)gSharedWindowGLContext)) {
         NS_WARNING("wglMakeCurrent failed");
         return false;
     }
 
     // Now we can grab all the other symbols that we couldn't without having
     // a context current.
 
-    LibrarySymbolLoader::SymLoadStruct pbufferSymbols[] = {
+    GLLibraryLoader::SymLoadStruct pbufferSymbols[] = {
         { (PRFuncPtr*) &fCreatePbuffer, { "wglCreatePbufferARB", "wglCreatePbufferEXT", NULL } },
         { (PRFuncPtr*) &fDestroyPbuffer, { "wglDestroyPbufferARB", "wglDestroyPbufferEXT", NULL } },
         { (PRFuncPtr*) &fGetPbufferDC, { "wglGetPbufferDCARB", "wglGetPbufferDCEXT", NULL } },
         { (PRFuncPtr*) &fBindTexImage, { "wglBindTexImageARB", "wglBindTexImageEXT", NULL } },
         { (PRFuncPtr*) &fReleaseTexImage, { "wglReleaseTexImageARB", "wglReleaseTexImageEXT", NULL } },
         { NULL, { NULL } }
     };
 
-    LibrarySymbolLoader::SymLoadStruct pixFmtSymbols[] = {
+    GLLibraryLoader::SymLoadStruct pixFmtSymbols[] = {
         { (PRFuncPtr*) &fChoosePixelFormat, { "wglChoosePixelFormatARB", "wglChoosePixelFormatEXT", NULL } },
         { (PRFuncPtr*) &fGetPixelFormatAttribiv, { "wglGetPixelFormatAttribivARB", "wglGetPixelFormatAttribivEXT", NULL } },
         { NULL, { NULL } }
     };
 
-    if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &pbufferSymbols[0],
-         (LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress))
+    if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &pbufferSymbols[0],
+         (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress))
     {
         // this isn't an error, just means that pbuffers aren't supported
         fCreatePbuffer = nsnull;
     }
 
-    if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &pixFmtSymbols[0],
-         (LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress))
+    if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &pixFmtSymbols[0],
+         (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress))
     {
         // this isn't an error, just means that we don't have the pixel format extension
         fChoosePixelFormat = nsnull;
     }
 
-    LibrarySymbolLoader::SymLoadStruct extensionsSymbols[] = {
+    GLLibraryLoader::SymLoadStruct extensionsSymbols[] = {
         { (PRFuncPtr *) &fGetExtensionsString, { "wglGetExtensionsStringARB", NULL} },
         { NULL, { NULL } }
     };
 
-    LibrarySymbolLoader::SymLoadStruct robustnessSymbols[] = {
+    GLLibraryLoader::SymLoadStruct robustnessSymbols[] = {
         { (PRFuncPtr *) &fCreateContextAttribs, { "wglCreateContextAttribsARB", NULL} },
         { NULL, { NULL } }
     };
 
-    if (LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &extensionsSymbols[0],
-        (LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress)) {
+    if (GLLibraryLoader::LoadSymbols(mOGLLibrary, &extensionsSymbols[0],
+        (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress)) {
         const char *wglExts = fGetExtensionsString(gSharedWindowDC);
         if (wglExts && HasExtension(wglExts, "WGL_ARB_create_context")) {
-            LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &robustnessSymbols[0],
-            (LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress);
+            GLLibraryLoader::LoadSymbols(mOGLLibrary, &robustnessSymbols[0],
+            (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress);
             if (HasExtension(wglExts, "WGL_ARB_create_context_robustness")) {
                 mHasRobustness = true;
             }
         }
     }
 
     // reset back to the previous context, just in case
     fMakeCurrent(curDC, curCtx);
--- a/gfx/gl/GLDefs.h
+++ b/gfx/gl/GLDefs.h
@@ -65,28 +65,28 @@ typedef double GLclampd;
 typedef void GLvoid;
 
 typedef char GLchar;
 #ifndef __gl2_h_
 typedef ptrdiff_t GLsizeiptr;
 typedef ptrdiff_t GLintptr;
 #endif
 
+#endif /* #if !defined(__gltypes_h_) && !defined(__gl_h_) */
+
 #ifndef GLAPIENTRY
 # ifdef WIN32
 #  define GLAPIENTRY APIENTRY
 #  define GLAPI
 # else
 #  define GLAPIENTRY
 #  define GLAPI
 # endif
 #endif
 
-#endif /* #if !defined(__gltypes_h_) && !defined(__gl_h_) */
-
 #define LOCAL_GL_VERSION_1_1 1
 #define LOCAL_GL_ACCUM 0x0100
 #define LOCAL_GL_LOAD 0x0101
 #define LOCAL_GL_RETURN 0x0102
 #define LOCAL_GL_MULT 0x0103
 #define LOCAL_GL_ADD 0x0104
 #define LOCAL_GL_NEVER 0x0200
 #define LOCAL_GL_LESS 0x0201
new file mode 100644
--- /dev/null
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -0,0 +1,371 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLLibraryEGL.h"
+
+#include "gfxCrashReporterUtils.h"
+#include "mozilla/Preferences.h"
+
+// We only need to explicitly dlopen egltrace
+// on android as we can use LD_PRELOAD or other tricks
+// on other platforms. We look for it in /data/local
+// as that's writeable by all users
+#define APITRACE_LIB "/data/local/egltrace.so"
+
+#define EGL_LIB "libEGL.so"
+#define EGL_LIB1 "libEGL.so.1"
+
+#if defined(XP_WIN)
+
+#define EGL_LIB "libEGL.dll"
+
+#endif
+
+namespace mozilla {
+namespace gl {
+
+#ifdef DEBUG
+#undef BEFORE_GL_CALL
+#undef AFTER_GL_CALL
+
+#define BEFORE_GL_CALL do {          \
+    BeforeGLCall(MOZ_FUNCTION_NAME); \
+} while (0)
+
+#define AFTER_GL_CALL do {           \
+    AfterGLCall(MOZ_FUNCTION_NAME);  \
+} while (0)
+
+static void BeforeGLCall(const char* glFunction)
+{
+    if (GLContext::DebugMode()) {
+        if (GLContext::DebugMode() & GLContext::DebugTrace)
+            printf_stderr("[egl] > %s\n", glFunction);
+    }
+}
+
+static void AfterGLCall(const char* glFunction)
+{
+    if (GLContext::DebugMode() & GLContext::DebugTrace) {
+        printf_stderr("[egl] < %s\n", glFunction);
+    }
+}
+
+// We rely on the fact that GLContext.h #defines BEFORE_GL_CALL and
+// AFTER_GL_CALL to nothing if !defined(DEBUG).
+#endif
+
+static PRLibrary* LoadApitraceLibrary()
+{
+    static PRLibrary* sApitraceLibrary = NULL;
+
+    if (sApitraceLibrary)
+        return sApitraceLibrary;
+
+#if defined(ANDROID)
+    nsCString logFile = Preferences::GetCString("gfx.apitrace.logfile");
+
+    if (logFile.IsEmpty()) {
+        logFile = "firefox.trace";
+    }
+
+    // The firefox process can't write to /data/local, but it can write
+    // to $GRE_HOME/
+    nsCAutoString logPath;
+    logPath.AppendPrintf("%s/%s", getenv("GRE_HOME"), logFile.get());
+
+    // apitrace uses the TRACE_FILE environment variable to determine where
+    // to log trace output to
+    printf_stderr("Logging GL tracing output to %s", logPath.get());
+    setenv("TRACE_FILE", logPath.get(), false);
+
+    printf_stderr("Attempting load of %s\n", APITRACE_LIB);
+
+    sApitraceLibrary = PR_LoadLibrary(APITRACE_LIB);
+#endif
+
+    return sApitraceLibrary;
+}
+
+bool
+GLLibraryEGL::EnsureInitialized()
+{
+    if (mInitialized) {
+        return true;
+    }
+
+    mozilla::ScopedGfxFeatureReporter reporter("EGL");
+
+#ifdef XP_WIN
+    // Allow for explicitly specifying the location of libEGL.dll and
+    // libGLESv2.dll.
+    do {
+        nsCOMPtr<nsILocalFile> eglFile, glesv2File;
+        nsresult rv = Preferences::GetComplex("gfx.angle.egl.path",
+                                              NS_GET_IID(nsILocalFile),
+                                              getter_AddRefs(eglFile));
+        if (NS_FAILED(rv) || !eglFile)
+            break;
+
+        nsCAutoString s;
+
+        // note that we have to load the libs in this order, because libEGL.dll
+        // depends on libGLESv2.dll, but is not/may not be in our search path.
+        nsCOMPtr<nsIFile> f;
+        eglFile->Clone(getter_AddRefs(f));
+        glesv2File = do_QueryInterface(f);
+        if (!glesv2File)
+            break;
+
+        glesv2File->Append(NS_LITERAL_STRING("libGLESv2.dll"));
+
+        PRLibrary *glesv2lib = nsnull; // this will be leaked on purpose
+        glesv2File->Load(&glesv2lib);
+        if (!glesv2lib)
+            break;
+
+        eglFile->Append(NS_LITERAL_STRING("libEGL.dll"));
+        eglFile->Load(&mEGLLibrary);
+    } while (false);
+#endif
+
+    if (!mEGLLibrary) {
+        mEGLLibrary = LoadApitraceLibrary();
+
+        if (!mEGLLibrary) {
+            printf_stderr("Attempting load of %s\n", EGL_LIB);
+            mEGLLibrary = PR_LoadLibrary(EGL_LIB);
+#if defined(XP_UNIX)
+            if (!mEGLLibrary) {
+                mEGLLibrary = PR_LoadLibrary(EGL_LIB1);
+            }
+#endif
+        }
+    }
+
+    if (!mEGLLibrary) {
+        NS_WARNING("Couldn't load EGL LIB.");
+        return false;
+    }
+
+#define SYMBOL(name) \
+{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, NULL } }
+
+    GLLibraryLoader::SymLoadStruct earlySymbols[] = {
+        SYMBOL(GetDisplay),
+        SYMBOL(GetCurrentSurface),
+        SYMBOL(GetCurrentContext),
+        SYMBOL(MakeCurrent),
+        SYMBOL(DestroyContext),
+        SYMBOL(CreateContext),
+        SYMBOL(DestroySurface),
+        SYMBOL(CreateWindowSurface),
+        SYMBOL(CreatePbufferSurface),
+        SYMBOL(CreatePixmapSurface),
+        SYMBOL(BindAPI),
+        SYMBOL(Initialize),
+        SYMBOL(ChooseConfig),
+        SYMBOL(GetError),
+        SYMBOL(GetConfigs),
+        SYMBOL(GetConfigAttrib),
+        SYMBOL(WaitNative),
+        SYMBOL(GetProcAddress),
+        SYMBOL(SwapBuffers),
+        SYMBOL(CopyBuffers),
+        SYMBOL(QueryString),
+        SYMBOL(QueryContext),
+        SYMBOL(BindTexImage),
+        SYMBOL(ReleaseTexImage),
+        SYMBOL(QuerySurface),
+#ifdef MOZ_WIDGET_GONK
+        SYMBOL(SetSwapRectangleANDROID),
+#endif
+        { NULL, { NULL } }
+    };
+
+    if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
+        NS_WARNING("Couldn't find required entry points in EGL library (early init)");
+        return false;
+    }
+
+#if defined(MOZ_X11) && defined(MOZ_EGL_XRENDER_COMPOSITE)
+    mEGLDisplay = fGetDisplay((EGLNativeDisplayType) gdk_x11_get_default_xdisplay());
+#else
+    mEGLDisplay = fGetDisplay(EGL_DEFAULT_DISPLAY);
+#endif
+    if (!fInitialize(mEGLDisplay, NULL, NULL))
+        return false;
+
+    const char *vendor = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
+    if (vendor && (strstr(vendor, "TransGaming") != 0 || strstr(vendor, "Google Inc.") != 0)) {
+        mIsANGLE = true;
+    }
+    
+    const char *extensions = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS);
+    if (!extensions)
+        extensions = "";
+
+    printf_stderr("Extensions: %s 0x%02x\n", extensions, extensions[0]);
+    printf_stderr("Extensions length: %d\n", strlen(extensions));
+
+    // note the extra space -- this ugliness tries to match
+    // EGL_KHR_image in the middle of the string, or right at the
+    // end.  It's a prefix for other extensions, so we have to do
+    // this...
+    bool hasKHRImage = false;
+    if (strstr(extensions, "EGL_KHR_image ") ||
+        (strlen(extensions) >= strlen("EGL_KHR_image") &&
+         strcmp(extensions+(strlen(extensions)-strlen("EGL_KHR_image")), "EGL_KHR_image")))
+    {
+        hasKHRImage = true;
+    }
+
+    if (strstr(extensions, "EGL_KHR_image_base")) {
+        mHave_EGL_KHR_image_base = true;
+    }
+        
+    if (strstr(extensions, "EGL_KHR_image_pixmap")) {
+        mHave_EGL_KHR_image_pixmap = true;
+        
+    }
+
+    if (strstr(extensions, "EGL_KHR_gl_texture_2D_image")) {
+        mHave_EGL_KHR_gl_texture_2D_image = true;
+    }
+
+    if (strstr(extensions, "EGL_KHR_lock_surface")) {
+        mHave_EGL_KHR_lock_surface = true;
+    }
+
+    if (hasKHRImage) {
+        GLLibraryLoader::SymLoadStruct khrSymbols[] = {
+            { (PRFuncPtr*) &mSymbols.fCreateImageKHR, { "eglCreateImageKHR", NULL } },
+            { (PRFuncPtr*) &mSymbols.fDestroyImageKHR, { "eglDestroyImageKHR", NULL } },
+            { (PRFuncPtr*) &mSymbols.fImageTargetTexture2DOES, { "glEGLImageTargetTexture2DOES", NULL } },
+            { NULL, { NULL } }
+        };
+
+        GLLibraryLoader::LoadSymbols(mEGLLibrary, &khrSymbols[0],
+                                         (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
+    }
+
+    if (mHave_EGL_KHR_lock_surface) {
+        GLLibraryLoader::SymLoadStruct lockSymbols[] = {
+            { (PRFuncPtr*) &mSymbols.fLockSurfaceKHR, { "eglLockSurfaceKHR", NULL } },
+            { (PRFuncPtr*) &mSymbols.fUnlockSurfaceKHR, { "eglUnlockSurfaceKHR", NULL } },
+            { NULL, { NULL } }
+        };
+
+        GLLibraryLoader::LoadSymbols(mEGLLibrary, &lockSymbols[0],
+                                         (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
+        if (!mSymbols.fLockSurfaceKHR) {
+            mHave_EGL_KHR_lock_surface = false;
+        }
+    }
+
+    if (!mSymbols.fCreateImageKHR) {
+        mHave_EGL_KHR_image_base = false;
+        mHave_EGL_KHR_image_pixmap = false;
+        mHave_EGL_KHR_gl_texture_2D_image = false;
+    }
+
+    if (!mSymbols.fImageTargetTexture2DOES) {
+        mHave_EGL_KHR_gl_texture_2D_image = false;
+    }
+
+    if (strstr(extensions, "EGL_ANGLE_surface_d3d_texture_2d_share_handle")) {
+        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
+            { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", NULL } },
+            { NULL, { NULL } }
+        };
+
+        GLLibraryLoader::LoadSymbols(mEGLLibrary, &d3dSymbols[0],
+                                         (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
+        if (mSymbols.fQuerySurfacePointerANGLE) {
+            mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle = true;
+        }
+    }
+
+    if (strstr(extensions, "EGL_EXT_create_context_robustness")) {
+        mHasRobustness = true;
+    }
+
+    mInitialized = true;
+    reporter.SetSuccessful();
+    return true;
+}
+
+void
+GLLibraryEGL::DumpEGLConfig(EGLConfig cfg)
+{
+    int attrval;
+    int err;
+
+#define ATTR(_x) do {                                                   \
+        fGetConfigAttrib(mEGLDisplay, cfg, LOCAL_EGL_##_x, &attrval);  \
+        if ((err = fGetError()) != 0x3000) {                        \
+            printf_stderr("  %s: ERROR (0x%04x)\n", #_x, err);        \
+        } else {                                                    \
+            printf_stderr("  %s: %d (0x%04x)\n", #_x, attrval, attrval); \
+        }                                                           \
+    } while(0)
+
+    printf_stderr("EGL Config: %d [%p]\n", (int)(intptr_t)cfg, cfg);
+
+    ATTR(BUFFER_SIZE);
+    ATTR(ALPHA_SIZE);
+    ATTR(BLUE_SIZE);
+    ATTR(GREEN_SIZE);
+    ATTR(RED_SIZE);
+    ATTR(DEPTH_SIZE);
+    ATTR(STENCIL_SIZE);
+    ATTR(CONFIG_CAVEAT);
+    ATTR(CONFIG_ID);
+    ATTR(LEVEL);
+    ATTR(MAX_PBUFFER_HEIGHT);
+    ATTR(MAX_PBUFFER_PIXELS);
+    ATTR(MAX_PBUFFER_WIDTH);
+    ATTR(NATIVE_RENDERABLE);
+    ATTR(NATIVE_VISUAL_ID);
+    ATTR(NATIVE_VISUAL_TYPE);
+    ATTR(PRESERVED_RESOURCES);
+    ATTR(SAMPLES);
+    ATTR(SAMPLE_BUFFERS);
+    ATTR(SURFACE_TYPE);
+    ATTR(TRANSPARENT_TYPE);
+    ATTR(TRANSPARENT_RED_VALUE);
+    ATTR(TRANSPARENT_GREEN_VALUE);
+    ATTR(TRANSPARENT_BLUE_VALUE);
+    ATTR(BIND_TO_TEXTURE_RGB);
+    ATTR(BIND_TO_TEXTURE_RGBA);
+    ATTR(MIN_SWAP_INTERVAL);
+    ATTR(MAX_SWAP_INTERVAL);
+    ATTR(LUMINANCE_SIZE);
+    ATTR(ALPHA_MASK_SIZE);
+    ATTR(COLOR_BUFFER_TYPE);
+    ATTR(RENDERABLE_TYPE);
+    ATTR(CONFORMANT);
+
+#undef ATTR
+}
+
+void
+GLLibraryEGL::DumpEGLConfigs()
+{
+    int nc = 0;
+    fGetConfigs(mEGLDisplay, NULL, 0, &nc);
+    EGLConfig *ec = new EGLConfig[nc];
+    fGetConfigs(mEGLDisplay, ec, nc, &nc);
+
+    for (int i = 0; i < nc; ++i) {
+        printf_stderr ("========= EGL Config %d ========\n", i);
+        DumpEGLConfig(ec[i]);
+    }
+
+    delete [] ec;
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
+
new file mode 100644
--- /dev/null
+++ b/gfx/gl/GLLibraryEGL.h
@@ -0,0 +1,470 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLLIBRARYEGL_H_
+#define GLLIBRARYEGL_H_
+
+#include "GLContext.h"
+#include "GLLibraryLoader.h"
+
+#include "nsILocalFile.h"
+
+typedef int EGLint;
+typedef unsigned int EGLBoolean;
+typedef unsigned int EGLenum;
+typedef void *EGLConfig;
+typedef void *EGLContext;
+typedef void *EGLDisplay;
+typedef void *EGLSurface;
+typedef void *EGLClientBuffer;
+typedef void *EGLCastToRelevantPtr;
+typedef void *EGLImageKHR;
+typedef void *GLeglImageOES;
+
+#ifdef ANDROID
+
+typedef void *EGLNativeDisplayType;
+typedef void *EGLNativePixmapType;
+typedef void *EGLNativeWindowType;
+
+#elif defined(XP_WIN)
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+
+#include <windows.h>
+
+typedef HDC EGLNativeDisplayType;
+typedef HBITMAP EGLNativePixmapType;
+typedef HWND EGLNativeWindowType;
+
+#define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
+
+#endif
+
+#ifdef MOZ_WIDGET_QT
+#define EGL_DEFAULT_DISPLAY  ((EGLNativeDisplayType)QX11Info::display())
+#else
+#define EGL_DEFAULT_DISPLAY  ((EGLNativeDisplayType)0)
+#endif
+#define EGL_NO_CONTEXT       ((EGLContext)0)
+#define EGL_NO_DISPLAY       ((EGLDisplay)0)
+#define EGL_NO_SURFACE       ((EGLSurface)0)
+
+#define EGL_DISPLAY()        sEGLLibrary.Display()
+
+namespace mozilla {
+namespace gl {
+
+class GLLibraryEGL
+{
+public:
+    GLLibraryEGL() 
+        : mInitialized(false),
+          mEGLLibrary(nsnull),
+          mHasRobustness(false),
+          mIsANGLE(false),
+          mHave_EGL_KHR_image_base(false),
+          mHave_EGL_KHR_image_pixmap(false),
+          mHave_EGL_KHR_gl_texture_2D_image(false),
+          mHave_EGL_KHR_lock_surface(false),
+          mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle(false)
+    {
+    }
+
+    EGLDisplay fGetDisplay(void* display_id)
+    {
+        BEFORE_GL_CALL;
+        EGLDisplay disp = mSymbols.fGetDisplay(display_id);
+        AFTER_GL_CALL;
+        return disp;
+    }
+
+    EGLSurface fGetCurrentSurface(EGLint id)
+    {
+        BEFORE_GL_CALL;
+        EGLSurface surf = mSymbols.fGetCurrentSurface(id);
+        AFTER_GL_CALL;
+        return surf;
+    }
+
+    EGLContext fGetCurrentContext()
+    {
+        BEFORE_GL_CALL;
+        EGLContext context = mSymbols.fGetCurrentContext();
+        AFTER_GL_CALL;
+        return context;
+    }
+
+    EGLBoolean fMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fMakeCurrent(dpy, draw, read, ctx);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLBoolean fDestroyContext(EGLDisplay dpy, EGLContext ctx)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fDestroyContext(dpy, ctx);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLContext fCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+    {
+        BEFORE_GL_CALL;
+        EGLContext ctx = mSymbols.fCreateContext(dpy, config, share_context, attrib_list);
+        AFTER_GL_CALL;
+        return ctx;
+    }
+
+    EGLBoolean fDestroySurface(EGLDisplay dpy, EGLSurface surface)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fDestroySurface(dpy, surface);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLSurface fCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
+    {
+        BEFORE_GL_CALL;
+        EGLSurface surf = mSymbols.fCreateWindowSurface(dpy, config, win, attrib_list);
+        AFTER_GL_CALL;
+        return surf;
+    }
+
+    EGLSurface fCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+    {
+        BEFORE_GL_CALL;
+        EGLSurface surf = mSymbols.fCreatePbufferSurface(dpy, config, attrib_list);
+        AFTER_GL_CALL;
+        return surf;
+    }
+
+    EGLSurface fCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+    {
+        BEFORE_GL_CALL;
+        EGLSurface surf = mSymbols.fCreatePixmapSurface(dpy, config, pixmap, attrib_list);
+        AFTER_GL_CALL;
+        return surf;
+    }
+
+    EGLBoolean fBindAPI(EGLenum api)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fBindAPI(api);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLBoolean fInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fInitialize(dpy, major, minor);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLBoolean fChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fChooseConfig(dpy, attrib_list, configs, config_size, num_config);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLint fGetError()
+    {
+        BEFORE_GL_CALL;
+        EGLint i = mSymbols.fGetError();
+        AFTER_GL_CALL;
+        return i;
+    }
+
+    EGLBoolean fGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fGetConfigAttrib(dpy, config, attribute, value);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLBoolean fGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fGetConfigs(dpy, configs, config_size, num_config);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLBoolean fWaitNative(EGLint engine)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fWaitNative(engine);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLCastToRelevantPtr fGetProcAddress(const char *procname)
+    {
+        BEFORE_GL_CALL;
+        EGLCastToRelevantPtr p = mSymbols.fGetProcAddress(procname);
+        AFTER_GL_CALL;
+        return p;
+    }
+
+    EGLBoolean fSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fSwapBuffers(dpy, surface);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLBoolean fCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fCopyBuffers(dpy, surface, target);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    const GLubyte* fQueryString(EGLDisplay dpy, EGLint name)
+    {
+        BEFORE_GL_CALL;
+        const GLubyte* b = mSymbols.fQueryString(dpy, name);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLBoolean fQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fQueryContext(dpy, ctx, attribute, value);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLBoolean fBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fBindTexImage(dpy, surface, buffer);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLBoolean fReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fReleaseTexImage(dpy, surface, buffer);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLImageKHR fCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+    {
+         BEFORE_GL_CALL;
+         EGLImageKHR i = mSymbols.fCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
+         AFTER_GL_CALL;
+         return i;
+    }
+
+    EGLBoolean fDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fDestroyImageKHR(dpy, image);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+#ifdef MOZ_WIDGET_GONK
+    EGLBoolean fSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface surface, EGLint left, EGLint top, EGLint width, EGLint height)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fSetSwapRectangleANDROID(dpy, surface, left, top, width, height);
+        AFTER_GL_CALL;
+        return b;
+    }
+#endif
+
+    // New extension which allow us to lock texture and get raw image pointer
+    EGLBoolean fLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fLockSurfaceKHR(dpy, surface, attrib_list);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLBoolean fUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fUnlockSurfaceKHR(dpy, surface);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLBoolean fQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fQuerySurface(dpy, surface, attribute, value);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    EGLBoolean fQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
+    {
+        BEFORE_GL_CALL;
+        EGLBoolean b = mSymbols.fQuerySurfacePointerANGLE(dpy, surface, attribute, value);
+        AFTER_GL_CALL;
+        return b;
+    }
+
+    // This is EGL specific GL ext symbol "glEGLImageTargetTexture2DOES"
+    // Lets keep it here for now.
+    void fImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+    {
+        BEFORE_GL_CALL;
+        mSymbols.fImageTargetTexture2DOES(target, image);
+        AFTER_GL_CALL;
+    }
+
+    EGLDisplay Display() {
+        return mEGLDisplay;
+    }
+
+    bool IsANGLE() {
+        return mIsANGLE;
+    }
+
+    bool HasKHRImageBase() {
+        return mHave_EGL_KHR_image_base;
+    }
+
+    bool HasKHRImagePixmap() {
+        return mHave_EGL_KHR_image_pixmap;
+    }
+
+    bool HasKHRImageTexture2D() {
+        return mHave_EGL_KHR_gl_texture_2D_image;
+    }
+
+    bool HasKHRLockSurface() {
+        return mHave_EGL_KHR_lock_surface;
+    }
+
+    bool HasANGLESurfaceD3DTexture2DShareHandle() {
+        return mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle;
+    }
+
+    bool HasRobustness() {
+        return mHasRobustness;
+    }
+
+    bool EnsureInitialized();
+
+    void DumpEGLConfig(EGLConfig cfg);
+    void DumpEGLConfigs();
+
+    struct {
+        typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void *display_id);
+        pfnGetDisplay fGetDisplay;
+        typedef EGLSurface (GLAPIENTRY * pfnGetCurrentSurface)(EGLint);
+        pfnGetCurrentSurface fGetCurrentSurface;
+        typedef EGLContext (GLAPIENTRY * pfnGetCurrentContext)(void);
+        pfnGetCurrentContext fGetCurrentContext;
+        typedef EGLBoolean (GLAPIENTRY * pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+        pfnMakeCurrent fMakeCurrent;
+        typedef EGLBoolean (GLAPIENTRY * pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx);
+        pfnDestroyContext fDestroyContext;
+        typedef EGLContext (GLAPIENTRY * pfnCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
+        pfnCreateContext fCreateContext;
+        typedef EGLBoolean (GLAPIENTRY * pfnDestroySurface)(EGLDisplay dpy, EGLSurface surface);
+        pfnDestroySurface fDestroySurface;
+        typedef EGLSurface (GLAPIENTRY * pfnCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
+        pfnCreateWindowSurface fCreateWindowSurface;
+        typedef EGLSurface (GLAPIENTRY * pfnCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+        pfnCreatePbufferSurface fCreatePbufferSurface;
+        typedef EGLSurface (GLAPIENTRY * pfnCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
+        pfnCreatePixmapSurface fCreatePixmapSurface;
+        typedef EGLBoolean (GLAPIENTRY * pfnBindAPI)(EGLenum api);
+        pfnBindAPI fBindAPI;
+        typedef EGLBoolean (GLAPIENTRY * pfnInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
+        pfnInitialize fInitialize;
+        typedef EGLBoolean (GLAPIENTRY * pfnChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+        pfnChooseConfig fChooseConfig;
+        typedef EGLint (GLAPIENTRY * pfnGetError)(void);
+        pfnGetError fGetError;
+        typedef EGLBoolean (GLAPIENTRY * pfnGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+        pfnGetConfigAttrib fGetConfigAttrib;
+        typedef EGLBoolean (GLAPIENTRY * pfnGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+        pfnGetConfigs fGetConfigs;
+        typedef EGLBoolean (GLAPIENTRY * pfnWaitNative)(EGLint engine);
+        pfnWaitNative fWaitNative;
+        typedef EGLCastToRelevantPtr (GLAPIENTRY * pfnGetProcAddress)(const char *procname);
+        pfnGetProcAddress fGetProcAddress;
+        typedef EGLBoolean (GLAPIENTRY * pfnSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
+        pfnSwapBuffers fSwapBuffers;
+        typedef EGLBoolean (GLAPIENTRY * pfnCopyBuffers)(EGLDisplay dpy, EGLSurface surface,
+                                                         EGLNativePixmapType target);
+        pfnCopyBuffers fCopyBuffers;
+        typedef const GLubyte* (GLAPIENTRY * pfnQueryString)(EGLDisplay, EGLint name);
+        pfnQueryString fQueryString;
+        typedef EGLBoolean (GLAPIENTRY * pfnQueryContext)(EGLDisplay dpy, EGLContext ctx,
+                                                          EGLint attribute, EGLint *value);
+        pfnQueryContext fQueryContext;
+        typedef EGLBoolean (GLAPIENTRY * pfnBindTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
+        pfnBindTexImage fBindTexImage;
+        typedef EGLBoolean (GLAPIENTRY * pfnReleaseTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
+        pfnReleaseTexImage fReleaseTexImage;
+        typedef EGLImageKHR (GLAPIENTRY * pfnCreateImageKHR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+        pfnCreateImageKHR fCreateImageKHR;
+        typedef EGLBoolean (GLAPIENTRY * pfnDestroyImageKHR)(EGLDisplay dpy, EGLImageKHR image);
+        pfnDestroyImageKHR fDestroyImageKHR;
+#ifdef MOZ_WIDGET_GONK
+        typedef EGLBoolean (GLAPIENTRY * pfnSetSwapRectangleANDROID)(EGLDisplay dpy, EGLSurface surface, EGLint left, EGLint top, EGLint width, EGLint height);
+        pfnSetSwapRectangleANDROID fSetSwapRectangleANDROID;
+#endif
+
+        // New extension which allow us to lock texture and get raw image pointer
+        typedef EGLBoolean (GLAPIENTRY * pfnLockSurfaceKHR)(EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
+        pfnLockSurfaceKHR fLockSurfaceKHR;
+        typedef EGLBoolean (GLAPIENTRY * pfnUnlockSurfaceKHR)(EGLDisplay dpy, EGLSurface surface);
+        pfnUnlockSurfaceKHR fUnlockSurfaceKHR;
+        typedef EGLBoolean (GLAPIENTRY * pfnQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+        pfnQuerySurface fQuerySurface;
+
+        typedef EGLBoolean (GLAPIENTRY * pfnQuerySurfacePointerANGLE)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
+        pfnQuerySurfacePointerANGLE fQuerySurfacePointerANGLE;
+
+        // This is EGL specific GL ext symbol "glEGLImageTargetTexture2DOES"
+        // Lets keep it here for now.
+        typedef void (GLAPIENTRY * pfnImageTargetTexture2DOES)(GLenum target, GLeglImageOES image);
+        pfnImageTargetTexture2DOES fImageTargetTexture2DOES;
+    } mSymbols;
+
+private:
+    bool mInitialized;
+    PRLibrary* mEGLLibrary;
+    EGLDisplay mEGLDisplay;
+
+    bool mIsANGLE;
+    bool mHasRobustness;
+
+    bool mHave_EGL_KHR_image_base;
+    bool mHave_EGL_KHR_image_pixmap;
+    bool mHave_EGL_KHR_gl_texture_2D_image;
+    bool mHave_EGL_KHR_lock_surface;
+    bool mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle;
+};
+
+} /* namespace gl */
+} /* namespace mozilla */
+
+#endif /* GLLIBRARYEGL_H_ */
+
new file mode 100644
--- /dev/null
+++ b/gfx/gl/GLLibraryLoader.cpp
@@ -0,0 +1,100 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GLLibraryLoader.h"
+
+namespace mozilla {
+namespace gl {
+
+bool
+GLLibraryLoader::OpenLibrary(const char *library)
+{
+    PRLibSpec lspec;
+    lspec.type = PR_LibSpec_Pathname;
+    lspec.value.pathname = library;
+
+    mLibrary = PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_LOCAL);
+    if (!mLibrary)
+        return false;
+
+    return true;
+}
+
+bool
+GLLibraryLoader::LoadSymbols(SymLoadStruct *firstStruct, bool tryplatform, const char *prefix)
+{
+    return LoadSymbols(mLibrary, firstStruct, tryplatform ? mLookupFunc : nsnull, prefix);
+}
+
+PRFuncPtr
+GLLibraryLoader::LookupSymbol(PRLibrary *lib,
+                                  const char *sym,
+                                  PlatformLookupFunction lookupFunction)
+{
+    PRFuncPtr res = 0;
+
+    // try finding it in the library directly, if we have one
+    if (lib) {
+        res = PR_FindFunctionSymbol(lib, sym);
+    }
+
+    // then try looking it up via the lookup symbol
+    if (!res && lookupFunction) {
+        res = lookupFunction(sym);
+    }
+
+    // finally just try finding it in the process
+    if (!res) {
+        PRLibrary *leakedLibRef;
+        res = PR_FindFunctionSymbolAndLibrary(sym, &leakedLibRef);
+    }
+
+    return res;
+}
+
+bool
+GLLibraryLoader::LoadSymbols(PRLibrary *lib,
+                                 SymLoadStruct *firstStruct,
+                                 PlatformLookupFunction lookupFunction,
+                                 const char *prefix)
+{
+    char sbuf[MAX_SYMBOL_LENGTH * 2];
+    int failCount = 0;
+
+    SymLoadStruct *ss = firstStruct;
+    while (ss->symPointer) {
+        *ss->symPointer = 0;
+
+        for (int i = 0; i < MAX_SYMBOL_NAMES; i++) {
+            if (ss->symNames[i] == nsnull)
+                break;
+
+            const char *s = ss->symNames[i];
+            if (prefix && *prefix != 0) {
+                strcpy(sbuf, prefix);
+                strcat(sbuf, ss->symNames[i]);
+                s = sbuf;
+            }
+
+            PRFuncPtr p = LookupSymbol(lib, s, lookupFunction);
+            if (p) {
+                *ss->symPointer = p;
+                break;
+            }
+        }
+
+        if (*ss->symPointer == 0) {
+            fprintf (stderr, "Can't find symbol '%s'\n", ss->symNames[0]);
+            failCount++;
+        }
+
+        ss++;
+    }
+
+    return failCount == 0 ? true : false;
+}
+
+} /* namespace gl */
+} /* namespace mozilla */
+
new file mode 100644
--- /dev/null
+++ b/gfx/gl/GLLibraryLoader.h
@@ -0,0 +1,66 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GLLIBRARYLOADER_H_
+#define GLLIBRARYLOADER_H_
+
+#include <stdio.h>
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+#include "GLDefs.h"
+#include "mozilla/Util.h"
+#include "nscore.h"
+#include "prlink.h"
+
+namespace mozilla {
+namespace gl {
+
+class GLLibraryLoader
+{
+public:
+    bool OpenLibrary(const char *library);
+
+    typedef PRFuncPtr (GLAPIENTRY * PlatformLookupFunction) (const char *);
+
+    enum {
+        MAX_SYMBOL_NAMES = 5,
+        MAX_SYMBOL_LENGTH = 128
+    };
+
+    typedef struct {
+        PRFuncPtr *symPointer;
+        const char *symNames[MAX_SYMBOL_NAMES];
+    } SymLoadStruct;
+
+    bool LoadSymbols(SymLoadStruct *firstStruct,
+                       bool tryplatform = false,
+                       const char *prefix = nsnull);
+
+    /*
+     * Static version of the functions in this class
+     */
+    static PRFuncPtr LookupSymbol(PRLibrary *lib,
+                                  const char *symname,
+                                  PlatformLookupFunction lookupFunction = nsnull);
+    static bool LoadSymbols(PRLibrary *lib,
+                              SymLoadStruct *firstStruct,
+                              PlatformLookupFunction lookupFunction = nsnull,
+                              const char *prefix = nsnull);
+protected:
+    GLLibraryLoader() {
+        mLibrary = nsnull;
+        mLookupFunc = nsnull;
+    }
+
+    PRLibrary *mLibrary;
+    PlatformLookupFunction mLookupFunc;
+};
+
+} /* namespace gl */
+} /* namespace mozilla */
+
+#endif /* GLLIBRARYLOADER_H_ */
--- a/gfx/gl/Makefile.in
+++ b/gfx/gl/Makefile.in
@@ -46,16 +46,17 @@ LIBXUL_LIBRARY	= 1
 EXPORT_LIBRARY	= 1
 
 EXPORTS	= \
 	GLDefs.h \
 	GLContext.h \
 	GLContextSymbols.h \
 	GLContextProvider.h \
 	GLContextProviderImpl.h \
+	GLLibraryLoader.h \
 	EGLUtils.h \
 	ForceDiscreteGPUHelperCGL.h \
 	$(NULL)
 
 ifdef MOZ_X11
 EXPORTS += \
 	GLXLibrary.h \
 	$(NULL)
@@ -65,16 +66,17 @@ endif
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 EXPORTS	+= \
 	WGLLibrary.h \
 	$(NULL)
 endif
 
 CPPSRCS	= \
 	GLContext.cpp \
+	GLLibraryLoader.cpp \
 	GLContextProviderOSMesa.cpp \
 	$(NULL)
 
 GL_PROVIDER = Null
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 GL_PROVIDER = WGL
 endif
@@ -113,19 +115,25 @@ endif
 
 # Mac is a special snowflake
 ifeq ($(GL_PROVIDER),CGL)
 CMMSRCS += GLContextProvider$(GL_PROVIDER).mm
 else
 CPPSRCS += GLContextProvider$(GL_PROVIDER).cpp
 endif
 
+ifeq ($(GL_PROVIDER),EGL)
+CPPSRCS += GLLibraryEGL.cpp
+endif
+
 # Win32 is a special snowflake, for ANGLE
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
-CPPSRCS += GLContextProviderEGL.cpp
+CPPSRCS += \
+	GLContextProviderEGL.cpp \
+	GLLibraryEGL.cpp
 endif
 
 ifdef MOZ_JAVA_COMPOSITOR
 DEFINES += -DMOZ_JAVA_COMPOSITOR
 endif
 
 include $(topsrcdir)/config/rules.mk