yotis avatar yotis committed f29cf75

Removed loaders from public API, added thread local storage support

Now there is a big Loader struct that contains all pointer functions,
this improves considerably compile times

GLXX_TLS is defined by default, this enables multiple contexts when used
from different threads at the same time

Comments (0)

Files changed (10)

generator/glXxx.py

         cpp.write(' */\n')
         
         cpp.write('''
+// Comment the following line to disable thread local storage
+#define GLXX_TLS 
+
 #ifdef __linux__
 
 #include "glXxx.h"
 #include <cassert>
 #include <string>
 #include <vector>
+#include <set>
 #include <sstream>
 #include <iterator>
 #include <algorithm>

generator/glxx.py

     {
         using namespace gl_version_1_0;
         using namespace gl_version_1_0_deprecated;
-
-        class Loader :
-                public gl_version_1_0::Loader,
-                public gl_version_1_0_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_1_0();
     
         using namespace gl_1_0;
         using namespace gl_version_1_1;
         using namespace gl_version_1_1_deprecated;
-
-        class Loader :
-                public gl_1_0::Loader,
-                public gl_version_1_1::Loader,
-                public gl_version_1_1_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_1_1();
     
         using namespace gl_1_1;
         using namespace gl_version_1_2;
         using namespace gl_version_1_2_deprecated;
-
-        class Loader :
-                public gl_1_1::Loader,
-                public gl_version_1_2::Loader,
-                public gl_version_1_2_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_1_2();
     
         using namespace gl_1_2;
         using namespace gl_version_1_3;
         using namespace gl_version_1_3_deprecated;
-
-        class Loader :
-                public gl_1_2::Loader,
-                public gl_version_1_3::Loader,
-                public gl_version_1_3_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_1_3();
     
         using namespace gl_1_3;
         using namespace gl_version_1_4;
         using namespace gl_version_1_4_deprecated;
-
-        class Loader :
-                public gl_1_3::Loader,
-                public gl_version_1_4::Loader,
-                public gl_version_1_4_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_1_4();
     
         using namespace gl_1_4;
         using namespace gl_version_1_5;
         using namespace gl_version_1_5_deprecated;
-
-        class Loader :
-                public gl_1_4::Loader,
-                public gl_version_1_5::Loader,
-                public gl_version_1_5_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_1_5();
     
         using namespace gl_1_5;
         using namespace gl_version_2_0;
         using namespace gl_version_2_0_deprecated;
-
-        class Loader :
-                public gl_1_5::Loader,
-                public gl_version_2_0::Loader,
-                public gl_version_2_0_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_2_0();
     
         using namespace gl_2_0;
         using namespace gl_version_2_1;
         using namespace gl_version_2_1_deprecated;
-
-        class Loader :
-                public gl_2_0::Loader,
-                public gl_version_2_1::Loader,
-                public gl_version_2_1_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_2_1();
     
         using namespace gl_2_1;
         using namespace gl_version_3_0;
         using namespace gl_version_3_0_deprecated;
-
-        class Loader :
-                public gl_2_1::Loader,
-                public gl_version_3_0::Loader,
-                public gl_version_3_0_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_3_0();
     
         using namespace gl_3_0;
         using namespace gl_version_3_1;
         using namespace gl_version_3_1_deprecated;
-
-        class Loader :
-                public gl_3_0::Loader,
-                public gl_version_3_1::Loader,
-                public gl_version_3_1_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_3_1_compatibility();
     
         using namespace gl_3_1_compatibility;
         using namespace gl_version_3_2;
         using namespace gl_version_3_2_deprecated;
-
-        class Loader :
-                public gl_3_1_compatibility::Loader,
-                public gl_version_3_2::Loader,
-                public gl_version_3_2_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_3_2_compatibility();
     
         using namespace gl_3_2_compatibility;
         using namespace gl_version_3_3;
         using namespace gl_version_3_3_deprecated;
-
-        class Loader :
-                public gl_3_2_compatibility::Loader,
-                public gl_version_3_3::Loader,
-                public gl_version_3_3_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_3_3_compatibility();
     
         using namespace gl_3_3_compatibility;
         using namespace gl_version_4_0;
         using namespace gl_version_4_0_deprecated;
-
-        class Loader :
-                public gl_3_3_compatibility::Loader,
-                public gl_version_4_0::Loader,
-                public gl_version_4_0_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_4_0_compatibility();
     
         using namespace gl_4_0_compatibility;
         using namespace gl_version_4_1;
         using namespace gl_version_4_1_deprecated;
-
-        class Loader :
-                public gl_4_0_compatibility::Loader,
-                public gl_version_4_1::Loader,
-                public gl_version_4_1_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_4_1_compatibility();
     
         using namespace gl_4_1_compatibility;
         using namespace gl_version_4_2;
         using namespace gl_version_4_2_deprecated;
-
-        class Loader :
-                public gl_4_1_compatibility::Loader,
-                public gl_version_4_2::Loader,
-                public gl_version_4_2_deprecated::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_4_2_compatibility();
 
         using namespace gl_version_2_1;
         using namespace gl_version_3_0;
         using namespace gl_version_3_1;
-
-        class Loader :
-                public gl_version_1_0::Loader,
-                public gl_version_1_1::Loader,
-                public gl_version_1_2::Loader,
-                public gl_version_1_3::Loader,
-                public gl_version_1_4::Loader,
-                public gl_version_1_5::Loader,
-                public gl_version_2_0::Loader,
-                public gl_version_2_1::Loader,
-                public gl_version_3_0::Loader,
-                public gl_version_3_1::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_3_1_core();
     
     {
         using namespace gl_3_1_core;
         using namespace gl_version_3_2;
-
-        class Loader :
-                public gl_3_1_core::Loader,
-                public gl_version_3_2::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_3_2_core();
     
     {
         using namespace gl_3_2_core;
         using namespace gl_version_3_3;
-
-        class Loader :
-                public gl_3_2_core::Loader,
-                public gl_version_3_3::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_3_3_core();
     
     {
         using namespace gl_3_3_core;
         using namespace gl_version_4_0;
-
-        class Loader :
-                public gl_3_3_core::Loader,
-                public gl_version_4_0::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_4_0_core();
     
     {
         using namespace gl_4_0_core;
         using namespace gl_version_4_1;
-
-        class Loader :
-                public gl_4_0_core::Loader,
-                public gl_version_4_1::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_4_1_core();
     
     {
         using namespace gl_4_1_core;
         using namespace gl_version_4_2;
-
-        class Loader :
-                public gl_4_1_core::Loader,
-                public gl_version_4_2::Loader
-        {
-            bool is_loaded;
-        public:
-            Loader();
-            inline const bool isLoaded();
-        };
     }
     bool load_gl_4_2_core();
     
         cpp_out.write(' */\n')
         
         cpp_out.write('''
+// Comment the following line to disable thread local storage
+#define GLXX_TLS
+
 #include "glxx.h"
 #include <iostream>
 #include <iterator>
 #include <string>
 #include <sstream>
 #include <vector>
+#include <set>
 #include <algorithm>
 #include <memory>
 
     #endif // _WIN32
 
 
+    typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGPROC)(GLenum name);
     bool IsVersionSupported(int major, int minor)
     {
         assert(GetCurrentCtx() && "IsVersionSupported called without a current context");
-        gl_version_1_0::PFNGLGETSTRINGPROC glGetString = 
-                (gl_version_1_0::PFNGLGETSTRINGPROC)GetProcAddr("glGetString"); 
+
+        PFNGLGETSTRINGPROC glGetString = (PFNGLGETSTRINGPROC)GetProcAddr("glGetString");
         const char* version = (const char*)glGetString(GL_VERSION);
         int ctx_maj = version[0] - 48;
         int ctx_min = version[2] - 48;
         return true;
     }
 
