Revert "Revert 164047 - Make GL calls go through subclassable class."

This reverts commit 25afcfe213ffd88f8e9370d4ff1ee23ecf9ae16c.

BUG=155557
[email protected]

Review URL: https://codereview.chromium.org/11264041

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@164095 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/content/common/gpu/gpu_channel_manager.cc b/content/common/gpu/gpu_channel_manager.cc
index d39736a..41a51c09 100644
--- a/content/common/gpu/gpu_channel_manager.cc
+++ b/content/common/gpu/gpu_channel_manager.cc
@@ -58,7 +58,8 @@
 
 gpu::gles2::ProgramCache* GpuChannelManager::program_cache() {
   if (!program_cache_.get() &&
-      (gfx::g_ARB_get_program_binary || gfx::g_OES_get_program_binary) &&
+      (gfx::g_driver_gl.ext.b_ARB_get_program_binary ||
+       gfx::g_driver_gl.ext.b_OES_get_program_binary) &&
       !CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kDisableGpuProgramCache)) {
     program_cache_.reset(new gpu::gles2::MemoryProgramCache());
diff --git a/gpu/command_buffer/service/program_manager.cc b/gpu/command_buffer/service/program_manager.cc
index e86912e..dcc6745 100644
--- a/gpu/command_buffer/service/program_manager.cc
+++ b/gpu/command_buffer/service/program_manager.cc
@@ -531,7 +531,7 @@
 
   if (link) {
     before_time = TimeTicks::HighResNow();
-    if (cache && gfx::g_GL_ARB_get_program_binary) {
+    if (cache && gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary) {
       glProgramParameteri(service_id(),
                           PROGRAM_BINARY_RETRIEVABLE_HINT,
                           GL_TRUE);
diff --git a/gpu/command_buffer/service/program_manager_unittest.cc b/gpu/command_buffer/service/program_manager_unittest.cc
index 227a81fb..8499ff3 100644
--- a/gpu/command_buffer/service/program_manager_unittest.cc
+++ b/gpu/command_buffer/service/program_manager_unittest.cc
@@ -1287,7 +1287,7 @@
 
   void SetExpectationsForProgramLink(GLuint service_program_id) {
     TestHelper::SetupShader(gl_.get(), NULL, 0, NULL, 0, service_program_id);
-    if (gfx::g_GL_ARB_get_program_binary) {
+    if (gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary) {
       EXPECT_CALL(*gl_.get(),
                   ProgramParameteri(service_program_id,
                                     PROGRAM_BINARY_RETRIEVABLE_HINT,
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py
index 72c9eb1e..0090602 100755
--- a/ui/gl/generate_bindings.py
+++ b/ui/gl/generate_bindings.py
@@ -1145,10 +1145,6 @@
 
 class GLContext;
 
-void InitializeGLBindings%(name)s();
-void InitializeGLExtensionBindings%(name)s(GLContext* context);
-void InitializeDebugGLBindings%(name)s();
-void ClearGLBindings%(name)s();
 """ % {'name': set_name.upper()})
 
   # Write typedefs for function pointer types. Always use the GL name for the
@@ -1160,30 +1156,89 @@
 
   # Write declarations for booleans indicating which extensions are available.
   file.write('\n')
+  file.write("struct Extensions%s {\n" % set_name.upper())
   for extension, ext_functions in used_extension_functions:
-    file.write('GL_EXPORT extern bool g_%s;\n' % extension)
+    file.write('  bool b_%s;\n' % extension)
+  file.write('};\n')
+  file.write('\n')
 
-  # Write declarations for function pointers. Always use the GL name for the
-  # declaration.
-  file.write('\n')
+  # Write Procs struct.
+  file.write("struct Procs%s {\n" % set_name.upper())
   for func in functions:
-    file.write('GL_EXPORT extern %sProc g_%s;\n' %
-               (func['names'][0], func['names'][0]))
+    file.write('  %sProc %sFn;\n' % (func['names'][0], func['names'][0]))
+  file.write('};\n')
   file.write('\n')
+
+  # Write Driver struct.
+  file.write(
+"""struct GL_EXPORT Driver%(name)s {
+  void InitializeBindings();
+  void InitializeExtensionBindings(GLContext* context);
+  void InitializeDebugBindings();
+  void ClearBindings();
+  void UpdateDebugExtensionBindings();
+
+  Procs%(name)s fn;
+  Procs%(name)s debug_fn;
+  Extensions%(name)s ext;
+""" % {'name': set_name.upper()})
+  file.write('};\n')
+  file.write('\n')
+
+  # Write Api class.
+  file.write(
+"""class GL_EXPORT %(name)sApi {
+ public:
+  %(name)sApi();
+  virtual ~%(name)sApi();
+
+""" % {'name': set_name.upper()})
+  for func in functions:
+    file.write('  virtual %s %sFn(%s) = 0;\n' %
+      (func['return_type'], func['names'][0], func['arguments']))
+  file.write('};\n')
+  file.write('\n')
+
   file.write( '}  // namespace gfx\n')
 
   # Write macros to invoke function pointers. Always use the GL name for the
   # macro.
   file.write('\n')
   for func in functions:
-    file.write('#define %s ::gfx::g_%s\n' %
-        (func['names'][0], func['names'][0]))
+    file.write('#define %s ::gfx::g_current_%s_context->%sFn\n' %
+        (func['names'][0], set_name.lower(), func['names'][0]))
 
   file.write('\n')
   file.write('#endif  //  UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' %
       set_name.upper())
 
 
+def GenerateAPIHeader(file, functions, set_name, used_extension_functions):
+  """Generates gl_binding_api_autogen_x.h"""
+
+  # Write file header.
+  file.write(
+"""// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is automatically generated.
+
+#ifndef UI_GFX_GL_GL_BINDINGS_API_AUTOGEN_%(name)s_H_
+#define UI_GFX_GL_GL_BINDINGS_API_AUTOGEN_%(name)s_H_
+
+""" % {'name': set_name.upper()})
+
+  # Write API declaration.
+  for func in functions:
+    file.write('  virtual %s %sFn(%s) OVERRIDE;\n' %
+      (func['return_type'], func['names'][0], func['arguments']))
+
+  file.write('\n')
+  file.write('#endif  //  UI_GFX_GL_GL_BINDINGS_API_AUTOGEN_%s_H_\n' %
+      set_name.upper())
+
+
 def GenerateSource(file, functions, set_name, used_extension_functions):
   """Generates gl_binding_autogen_x.cc"""
 
@@ -1200,53 +1255,47 @@
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_%s_api_implementation.h"
 
 using gpu::gles2::GLES2Util;
 
 namespace gfx {
-""")
-  # Write definitions for booleans indicating which extensions are available.
-  for extension, ext_functions in used_extension_functions:
-    file.write('bool g_%s;\n' % extension)
+""" % set_name.lower())
 
   # Write definitions of function pointers.
   file.write('\n')
   file.write('static bool g_debugBindingsInitialized;\n')
-  file.write('static void UpdateDebugGLExtensionBindings();\n')
+  file.write('Driver%s g_driver_%s;\n' % (set_name.upper(), set_name.lower()))
   file.write('\n')
-  for func in functions:
-    file.write('%sProc g_%s;\n' % (func['names'][0], func['names'][0]))
-
-  file.write('\n')
-  for func in functions:
-    file.write('static %sProc g_debug_%s;\n' %
-               (func['names'][0], func['names'][0]))
 
   # Write function to initialize the core function pointers. The code assumes
   # any non-NULL pointer returned by GetGLCoreProcAddress() is valid, although
   # it may be overwritten by an extension function pointer later.
   file.write('\n')
-  file.write('void InitializeGLBindings%s() {\n' % set_name.upper())
+  file.write('void Driver%s::InitializeBindings() {\n' %
+             set_name.upper())
   for func in functions:
     first_name = func['names'][0]
     for i, name in enumerate(func['names']):
       if i:
-        file.write('  if (!g_%s)\n  ' % first_name)
+        file.write('  if (!fn.%sFn)\n  ' % first_name)
       file.write(
-          '  g_%s = reinterpret_cast<%sProc>(GetGLCoreProcAddress("%s"));\n' %
-              (first_name, first_name, name))
+          '  fn.%sFn = reinterpret_cast<%sProc>('
+          'GetGLCoreProcAddress("%s"));\n' %
+          (first_name, first_name, name))
   file.write('}\n')
   file.write('\n')
 
   # Write function to initialize the extension function pointers. This function
   # uses a current context to query which extensions are actually supported.
-  file.write('void InitializeGLExtensionBindings%s(GLContext* context) {\n' %
-      set_name.upper())
+  file.write("""void Driver%s::InitializeExtensionBindings(
+    GLContext* context) {
+""" % set_name.upper())
   file.write('  DCHECK(context && context->IsCurrent(NULL));\n')
   for extension, ext_functions in used_extension_functions:
-    file.write('  g_%s = context->HasExtension("%s");\n' %
+    file.write('  ext.b_%s = context->HasExtension("%s");\n' %
         (extension, extension))
-    file.write('  if (g_%s) {\n' %
+    file.write('  if (ext.b_%s) {\n' %
         (extension))
     queried_entry_points = set()
     for entry_point_name, function_name in ext_functions:
@@ -1254,14 +1303,14 @@
       # alternatives for the same entry point (e.g.,
       # GL_ARB_blend_func_extended).
       if entry_point_name in queried_entry_points:
-        file.write('    if (!g_%s)\n  ' % entry_point_name)
+        file.write('    if (!fn.%sFn)\n  ' % entry_point_name)
       file.write(
-         '    g_%s = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' %
+         '    fn.%sFn = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' %
              (entry_point_name, entry_point_name, function_name))
       queried_entry_points.add(entry_point_name)
     file.write('  }\n')
   file.write('  if (g_debugBindingsInitialized)\n')
-  file.write('    UpdateDebugGLExtensionBindings();\n')
+  file.write('    UpdateDebugExtensionBindings();\n')
   file.write('}\n')
   file.write('\n')
 
@@ -1314,15 +1363,15 @@
     if return_type == 'void':
       file.write('  GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
           (function_name, log_argument_names))
-      file.write('  g_debug_%s(%s);\n' %
-          (function_name, argument_names))
+      file.write('  g_driver_%s.debug_fn.%sFn(%s);\n' %
+          (set_name.lower(), function_name, argument_names))
       if 'logging_code' in func:
         file.write("%s\n" % func['logging_code'])
     else:
       file.write('  GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
           (function_name, log_argument_names))
-      file.write('  %s result = g_debug_%s(%s);\n' %
-          (return_type, function_name, argument_names))
+      file.write('  %s result = g_driver_%s.debug_fn.%sFn(%s);\n' %
+          (return_type, set_name.lower(), function_name, argument_names))
       if 'logging_code' in func:
         file.write("%s\n" % func['logging_code'])
       else:
@@ -1333,12 +1382,13 @@
 
   # Write function to initialize the debug function pointers.
   file.write('\n')
-  file.write('void InitializeDebugGLBindings%s() {\n' % set_name.upper())
+  file.write('void Driver%s::InitializeDebugBindings() {\n' %
+             set_name.upper())
   for func in functions:
     first_name = func['names'][0]
-    file.write('  if (!g_debug_%s) {\n' % first_name)
-    file.write('    g_debug_%s = g_%s;\n' % (first_name, first_name))
-    file.write('    g_%s = Debug_%s;\n' % (first_name, first_name))
+    file.write('  if (!debug_fn.%sFn) {\n' % first_name)
+    file.write('    debug_fn.%sFn = fn.%sFn;\n' % (first_name, first_name))
+    file.write('    fn.%sFn = Debug_%s;\n' % (first_name, first_name))
     file.write('  }\n')
   file.write('  g_debugBindingsInitialized = true;\n')
   file.write('}\n')
@@ -1346,32 +1396,46 @@
   # Write function to update the debug function pointers to extension functions
   # after the extensions have been initialized.
   file.write('\n')
-  file.write('static void UpdateDebugGLExtensionBindings() {\n')
+  file.write('void Driver%s::UpdateDebugExtensionBindings() {\n' %
+             set_name.upper())
   for extension, ext_functions in used_extension_functions:
     for name, _ in ext_functions:
-      file.write('  if (g_debug_%s != g_%s &&\n' % (name, name))
-      file.write('      g_%s != Debug_%s) {\n' % (name, name))
-      file.write('    g_debug_%s = g_%s;\n' % (name, name))
-      file.write('    g_%s = Debug_%s;\n' % (name, name))
+      file.write('  if (debug_fn.%sFn != fn.%sFn &&\n' % (name, name))
+      file.write('      fn.%sFn != Debug_%s) {\n' % (name, name))
+      file.write('    debug_fn.%sFn = fn.%sFn;\n' % (name, name))
+      file.write('    fn.%sFn = Debug_%s;\n' % (name, name))
       file.write('  }\n')
   file.write('}\n')
 
   # Write function to clear all function pointers.
   file.write('\n')
-  file.write('void ClearGLBindings%s() {\n' % set_name.upper())
-  # Clear the availability of GL extensions.
-  for extension, ext_functions in used_extension_functions:
-    file.write('  g_%s = false;\n' % extension)
-  # Clear GL bindings.
-  file.write('\n')
+  file.write("""void Driver%s::ClearBindings() {
+  memset(this, 0, sizeof(*this));
+}
+""" % set_name.upper())
+
+  # Write RealGLApi functions
   for func in functions:
-    file.write('  g_%s = NULL;\n' % func['names'][0])
-  # Clear debug GL bindings.
-  file.write('\n')
-  for func in functions:
-    file.write('  g_debug_%s = NULL;\n' % func['names'][0])
-  file.write('  g_debugBindingsInitialized = false;\n')
-  file.write('}\n')
+    names = func['names']
+    return_type = func['return_type']
+    arguments = func['arguments']
+    file.write('\n')
+    file.write('%s Real%sApi::%sFn(%s) {\n' %
+        (return_type, set_name.upper(), names[0], arguments))
+    argument_names = re.sub(
+        r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments)
+    argument_names = re.sub(
+        r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names)
+    if argument_names == 'void' or argument_names == '':
+      argument_names = ''
+    function_name = names[0]
+    if return_type == 'void':
+      file.write('  driver_->fn.%sFn(%s);\n' %
+          (function_name, argument_names))
+    else:
+      file.write('  return driver_->fn.%sFn(%s);\n' %
+          (function_name, argument_names))
+    file.write('}\n')
 
   file.write('\n')
   file.write('}  // namespace gfx\n')
@@ -1572,6 +1636,12 @@
     GenerateHeader(header_file, functions, set_name, used_extension_functions)
     header_file.close()
 
+    header_file = open(
+        os.path.join(dir, 'gl_bindings_api_autogen_%s.h' % set_name), 'wb')
+    GenerateAPIHeader(
+        header_file, functions, set_name, used_extension_functions)
+    header_file.close()
+
     source_file = open(
         os.path.join(dir, 'gl_bindings_autogen_%s.cc' % set_name), 'wb')
     GenerateSource(source_file, functions, set_name, used_extension_functions)
diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp
index 32d5e69b..7d36d90 100644
--- a/ui/gl/gl.gyp
+++ b/ui/gl/gl.gyp
@@ -53,6 +53,8 @@
         'gl_export.h',
         'gl_fence.cc',
         'gl_fence.h',
+        'gl_gl_api_implementation.cc',
+        'gl_gl_api_implementation.h',
         'gl_image.cc',
         'gl_image.h',
         'gl_image_android.cc',
@@ -69,6 +71,8 @@
         'gl_implementation_win.cc',
         'gl_interface.cc',
         'gl_interface.h',
+        'gl_osmesa_api_implementation.cc',
+        'gl_osmesa_api_implementation.h',
         'gl_share_group.cc',
         'gl_share_group.h',
         'gl_surface.cc',
@@ -114,15 +118,20 @@
           'outputs': [
             '<(gl_binding_output_dir)/gl_bindings_autogen_egl.cc',
             '<(gl_binding_output_dir)/gl_bindings_autogen_egl.h',
+            '<(gl_binding_output_dir)/gl_bindings_autogen_api_egl.h',
             '<(gl_binding_output_dir)/gl_bindings_autogen_gl.cc',
             '<(gl_binding_output_dir)/gl_bindings_autogen_gl.h',
+            '<(gl_binding_output_dir)/gl_bindings_autogen_api_gl.h',
             '<(gl_binding_output_dir)/gl_bindings_autogen_glx.cc',
             '<(gl_binding_output_dir)/gl_bindings_autogen_glx.h',
+            '<(gl_binding_output_dir)/gl_bindings_autogen_api_glx.h',
             '<(gl_binding_output_dir)/gl_bindings_autogen_mock.cc',
             '<(gl_binding_output_dir)/gl_bindings_autogen_osmesa.cc',
             '<(gl_binding_output_dir)/gl_bindings_autogen_osmesa.h',
+            '<(gl_binding_output_dir)/gl_bindings_autogen_api_osmesa.h',
             '<(gl_binding_output_dir)/gl_bindings_autogen_wgl.cc',
             '<(gl_binding_output_dir)/gl_bindings_autogen_wgl.h',
+            '<(gl_binding_output_dir)/gl_bindings_autogen_api_wgl.h',
           ],
           'action': [
             'python',
@@ -140,6 +149,8 @@
             'gl_context_egl.h',
             'gl_surface_egl.cc',
             'gl_surface_egl.h',
+            'gl_egl_api_implementation.cc',
+            'gl_egl_api_implementation.h',
             '<(gl_binding_output_dir)/gl_bindings_autogen_egl.cc',
             '<(gl_binding_output_dir)/gl_bindings_autogen_egl.h',
           ],
@@ -151,10 +162,14 @@
           'sources': [
             'gl_context_glx.cc',
             'gl_context_glx.h',
+            'gl_glx_api_implementation.cc',
+            'gl_glx_api_implementation.h',
             'gl_image_glx.cc',
             'gl_image_glx.h',
             'gl_surface_glx.cc',
             'gl_surface_glx.h',
+            'gl_egl_api_implementation.cc',
+            'gl_egl_api_implementation.h',
             '<(gl_binding_output_dir)/gl_bindings_autogen_glx.cc',
             '<(gl_binding_output_dir)/gl_bindings_autogen_glx.h',
           ],
@@ -174,8 +189,12 @@
           'sources': [
             'gl_context_wgl.cc',
             'gl_context_wgl.h',
+            'gl_egl_api_implementation.cc',
+            'gl_egl_api_implementation.h',
             'gl_surface_wgl.cc',
             'gl_surface_wgl.h',
+            'gl_wgl_api_implementation.cc',
+            'gl_wgl_api_implementation.h',
             '<(gl_binding_output_dir)/gl_bindings_autogen_wgl.cc',
             '<(gl_binding_output_dir)/gl_bindings_autogen_wgl.h',
           ],
@@ -207,8 +226,6 @@
             'android_native_window.h',
           ],
           'sources!': [
-            '<(gl_binding_output_dir)/gl_bindings_autogen_osmesa.cc',
-            '<(gl_binding_output_dir)/gl_bindings_autogen_osmesa.h',
             'gl_context_osmesa.cc',
             'system_monitor_posix.cc',
           ],
diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h
index 4999e8d..adf956b 100644
--- a/ui/gl/gl_bindings.h
+++ b/ui/gl/gl_bindings.h
@@ -96,6 +96,32 @@
 
 namespace gfx {
 
+GL_EXPORT extern GLApi* g_current_gl_context;
+GL_EXPORT extern OSMESAApi* g_current_osmesa_context;
+GL_EXPORT extern DriverGL g_driver_gl;
+GL_EXPORT extern DriverOSMESA g_driver_osmesa;
+
+#if defined(OS_WIN)
+
+GL_EXPORT extern EGLApi* g_current_egl_context;
+GL_EXPORT extern WGLApi* g_current_wgl_context;
+GL_EXPORT extern DriverEGL g_driver_egl;
+GL_EXPORT extern DriverWGL g_driver_wgl;
+
+#elif defined(USE_X11)
+
+GL_EXPORT extern EGLApi* g_current_egl_context;
+GL_EXPORT extern GLXApi* g_current_glx_context;
+GL_EXPORT extern DriverEGL g_driver_egl;
+GL_EXPORT extern DriverGLX g_driver_glx;
+
+#elif defined(OS_ANDROID)
+
+GL_EXPORT extern EGLApi* g_current_egl_context;
+GL_EXPORT extern DriverEGL g_driver_egl;
+
+#endif
+
 // Find an entry point to the mock GL implementation.
 void* GL_BINDING_CALL GetMockGLProcAddress(const char* name);
 
diff --git a/ui/gl/gl_context_glx.cc b/ui/gl/gl_context_glx.cc
index dc8226b4..3ab750b 100644
--- a/ui/gl/gl_context_glx.cc
+++ b/ui/gl/gl_context_glx.cc
@@ -219,12 +219,14 @@
 
 void GLContextGLX::SetSwapInterval(int interval) {
   DCHECK(IsCurrent(NULL));
-  if (HasExtension("GLX_EXT_swap_control") && glXSwapIntervalEXT) {
+  if (HasExtension("GLX_EXT_swap_control") &&
+      g_driver_glx.fn.glXSwapIntervalEXTFn) {
     glXSwapIntervalEXT(
         display_,
         glXGetCurrentDrawable(),
         interval);
-  } else if (HasExtension("GLX_MESA_swap_control") && glXSwapIntervalMESA) {
+  } else if (HasExtension("GLX_MESA_swap_control") &&
+             g_driver_glx.fn.glXSwapIntervalMESAFn) {
     glXSwapIntervalMESA(interval);
   } else {
     if(interval == 0)
diff --git a/ui/gl/gl_context_wgl.cc b/ui/gl/gl_context_wgl.cc
index e6b8307..c136641 100644
--- a/ui/gl/gl_context_wgl.cc
+++ b/ui/gl/gl_context_wgl.cc
@@ -25,9 +25,9 @@
 
 std::string GLContextWGL::GetExtensions() {
   const char* extensions = NULL;
-  if (wglGetExtensionsStringARB)
+  if (g_driver_wgl.fn.wglGetExtensionsStringARBFn)
     extensions = wglGetExtensionsStringARB(GLSurfaceWGL::GetDisplayDC());
-  else if (wglGetExtensionsStringEXT)
+  else if (g_driver_wgl.fn.wglGetExtensionsStringEXTFn)
     extensions = wglGetExtensionsStringEXT();
 
   if (extensions)
@@ -129,7 +129,7 @@
 
 void GLContextWGL::SetSwapInterval(int interval) {
   DCHECK(IsCurrent(NULL));
-  if (gfx::g_WGL_EXT_swap_control) {
+  if (gfx::g_driver_wgl.ext.b_WGL_EXT_swap_control) {
     wglSwapIntervalEXT(interval);
   } else {
       LOG(WARNING) <<
diff --git a/ui/gl/gl_egl_api_implementation.cc b/ui/gl/gl_egl_api_implementation.cc
new file mode 100644
index 0000000..aa25ef4c
--- /dev/null
+++ b/ui/gl/gl_egl_api_implementation.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gl/gl_egl_api_implementation.h"
+
+namespace gfx {
+
+RealEGLApi* g_real_egl;
+
+void InitializeGLBindingsEGL() {
+  g_driver_egl.InitializeBindings();
+  if (!g_real_egl) {
+    g_real_egl = new RealEGLApi();
+  }
+  g_real_egl->Initialize(&g_driver_egl);
+  g_current_egl_context = g_real_egl;
+}
+
+void InitializeGLExtensionBindingsEGL(GLContext* context) {
+  g_driver_egl.InitializeExtensionBindings(context);
+}
+
+void InitializeDebugGLBindingsEGL() {
+  g_driver_egl.InitializeDebugBindings();
+}
+
+void ClearGLBindingsEGL() {
+  if (g_real_egl) {
+    delete g_real_egl;
+    g_real_egl = NULL;
+  }
+  g_current_egl_context = NULL;
+  g_driver_egl.ClearBindings();
+}
+
+EGLApi::EGLApi() {
+}
+
+EGLApi::~EGLApi() {
+}
+
+RealEGLApi::RealEGLApi() {
+}
+
+void RealEGLApi::Initialize(DriverEGL* driver) {
+  driver_ = driver;
+}
+
+}  // namespace gfx
+
+
diff --git a/ui/gl/gl_egl_api_implementation.h b/ui/gl/gl_egl_api_implementation.h
new file mode 100644
index 0000000..adb71d4
--- /dev/null
+++ b/ui/gl/gl_egl_api_implementation.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GL_EGL_API_IMPLEMENTATION_H_
+#define UI_GL_EGL_API_IMPLEMENTATION_H_
+
+#include "base/compiler_specific.h"
+#include "gl_bindings.h"
+#include "ui/gl/gl_export.h"
+
+namespace gfx {
+
+class GLContext;
+
+void InitializeGLBindingsEGL();
+void InitializeGLExtensionBindingsEGL(GLContext* context);
+void InitializeDebugGLBindingsEGL();
+void ClearGLBindingsEGL();
+
+class GL_EXPORT RealEGLApi : public EGLApi {
+ public:
+  RealEGLApi();
+  void Initialize(DriverEGL* driver);
+
+  // Include the auto-generated part of this class. We split this because
+  // it means we can easily edit the non-auto generated parts right here in
+  // this file instead of having to edit some template or the code generator.
+  #include "gl_bindings_api_autogen_egl.h"
+
+ private:
+  DriverEGL* driver_;
+};
+
+}  // namespace gfx
+
+#endif  // UI_GL_EGL_API_IMPLEMENTATION_H_
+
+
+
diff --git a/ui/gl/gl_fence.cc b/ui/gl/gl_fence.cc
index 183a12d5..9a3523e 100644
--- a/ui/gl/gl_fence.cc
+++ b/ui/gl/gl_fence.cc
@@ -82,9 +82,9 @@
 
 // static
 GLFence* GLFence::Create() {
-  if (gfx::g_GL_NV_fence) {
+  if (gfx::g_driver_gl.ext.b_GL_NV_fence) {
     return new GLFenceNVFence();
-  } else if (gfx::g_GL_ARB_sync) {
+  } else if (gfx::g_driver_gl.ext.b_GL_ARB_sync) {
     return new GLFenceARBSync();
   } else {
     return NULL;
@@ -93,7 +93,8 @@
 
 // static
 bool GLFence::IsContextLost() {
-  if (!gfx::g_GL_ARB_robustness && !gfx::g_GL_EXT_robustness)
+  if (!gfx::g_driver_gl.ext.b_GL_ARB_robustness &&
+      !gfx::g_driver_gl.ext.b_GL_EXT_robustness)
     return false;
 
   if (!gfx::GLContext::GetCurrent() ||
diff --git a/ui/gl/gl_gl_api_implementation.cc b/ui/gl/gl_gl_api_implementation.cc
new file mode 100644
index 0000000..0a6bf8c
--- /dev/null
+++ b/ui/gl/gl_gl_api_implementation.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gl/gl_gl_api_implementation.h"
+
+namespace gfx {
+
+RealGLApi* g_real_gl;
+
+void InitializeGLBindingsGL() {
+  g_driver_gl.InitializeBindings();
+  if (!g_real_gl) {
+    g_real_gl = new RealGLApi();
+  }
+  g_real_gl->Initialize(&g_driver_gl);
+  g_current_gl_context = g_real_gl;
+}
+
+void InitializeGLExtensionBindingsGL(GLContext* context) {
+  g_driver_gl.InitializeExtensionBindings(context);
+}
+
+void InitializeDebugGLBindingsGL() {
+  g_driver_gl.InitializeDebugBindings();
+}
+
+void ClearGLBindingsGL() {
+  if (g_real_gl) {
+    delete g_real_gl;
+    g_real_gl = NULL;
+  }
+  g_current_gl_context = NULL;
+  g_driver_gl.ClearBindings();
+}
+
+GLApi::GLApi() {
+}
+
+GLApi::~GLApi() {
+}
+
+RealGLApi::RealGLApi() {
+}
+
+void RealGLApi::Initialize(DriverGL* driver) {
+  driver_ = driver;
+}
+
+}  // namespace gfx
+
+
diff --git a/ui/gl/gl_gl_api_implementation.h b/ui/gl/gl_gl_api_implementation.h
new file mode 100644
index 0000000..5c70b38c
--- /dev/null
+++ b/ui/gl/gl_gl_api_implementation.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GL_GL_API_IMPLEMENTATION_H_
+#define UI_GL_GL_API_IMPLEMENTATION_H_
+
+#include "base/compiler_specific.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_export.h"
+
+namespace gfx {
+
+class GLContext;
+
+void InitializeGLBindingsGL();
+void InitializeGLExtensionBindingsGL(GLContext* context);
+void InitializeDebugGLBindingsGL();
+void ClearGLBindingsGL();
+
+class GL_EXPORT RealGLApi : public GLApi {
+ public:
+  RealGLApi();
+  void Initialize(DriverGL* driver);
+
+  // Include the auto-generated part of this class. We split this because
+  // it means we can easily edit the non-auto generated parts right here in
+  // this file instead of having to edit some template or the code generator.
+  #include "gl_bindings_api_autogen_gl.h"
+
+ private:
+  DriverGL* driver_;
+};
+
+}  // namespace gfx
+
+#endif  // UI_GL_GL_API_IMPLEMENTATION_H_
+
+
+
diff --git a/ui/gl/gl_glx_api_implementation.cc b/ui/gl/gl_glx_api_implementation.cc
new file mode 100644
index 0000000..9897119
--- /dev/null
+++ b/ui/gl/gl_glx_api_implementation.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gl/gl_glx_api_implementation.h"
+
+namespace gfx {
+
+RealGLXApi* g_real_glx;
+
+void InitializeGLBindingsGLX() {
+  g_driver_glx.InitializeBindings();
+  if (!g_real_glx) {
+    g_real_glx = new RealGLXApi();
+  }
+  g_real_glx->Initialize(&g_driver_glx);
+  g_current_glx_context = g_real_glx;
+}
+
+void InitializeGLExtensionBindingsGLX(GLContext* context) {
+  g_driver_glx.InitializeExtensionBindings(context);
+}
+
+void InitializeDebugGLBindingsGLX() {
+  g_driver_glx.InitializeDebugBindings();
+}
+
+void ClearGLBindingsGLX() {
+  if (g_real_glx) {
+    delete g_real_glx;
+    g_real_glx = NULL;
+  }
+  g_current_glx_context = NULL;
+  g_driver_glx.ClearBindings();
+}
+
+GLXApi::GLXApi() {
+}
+
+GLXApi::~GLXApi() {
+}
+
+RealGLXApi::RealGLXApi() {
+}
+
+void RealGLXApi::Initialize(DriverGLX* driver) {
+  driver_ = driver;
+}
+
+}  // namespace gfx
+
+
diff --git a/ui/gl/gl_glx_api_implementation.h b/ui/gl/gl_glx_api_implementation.h
new file mode 100644
index 0000000..0be72249
--- /dev/null
+++ b/ui/gl/gl_glx_api_implementation.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GL_GLX_API_IMPLEMENTATION_H_
+#define UI_GL_GLX_API_IMPLEMENTATION_H_
+
+#include "base/compiler_specific.h"
+#include "gl_bindings.h"
+#include "ui/gl/gl_export.h"
+
+namespace gfx {
+
+class GLContext;
+
+void InitializeGLBindingsGLX();
+void InitializeGLExtensionBindingsGLX(GLContext* context);
+void InitializeDebugGLBindingsGLX();
+void ClearGLBindingsGLX();
+
+class GL_EXPORT RealGLXApi : public GLXApi {
+ public:
+  RealGLXApi();
+  void Initialize(DriverGLX* driver);
+
+  // Include the auto-generated part of this class. We split this because
+  // it means we can easily edit the non-auto generated parts right here in
+  // this file instead of having to edit some template or the code generator.
+  #include "gl_bindings_api_autogen_glx.h"
+
+ private:
+  DriverGLX* driver_;
+};
+
+}  // namespace gfx
+
+#endif  // UI_GL_GLX_API_IMPLEMENTATION_H_
+
+
+
diff --git a/ui/gl/gl_implementation.cc b/ui/gl/gl_implementation.cc
index 0a10f22..a97a4df5 100644
--- a/ui/gl/gl_implementation.cc
+++ b/ui/gl/gl_implementation.cc
@@ -10,6 +10,7 @@
 #include "base/at_exit.h"
 #include "base/command_line.h"
 #include "base/logging.h"
+#include "ui/gl/gl_bindings.h"
 
 namespace gfx {
 
@@ -62,6 +63,25 @@
 
 }
 
+GLApi* g_current_gl_context;
+OSMESAApi* g_current_osmesa_context;
+
+#if defined(OS_WIN)
+
+EGLApi* g_current_egl_context;
+WGLApi* g_current_wgl_context;
+
+#elif defined(USE_X11)
+
+EGLApi* g_current_egl_context;
+GLXApi* g_current_glx_context;
+
+#elif defined(OS_ANDROID)
+
+EGLApi* g_current_egl_context;
+
+#endif
+
 GLImplementation GetNamedGLImplementation(const std::string& name) {
   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) {
     if (name == kGLImplementationNamePairs[i].name)
diff --git a/ui/gl/gl_implementation_android.cc b/ui/gl/gl_implementation_android.cc
index 052f48f..4dab47c 100644
--- a/ui/gl/gl_implementation_android.cc
+++ b/ui/gl/gl_implementation_android.cc
@@ -9,7 +9,10 @@
 #include "base/native_library.h"
 #include "base/path_service.h"
 #include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_egl_api_implementation.h"
+#include "ui/gl/gl_gl_api_implementation.h"
 #include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_osmesa_api_implementation.h"
 
 namespace gfx {
 
@@ -83,8 +86,8 @@
 
       // These two functions take single precision float rather than double
       // precision float parameters in GLES.
-      ::gfx::g_glClearDepth = MarshalClearDepthToClearDepthf;
-      ::gfx::g_glDepthRange = MarshalDepthRangeToDepthRangef;
+      ::gfx::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
+      ::gfx::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
       break;
     }
     case kGLImplementationMockGL: {
diff --git a/ui/gl/gl_implementation_linux.cc b/ui/gl/gl_implementation_linux.cc
index e5ca5f6..dc81fbc 100644
--- a/ui/gl/gl_implementation_linux.cc
+++ b/ui/gl/gl_implementation_linux.cc
@@ -12,7 +12,11 @@
 #include "base/path_service.h"
 #include "base/threading/thread_restrictions.h"
 #include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_egl_api_implementation.h"
+#include "ui/gl/gl_gl_api_implementation.h"
+#include "ui/gl/gl_glx_api_implementation.h"
 #include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_osmesa_api_implementation.h"
 #include "ui/gl/gl_switches.h"
 
 namespace gfx {
@@ -165,8 +169,8 @@
 
       // These two functions take single precision float rather than double
       // precision float parameters in GLES.
-      ::gfx::g_glClearDepth = MarshalClearDepthToClearDepthf;
-      ::gfx::g_glDepthRange = MarshalDepthRangeToDepthRangef;
+      ::gfx::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
+      ::gfx::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
       break;
     }
     case kGLImplementationMockGL: {
diff --git a/ui/gl/gl_implementation_mac.cc b/ui/gl/gl_implementation_mac.cc
index 500999a..d22082e 100644
--- a/ui/gl/gl_implementation_mac.cc
+++ b/ui/gl/gl_implementation_mac.cc
@@ -10,7 +10,9 @@
 #include "base/path_service.h"
 #include "base/threading/thread_restrictions.h"
 #include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_gl_api_implementation.h"
 #include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_osmesa_api_implementation.h"
 
 namespace gfx {
 namespace {
diff --git a/ui/gl/gl_implementation_win.cc b/ui/gl/gl_implementation_win.cc
index eaec391..ac1e3bf 100644
--- a/ui/gl/gl_implementation_win.cc
+++ b/ui/gl/gl_implementation_win.cc
@@ -15,7 +15,11 @@
 #include "base/stringprintf.h"
 #include "base/threading/thread_restrictions.h"
 #include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_egl_api_implementation.h"
+#include "ui/gl/gl_gl_api_implementation.h"
 #include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_osmesa_api_implementation.h"
+#include "ui/gl/gl_wgl_api_implementation.h"
 
 #if defined(ENABLE_SWIFTSHADER)
 #include "software_renderer.h"
@@ -24,6 +28,7 @@
 namespace gfx {
 
 namespace {
+
 // This is the D3DX_SDK_VERSION for the last 'separate' DirectX SDK which
 // is from June 2010. Since June 2012 Microsoft includes DirectX in the regular
 // Windows SDK and the D3DX library has been deprecated.
@@ -181,8 +186,8 @@
 
       // These two functions take single precision float rather than double
       // precision float parameters in GLES.
-      ::gfx::g_glClearDepth = MarshalClearDepthToClearDepthf;
-      ::gfx::g_glDepthRange = MarshalDepthRangeToDepthRangef;
+      ::gfx::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
+      ::gfx::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
       break;
     }
     case kGLImplementationDesktopGL: {
diff --git a/ui/gl/gl_osmesa_api_implementation.cc b/ui/gl/gl_osmesa_api_implementation.cc
new file mode 100644
index 0000000..458a9e5
--- /dev/null
+++ b/ui/gl/gl_osmesa_api_implementation.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gl/gl_osmesa_api_implementation.h"
+
+namespace gfx {
+
+RealOSMESAApi* g_real_osmesa;
+
+void InitializeGLBindingsOSMESA() {
+  g_driver_osmesa.InitializeBindings();
+  if (!g_real_osmesa) {
+    g_real_osmesa = new RealOSMESAApi();
+  }
+  g_real_osmesa->Initialize(&g_driver_osmesa);
+  g_current_osmesa_context = g_real_osmesa;
+}
+
+void InitializeGLExtensionBindingsOSMESA(GLContext* context) {
+  g_driver_osmesa.InitializeExtensionBindings(context);
+}
+
+void InitializeDebugGLBindingsOSMESA() {
+  g_driver_osmesa.InitializeDebugBindings();
+}
+
+void ClearGLBindingsOSMESA() {
+  if (g_real_osmesa) {
+    delete g_real_osmesa;
+    g_real_osmesa = NULL;
+  }
+  g_current_osmesa_context = NULL;
+  g_driver_osmesa.ClearBindings();
+}
+
+OSMESAApi::OSMESAApi() {
+}
+
+OSMESAApi::~OSMESAApi() {
+}
+
+RealOSMESAApi::RealOSMESAApi() {
+}
+
+void RealOSMESAApi::Initialize(DriverOSMESA* driver) {
+  driver_ = driver;
+}
+
+}  // namespace gfx
+
+
diff --git a/ui/gl/gl_osmesa_api_implementation.h b/ui/gl/gl_osmesa_api_implementation.h
new file mode 100644
index 0000000..95271f4
--- /dev/null
+++ b/ui/gl/gl_osmesa_api_implementation.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GL_OSMESA_API_IMPLEMENTATION_H_
+#define UI_GL_OSMESA_API_IMPLEMENTATION_H_
+
+#include "base/compiler_specific.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_export.h"
+
+namespace gfx {
+
+class GLContext;
+
+void InitializeGLBindingsOSMESA();
+void InitializeGLExtensionBindingsOSMESA(GLContext* context);
+void InitializeDebugGLBindingsOSMESA();
+void ClearGLBindingsOSMESA();
+
+class GL_EXPORT RealOSMESAApi : public OSMESAApi {
+ public:
+  RealOSMESAApi();
+  void Initialize(DriverOSMESA* driver);
+
+  // Include the auto-generated part of this class. We split this because
+  // it means we can easily edit the non-auto generated parts right here in
+  // this file instead of having to edit some template or the code generator.
+  #include "gl_bindings_api_autogen_osmesa.h"
+
+ private:
+  DriverOSMESA* driver_;
+};
+
+}  // namespace gfx
+
+#endif  // UI_GL_OSMESA_API_IMPLEMENTATION_H_
+
+
+
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc
index 2fe37109..e9a9618ed6 100644
--- a/ui/gl/gl_surface_egl.cc
+++ b/ui/gl/gl_surface_egl.cc
@@ -200,12 +200,13 @@
   };
 
   // Create a surface for the native window.
-  surface_ = eglCreateWindowSurface(GetDisplay(),
-                                    GetConfig(),
-                                    window_,
-                                    gfx::g_EGL_NV_post_sub_buffer ?
-                                        egl_window_attributes_sub_buffer :
-                                        NULL);
+  surface_ = eglCreateWindowSurface(
+      GetDisplay(),
+      GetConfig(),
+      window_,
+      gfx::g_driver_egl.ext.b_EGL_NV_post_sub_buffer ?
+          egl_window_attributes_sub_buffer :
+          NULL);
 
   if (!surface_) {
     LOG(ERROR) << "eglCreateWindowSurface failed with error "
@@ -490,10 +491,10 @@
   NOTREACHED();
   return NULL;
 #else
-  if (!g_EGL_ANGLE_query_surface_pointer)
+  if (!gfx::g_driver_egl.ext.b_EGL_ANGLE_query_surface_pointer)
     return NULL;
 
-  if (!g_EGL_ANGLE_surface_d3d_texture_2d_share_handle)
+  if (!gfx::g_driver_egl.ext.b_EGL_ANGLE_surface_d3d_texture_2d_share_handle)
     return NULL;
 
   void* handle;
diff --git a/ui/gl/gl_surface_glx.cc b/ui/gl/gl_surface_glx.cc
index 6e16754..f810114 100644
--- a/ui/gl/gl_surface_glx.cc
+++ b/ui/gl/gl_surface_glx.cc
@@ -122,7 +122,7 @@
   // On Intel drivers, the frame buffer won't be resize until the next swap. If
   // we only do PostSubBuffer, then we're stuck in the old size. Force a swap
   // now.
-  if (gfx::g_GLX_MESA_copy_sub_buffer && size_ != size)
+  if (gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer && size_ != size)
     SwapBuffers();
   size_ = size;
   return true;
@@ -149,7 +149,7 @@
 
 std::string NativeViewGLSurfaceGLX::GetExtensions() {
   std::string extensions = GLSurface::GetExtensions();
-  if (g_GLX_MESA_copy_sub_buffer) {
+  if (gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer) {
     extensions += extensions.empty() ? "" : " ";
     extensions += "GL_CHROMIUM_post_sub_buffer";
   }
@@ -219,7 +219,7 @@
 
 bool NativeViewGLSurfaceGLX::PostSubBuffer(
     int x, int y, int width, int height) {
-  DCHECK(g_GLX_MESA_copy_sub_buffer);
+  DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer);
   glXCopySubBufferMESA(g_display, window_, x, y, width, height);
   return true;
 }
diff --git a/ui/gl/gl_surface_wgl.cc b/ui/gl/gl_surface_wgl.cc
index a72c825..7e1c3a7 100644
--- a/ui/gl/gl_surface_wgl.cc
+++ b/ui/gl/gl_surface_wgl.cc
@@ -7,6 +7,8 @@
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_gl_api_implementation.h"
+#include "ui/gl/gl_wgl_api_implementation.h"
 
 namespace gfx {
 
@@ -306,7 +308,7 @@
 bool PbufferGLSurfaceWGL::Initialize() {
   DCHECK(!device_context_);
 
-  if (!wglCreatePbufferARB) {
+  if (!gfx::g_driver_wgl.fn.wglCreatePbufferARBFn) {
     LOG(ERROR) << "wglCreatePbufferARB not available.";
     Destroy();
     return false;
diff --git a/ui/gl/gl_wgl_api_implementation.cc b/ui/gl/gl_wgl_api_implementation.cc
new file mode 100644
index 0000000..332698a
--- /dev/null
+++ b/ui/gl/gl_wgl_api_implementation.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gl/gl_wgl_api_implementation.h"
+
+namespace gfx {
+
+RealWGLApi* g_real_wgl;
+
+void InitializeGLBindingsWGL() {
+  g_driver_wgl.InitializeBindings();
+  if (!g_real_wgl) {
+    g_real_wgl = new RealWGLApi();
+  }
+  g_real_wgl->Initialize(&g_driver_wgl);
+  g_current_wgl_context = g_real_wgl;
+}
+
+void InitializeGLExtensionBindingsWGL(GLContext* context) {
+  g_driver_wgl.InitializeExtensionBindings(context);
+}
+
+void InitializeDebugGLBindingsWGL() {
+  g_driver_wgl.InitializeDebugBindings();
+}
+
+void ClearGLBindingsWGL() {
+  if (g_real_wgl) {
+    delete g_real_wgl;
+    g_real_wgl = NULL;
+  }
+  g_current_wgl_context = NULL;
+  g_driver_wgl.ClearBindings();
+}
+
+WGLApi::WGLApi() {
+}
+
+WGLApi::~WGLApi() {
+}
+
+RealWGLApi::RealWGLApi() {
+}
+
+void RealWGLApi::Initialize(DriverWGL* driver) {
+  driver_ = driver;
+}
+
+}  // namespace gfx
+
+
diff --git a/ui/gl/gl_wgl_api_implementation.h b/ui/gl/gl_wgl_api_implementation.h
new file mode 100644
index 0000000..35afd0a
--- /dev/null
+++ b/ui/gl/gl_wgl_api_implementation.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GL_WGL_API_IMPLEMENTATION_H_
+#define UI_GL_WGL_API_IMPLEMENTATION_H_
+
+#include "base/compiler_specific.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_export.h"
+
+namespace gfx {
+
+class GLContext;
+
+void InitializeGLBindingsWGL();
+void InitializeGLExtensionBindingsWGL(GLContext* context);
+void InitializeDebugGLBindingsWGL();
+void ClearGLBindingsWGL();
+
+class GL_EXPORT RealWGLApi : public WGLApi {
+ public:
+  RealWGLApi();
+  void Initialize(DriverWGL* driver);
+
+  // Include the auto-generated part of this class. We split this because
+  // it means we can easily edit the non-auto generated parts right here in
+  // this file instead of having to edit some template or the code generator.
+  #include "gl_bindings_api_autogen_wgl.h"
+
+ private:
+  DriverWGL* driver_;
+};
+
+}  // namespace gfx
+
+#endif  // UI_GL_WGL_API_IMPLEMENTATION_H_
+
+
+