+
+    typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC)(GLenum name, GLuint index);
+    typedef void (APIENTRYP PFNGLGETINTEGERVPROC)(GLenum pname, GLint* params);
+
     bool IsExtensionSupported(const char* extension)
     {
         assert(GetCurrentCtx() && "IsExtensionSupported called without a current context");
-        gl_version_1_0::PFNGLGETSTRINGPROC glGetString = 
-                (gl_version_1_0::PFNGLGETSTRINGPROC)GetProcAddr("glGetString"); 
+
+        PFNGLGETSTRINGPROC glGetString = (PFNGLGETSTRINGPROC)GetProcAddr("glGetString");
         const char* version = (const char*)glGetString(GL_VERSION);
         int ctx_major = version[0] - 48;
         if (ctx_major >= 3) {
-            gl_version_3_0::PFNGLGETSTRINGIPROC glGetStringi = 
-                    (gl_version_3_0::PFNGLGETSTRINGIPROC)GetProcAddr("glGetStringi");
-            gl_version_1_0::PFNGLGETINTEGERVPROC glGetIntegerv = 
-                    (gl_version_1_0::PFNGLGETINTEGERVPROC)GetProcAddr("glGetIntegerv");  
+            PFNGLGETSTRINGIPROC glGetStringi = (PFNGLGETSTRINGIPROC)GetProcAddr("glGetStringi");
+            PFNGLGETINTEGERVPROC glGetIntegerv = (PFNGLGETINTEGERVPROC)GetProcAddr("glGetIntegerv");
             int num_extensions = 0;
             glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
             for (int i = 0; i < num_extensions; ++i) {
             return true;
         }
     }
-
+    
 
 ''')
 
 bool has_gl_4_2() { return IsVersionSupported(4, 2); }
 
 
-gl_1_0::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_version_1_0::Loader::isLoaded() &&
-            gl_version_1_0_deprecated::Loader::isLoaded();
-}
-const bool gl_1_0::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_1_0()
 { 
     return load_version_1_0() && load_version_1_0_deprecated();
 }
 
-gl_1_1::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_1_0::Loader::isLoaded() &&
-            gl_version_1_1::Loader::isLoaded() &&
-            gl_version_1_1_deprecated::Loader::isLoaded();
-}
-const bool gl_1_1::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_1_1()
 { 
     return load_gl_1_0() && load_version_1_1() && load_version_1_1_deprecated();
 }
 
-gl_1_2::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_1_1::Loader::isLoaded() &&
-            gl_version_1_2::Loader::isLoaded() &&
-            gl_version_1_2_deprecated::Loader::isLoaded();
-}
-const bool gl_1_2::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_1_2()
 {
     return load_gl_1_1() && load_version_1_2() && load_version_1_2_deprecated();
 }
 
-
-gl_1_3::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_1_2::Loader::isLoaded() &&
-            gl_version_1_3::Loader::isLoaded() &&
-            gl_version_1_3_deprecated::Loader::isLoaded();
-}
-const bool gl_1_3::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_1_3()
 {
     return load_gl_1_2() && load_version_1_3() && load_version_1_3_deprecated();
 }
 
-gl_1_4::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_1_3::Loader::isLoaded() &&
-            gl_version_1_4::Loader::isLoaded() &&
-            gl_version_1_4_deprecated::Loader::isLoaded();
-}
-const bool gl_1_4::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_1_4()
 {
     return load_gl_1_3() && load_version_1_4() && load_version_1_4_deprecated();
 }
 
-gl_1_5::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_1_4::Loader::isLoaded() &&
-            gl_version_1_5::Loader::isLoaded() &&
-            gl_version_1_5_deprecated::Loader::isLoaded();
-}
-const bool gl_1_5::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_1_5()
 {
     return load_gl_1_4() && load_version_1_5() && load_version_1_5_deprecated();
 }
 
-gl_2_0::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_1_5::Loader::isLoaded() &&
-            gl_version_2_0::Loader::isLoaded() &&
-            gl_version_2_0_deprecated::Loader::isLoaded();
-}
-const bool gl_2_0::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_2_0() 
 {
     return load_gl_1_5() && load_version_2_0() && load_version_2_0_deprecated();
 }
 
-gl_2_1::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_2_0::Loader::isLoaded() &&
-            gl_version_2_1::Loader::isLoaded() &&
-            gl_version_2_1_deprecated::Loader::isLoaded();
-}
-const bool gl_2_1::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_2_1()
 {
     return load_gl_2_0() && load_version_2_1() && load_version_2_1_deprecated();
 }
 
-gl_3_0::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_2_1::Loader::isLoaded() &&
-            gl_version_3_0::Loader::isLoaded() &&
-            gl_version_3_0_deprecated::Loader::isLoaded();
-}
-const bool gl_3_0::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_3_0() 
 {
     return load_gl_2_1() && load_version_3_0() && load_version_3_0_deprecated();
 }
 
-gl_3_1_compatibility::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_3_0::Loader::isLoaded() &&
-            gl_version_3_1::Loader::isLoaded() &&
-            gl_version_3_1_deprecated::Loader::isLoaded();
-}
-const bool gl_3_1_compatibility::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_3_1_compatibility() 
 {
     return load_gl_3_0() && load_version_3_1() && load_version_3_1_deprecated();
 }
 
-gl_3_2_compatibility::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_3_1_compatibility::Loader::isLoaded() &&
-            gl_version_3_2::Loader::isLoaded() &&
-            gl_version_3_2_deprecated::Loader::isLoaded();
-}
-const bool gl_3_2_compatibility::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_3_2_compatibility() 
 {
     return load_gl_3_1_compatibility() && load_version_3_2() && load_version_3_2_deprecated();
 }
 
-gl_3_3_compatibility::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_3_2_compatibility::Loader::isLoaded() &&
-            gl_version_3_3::Loader::isLoaded() &&
-            gl_version_3_3_deprecated::Loader::isLoaded();
-}
-const bool gl_3_3_compatibility::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_3_3_compatibility() 
 {
     return load_gl_3_2_compatibility() && load_version_3_3() && load_version_3_3_deprecated();
 }
 
-gl_4_0_compatibility::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_3_3_compatibility::Loader::isLoaded() &&
-            gl_version_4_0::Loader::isLoaded() &&
-            gl_version_4_0_deprecated::Loader::isLoaded();
-}
-const bool gl_4_0_compatibility::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_4_0_compatibility()
 {
     return load_gl_3_3_compatibility() && load_version_4_0() && load_version_4_0_deprecated();
 }
 
-gl_4_1_compatibility::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_4_0_compatibility::Loader::isLoaded() &&
-            gl_version_4_1::Loader::isLoaded() &&
-            gl_version_4_1_deprecated::Loader::isLoaded();
-}
-const bool gl_4_1_compatibility::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_4_1_compatibility()
 {
     return load_gl_4_0_compatibility() && load_version_4_1() && load_version_4_1_deprecated();
 }
 
-gl_4_2_compatibility::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_4_1_compatibility::Loader::isLoaded() &&
-            gl_version_4_2::Loader::isLoaded() &&
-            gl_version_4_2_deprecated::Loader::isLoaded();
-}
-const bool gl_4_2_compatibility::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_4_2_compatibility() 
 {
     return load_gl_4_1_compatibility() && load_version_4_2() && load_version_4_2_deprecated();
 }
 
 // Core 
-gl_3_1_core::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_version_1_0::Loader::isLoaded() &&
-            gl_version_1_1::Loader::isLoaded() &&
-            gl_version_1_2::Loader::isLoaded() &&
-            gl_version_1_3::Loader::isLoaded() &&
-            gl_version_1_4::Loader::isLoaded() &&
-            gl_version_1_5::Loader::isLoaded() &&
-            gl_version_2_0::Loader::isLoaded() &&
-            gl_version_2_1::Loader::isLoaded() &&
-            gl_version_3_0::Loader::isLoaded() &&
-            gl_version_3_1::Loader::isLoaded();
-}
-const bool gl_3_1_core::Loader::isLoaded()
-{
-    return is_loaded;
-}
+
 bool load_gl_3_1_core() 
 {
     return load_version_1_0() && load_version_1_1() && load_version_1_2() && 
         load_version_3_0() && load_version_3_1();
 }
 
-gl_3_2_core::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_3_1_core::Loader::isLoaded() &&
-            gl_version_3_2::Loader::isLoaded();
-}
-const bool gl_3_2_core::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_3_2_core() 
 { 
     return load_gl_3_1_core() && load_version_3_2(); 
 }
 
-gl_3_3_core::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_3_2_core::Loader::isLoaded() &&
-            gl_version_3_3::Loader::isLoaded();
-}
-const bool gl_3_3_core::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_3_3_core()
 { 
     return load_gl_3_2_core() && load_version_3_3();
 }
 
-gl_4_0_core::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_3_3_core::Loader::isLoaded() &&
-            gl_version_4_0::Loader::isLoaded();
-}
-const bool gl_4_0_core::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_4_0_core() 
 {
     return load_gl_3_3_core() && load_version_4_0(); 
 }
 
-gl_4_1_core::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_4_0_core::Loader::isLoaded() &&
-            gl_version_4_1::Loader::isLoaded();
-}
-const bool gl_4_1_core::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_4_1_core()
 {
     return load_gl_4_0_core() && load_version_4_1();
 }
 
-gl_4_2_core::Loader::Loader()
-    : is_loaded(true)
-{
-    is_loaded = gl_4_1_core::Loader::isLoaded() &&
-            gl_version_4_2::Loader::isLoaded();
-}
-const bool gl_4_2_core::Loader::isLoaded()
-{
-    return is_loaded;
-}
 bool load_gl_4_2_core()
 {
     return load_gl_4_1_core() && load_version_4_2();

generator/parse.py

             deprecated_versions.insert(categories.index(missing_depr_cat)+1, missing_depr_cat + '_DEPRECATED')
         print deprecated_versions
 
+#############################################
+# Big cpp loader with all functions.
+###################
+        
+    out_cpp.append('''
+    struct Loader {''')
+    for f in functions:
+        out_cpp.append(
+'        typedef %s (APIENTRYP PFN%s%sPROC)(%s);' % 
+                    (tm[f.returns], prefix.upper(), f.name.upper(), ', '.join(f.make_param_list(tm))))
+        out_cpp.append(
+'        PFN%s%sPROC %s;' % (prefix.upper(), f.name.upper(), f.name))
+    out_cpp.append('''
+        Loader() { memset(this, 0, sizeof(Loader)); }
+    };
+    
+#ifdef GLXX_TLS
+    #if defined(_WIN32) || defined(WIN32)
+    __declspec(thread) Loader* current_loader = 0;
+    #endif
+    #if defined(__linux__)
+    __thread Loader* current_loader = 0;
+    #endif
+#else
+    Loader* current_loader = 0;
+#endif //GLXX_TLS
 
+
+    std::vector<std::tr1::shared_ptr<Loader> > loaders;
+    std::set<GLuint> unused_loader_indices;
+
+    GLuint GenLoader()
+    {
+        if (unused_loader_indices.empty()) {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            return loaders.size() - 1;
+        } else {
+            GLuint first_unused_loader = *(unused_loader_indices.begin());
+            loaders[first_unused_loader].reset(new Loader);
+            unused_loader_indices.erase(unused_loader_indices.begin());
+            return first_unused_loader;
+        }
+    }
+
+    void BindLoader(GLuint loader)
+    {
+        current_loader = loaders[loader].get();
+    }
+
+    void DeleteLoader(GLuint loader)
+    {
+        if (loaders[loader].get() == current_loader) {
+            if (!loaders.empty())
+                current_loader = loaders[0].get();
+            else
+                current_loader = 0;
+        }
+        loaders[loader].reset();
+        unused_loader_indices.insert(loader);
+    }
+
+    ''')
+    
+        
+        
     for category in categories:
         category_functions = []
 
         # todo: remove empty loaders, leave only the has_.. functions.
         out_h.append('''
 
-#ifndef %s_%s
-%s
-    bool has_%s();
+#ifndef %s_%s''' % (prefix.upper(), category))
+
+        if passes:
+            out_h.append('\n'.join(passes))
+        
+        m = re_parse_version.match(category)
+        if not m:
+            out_h.append('''    
+    bool has_%s();''' % category.lower())
+        out_h.append('''
     namespace %s_%s
-    {''' % (prefix.upper(), category,
-            '\n'.join(passes),
-            category.lower(), 
-            prefix.lower(), category.lower()))
-                
-        for fun in category_functions:
-            out_h.append(
-'        typedef %s (APIENTRYP PFN%s%sPROC)(%s);' % 
-                    (tm[fun.returns], prefix.upper(), fun.name.upper(), ', '.join(fun.make_param_list(tm))))
-            
-        out_h.append('''
-        class Loader
-        {
-        public:
-            Loader();
-            inline bool isLoaded() const { return is_loaded; }''')
-
-        for fun in category_functions:
-            out_h.append(
-'            PFN%s%sPROC %s;' % (prefix.upper(), fun.name.upper(), fun.name))
-        out_h.append('''
-        private:
-            bool is_loaded;
-        };
-''')
-        
+    {''' % (prefix.lower(), category.lower()))
+                        
         for fun in category_functions:
             out_h.append(
 '        %s %s%s(%s);' % (tm[fun.returns], prefix, fun.name, ', '.join(fun.make_param_list(tm))))
                 
-        out_h.append('''
-    } // namespace %s_%s
+        out_h.append(
+'''    } // namespace %s_%s
+
     bool load_%s();
 %s
 #define %s_%s
         passes_end = [p for p in passes_end if p.startswith('#endif')]
 
         out_cpp.append('\n'.join(passes))
-        out_cpp.append("""
-%s_%s::Loader::Loader() :""" % (prefix.lower(), category.lower()))
+
+        out_cpp.append(
+'''    bool load_%s()
+    {        
+        assert(GetCurrentCtx() && "load_%s() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
+''' % (category.lower(), category.lower()))
         
         for fun in category_functions:
             out_cpp.append(
-'        %s(0),' % fun.name)
-            
-        out_cpp.append('''
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "%s_%s::Loader initialized without a current context");''' 
-                % (prefix.lower(), category.lower()))
+'''        current_loader->%s = (Loader::PFN%s%sPROC) GetProcAddr("%s%s");
+        if (!current_loader->%s) is_loaded = false;''' % (fun.name, prefix.upper(), fun.name.upper(), prefix, fun.name, fun.name))
         
-        for fun in category_functions:
+        out_cpp.append('''        
+        return is_loaded;
+    }''')
+        m = re_parse_version.match(category)
+        if not m:
             out_cpp.append('''
-    %s = (PFN%s%sPROC) GetProcAddr("%s%s");
-    if (!%s)
-        is_loaded = false;''' % (fun.name, prefix.upper(), fun.name.upper(), prefix, fun.name, fun.name))
-        
-        out_cpp.append(
-'}')
-        m = re_parse_version.match(category)
-        if m:
-            out_cpp.append("""
-bool has_%s() 
-{
-    return IsVersionSupported(%s, %s);
-}
-""" % (category.lower(), m.group('major'), m.group('minor')))
-        else:
-            out_cpp.append("""
-bool has_%s() 
-{
-    return IsExtensionSupported("%s_%s");
-}
-""" % (category.lower(), prefix.upper(), category))
-        
-        out_cpp.append("""
-std::auto_ptr<%s_%s::Loader> default_%s_loader;
-
-bool load_%s() 
-{
-    default_%s_loader.reset(new %s_%s::Loader);
-    return default_%s_loader->isLoaded();
-}
-""" % (prefix.lower(), category.lower(), category.lower(), 
-       category.lower(),
-       category.lower(), prefix.lower(), category.lower(),
-       category.lower()))
+    bool has_%s()
+    {
+        return IsExtensionSupported("%s_%s");
+    }
+''' % (category.lower(), prefix.upper(), category))
             
         for fun in category_functions:
             param_list = ', '.join(fun.make_param_list(tm))
             fun_ret = ''
             if fun.returns != 'void': fun_ret = 'return '
             out_cpp.append('''
-%s %s_%s::%s%s(%s)
-{
-    %sdefault_%s_loader->%s(%s);
-}''' % (tm[fun.returns], prefix.lower(), category.lower(), prefix, fun.name, param_list,
-         fun_ret, category.lower(), fun.name, ', '.join([p.name for p in fun.params])))
+    %s %s_%s::%s%s(%s)
+    {
+        %scurrent_loader->%s(%s);
+    }''' % (tm[fun.returns], prefix.lower(), category.lower(), prefix, fun.name, param_list,
+                fun_ret, fun.name, ', '.join([p.name for p in fun.params])))
 
         out_cpp.append('\n'.join(passes_end))
         

generator/wglxx.py

             cpp.write(' */\n')
             
             cpp.write('''
+// Comment the following line to disable thread local storage
+#define GLXX_TLS            
+            
 #if defined(_WIN32) || defined(WIN32)
 
 #include "wglxx.h"
 #include <string>
 #include <sstream>
 #include <vector>
+#include <set>
 #include <algorithm>
 #include <memory>
 
         return GetProcAddress(h, function_name);
     }
 
+    typedef const char * (APIENTRYP PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc);
     bool IsExtensionSupported(const char* extension)
     {
         using std::string;
 
         assert(GetCurrentCtx() && "wglxx: IsExtensionSupported called without a current context");
 
-        wgl_arb_extensions_string::PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
-        wglGetExtensionsStringARB = (wgl_arb_extensions_string::PFNWGLGETEXTENSIONSSTRINGARBPROC)
-                GetProcAddr("wglGetExtensionsStringARB");
+        PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0;
+        wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) GetProcAddr("wglGetExtensionsStringARB");
         if (!wglGetExtensionsStringARB)
             return false;
 
             return false;
         return true;
     }
+    
 ''')
             
             cpp.write(wgl_spec_source)
  * IN THE SOFTWARE.
  */
 
+// Comment the following line to disable thread local storage
+#define GLXX_TLS 
+
 #ifdef __linux__
 
 #include "glXxx.h"
 #include <cassert>
 #include <string>
 #include <vector>
+#include <set>
 #include <sstream>
 #include <iterator>
 #include <algorithm>
         return false;
     }
 
+    struct Loader {
+        typedef GLXFBConfig * (APIENTRYP PFNGLXGETFBCONFIGSPROC)(Display* dpy, int screen, int* nelements);
+        PFNGLXGETFBCONFIGSPROC GetFBConfigs;
+        typedef GLXFBConfig * (APIENTRYP PFNGLXCHOOSEFBCONFIGPROC)(Display* dpy, int screen, const int* attrib_list, int* nelements);
+        PFNGLXCHOOSEFBCONFIGPROC ChooseFBConfig;
+        typedef int (APIENTRYP PFNGLXGETFBCONFIGATTRIBPROC)(Display* dpy, GLXFBConfig config, int attribute, int* value);
+        PFNGLXGETFBCONFIGATTRIBPROC GetFBConfigAttrib;
+        typedef XVisualInfo * (APIENTRYP PFNGLXGETVISUALFROMFBCONFIGPROC)(Display* dpy, GLXFBConfig config);
+        PFNGLXGETVISUALFROMFBCONFIGPROC GetVisualFromFBConfig;
+        typedef GLXWindow (APIENTRYP PFNGLXCREATEWINDOWPROC)(Display* dpy, GLXFBConfig config, Window win, const int* attrib_list);
+        PFNGLXCREATEWINDOWPROC CreateWindow;
+        typedef void (APIENTRYP PFNGLXDESTROYWINDOWPROC)(Display* dpy, GLXWindow win);
+        PFNGLXDESTROYWINDOWPROC DestroyWindow;
+        typedef GLXPixmap (APIENTRYP PFNGLXCREATEPIXMAPPROC)(Display* dpy, GLXFBConfig config, Pixmap pixmap, const int* attrib_list);
+        PFNGLXCREATEPIXMAPPROC CreatePixmap;
+        typedef void (APIENTRYP PFNGLXDESTROYPIXMAPPROC)(Display* dpy, GLXPixmap pixmap);
+        PFNGLXDESTROYPIXMAPPROC DestroyPixmap;
+        typedef GLXPbuffer (APIENTRYP PFNGLXCREATEPBUFFERPROC)(Display* dpy, GLXFBConfig config, const int* attrib_list);
+        PFNGLXCREATEPBUFFERPROC CreatePbuffer;
+        typedef void (APIENTRYP PFNGLXDESTROYPBUFFERPROC)(Display* dpy, GLXPbuffer pbuf);
+        PFNGLXDESTROYPBUFFERPROC DestroyPbuffer;
+        typedef void (APIENTRYP PFNGLXQUERYDRAWABLEPROC)(Display* dpy, GLXDrawable draw, int attribute, unsigned int* value);
+        PFNGLXQUERYDRAWABLEPROC QueryDrawable;
+        typedef GLXContext (APIENTRYP PFNGLXCREATENEWCONTEXTPROC)(Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+        PFNGLXCREATENEWCONTEXTPROC CreateNewContext;
+        typedef Bool (APIENTRYP PFNGLXMAKECONTEXTCURRENTPROC)(Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+        PFNGLXMAKECONTEXTCURRENTPROC MakeContextCurrent;
+        typedef GLXDrawable (APIENTRYP PFNGLXGETCURRENTREADDRAWABLEPROC)();
+        PFNGLXGETCURRENTREADDRAWABLEPROC GetCurrentReadDrawable;
+        typedef Display * (APIENTRYP PFNGLXGETCURRENTDISPLAYPROC)();
+        PFNGLXGETCURRENTDISPLAYPROC GetCurrentDisplay;
+        typedef int (APIENTRYP PFNGLXQUERYCONTEXTPROC)(Display* dpy, GLXContext ctx, int attribute, int* value);
+        PFNGLXQUERYCONTEXTPROC QueryContext;
+        typedef void (APIENTRYP PFNGLXSELECTEVENTPROC)(Display* dpy, GLXDrawable draw, unsigned long event_mask);
+        PFNGLXSELECTEVENTPROC SelectEvent;
+        typedef void (APIENTRYP PFNGLXGETSELECTEDEVENTPROC)(Display* dpy, GLXDrawable draw, unsigned long* event_mask);
+        PFNGLXGETSELECTEDEVENTPROC GetSelectedEvent;
+        typedef __GLXextFuncPtr (APIENTRYP PFNGLXGETPROCADDRESSPROC)(const GLubyte* procName);
+        PFNGLXGETPROCADDRESSPROC GetProcAddress;
+        typedef __GLXextFuncPtr (APIENTRYP PFNGLXGETPROCADDRESSARBPROC)(const GLubyte* procName);
+        PFNGLXGETPROCADDRESSARBPROC GetProcAddressARB;
+        typedef GLXContext (APIENTRYP PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int* attrib_list);
+        PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
+        typedef int (APIENTRYP PFNGLXSWAPINTERVALSGIPROC)(int interval);
+        PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
+        typedef int (APIENTRYP PFNGLXGETVIDEOSYNCSGIPROC)(unsigned int* count);
+        PFNGLXGETVIDEOSYNCSGIPROC GetVideoSyncSGI;
+        typedef int (APIENTRYP PFNGLXWAITVIDEOSYNCSGIPROC)(int divisor, int remainder, unsigned int* count);
+        PFNGLXWAITVIDEOSYNCSGIPROC WaitVideoSyncSGI;
+        typedef Bool (APIENTRYP PFNGLXMAKECURRENTREADSGIPROC)(Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+        PFNGLXMAKECURRENTREADSGIPROC MakeCurrentReadSGI;
+        typedef GLXDrawable (APIENTRYP PFNGLXGETCURRENTREADDRAWABLESGIPROC)();
+        PFNGLXGETCURRENTREADDRAWABLESGIPROC GetCurrentReadDrawableSGI;
+        typedef GLXVideoSourceSGIX (APIENTRYP PFNGLXCREATEGLXVIDEOSOURCESGIXPROC)(Display* display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode);
+        PFNGLXCREATEGLXVIDEOSOURCESGIXPROC CreateGLXVideoSourceSGIX;
+        typedef void (APIENTRYP PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC)(Display* dpy, GLXVideoSourceSGIX glxvideosource);
+        PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC DestroyGLXVideoSourceSGIX;
+        typedef Display * (APIENTRYP PFNGLXGETCURRENTDISPLAYEXTPROC)();
+        PFNGLXGETCURRENTDISPLAYEXTPROC GetCurrentDisplayEXT;
+        typedef int (APIENTRYP PFNGLXQUERYCONTEXTINFOEXTPROC)(Display* dpy, GLXContext context, int attribute, int* value);
+        PFNGLXQUERYCONTEXTINFOEXTPROC QueryContextInfoEXT;
+        typedef GLXContextID (APIENTRYP PFNGLXGETCONTEXTIDEXTPROC)(const GLXContext context);
+        PFNGLXGETCONTEXTIDEXTPROC GetContextIDEXT;
+        typedef GLXContext (APIENTRYP PFNGLXIMPORTCONTEXTEXTPROC)(Display* dpy, GLXContextID contextID);
+        PFNGLXIMPORTCONTEXTEXTPROC ImportContextEXT;
+        typedef void (APIENTRYP PFNGLXFREECONTEXTEXTPROC)(Display* dpy, GLXContext context);
+        PFNGLXFREECONTEXTEXTPROC FreeContextEXT;
+        typedef int (APIENTRYP PFNGLXGETFBCONFIGATTRIBSGIXPROC)(Display* dpy, GLXFBConfigSGIX config, int attribute, int* value);
+        PFNGLXGETFBCONFIGATTRIBSGIXPROC GetFBConfigAttribSGIX;
+        typedef GLXFBConfigSGIX * (APIENTRYP PFNGLXCHOOSEFBCONFIGSGIXPROC)(Display* dpy, int screen, int* attrib_list, int* nelements);
+        PFNGLXCHOOSEFBCONFIGSGIXPROC ChooseFBConfigSGIX;
+        typedef GLXPixmap (APIENTRYP PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC)(Display* dpy, GLXFBConfigSGIX config, Pixmap pixmap);
+        PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC CreateGLXPixmapWithConfigSGIX;
+        typedef GLXContext (APIENTRYP PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)(Display* dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct);
+        PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC CreateContextWithConfigSGIX;
+        typedef XVisualInfo * (APIENTRYP PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)(Display* dpy, GLXFBConfigSGIX config);
+        PFNGLXGETVISUALFROMFBCONFIGSGIXPROC GetVisualFromFBConfigSGIX;
+        typedef GLXFBConfigSGIX (APIENTRYP PFNGLXGETFBCONFIGFROMVISUALSGIXPROC)(Display* dpy, XVisualInfo* vis);
+        PFNGLXGETFBCONFIGFROMVISUALSGIXPROC GetFBConfigFromVisualSGIX;
+        typedef GLXPbufferSGIX (APIENTRYP PFNGLXCREATEGLXPBUFFERSGIXPROC)(Display* dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int* attrib_list);
+        PFNGLXCREATEGLXPBUFFERSGIXPROC CreateGLXPbufferSGIX;
+        typedef void (APIENTRYP PFNGLXDESTROYGLXPBUFFERSGIXPROC)(Display* dpy, GLXPbufferSGIX pbuf);
+        PFNGLXDESTROYGLXPBUFFERSGIXPROC DestroyGLXPbufferSGIX;
+        typedef int (APIENTRYP PFNGLXQUERYGLXPBUFFERSGIXPROC)(Display* dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int* value);
+        PFNGLXQUERYGLXPBUFFERSGIXPROC QueryGLXPbufferSGIX;
+        typedef void (APIENTRYP PFNGLXSELECTEVENTSGIXPROC)(Display* dpy, GLXDrawable drawable, unsigned long mask);
+        PFNGLXSELECTEVENTSGIXPROC SelectEventSGIX;
+        typedef void (APIENTRYP PFNGLXGETSELECTEDEVENTSGIXPROC)(Display* dpy, GLXDrawable drawable, unsigned long* mask);
+        PFNGLXGETSELECTEDEVENTSGIXPROC GetSelectedEventSGIX;
+        typedef void (APIENTRYP PFNGLXCUSHIONSGIPROC)(Display* dpy, Window window, float cushion);
+        PFNGLXCUSHIONSGIPROC CushionSGI;
+        typedef int (APIENTRYP PFNGLXBINDCHANNELTOWINDOWSGIXPROC)(Display* display, int screen, int channel, Window window);
+        PFNGLXBINDCHANNELTOWINDOWSGIXPROC BindChannelToWindowSGIX;
+        typedef int (APIENTRYP PFNGLXCHANNELRECTSGIXPROC)(Display* display, int screen, int channel, int x, int y, int w, int h);
+        PFNGLXCHANNELRECTSGIXPROC ChannelRectSGIX;
+        typedef int (APIENTRYP PFNGLXQUERYCHANNELRECTSGIXPROC)(Display* display, int screen, int channel, int* dx, int* dy, int* dw, int* dh);
+        PFNGLXQUERYCHANNELRECTSGIXPROC QueryChannelRectSGIX;
+        typedef int (APIENTRYP PFNGLXQUERYCHANNELDELTASSGIXPROC)(Display* display, int screen, int channel, int* x, int* y, int* w, int* h);
+        PFNGLXQUERYCHANNELDELTASSGIXPROC QueryChannelDeltasSGIX;
+        typedef int (APIENTRYP PFNGLXCHANNELRECTSYNCSGIXPROC)(Display* display, int screen, int channel, GLenum synctype);
+        PFNGLXCHANNELRECTSYNCSGIXPROC ChannelRectSyncSGIX;
+        typedef Bool (APIENTRYP PFNGLXASSOCIATEDMPBUFFERSGIXPROC)(Display* dpy, GLXPbufferSGIX pbuffer, DMparams* params, DMbuffer dmbuffer);
+        PFNGLXASSOCIATEDMPBUFFERSGIXPROC AssociateDMPbufferSGIX;
+        typedef void (APIENTRYP PFNGLXJOINSWAPGROUPSGIXPROC)(Display* dpy, GLXDrawable drawable, GLXDrawable member);
+        PFNGLXJOINSWAPGROUPSGIXPROC JoinSwapGroupSGIX;
+        typedef void (APIENTRYP PFNGLXBINDSWAPBARRIERSGIXPROC)(Display* dpy, GLXDrawable drawable, int barrier);
+        PFNGLXBINDSWAPBARRIERSGIXPROC BindSwapBarrierSGIX;
+        typedef Bool (APIENTRYP PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC)(Display* dpy, int screen, int* max);
+        PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC QueryMaxSwapBarriersSGIX;
+        typedef Status (APIENTRYP PFNGLXGETTRANSPARENTINDEXSUNPROC)(Display* dpy, Window overlay, Window underlay, long* pTransparentIndex);
+        PFNGLXGETTRANSPARENTINDEXSUNPROC GetTransparentIndexSUN;
+        typedef void (APIENTRYP PFNGLXCOPYSUBBUFFERMESAPROC)(Display* dpy, GLXDrawable drawable, int x, int y, int width, int height);
+        PFNGLXCOPYSUBBUFFERMESAPROC CopySubBufferMESA;
+        typedef GLXPixmap (APIENTRYP PFNGLXCREATEGLXPIXMAPMESAPROC)(Display* dpy, XVisualInfo* visual, Pixmap pixmap, Colormap cmap);
+        PFNGLXCREATEGLXPIXMAPMESAPROC CreateGLXPixmapMESA;
+        typedef Bool (APIENTRYP PFNGLXRELEASEBUFFERSMESAPROC)(Display* dpy, GLXDrawable drawable);
+        PFNGLXRELEASEBUFFERSMESAPROC ReleaseBuffersMESA;
+        typedef Bool (APIENTRYP PFNGLXSET3DFXMODEMESAPROC)(int mode);
+        PFNGLXSET3DFXMODEMESAPROC Set3DfxModeMESA;
+        typedef Bool (APIENTRYP PFNGLXGETSYNCVALUESOMLPROC)(Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc);
+        PFNGLXGETSYNCVALUESOMLPROC GetSyncValuesOML;
+        typedef Bool (APIENTRYP PFNGLXGETMSCRATEOMLPROC)(Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator);
+        PFNGLXGETMSCRATEOMLPROC GetMscRateOML;
+        typedef int64_t (APIENTRYP PFNGLXSWAPBUFFERSMSCOMLPROC)(Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder);
+        PFNGLXSWAPBUFFERSMSCOMLPROC SwapBuffersMscOML;
+        typedef Bool (APIENTRYP PFNGLXWAITFORMSCOMLPROC)(Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc);
+        PFNGLXWAITFORMSCOMLPROC WaitForMscOML;
+        typedef Bool (APIENTRYP PFNGLXWAITFORSBCOMLPROC)(Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc);
+        PFNGLXWAITFORSBCOMLPROC WaitForSbcOML;
+        typedef GLXHyperpipeNetworkSGIX * (APIENTRYP PFNGLXQUERYHYPERPIPENETWORKSGIXPROC)(Display* dpy, int* npipes);
+        PFNGLXQUERYHYPERPIPENETWORKSGIXPROC QueryHyperpipeNetworkSGIX;
+        typedef int (APIENTRYP PFNGLXHYPERPIPECONFIGSGIXPROC)(Display* dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX* cfg, int* hpId);
+        PFNGLXHYPERPIPECONFIGSGIXPROC HyperpipeConfigSGIX;
+        typedef GLXHyperpipeConfigSGIX * (APIENTRYP PFNGLXQUERYHYPERPIPECONFIGSGIXPROC)(Display* dpy, int hpId, int* npipes);
+        PFNGLXQUERYHYPERPIPECONFIGSGIXPROC QueryHyperpipeConfigSGIX;
+        typedef int (APIENTRYP PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC)(Display* dpy, int hpId);
+        PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC DestroyHyperpipeConfigSGIX;
+        typedef int (APIENTRYP PFNGLXBINDHYPERPIPESGIXPROC)(Display* dpy, int hpId);
+        PFNGLXBINDHYPERPIPESGIXPROC BindHyperpipeSGIX;
+        typedef int (APIENTRYP PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC)(Display* dpy, int timeSlice, int attrib, int size, void* attribList, void* returnAttribList);
+        PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC QueryHyperpipeBestAttribSGIX;
+        typedef int (APIENTRYP PFNGLXHYPERPIPEATTRIBSGIXPROC)(Display* dpy, int timeSlice, int attrib, int size, void* attribList);
+        PFNGLXHYPERPIPEATTRIBSGIXPROC HyperpipeAttribSGIX;
+        typedef int (APIENTRYP PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC)(Display* dpy, int timeSlice, int attrib, int size, void* returnAttribList);
+        PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC QueryHyperpipeAttribSGIX;
+        typedef unsigned int (APIENTRYP PFNGLXGETAGPOFFSETMESAPROC)(const void* pointer);
+        PFNGLXGETAGPOFFSETMESAPROC GetAGPOffsetMESA;
+        typedef void (APIENTRYP PFNGLXBINDTEXIMAGEEXTPROC)(Display* dpy, GLXDrawable drawable, int buffer, const int* attrib_list);
+        PFNGLXBINDTEXIMAGEEXTPROC BindTexImageEXT;
+        typedef void (APIENTRYP PFNGLXRELEASETEXIMAGEEXTPROC)(Display* dpy, GLXDrawable drawable, int buffer);
+        PFNGLXRELEASETEXIMAGEEXTPROC ReleaseTexImageEXT;
+        typedef unsigned int * (APIENTRYP PFNGLXENUMERATEVIDEODEVICESNVPROC)(Display* dpy, int screen, int* nelements);
+        PFNGLXENUMERATEVIDEODEVICESNVPROC EnumerateVideoDevicesNV;
+        typedef int (APIENTRYP PFNGLXBINDVIDEODEVICENVPROC)(Display* dpy, unsigned int video_slot, unsigned int video_device, const int* attrib_list);
+        PFNGLXBINDVIDEODEVICENVPROC BindVideoDeviceNV;
+        typedef int (APIENTRYP PFNGLXGETVIDEODEVICENVPROC)(Display* dpy, int screen, int numVideoDevices, GLXVideoDeviceNV* pVideoDevice);
+        PFNGLXGETVIDEODEVICENVPROC GetVideoDeviceNV;
+        typedef int (APIENTRYP PFNGLXRELEASEVIDEODEVICENVPROC)(Display* dpy, int screen, GLXVideoDeviceNV VideoDevice);
+        PFNGLXRELEASEVIDEODEVICENVPROC ReleaseVideoDeviceNV;
+        typedef int (APIENTRYP PFNGLXBINDVIDEOIMAGENVPROC)(Display* dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer);
+        PFNGLXBINDVIDEOIMAGENVPROC BindVideoImageNV;
+        typedef int (APIENTRYP PFNGLXRELEASEVIDEOIMAGENVPROC)(Display* dpy, GLXPbuffer pbuf);
+        PFNGLXRELEASEVIDEOIMAGENVPROC ReleaseVideoImageNV;
+        typedef int (APIENTRYP PFNGLXSENDPBUFFERTOVIDEONVPROC)(Display* dpy, GLXPbuffer pbuf, int iBufferType, unsigned long* pulCounterPbuffer, GLboolean bBlock);
+        PFNGLXSENDPBUFFERTOVIDEONVPROC SendPbufferToVideoNV;
+        typedef int (APIENTRYP PFNGLXGETVIDEOINFONVPROC)(Display* dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long* pulCounterOutputPbuffer, unsigned long* pulCounterOutputVideo);
+        PFNGLXGETVIDEOINFONVPROC GetVideoInfoNV;
+        typedef Bool (APIENTRYP PFNGLXJOINSWAPGROUPNVPROC)(Display* dpy, GLXDrawable drawable, GLuint group);
+        PFNGLXJOINSWAPGROUPNVPROC JoinSwapGroupNV;
+        typedef Bool (APIENTRYP PFNGLXBINDSWAPBARRIERNVPROC)(Display* dpy, GLuint group, GLuint barrier);
+        PFNGLXBINDSWAPBARRIERNVPROC BindSwapBarrierNV;
+        typedef Bool (APIENTRYP PFNGLXQUERYSWAPGROUPNVPROC)(Display* dpy, GLXDrawable drawable, GLuint* group, GLuint* barrier);
+        PFNGLXQUERYSWAPGROUPNVPROC QuerySwapGroupNV;
+        typedef Bool (APIENTRYP PFNGLXQUERYMAXSWAPGROUPSNVPROC)(Display* dpy, int screen, GLuint* maxGroups, GLuint* maxBarriers);
+        PFNGLXQUERYMAXSWAPGROUPSNVPROC QueryMaxSwapGroupsNV;
+        typedef Bool (APIENTRYP PFNGLXQUERYFRAMECOUNTNVPROC)(Display* dpy, int screen, GLuint* count);
+        PFNGLXQUERYFRAMECOUNTNVPROC QueryFrameCountNV;
+        typedef Bool (APIENTRYP PFNGLXRESETFRAMECOUNTNVPROC)(Display* dpy, int screen);
+        PFNGLXRESETFRAMECOUNTNVPROC ResetFrameCountNV;
+        typedef int (APIENTRYP PFNGLXBINDVIDEOCAPTUREDEVICENVPROC)(Display* dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device);
+        PFNGLXBINDVIDEOCAPTUREDEVICENVPROC BindVideoCaptureDeviceNV;
+        typedef GLXVideoCaptureDeviceNV * (APIENTRYP PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC)(Display* dpy, int screen, int* nelements);
+        PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC EnumerateVideoCaptureDevicesNV;
+        typedef void (APIENTRYP PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC)(Display* dpy, GLXVideoCaptureDeviceNV device);
+        PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC LockVideoCaptureDeviceNV;
+        typedef int (APIENTRYP PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC)(Display* dpy, GLXVideoCaptureDeviceNV device, int attribute, int* value);
+        PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC QueryVideoCaptureDeviceNV;
+        typedef void (APIENTRYP PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC)(Display* dpy, GLXVideoCaptureDeviceNV device);
+        PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC ReleaseVideoCaptureDeviceNV;
+        typedef int (APIENTRYP PFNGLXSWAPINTERVALEXTPROC)(Display* dpy, GLXDrawable drawable, int interval);
+        PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
+        typedef void (APIENTRYP PFNGLXCOPYIMAGESUBDATANVPROC)(Display* dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
+        PFNGLXCOPYIMAGESUBDATANVPROC CopyImageSubDataNV;
 
-glx_version_1_3::Loader::Loader() :
-        GetFBConfigs(0),
-        ChooseFBConfig(0),
-        GetFBConfigAttrib(0),
-        GetVisualFromFBConfig(0),
-        CreateWindow(0),
-        DestroyWindow(0),
-        CreatePixmap(0),
-        DestroyPixmap(0),
-        CreatePbuffer(0),
-        DestroyPbuffer(0),
-        QueryDrawable(0),
-        CreateNewContext(0),
-        MakeContextCurrent(0),
-        GetCurrentReadDrawable(0),
-        GetCurrentDisplay(0),
-        QueryContext(0),
-        SelectEvent(0),
-        GetSelectedEvent(0),
+        Loader() { memset(this, 0, sizeof(Loader)); }
+    };
+    
+#ifdef GLXX_TLS
+    #if defined(_WIN32) || defined(WIN32)
+    __declspec(thread) Loader* current_loader = 0;
+    #endif
+    #if defined(__linux__)
+    __thread Loader* current_loader = 0;
+    #endif
+#else
+    Loader* current_loader = 0;
+#endif //GLXX_TLS
 
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_version_1_3::Loader initialized without a current context");
 
-    GetFBConfigs = (PFNGLXGETFBCONFIGSPROC) GetProcAddr("glXGetFBConfigs");
-    if (!GetFBConfigs)
-        is_loaded = false;
+    std::vector<std::tr1::shared_ptr<Loader> > loaders;
+    std::set<GLuint> unused_loader_indices;
 
-    ChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) GetProcAddr("glXChooseFBConfig");
-    if (!ChooseFBConfig)
-        is_loaded = false;
+    GLuint GenLoader()
+    {
+        if (unused_loader_indices.empty()) {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            return loaders.size() - 1;
+        } else {
+            GLuint first_unused_loader = *(unused_loader_indices.begin());
+            loaders[first_unused_loader].reset(new Loader);
+            unused_loader_indices.erase(unused_loader_indices.begin());
+            return first_unused_loader;
+        }
+    }
 
-    GetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC) GetProcAddr("glXGetFBConfigAttrib");
-    if (!GetFBConfigAttrib)
-        is_loaded = false;
+    void BindLoader(GLuint loader)
+    {
+        current_loader = loaders[loader].get();
+    }
 
-    GetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC) GetProcAddr("glXGetVisualFromFBConfig");
-    if (!GetVisualFromFBConfig)
-        is_loaded = false;
+    void DeleteLoader(GLuint loader)
+    {
+        if (loaders[loader].get() == current_loader) {
+            if (!loaders.empty())
+                current_loader = loaders[0].get();
+            else
+                current_loader = 0;
+        }
+        loaders[loader].reset();
+        unused_loader_indices.insert(loader);
+    }
 
-    CreateWindow = (PFNGLXCREATEWINDOWPROC) GetProcAddr("glXCreateWindow");
-    if (!CreateWindow)
-        is_loaded = false;
+    
 
-    DestroyWindow = (PFNGLXDESTROYWINDOWPROC) GetProcAddr("glXDestroyWindow");
-    if (!DestroyWindow)
-        is_loaded = false;
+    bool load_version_1_3()
+    {        
+        assert(GetCurrentCtx() && "load_version_1_3() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
-    CreatePixmap = (PFNGLXCREATEPIXMAPPROC) GetProcAddr("glXCreatePixmap");
-    if (!CreatePixmap)
-        is_loaded = false;
+        current_loader->GetFBConfigs = (Loader::PFNGLXGETFBCONFIGSPROC) GetProcAddr("glXGetFBConfigs");
+        if (!current_loader->GetFBConfigs) is_loaded = false;
+        current_loader->ChooseFBConfig = (Loader::PFNGLXCHOOSEFBCONFIGPROC) GetProcAddr("glXChooseFBConfig");
+        if (!current_loader->ChooseFBConfig) is_loaded = false;
+        current_loader->GetFBConfigAttrib = (Loader::PFNGLXGETFBCONFIGATTRIBPROC) GetProcAddr("glXGetFBConfigAttrib");
+        if (!current_loader->GetFBConfigAttrib) is_loaded = false;
+        current_loader->GetVisualFromFBConfig = (Loader::PFNGLXGETVISUALFROMFBCONFIGPROC) GetProcAddr("glXGetVisualFromFBConfig");
+        if (!current_loader->GetVisualFromFBConfig) is_loaded = false;
+        current_loader->CreateWindow = (Loader::PFNGLXCREATEWINDOWPROC) GetProcAddr("glXCreateWindow");
+        if (!current_loader->CreateWindow) is_loaded = false;
+        current_loader->DestroyWindow = (Loader::PFNGLXDESTROYWINDOWPROC) GetProcAddr("glXDestroyWindow");
+        if (!current_loader->DestroyWindow) is_loaded = false;
+        current_loader->CreatePixmap = (Loader::PFNGLXCREATEPIXMAPPROC) GetProcAddr("glXCreatePixmap");
+        if (!current_loader->CreatePixmap) is_loaded = false;
+        current_loader->DestroyPixmap = (Loader::PFNGLXDESTROYPIXMAPPROC) GetProcAddr("glXDestroyPixmap");
+        if (!current_loader->DestroyPixmap) is_loaded = false;
+        current_loader->CreatePbuffer = (Loader::PFNGLXCREATEPBUFFERPROC) GetProcAddr("glXCreatePbuffer");
+        if (!current_loader->CreatePbuffer) is_loaded = false;
+        current_loader->DestroyPbuffer = (Loader::PFNGLXDESTROYPBUFFERPROC) GetProcAddr("glXDestroyPbuffer");
+        if (!current_loader->DestroyPbuffer) is_loaded = false;
+        current_loader->QueryDrawable = (Loader::PFNGLXQUERYDRAWABLEPROC) GetProcAddr("glXQueryDrawable");
+        if (!current_loader->QueryDrawable) is_loaded = false;
+        current_loader->CreateNewContext = (Loader::PFNGLXCREATENEWCONTEXTPROC) GetProcAddr("glXCreateNewContext");
+        if (!current_loader->CreateNewContext) is_loaded = false;
+        current_loader->MakeContextCurrent = (Loader::PFNGLXMAKECONTEXTCURRENTPROC) GetProcAddr("glXMakeContextCurrent");
+        if (!current_loader->MakeContextCurrent) is_loaded = false;
+        current_loader->GetCurrentReadDrawable = (Loader::PFNGLXGETCURRENTREADDRAWABLEPROC) GetProcAddr("glXGetCurrentReadDrawable");
+        if (!current_loader->GetCurrentReadDrawable) is_loaded = false;
+        current_loader->GetCurrentDisplay = (Loader::PFNGLXGETCURRENTDISPLAYPROC) GetProcAddr("glXGetCurrentDisplay");
+        if (!current_loader->GetCurrentDisplay) is_loaded = false;
+        current_loader->QueryContext = (Loader::PFNGLXQUERYCONTEXTPROC) GetProcAddr("glXQueryContext");
+        if (!current_loader->QueryContext) is_loaded = false;
+        current_loader->SelectEvent = (Loader::PFNGLXSELECTEVENTPROC) GetProcAddr("glXSelectEvent");
+        if (!current_loader->SelectEvent) is_loaded = false;
+        current_loader->GetSelectedEvent = (Loader::PFNGLXGETSELECTEDEVENTPROC) GetProcAddr("glXGetSelectedEvent");
+        if (!current_loader->GetSelectedEvent) is_loaded = false;
+        
+        return is_loaded;
+    }
 
-    DestroyPixmap = (PFNGLXDESTROYPIXMAPPROC) GetProcAddr("glXDestroyPixmap");
-    if (!DestroyPixmap)
-        is_loaded = false;
+    GLXFBConfig * glx_version_1_3::glXGetFBConfigs(Display* dpy, int screen, int* nelements)
+    {
+        return current_loader->GetFBConfigs(dpy, screen, nelements);
+    }
 
-    CreatePbuffer = (PFNGLXCREATEPBUFFERPROC) GetProcAddr("glXCreatePbuffer");
-    if (!CreatePbuffer)
-        is_loaded = false;
+    GLXFBConfig * glx_version_1_3::glXChooseFBConfig(Display* dpy, int screen, const int* attrib_list, int* nelements)
+    {
+        return current_loader->ChooseFBConfig(dpy, screen, attrib_list, nelements);
+    }
 
-    DestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) GetProcAddr("glXDestroyPbuffer");
-    if (!DestroyPbuffer)
-        is_loaded = false;
+    int glx_version_1_3::glXGetFBConfigAttrib(Display* dpy, GLXFBConfig config, int attribute, int* value)
+    {
+        return current_loader->GetFBConfigAttrib(dpy, config, attribute, value);
+    }
 
-    QueryDrawable = (PFNGLXQUERYDRAWABLEPROC) GetProcAddr("glXQueryDrawable");
-    if (!QueryDrawable)
-        is_loaded = false;
+    XVisualInfo * glx_version_1_3::glXGetVisualFromFBConfig(Display* dpy, GLXFBConfig config)
+    {
+        return current_loader->GetVisualFromFBConfig(dpy, config);
+    }
 
-    CreateNewContext = (PFNGLXCREATENEWCONTEXTPROC) GetProcAddr("glXCreateNewContext");
-    if (!CreateNewContext)
-        is_loaded = false;
+    GLXWindow glx_version_1_3::glXCreateWindow(Display* dpy, GLXFBConfig config, Window win, const int* attrib_list)
+    {
+        return current_loader->CreateWindow(dpy, config, win, attrib_list);
+    }
 
-    MakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC) GetProcAddr("glXMakeContextCurrent");
-    if (!MakeContextCurrent)
-        is_loaded = false;
+    void glx_version_1_3::glXDestroyWindow(Display* dpy, GLXWindow win)
+    {
+        current_loader->DestroyWindow(dpy, win);
+    }
 
-    GetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC) GetProcAddr("glXGetCurrentReadDrawable");
-    if (!GetCurrentReadDrawable)
-        is_loaded = false;
+    GLXPixmap glx_version_1_3::glXCreatePixmap(Display* dpy, GLXFBConfig config, Pixmap pixmap, const int* attrib_list)
+    {
+        return current_loader->CreatePixmap(dpy, config, pixmap, attrib_list);
+    }
 
-    GetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC) GetProcAddr("glXGetCurrentDisplay");
-    if (!GetCurrentDisplay)
-        is_loaded = false;
+    void glx_version_1_3::glXDestroyPixmap(Display* dpy, GLXPixmap pixmap)
+    {
+        current_loader->DestroyPixmap(dpy, pixmap);
+    }
 
-    QueryContext = (PFNGLXQUERYCONTEXTPROC) GetProcAddr("glXQueryContext");
-    if (!QueryContext)
-        is_loaded = false;
+    GLXPbuffer glx_version_1_3::glXCreatePbuffer(Display* dpy, GLXFBConfig config, const int* attrib_list)
+    {
+        return current_loader->CreatePbuffer(dpy, config, attrib_list);
+    }
 
-    SelectEvent = (PFNGLXSELECTEVENTPROC) GetProcAddr("glXSelectEvent");
-    if (!SelectEvent)
-        is_loaded = false;
+    void glx_version_1_3::glXDestroyPbuffer(Display* dpy, GLXPbuffer pbuf)
+    {
+        current_loader->DestroyPbuffer(dpy, pbuf);
+    }
 
-    GetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC) GetProcAddr("glXGetSelectedEvent");
-    if (!GetSelectedEvent)
-        is_loaded = false;
-}
+    void glx_version_1_3::glXQueryDrawable(Display* dpy, GLXDrawable draw, int attribute, unsigned int* value)
+    {
+        current_loader->QueryDrawable(dpy, draw, attribute, value);
+    }
 
-bool has_version_1_3() 
-{
-    return IsVersionSupported(1, 3);
-}
+    GLXContext glx_version_1_3::glXCreateNewContext(Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
+    {
+        return current_loader->CreateNewContext(dpy, config, render_type, share_list, direct);
+    }
 
+    Bool glx_version_1_3::glXMakeContextCurrent(Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
+    {
+        return current_loader->MakeContextCurrent(dpy, draw, read, ctx);
+    }
 
-std::auto_ptr<glx_version_1_3::Loader> default_version_1_3_loader;
+    GLXDrawable glx_version_1_3::glXGetCurrentReadDrawable()
+    {
+        return current_loader->GetCurrentReadDrawable();
+    }
 
-bool load_version_1_3() 
-{
-    default_version_1_3_loader.reset(new glx_version_1_3::Loader);
-    return default_version_1_3_loader->isLoaded();
-}
+    Display * glx_version_1_3::glXGetCurrentDisplay()
+    {
+        return current_loader->GetCurrentDisplay();
+    }
 
+    int glx_version_1_3::glXQueryContext(Display* dpy, GLXContext ctx, int attribute, int* value)
+    {
+        return current_loader->QueryContext(dpy, ctx, attribute, value);
+    }
 
-GLXFBConfig * glx_version_1_3::glXGetFBConfigs(Display* dpy, int screen, int* nelements)
-{
-    return default_version_1_3_loader->GetFBConfigs(dpy, screen, nelements);
-}
+    void glx_version_1_3::glXSelectEvent(Display* dpy, GLXDrawable draw, unsigned long event_mask)
+    {
+        current_loader->SelectEvent(dpy, draw, event_mask);
+    }
 
-GLXFBConfig * glx_version_1_3::glXChooseFBConfig(Display* dpy, int screen, const int* attrib_list, int* nelements)
-{
-    return default_version_1_3_loader->ChooseFBConfig(dpy, screen, attrib_list, nelements);
-}
+    void glx_version_1_3::glXGetSelectedEvent(Display* dpy, GLXDrawable draw, unsigned long* event_mask)
+    {
+        current_loader->GetSelectedEvent(dpy, draw, event_mask);
+    }
 
-int glx_version_1_3::glXGetFBConfigAttrib(Display* dpy, GLXFBConfig config, int attribute, int* value)
-{
-    return default_version_1_3_loader->GetFBConfigAttrib(dpy, config, attribute, value);
-}
 
-XVisualInfo * glx_version_1_3::glXGetVisualFromFBConfig(Display* dpy, GLXFBConfig config)
-{
-    return default_version_1_3_loader->GetVisualFromFBConfig(dpy, config);
-}
+    bool load_version_1_4()
+    {        
+        assert(GetCurrentCtx() && "load_version_1_4() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
-GLXWindow glx_version_1_3::glXCreateWindow(Display* dpy, GLXFBConfig config, Window win, const int* attrib_list)
-{
-    return default_version_1_3_loader->CreateWindow(dpy, config, win, attrib_list);
-}
+        current_loader->GetProcAddress = (Loader::PFNGLXGETPROCADDRESSPROC) GetProcAddr("glXGetProcAddress");
+        if (!current_loader->GetProcAddress) is_loaded = false;
+        
+        return is_loaded;
+    }
 
-void glx_version_1_3::glXDestroyWindow(Display* dpy, GLXWindow win)
-{
-    default_version_1_3_loader->DestroyWindow(dpy, win);
-}
+    __GLXextFuncPtr glx_version_1_4::glXGetProcAddress(const GLubyte* procName)
+    {
+        return current_loader->GetProcAddress(procName);
+    }
 
-GLXPixmap glx_version_1_3::glXCreatePixmap(Display* dpy, GLXFBConfig config, Pixmap pixmap, const int* attrib_list)
-{
-    return default_version_1_3_loader->CreatePixmap(dpy, config, pixmap, attrib_list);
-}
 
-void glx_version_1_3::glXDestroyPixmap(Display* dpy, GLXPixmap pixmap)
-{
-    default_version_1_3_loader->DestroyPixmap(dpy, pixmap);
-}
+    bool load_arb_get_proc_address()
+    {        
+        assert(GetCurrentCtx() && "load_arb_get_proc_address() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
-GLXPbuffer glx_version_1_3::glXCreatePbuffer(Display* dpy, GLXFBConfig config, const int* attrib_list)
-{
-    return default_version_1_3_loader->CreatePbuffer(dpy, config, attrib_list);
-}
+        current_loader->GetProcAddressARB = (Loader::PFNGLXGETPROCADDRESSARBPROC) GetProcAddr("glXGetProcAddressARB");
+        if (!current_loader->GetProcAddressARB) is_loaded = false;
+        
+        return is_loaded;
+    }
 
-void glx_version_1_3::glXDestroyPbuffer(Display* dpy, GLXPbuffer pbuf)
-{
-    default_version_1_3_loader->DestroyPbuffer(dpy, pbuf);
-}
+    bool has_arb_get_proc_address()
+    {
+        return IsExtensionSupported("GLX_ARB_get_proc_address");
+    }
 
-void glx_version_1_3::glXQueryDrawable(Display* dpy, GLXDrawable draw, int attribute, unsigned int* value)
-{
-    default_version_1_3_loader->QueryDrawable(dpy, draw, attribute, value);
-}
 
-GLXContext glx_version_1_3::glXCreateNewContext(Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
-{
-    return default_version_1_3_loader->CreateNewContext(dpy, config, render_type, share_list, direct);
-}
+    __GLXextFuncPtr glx_arb_get_proc_address::glXGetProcAddressARB(const GLubyte* procName)
+    {
+        return current_loader->GetProcAddressARB(procName);
+    }
 
-Bool glx_version_1_3::glXMakeContextCurrent(Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
-{
-    return default_version_1_3_loader->MakeContextCurrent(dpy, draw, read, ctx);
-}
 
-GLXDrawable glx_version_1_3::glXGetCurrentReadDrawable()
-{
-    return default_version_1_3_loader->GetCurrentReadDrawable();
-}
+    bool load_arb_multisample()
+    {        
+        assert(GetCurrentCtx() && "load_arb_multisample() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
-Display * glx_version_1_3::glXGetCurrentDisplay()
-{
-    return default_version_1_3_loader->GetCurrentDisplay();
-}
+        
+        return is_loaded;
+    }
 
-int glx_version_1_3::glXQueryContext(Display* dpy, GLXContext ctx, int attribute, int* value)
-{
-    return default_version_1_3_loader->QueryContext(dpy, ctx, attribute, value);
-}
+    bool has_arb_multisample()
+    {
+        return IsExtensionSupported("GLX_ARB_multisample");
+    }
 
-void glx_version_1_3::glXSelectEvent(Display* dpy, GLXDrawable draw, unsigned long event_mask)
-{
-    default_version_1_3_loader->SelectEvent(dpy, draw, event_mask);
-}
 
-void glx_version_1_3::glXGetSelectedEvent(Display* dpy, GLXDrawable draw, unsigned long* event_mask)
-{
-    default_version_1_3_loader->GetSelectedEvent(dpy, draw, event_mask);
-}
 
+    bool load_arb_fbconfig_float()
+    {        
+        assert(GetCurrentCtx() && "load_arb_fbconfig_float() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
+        
+        return is_loaded;
+    }
 
-glx_version_1_4::Loader::Loader() :
-        GetProcAddress(0),
+    bool has_arb_fbconfig_float()
+    {
+        return IsExtensionSupported("GLX_ARB_fbconfig_float");
+    }
 
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_version_1_4::Loader initialized without a current context");
 
-    GetProcAddress = (PFNGLXGETPROCADDRESSPROC) GetProcAddr("glXGetProcAddress");
-    if (!GetProcAddress)
-        is_loaded = false;
-}
 
-bool has_version_1_4() 
-{
-    return IsVersionSupported(1, 4);
-}
+    bool load_arb_framebuffer_srgb()
+    {        
+        assert(GetCurrentCtx() && "load_arb_framebuffer_srgb() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
+        
+        return is_loaded;
+    }
 
-std::auto_ptr<glx_version_1_4::Loader> default_version_1_4_loader;
+    bool has_arb_framebuffer_srgb()
+    {
+        return IsExtensionSupported("GLX_ARB_framebuffer_sRGB");
+    }
 
-bool load_version_1_4() 
-{
-    default_version_1_4_loader.reset(new glx_version_1_4::Loader);
-    return default_version_1_4_loader->isLoaded();
-}
 
 
-__GLXextFuncPtr glx_version_1_4::glXGetProcAddress(const GLubyte* procName)
-{
-    return default_version_1_4_loader->GetProcAddress(procName);
-}
+    bool load_arb_create_context()
+    {        
+        assert(GetCurrentCtx() && "load_arb_create_context() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
+        current_loader->CreateContextAttribsARB = (Loader::PFNGLXCREATECONTEXTATTRIBSARBPROC) GetProcAddr("glXCreateContextAttribsARB");
+        if (!current_loader->CreateContextAttribsARB) is_loaded = false;
+        
+        return is_loaded;
+    }
 
+    bool has_arb_create_context()
+    {
+        return IsExtensionSupported("GLX_ARB_create_context");
+    }
 
-glx_arb_get_proc_address::Loader::Loader() :
-        GetProcAddressARB(0),
 
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_arb_get_proc_address::Loader initialized without a current context");
+    GLXContext glx_arb_create_context::glXCreateContextAttribsARB(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int* attrib_list)
+    {
+        return current_loader->CreateContextAttribsARB(dpy, config, share_context, direct, attrib_list);
+    }
 
-    GetProcAddressARB = (PFNGLXGETPROCADDRESSARBPROC) GetProcAddr("glXGetProcAddressARB");
-    if (!GetProcAddressARB)
-        is_loaded = false;
-}
 
-bool has_arb_get_proc_address() 
-{
-    return IsExtensionSupported("GLX_ARB_get_proc_address");
-}
+    bool load_arb_create_context_profile()
+    {        
+        assert(GetCurrentCtx() && "load_arb_create_context_profile() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
+        
+        return is_loaded;
+    }
 
-std::auto_ptr<glx_arb_get_proc_address::Loader> default_arb_get_proc_address_loader;
+    bool has_arb_create_context_profile()
+    {
+        return IsExtensionSupported("GLX_ARB_create_context_profile");
+    }
 
-bool load_arb_get_proc_address() 
-{
-    default_arb_get_proc_address_loader.reset(new glx_arb_get_proc_address::Loader);
-    return default_arb_get_proc_address_loader->isLoaded();
-}
 
 
-__GLXextFuncPtr glx_arb_get_proc_address::glXGetProcAddressARB(const GLubyte* procName)
-{
-    return default_arb_get_proc_address_loader->GetProcAddressARB(procName);
-}
+    bool load_arb_create_context_robustness()
+    {        
+        assert(GetCurrentCtx() && "load_arb_create_context_robustness() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
+        
+        return is_loaded;
+    }
 
+    bool has_arb_create_context_robustness()
+    {
+        return IsExtensionSupported("GLX_ARB_create_context_robustness");
+    }
 
-glx_arb_multisample::Loader::Loader() :
 
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_arb_multisample::Loader initialized without a current context");
-}
 
-bool has_arb_multisample() 
-{
-    return IsExtensionSupported("GLX_ARB_multisample");
-}
+    bool load_sgis_multisample()
+    {        
+        assert(GetCurrentCtx() && "load_sgis_multisample() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
+        
+        return is_loaded;
+    }
 
-std::auto_ptr<glx_arb_multisample::Loader> default_arb_multisample_loader;
+    bool has_sgis_multisample()
+    {
+        return IsExtensionSupported("GLX_SGIS_multisample");
+    }
 
-bool load_arb_multisample() 
-{
-    default_arb_multisample_loader.reset(new glx_arb_multisample::Loader);
-    return default_arb_multisample_loader->isLoaded();
-}
 
 
+    bool load_ext_visual_info()
+    {        
+        assert(GetCurrentCtx() && "load_ext_visual_info() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
+        
+        return is_loaded;
+    }
 
-glx_arb_fbconfig_float::Loader::Loader() :
+    bool has_ext_visual_info()
+    {
+        return IsExtensionSupported("GLX_EXT_visual_info");
+    }
 
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_arb_fbconfig_float::Loader initialized without a current context");
-}
 
-bool has_arb_fbconfig_float() 
-{
-    return IsExtensionSupported("GLX_ARB_fbconfig_float");
-}
 
+    bool load_sgi_swap_control()
+    {        
+        assert(GetCurrentCtx() && "load_sgi_swap_control() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
-std::auto_ptr<glx_arb_fbconfig_float::Loader> default_arb_fbconfig_float_loader;
+        current_loader->SwapIntervalSGI = (Loader::PFNGLXSWAPINTERVALSGIPROC) GetProcAddr("glXSwapIntervalSGI");
+        if (!current_loader->SwapIntervalSGI) is_loaded = false;
+        
+        return is_loaded;
+    }
 
-bool load_arb_fbconfig_float() 
-{
-    default_arb_fbconfig_float_loader.reset(new glx_arb_fbconfig_float::Loader);
-    return default_arb_fbconfig_float_loader->isLoaded();
-}
+    bool has_sgi_swap_control()
+    {
+        return IsExtensionSupported("GLX_SGI_swap_control");
+    }
 
 
+    int glx_sgi_swap_control::glXSwapIntervalSGI(int interval)
+    {
+        return current_loader->SwapIntervalSGI(interval);
+    }
 
 
-glx_arb_framebuffer_srgb::Loader::Loader() :
+    bool load_sgi_video_sync()
+    {        
+        assert(GetCurrentCtx() && "load_sgi_video_sync() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_arb_framebuffer_srgb::Loader initialized without a current context");
-}
+        current_loader->GetVideoSyncSGI = (Loader::PFNGLXGETVIDEOSYNCSGIPROC) GetProcAddr("glXGetVideoSyncSGI");
+        if (!current_loader->GetVideoSyncSGI) is_loaded = false;
+        current_loader->WaitVideoSyncSGI = (Loader::PFNGLXWAITVIDEOSYNCSGIPROC) GetProcAddr("glXWaitVideoSyncSGI");
+        if (!current_loader->WaitVideoSyncSGI) is_loaded = false;
+        
+        return is_loaded;
+    }
 
-bool has_arb_framebuffer_srgb() 
-{
-    return IsExtensionSupported("GLX_ARB_framebuffer_sRGB");
-}
+    bool has_sgi_video_sync()
+    {
+        return IsExtensionSupported("GLX_SGI_video_sync");
+    }
 
 
-std::auto_ptr<glx_arb_framebuffer_srgb::Loader> default_arb_framebuffer_srgb_loader;
+    int glx_sgi_video_sync::glXGetVideoSyncSGI(unsigned int* count)
+    {
+        return current_loader->GetVideoSyncSGI(count);
+    }
 
-bool load_arb_framebuffer_srgb() 
-{
-    default_arb_framebuffer_srgb_loader.reset(new glx_arb_framebuffer_srgb::Loader);
-    return default_arb_framebuffer_srgb_loader->isLoaded();
-}
+    int glx_sgi_video_sync::glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int* count)
+    {
+        return current_loader->WaitVideoSyncSGI(divisor, remainder, count);
+    }
 
 
+    bool load_sgi_make_current_read()
+    {        
+        assert(GetCurrentCtx() && "load_sgi_make_current_read() called without a current context");
+        
+        if (current_loader == 0)
+        {
+            loaders.push_back(std::tr1::shared_ptr<Loader>(new Loader));
+            current_loader = loaders[0].get();
+        }
+        
+        bool is_loaded = true;
 
+        current_loader->MakeCurrentReadSGI = (Loader::PFNGLXMAKECURRENTREADSGIPROC) GetProcAddr("glXMakeCurrentReadSGI");
+        if (!current_loader->MakeCurrentReadSGI) is_loaded = false;
+        current_loader->GetCurrentReadDrawableSGI = (Loader::PFNGLXGETCURRENTREADDRAWABLESGIPROC) GetProcAddr("glXGetCurrentReadDrawableSGI");
+        if (!current_loader->GetCurrentReadDrawableSGI) is_loaded = false;
+        
+        return is_loaded;
+    }
 
-glx_arb_create_context::Loader::Loader() :
-        CreateContextAttribsARB(0),
+    bool has_sgi_make_current_read()
+    {
+        return IsExtensionSupported("GLX_SGI_make_current_read");
+    }
 
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_arb_create_context::Loader initialized without a current context");
 
-    CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) GetProcAddr("glXCreateContextAttribsARB");
-    if (!CreateContextAttribsARB)
-        is_loaded = false;
-}
+    Bool glx_sgi_make_current_read::glXMakeCurrentReadSGI(Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
+    {
+        return current_loader->MakeCurrentReadSGI(dpy, draw, read, ctx);
+    }
 
-bool has_arb_create_context() 
-{
-    return IsExtensionSupported("GLX_ARB_create_context");
-}
-
-
-std::auto_ptr<glx_arb_create_context::Loader> default_arb_create_context_loader;
-
-bool load_arb_create_context() 
-{
-    default_arb_create_context_loader.reset(new glx_arb_create_context::Loader);
-    return default_arb_create_context_loader->isLoaded();
-}
-
-
-GLXContext glx_arb_create_context::glXCreateContextAttribsARB(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int* attrib_list)
-{
-    return default_arb_create_context_loader->CreateContextAttribsARB(dpy, config, share_context, direct, attrib_list);
-}
-
-
-
-glx_arb_create_context_profile::Loader::Loader() :
-
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_arb_create_context_profile::Loader initialized without a current context");
-}
-
-bool has_arb_create_context_profile() 
-{
-    return IsExtensionSupported("GLX_ARB_create_context_profile");
-}
-
-
-std::auto_ptr<glx_arb_create_context_profile::Loader> default_arb_create_context_profile_loader;
-
-bool load_arb_create_context_profile() 
-{
-    default_arb_create_context_profile_loader.reset(new glx_arb_create_context_profile::Loader);
-    return default_arb_create_context_profile_loader->isLoaded();
-}
-
-
-
-
-glx_arb_create_context_robustness::Loader::Loader() :
-
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_arb_create_context_robustness::Loader initialized without a current context");
-}
-
-bool has_arb_create_context_robustness() 
-{
-    return IsExtensionSupported("GLX_ARB_create_context_robustness");
-}
-
-
-std::auto_ptr<glx_arb_create_context_robustness::Loader> default_arb_create_context_robustness_loader;
-
-bool load_arb_create_context_robustness() 
-{
-    default_arb_create_context_robustness_loader.reset(new glx_arb_create_context_robustness::Loader);
-    return default_arb_create_context_robustness_loader->isLoaded();
-}
-
-
-
-
-glx_sgis_multisample::Loader::Loader() :
-
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_sgis_multisample::Loader initialized without a current context");
-}
-
-bool has_sgis_multisample() 
-{
-    return IsExtensionSupported("GLX_SGIS_multisample");
-}
-
-
-std::auto_ptr<glx_sgis_multisample::Loader> default_sgis_multisample_loader;
-
-bool load_sgis_multisample() 
-{
-    default_sgis_multisample_loader.reset(new glx_sgis_multisample::Loader);
-    return default_sgis_multisample_loader->isLoaded();
-}
-
-
-
-
-glx_ext_visual_info::Loader::Loader() :
-
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_ext_visual_info::Loader initialized without a current context");
-}
-
-bool has_ext_visual_info() 
-{
-    return IsExtensionSupported("GLX_EXT_visual_info");
-}
-
-
-std::auto_ptr<glx_ext_visual_info::Loader> default_ext_visual_info_loader;
-
-bool load_ext_visual_info() 
-{
-    default_ext_visual_info_loader.reset(new glx_ext_visual_info::Loader);
-    return default_ext_visual_info_loader->isLoaded();
-}
-
-
-
-
-glx_sgi_swap_control::Loader::Loader() :
-        SwapIntervalSGI(0),
-
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_sgi_swap_control::Loader initialized without a current context");
-
-    SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) GetProcAddr("glXSwapIntervalSGI");
-    if (!SwapIntervalSGI)
-        is_loaded = false;
-}
-
-bool has_sgi_swap_control() 
-{
-    return IsExtensionSupported("GLX_SGI_swap_control");
-}
-
-
-std::auto_ptr<glx_sgi_swap_control::Loader> default_sgi_swap_control_loader;
-
-bool load_sgi_swap_control() 
-{
-    default_sgi_swap_control_loader.reset(new glx_sgi_swap_control::Loader);
-    return default_sgi_swap_control_loader->isLoaded();
-}
-
-
-int glx_sgi_swap_control::glXSwapIntervalSGI(int interval)
-{
-    return default_sgi_swap_control_loader->SwapIntervalSGI(interval);
-}
-
-
-
-glx_sgi_video_sync::Loader::Loader() :
-        GetVideoSyncSGI(0),
-        WaitVideoSyncSGI(0),
-
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_sgi_video_sync::Loader initialized without a current context");
-
-    GetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGIPROC) GetProcAddr("glXGetVideoSyncSGI");
-    if (!GetVideoSyncSGI)
-        is_loaded = false;
-
-    WaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC) GetProcAddr("glXWaitVideoSyncSGI");
-    if (!WaitVideoSyncSGI)
-        is_loaded = false;
-}
-
-bool has_sgi_video_sync() 
-{
-    return IsExtensionSupported("GLX_SGI_video_sync");
-}
-
-
-std::auto_ptr<glx_sgi_video_sync::Loader> default_sgi_video_sync_loader;
-
-bool load_sgi_video_sync() 
-{
-    default_sgi_video_sync_loader.reset(new glx_sgi_video_sync::Loader);
-    return default_sgi_video_sync_loader->isLoaded();
-}
-
-
-int glx_sgi_video_sync::glXGetVideoSyncSGI(unsigned int* count)
-{
-    return default_sgi_video_sync_loader->GetVideoSyncSGI(count);
-}
-
-int glx_sgi_video_sync::glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int* count)
-{
-    return default_sgi_video_sync_loader->WaitVideoSyncSGI(divisor, remainder, count);
-}
-
-
-
-glx_sgi_make_current_read::Loader::Loader() :
-        MakeCurrentReadSGI(0),
-        GetCurrentReadDrawableSGI(0),
-
-        is_loaded(true)
-{
-    assert(GetCurrentCtx() && "glx_sgi_make_current_read::Loader initialized without a current context");
-
-    MakeCurrentReadSGI = (PFNGLXMAKECURRENTREADSGIPROC) GetProcAddr("glXMakeCurrentReadSGI");
-    if (!MakeCurrentReadSGI)
-        is_loaded = false;
-
-    GetCurrentReadDrawableSGI = (PFNGLXGETCURRENTREADDRAWABLESGIPROC) GetProcAddr("glXGetCurrentReadDrawableSGI");
-    if (!GetCurrentReadDrawableSGI)
-        is_loaded = false;
-}
-
-bool has_sgi_make_current_read() 
-{
-    return IsExtensionSupported("GLX_SGI_make_current_read");
-}
-
-
-std::auto_ptr<glx_sgi_make_current_read::Loader> default_sgi_make_current_read_loader;
-
-bool load_sgi_make_current_read() 
-{
-    default_sgi_make_current_read_loader.reset(new glx_sgi_make_current_read::Loader);
-    return default_sgi_make_current_read_loader->isLoaded();
-}
-
-
-Bool glx_sgi_make_current_read::glXMakeCurrentReadSGI(Display* dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
-{
-    return default_sgi_make_current_read_loader->MakeCurrentReadSGI(dpy, draw, read, ctx);
-}
-
-GLXDrawable glx_sgi_make_current_read::glXGetCurrentReadDrawableSGI()
-{
-    return default_sgi_make_current_read_loader->GetCurrentReadDrawableSGI();
-}
<