Update from https://crrev.com/314320

TBR=jamesr@chromium.org

Review URL: https://codereview.chromium.org/895853003
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn
index bdd7c98..bbd9363 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -26,6 +26,7 @@
     "android/surface_texture.h",
     "android/surface_texture_listener.cc",
     "android/surface_texture_listener.h",
+    "gl_bindings.cc",
     "gl_bindings.h",
     "gl_bindings_autogen_gl.cc",
     "gl_bindings_autogen_gl.h",
diff --git a/ui/gl/android/surface_texture.cc b/ui/gl/android/surface_texture.cc
index 3f55cbd..bf9012a 100644
--- a/ui/gl/android/surface_texture.cc
+++ b/ui/gl/android/surface_texture.cc
@@ -15,8 +15,7 @@
 #include "ui/gl/android/surface_texture_listener.h"
 #include "ui/gl/gl_bindings.h"
 
-// TODO(boliu): Remove this method when when we move off ICS. See
-// http://crbug.com/161864.
+// TODO(boliu): Remove this method when Chromium stops supporting ICS.
 bool GlContextMethodsAvailable() {
   bool available = base::android::BuildInfo::GetInstance()->sdk_int() >= 16;
   if (!available)
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py
index 7a339b6..5943bb6 100755
--- a/ui/gl/generate_bindings.py
+++ b/ui/gl/generate_bindings.py
@@ -12,6 +12,7 @@
 import platform
 import sys
 from subprocess import call
+from collections import namedtuple
 
 HEADER_PATHS = [
   '../../third_party/khronos',
@@ -20,22 +21,19 @@
   '../../gpu',
 ]
 
-"""In case there are multiple versions of the same function, one that's listed
-first takes priority if its conditions are met. If the function is an extension
-function, finding the extension from the extension string is a condition for
-binding it. The last version of the function is treated as a fallback option in
-case no other versions were bound, so a non-null function pointer in the
-bindings does not guarantee that the function is supported.
+UNCONDITIONALLY_BOUND_EXTENSIONS = set([
+  'WGL_ARB_extensions_string',
+  'WGL_EXT_extensions_string',
+  'GL_CHROMIUM_gles_depth_binding_hack', # crbug.com/448206
+])
 
-Function binding conditions can be specified manually by supplying a versions
+"""Function binding conditions can be specified manually by supplying a versions
 array instead of the names array. Each version has the following keys:
    name: Mandatory. Name of the function. Multiple versions can have the same
          name but different conditions.
-   gl_versions: List of GL versions where the function is found.
-   extensions: Extensions where the function is found. If not specified, the
-               extensions are determined based on GL header files.
-               If the function exists in an extension header, you may specify
-               an empty array to prevent making that a condition for binding.
+   extensions: Extra Extensions for which the function is bound. Only needed
+               in some cases where the extension cannot be parsed from the
+               headers.
 
 By default, the function gets its name from the first name in its names or
 versions array. This can be overridden by supplying a 'known_as' key.
@@ -48,15 +46,15 @@
   'names': ['glAttachShader'],
   'arguments': 'GLuint program, GLuint shader', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glBeginQuery',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glBeginQuery' }],
   'arguments': 'GLenum target, GLuint id', },
 { 'return_type': 'void',
-  'names': ['glBeginQueryARB', 'glBeginQueryEXT'],
+  'versions': [{ 'name': 'glBeginQueryARB' },
+               { 'name': 'glBeginQueryEXT',
+                 'extensions': ['GL_EXT_occlusion_query_boolean'] }],
   'arguments': 'GLenum target, GLuint id', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glBeginTransformFeedback',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glBeginTransformFeedback' }],
   'arguments': 'GLenum primitiveMode', },
 { 'return_type': 'void',
   'names': ['glBindAttribLocation'],
@@ -65,12 +63,10 @@
   'names': ['glBindBuffer'],
   'arguments': 'GLenum target, GLuint buffer', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glBindBufferBase',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glBindBufferBase' }],
   'arguments': 'GLenum target, GLuint index, GLuint buffer', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glBindBufferRange',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glBindBufferRange' }],
   'arguments': 'GLenum target, GLuint index, GLuint buffer, GLintptr offset, '
                'GLsizeiptr size', },
 { 'return_type': 'void',
@@ -87,22 +83,18 @@
   'names': ['glBindRenderbufferEXT', 'glBindRenderbuffer'],
   'arguments': 'GLenum target, GLuint renderbuffer', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glBindSampler',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.2 or higher.
+  'versions': [{ 'name': 'glBindSampler' }],
   'arguments': 'GLuint unit, GLuint sampler', },
 { 'return_type': 'void',
   'names': ['glBindTexture'],
   'arguments': 'GLenum target, GLuint texture', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glBindTransformFeedback',
-                 'gl_versions': ['gl4', 'es3'] }],
+  'versions': [{ 'name': 'glBindTransformFeedback' }],
   'arguments': 'GLenum target, GLuint id', },
 { 'return_type': 'void',
   'known_as': 'glBindVertexArrayOES',
   'versions': [{ 'name': 'glBindVertexArray',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] },
-               { 'name': 'glBindVertexArray',
-                 'extensions': ['GL_ARB_vertex_array_object'] },
+                 'extensions': ['GL_ARB_vertex_array_object'], },
                { 'name': 'glBindVertexArrayOES' },
                { 'name': 'glBindVertexArrayAPPLE',
                  'extensions': ['GL_APPLE_vertex_array_object'] }],
@@ -164,27 +156,24 @@
   'names': ['glClear'],
   'arguments': 'GLbitfield mask', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glClearBufferfi',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glClearBufferfi' }],
   'arguments': 'GLenum buffer, GLint drawbuffer, const GLfloat depth, '
                'GLint stencil', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glClearBufferfv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glClearBufferfv' }],
   'arguments': 'GLenum buffer, GLint drawbuffer, const GLfloat* value', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glClearBufferiv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glClearBufferiv' }],
   'arguments': 'GLenum buffer, GLint drawbuffer, const GLint* value', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glClearBufferuiv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glClearBufferuiv' }],
   'arguments': 'GLenum buffer, GLint drawbuffer, const GLuint* value', },
 { 'return_type': 'void',
   'names': ['glClearColor'],
   'arguments': 'GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha', },
 { 'return_type': 'void',
-  'names': ['glClearDepth'],
+  'versions': [{ 'name': 'glClearDepth',
+                 'extensions': ['GL_CHROMIUM_gles_depth_binding_hack'] }],
   'arguments': 'GLclampd depth', },
 { 'return_type': 'void',
   'names': ['glClearDepthf'],
@@ -193,7 +182,8 @@
   'names': ['glClearStencil'],
   'arguments': 'GLint s', },
 { 'return_type': 'GLenum',
-  'names': ['glClientWaitSync'],
+  'versions': [{ 'name': 'glClientWaitSync',
+                 'extensions': ['GL_ARB_sync'] }],
   'arguments': 'GLsync sync, GLbitfield flags, GLuint64 timeout', },
 { 'return_type': 'void',
   'names': ['glColorMask'],
@@ -208,8 +198,7 @@
       'GLenum target, GLint level, GLenum internalformat, GLsizei width, '
       'GLsizei height, GLint border, GLsizei imageSize, const void* data', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glCompressedTexImage3D',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glCompressedTexImage3D' }],
   'arguments':
       'GLenum target, GLint level, GLenum internalformat, GLsizei width, '
       'GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, '
@@ -222,15 +211,13 @@
       'const void* data', },
 # TODO(zmo): wait for MOCK_METHOD11.
 # { 'return_type': 'void',
-#   'versions': [{ 'name': 'glCompressedTexSubImage3D',
-#                  'gl_versions': ['gl3', 'gl4', 'es3'] }],
+#   'versions': [{ 'name': 'glCompressedTexSubImage3D' }],
 #   'arguments':
 #       'GLenum target, GLint level, GLint xoffset, GLint yoffset, '
 #       'GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, '
 #       'GLenum format, GLsizei imageSize, const void* data', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glCopyBufferSubData',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.1 or higher.
+  'versions': [{ 'name': 'glCopyBufferSubData' }],
   'arguments':
       'GLenum readTarget, GLenum writeTarget, GLintptr readOffset, '
       'GLintptr writeOffset, GLsizeiptr size', },
@@ -245,8 +232,7 @@
       'GLenum target, GLint level, GLint xoffset, '
       'GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glCopyTexSubImage3D',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glCopyTexSubImage3D' }],
   'arguments':
       'GLenum target, GLint level, GLint xoffset, GLint yoffset, '
       'GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height', },
@@ -260,7 +246,8 @@
   'names': ['glCullFace'],
   'arguments': 'GLenum mode', },
 { 'return_type': 'void',
-  'names': ['glDeleteBuffersARB', 'glDeleteBuffers'],
+  'names': ['glDeleteBuffers'],
+  'known_as': 'glDeleteBuffersARB',
   'arguments': 'GLsizei n, const GLuint* buffers', },
 { 'return_type': 'void',
   'known_as': 'glDeleteFencesAPPLE',
@@ -277,38 +264,36 @@
   'names': ['glDeleteProgram'],
   'arguments': 'GLuint program', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glDeleteQueries',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glDeleteQueries' }],
   'arguments': 'GLsizei n, const GLuint* ids', },
 { 'return_type': 'void',
-  'names': ['glDeleteQueriesARB', 'glDeleteQueriesEXT'],
+  'versions': [{ 'name': 'glDeleteQueriesARB'},
+               { 'name': 'glDeleteQueriesEXT',
+                 'extensions': ['GL_EXT_occlusion_query_boolean'] }],
   'arguments': 'GLsizei n, const GLuint* ids', },
 { 'return_type': 'void',
   'names': ['glDeleteRenderbuffersEXT', 'glDeleteRenderbuffers'],
   'arguments': 'GLsizei n, const GLuint* renderbuffers', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glDeleteSamplers',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.2 or higher.
+  'versions': [{ 'name': 'glDeleteSamplers' }],
   'arguments': 'GLsizei n, const GLuint* samplers', },
 { 'return_type': 'void',
   'names': ['glDeleteShader'],
   'arguments': 'GLuint shader', },
 { 'return_type': 'void',
-  'names': ['glDeleteSync'],
+  'versions': [{ 'name': 'glDeleteSync',
+                 'extensions': ['GL_ARB_sync'] }],
   'arguments': 'GLsync sync', },
 { 'return_type': 'void',
   'names': ['glDeleteTextures'],
   'arguments': 'GLsizei n, const GLuint* textures', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glDeleteTransformFeedbacks',
-                 'gl_versions': ['gl4', 'es3'] }],
+  'versions': [{ 'name': 'glDeleteTransformFeedbacks' }],
   'arguments': 'GLsizei n, const GLuint* ids', },
 { 'return_type': 'void',
   'known_as': 'glDeleteVertexArraysOES',
   'versions': [{ 'name': 'glDeleteVertexArrays',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] },
-               { 'name': 'glDeleteVertexArrays',
-                 'extensions': ['GL_ARB_vertex_array_object'] },
+                 'extensions': ['GL_ARB_vertex_array_object'], },
                { 'name': 'glDeleteVertexArraysOES' },
                { 'name': 'glDeleteVertexArraysAPPLE',
                  'extensions': ['GL_APPLE_vertex_array_object'] }],
@@ -320,7 +305,8 @@
   'names': ['glDepthMask'],
   'arguments': 'GLboolean flag', },
 { 'return_type': 'void',
-  'names': ['glDepthRange'],
+ 'versions': [{ 'name': 'glDepthRange',
+                'extensions': ['GL_CHROMIUM_gles_depth_binding_hack'] }],
   'arguments': 'GLclampd zNear, GLclampd zFar', },
 { 'return_type': 'void',
   'names': ['glDepthRangef'],
@@ -365,8 +351,7 @@
       'GLenum mode, GLsizei count, GLenum type, const void* indices, '
       'GLsizei primcount', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glDrawRangeElements',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glDrawRangeElements' }],
   'arguments': 'GLenum mode, GLuint start, GLuint end, GLsizei count, '
                'GLenum type, const void* indices', },
 { 'return_type': 'void',
@@ -382,18 +367,19 @@
   'names': ['glEnableVertexAttribArray'],
   'arguments': 'GLuint index', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glEndQuery',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glEndQuery' }],
   'arguments': 'GLenum target', },
 { 'return_type': 'void',
-  'names': ['glEndQueryARB', 'glEndQueryEXT'],
+  'versions': [{ 'name': 'glEndQueryARB' },
+               { 'name': 'glEndQueryEXT',
+                 'extensions': ['GL_EXT_occlusion_query_boolean'] }],
   'arguments': 'GLenum target', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glEndTransformFeedback',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glEndTransformFeedback' }],
   'arguments': 'void', },
 { 'return_type': 'GLsync',
-  'names': ['glFenceSync'],
+  'versions': [{ 'name': 'glFenceSync',
+                 'extensions': ['GL_ARB_sync'] }],
   'arguments': 'GLenum condition, GLbitfield flags', },
 { 'return_type': 'void',
   'names': ['glFinish'],
@@ -433,15 +419,15 @@
       'GLenum target, GLenum attachment, GLenum textarget, GLuint texture, '
       'GLint level, GLsizei samples', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glFramebufferTextureLayer',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glFramebufferTextureLayer' }],
   'arguments': 'GLenum target, GLenum attachment, GLuint texture, GLint level, '
                'GLint layer', },
 { 'return_type': 'void',
   'names': ['glFrontFace'],
   'arguments': 'GLenum mode', },
 { 'return_type': 'void',
-  'names': ['glGenBuffersARB', 'glGenBuffers'],
+  'names': ['glGenBuffers'],
+  'known_as': 'glGenBuffersARB',
   'arguments': 'GLsizei n, GLuint* buffers', },
 { 'return_type': 'void',
   'names': ['glGenerateMipmapEXT', 'glGenerateMipmap'],
@@ -458,32 +444,29 @@
   'names': ['glGenFramebuffersEXT', 'glGenFramebuffers'],
   'arguments': 'GLsizei n, GLuint* framebuffers', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGenQueries',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glGenQueries' }],
   'arguments': 'GLsizei n, GLuint* ids', },
 { 'return_type': 'void',
-  'names': ['glGenQueriesARB', 'glGenQueriesEXT'],
+  'versions': [{ 'name': 'glGenQueriesARB', },
+               { 'name' : 'glGenQueriesEXT',
+                 'extensions': ['GL_EXT_occlusion_query_boolean'] }],
   'arguments': 'GLsizei n, GLuint* ids', },
 { 'return_type': 'void',
   'names': ['glGenRenderbuffersEXT', 'glGenRenderbuffers'],
   'arguments': 'GLsizei n, GLuint* renderbuffers', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGenSamplers',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.2 or higher.
+  'versions': [{ 'name': 'glGenSamplers' }],
   'arguments': 'GLsizei n, GLuint* samplers', },
 { 'return_type': 'void',
   'names': ['glGenTextures'],
   'arguments': 'GLsizei n, GLuint* textures', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGenTransformFeedbacks',
-                 'gl_versions': ['gl4', 'es3'] }],
+  'versions': [{ 'name': 'glGenTransformFeedbacks' }],
   'arguments': 'GLsizei n, GLuint* ids', },
 { 'return_type': 'void',
   'known_as': 'glGenVertexArraysOES',
   'versions': [{ 'name': 'glGenVertexArrays',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] },
-               { 'name': 'glGenVertexArrays',
-                 'extensions': ['GL_ARB_vertex_array_object'] },
+                 'extensions': ['GL_ARB_vertex_array_object'], },
                { 'name': 'glGenVertexArraysOES' },
                { 'name': 'glGenVertexArraysAPPLE',
                  'extensions': ['GL_APPLE_vertex_array_object'] }],
@@ -499,18 +482,15 @@
       'GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, '
       'GLint* size, GLenum* type, char* name', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetActiveUniformBlockiv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.1 or higher.
+  'versions': [{ 'name': 'glGetActiveUniformBlockiv' }],
   'arguments': 'GLuint program, GLuint uniformBlockIndex, GLenum pname, '
                'GLint* params', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetActiveUniformBlockName',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.1 or higher.
+  'versions': [{ 'name': 'glGetActiveUniformBlockName' }],
   'arguments': 'GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, '
                'GLsizei* length, char* uniformBlockName', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetActiveUniformsiv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.1 or higher.
+  'versions': [{ 'name': 'glGetActiveUniformsiv' }],
   'arguments': 'GLuint program, GLsizei uniformCount, '
                'const GLuint* uniformIndices, GLenum pname, GLint* params', },
 { 'return_type': 'void',
@@ -539,8 +519,7 @@
   'names': ['glGetFloatv'],
   'arguments': 'GLenum pname, GLfloat* params', },
 { 'return_type': 'GLint',
-  'versions': [{ 'name': 'glGetFragDataLocation',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glGetFragDataLocation' }],
   'arguments': 'GLuint program, const char* name', },
 { 'return_type': 'void',
   'names': ['glGetFramebufferAttachmentParameterivEXT',
@@ -554,30 +533,26 @@
             'glGetGraphicsResetStatus'],
   'arguments': 'void', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetInteger64i_v',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.2 or higher.
+  'versions': [{ 'name': 'glGetInteger64i_v' }],
   'arguments': 'GLenum target, GLuint index, GLint64* data', },
 { 'return_type': 'void',
   'names': ['glGetInteger64v'],
   'arguments': 'GLenum pname, GLint64* params', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetIntegeri_v',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glGetIntegeri_v' }],
   'arguments': 'GLenum target, GLuint index, GLint* data', },
 { 'return_type': 'void',
   'names': ['glGetIntegerv'],
   'arguments': 'GLenum pname, GLint* params', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetInternalformativ',
-                 'gl_versions': ['gl4', 'es3'] }],  # GL 4.2 or higher.
+  'versions': [{ 'name': 'glGetInternalformativ' }],
   'arguments': 'GLenum target, GLenum internalformat, GLenum pname, '
                'GLsizei bufSize, GLint* params', },
 { 'return_type': 'void',
   'known_as': 'glGetProgramBinary',
   'versions': [{ 'name': 'glGetProgramBinaryOES' },
                { 'name': 'glGetProgramBinary',
-                 'extensions': ['GL_ARB_get_program_binary'] },
-               { 'name': 'glGetProgramBinary' }],
+                 'extensions': ['GL_ARB_get_program_binary'] }],
   'arguments': 'GLuint program, GLsizei bufSize, GLsizei* length, '
                'GLenum* binaryFormat, GLvoid* binary' },
 { 'return_type': 'void',
@@ -588,42 +563,45 @@
   'names': ['glGetProgramiv'],
   'arguments': 'GLuint program, GLenum pname, GLint* params', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetQueryiv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glGetQueryiv' }],
   'arguments': 'GLenum target, GLenum pname, GLint* params', },
 { 'return_type': 'void',
-  'names': ['glGetQueryivARB', 'glGetQueryivEXT'],
+  'versions': [{ 'name': 'glGetQueryivARB' },
+               { 'name': 'glGetQueryivEXT',
+                 'extensions': ['GL_EXT_occlusion_query_boolean'] }],
   'arguments': 'GLenum target, GLenum pname, GLint* params', },
 { 'return_type': 'void',
-  'names': ['glGetQueryObjecti64v'],
+  'versions': [{ 'name': 'glGetQueryObjecti64v',
+                 'extensions': ['GL_ARB_timer_query'] },
+               { 'name': 'glGetQueryObjecti64vEXT' }],
   'arguments': 'GLuint id, GLenum pname, GLint64* params', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetQueryObjectiv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'names': ['glGetQueryObjectiv'],
   'arguments': 'GLuint id, GLenum pname, GLint* params', },
 { 'return_type': 'void',
   'names': ['glGetQueryObjectivARB', 'glGetQueryObjectivEXT'],
   'arguments': 'GLuint id, GLenum pname, GLint* params', },
 { 'return_type': 'void',
-  'names': ['glGetQueryObjectui64v', 'glGetQueryObjectui64vEXT'],
+  'versions': [{ 'name': 'glGetQueryObjectui64v',
+                 'extensions': ['GL_ARB_timer_query'] },
+               { 'name': 'glGetQueryObjectui64vEXT' }],
   'arguments': 'GLuint id, GLenum pname, GLuint64* params', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetQueryObjectuiv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glGetQueryObjectuiv' }],
   'arguments': 'GLuint id, GLenum pname, GLuint* params', },
 { 'return_type': 'void',
-  'names': ['glGetQueryObjectuivARB', 'glGetQueryObjectuivEXT'],
+  'versions': [{ 'name': 'glGetQueryObjectuivARB' },
+               { 'name': 'glGetQueryObjectuivEXT',
+                 'extensions': ['GL_EXT_occlusion_query_boolean'] }],
   'arguments': 'GLuint id, GLenum pname, GLuint* params', },
 { 'return_type': 'void',
   'names': ['glGetRenderbufferParameterivEXT', 'glGetRenderbufferParameteriv'],
   'arguments': 'GLenum target, GLenum pname, GLint* params', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetSamplerParameterfv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.2 or higher.
+  'versions': [{ 'name': 'glGetSamplerParameterfv' }],
   'arguments': 'GLuint sampler, GLenum pname, GLfloat* params', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetSamplerParameteriv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.2 or higher.
+  'versions': [{ 'name': 'glGetSamplerParameteriv' }],
   'arguments': 'GLuint sampler, GLenum pname, GLint* params', },
 { 'return_type': 'void',
   'names': ['glGetShaderInfoLog'],
@@ -644,7 +622,8 @@
   'names': ['glGetString'],
   'arguments': 'GLenum name', },
 { 'return_type': 'void',
-  'names': ['glGetSynciv'],
+  'versions': [{ 'name': 'glGetSynciv',
+                 'extensions': ['GL_ARB_sync'] }],
   'arguments':
     'GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length,'
     'GLint* values', },
@@ -661,8 +640,7 @@
   'names': ['glGetTexParameteriv'],
   'arguments': 'GLenum target, GLenum pname, GLint* params', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetTransformFeedbackVarying',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glGetTransformFeedbackVarying' }],
   'arguments': 'GLuint program, GLuint index, GLsizei bufSize, '
                'GLsizei* length, GLenum* type, char* name', },
 { 'return_type': 'void',
@@ -670,15 +648,13 @@
   'arguments':
       'GLuint shader, GLsizei bufsize, GLsizei* length, char* source', },
 { 'return_type': 'GLuint',
-  'versions': [{ 'name': 'glGetUniformBlockIndex',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.1 or higher.
+  'versions': [{ 'name': 'glGetUniformBlockIndex' }],
   'arguments': 'GLuint program, const char* uniformBlockName', },
 { 'return_type': 'void',
   'names': ['glGetUniformfv'],
   'arguments': 'GLuint program, GLint location, GLfloat* params', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glGetUniformIndices',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.1 or higher.
+  'versions': [{ 'name': 'glGetUniformIndices' }],
   'arguments': 'GLuint program, GLsizei uniformCount, '
                'const char* const* uniformNames, GLuint* uniformIndices', },
 { 'return_type': 'void',
@@ -703,13 +679,11 @@
   'names': ['glInsertEventMarkerEXT'],
   'arguments': 'GLsizei length, const char* marker', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glInvalidateFramebuffer',
-                 'gl_versions': ['gl4', 'es3'] }],  # GL 4.3 or higher.
+  'versions': [{ 'name': 'glInvalidateFramebuffer' }],
   'arguments': 'GLenum target, GLsizei numAttachments, '
       'const GLenum* attachments' },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glInvalidateSubFramebuffer',
-                 'gl_versions': ['gl4', 'es3'] }],  # GL 4.3 or higher.
+  'versions': [{ 'name': 'glInvalidateSubFramebuffer' }],
   'arguments':
       'GLenum target, GLsizei numAttachments, const GLenum* attachments, '
       'GLint x, GLint y, GLint width, GLint height', },
@@ -734,38 +708,36 @@
   'names': ['glIsProgram'],
   'arguments': 'GLuint program', },
 { 'return_type': 'GLboolean',
-  'versions': [{ 'name': 'glIsQuery',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glIsQuery' }],
   'arguments': 'GLuint query', },
 { 'return_type': 'GLboolean',
-  'names': ['glIsQueryARB', 'glIsQueryEXT'],
+  'versions': [{ 'name': 'glIsQueryARB' },
+               { 'name': 'glIsQueryEXT',
+                 'extensions': ['GL_EXT_occlusion_query_boolean'] }],
   'arguments': 'GLuint query', },
 { 'return_type': 'GLboolean',
   'names': ['glIsRenderbufferEXT', 'glIsRenderbuffer'],
   'arguments': 'GLuint renderbuffer', },
 { 'return_type': 'GLboolean',
-  'versions': [{ 'name': 'glIsSampler',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.2 or higher.
+  'versions': [{ 'name': 'glIsSampler' }],
   'arguments': 'GLuint sampler', },
 { 'return_type': 'GLboolean',
   'names': ['glIsShader'],
   'arguments': 'GLuint shader', },
 { 'return_type': 'GLboolean',
-  'names': ['glIsSync'],
+  'versions': [{ 'name': 'glIsSync',
+                 'extensions': ['GL_ARB_sync'] }],
   'arguments': 'GLsync sync', },
 { 'return_type': 'GLboolean',
   'names': ['glIsTexture'],
   'arguments': 'GLuint texture', },
 { 'return_type': 'GLboolean',
-  'versions': [{ 'name': 'glIsTransformFeedback',
-                 'gl_versions': ['gl4', 'es3'] }],
+  'versions': [{ 'name': 'glIsTransformFeedback' }],
   'arguments': 'GLuint id', },
 { 'return_type': 'GLboolean',
   'known_as': 'glIsVertexArrayOES',
   'versions': [{ 'name': 'glIsVertexArray',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] },
-               { 'name': 'glIsVertexArray',
-                 'extensions': ['GL_ARB_vertex_array_object'] },
+                 'extensions': ['GL_ARB_vertex_array_object'], },
                { 'name': 'glIsVertexArrayOES' },
                { 'name': 'glIsVertexArrayAPPLE',
                  'extensions': ['GL_APPLE_vertex_array_object'] }],
@@ -783,8 +755,6 @@
 { 'return_type': 'void*',
   'known_as': 'glMapBufferRange',
   'versions': [{ 'name': 'glMapBufferRange',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] },
-               { 'name': 'glMapBufferRange',
                  'extensions': ['GL_ARB_map_buffer_range'] },
                { 'name': 'glMapBufferRangeEXT',
                  'extensions': ['GL_EXT_map_buffer_range'] }],
@@ -793,24 +763,17 @@
 { 'return_type': 'void',
   'known_as': 'glMatrixLoadfEXT',
   'versions': [{ 'name': 'glMatrixLoadfEXT',
-                 'gl_versions': ['gl4'],
-                 'extensions': ['GL_EXT_direct_state_access'] },
-               { 'name': 'glMatrixLoadfEXT',
-                 'gl_versions': ['es3'],
-                 'extensions': ['GL_NV_path_rendering'] }],
+                 'extensions': ['GL_EXT_direct_state_access',
+                                'GL_NV_path_rendering'] }],
   'arguments': 'GLenum matrixMode, const GLfloat* m' },
 { 'return_type': 'void',
   'known_as': 'glMatrixLoadIdentityEXT',
   'versions': [{ 'name': 'glMatrixLoadIdentityEXT',
-                 'gl_versions': ['gl4'],
-                 'extensions': ['GL_EXT_direct_state_access'] },
-               { 'name': 'glMatrixLoadIdentityEXT',
-                 'gl_versions': ['es3'],
-                 'extensions': ['GL_NV_path_rendering'] }],
+                 'extensions': ['GL_EXT_direct_state_access',
+                                'GL_NV_path_rendering'] },],
   'arguments': 'GLenum matrixMode' },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glPauseTransformFeedback',
-                 'gl_versions': ['gl4', 'es3'] }],
+  'versions': [{ 'name': 'glPauseTransformFeedback' }],
   'arguments': 'void', },
 { 'return_type': 'void',
   'names': ['glPixelStorei'],
@@ -828,20 +791,20 @@
   'known_as': 'glProgramBinary',
   'versions': [{ 'name': 'glProgramBinaryOES' },
                { 'name': 'glProgramBinary',
-                 'extensions': ['GL_ARB_get_program_binary'] },
-               { 'name': 'glProgramBinary' }],
+                 'extensions': ['GL_ARB_get_program_binary'] }],
   'arguments': 'GLuint program, GLenum binaryFormat, '
                'const GLvoid* binary, GLsizei length' },
 { 'return_type': 'void',
   'versions': [{ 'name': 'glProgramParameteri',
-                 'extensions': ['GL_ARB_get_program_binary'] },
-               { 'name': 'glProgramParameteri' }],
+                 'extensions': ['GL_ARB_get_program_binary'] }],
   'arguments': 'GLuint program, GLenum pname, GLint value' },
 { 'return_type': 'void',
   'names': ['glPushGroupMarkerEXT'],
   'arguments': 'GLsizei length, const char* marker', },
 { 'return_type': 'void',
-  'names': ['glQueryCounter', 'glQueryCounterEXT'],
+  'versions': [{ 'name': 'glQueryCounter',
+                 'extensions': ['GL_ARB_timer_query'] },
+               { 'name': 'glQueryCounterEXT' }],
   'arguments': 'GLuint id, GLenum target', },
 { 'return_type': 'void',
   'names': ['glReadBuffer'],
@@ -894,27 +857,22 @@
   'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
                'GLsizei width, GLsizei height', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glResumeTransformFeedback',
-                 'gl_versions': ['gl4', 'es3'] }],
+  'versions': [{ 'name': 'glResumeTransformFeedback' }],
   'arguments': 'void', },
 { 'return_type': 'void',
   'names': ['glSampleCoverage'],
   'arguments': 'GLclampf value, GLboolean invert', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glSamplerParameterf',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.2 or higher.
+  'versions': [{ 'name': 'glSamplerParameterf' }],
   'arguments': 'GLuint sampler, GLenum pname, GLfloat param', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glSamplerParameterfv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.2 or higher.
+  'versions': [{ 'name': 'glSamplerParameterfv' }],
   'arguments': 'GLuint sampler, GLenum pname, const GLfloat* params', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glSamplerParameteri',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.2 or higher.
+  'versions': [{ 'name': 'glSamplerParameteri' }],
   'arguments': 'GLuint sampler, GLenum pname, GLint param', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glSamplerParameteriv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.2 or higher.
+  'versions': [{ 'name': 'glSamplerParameteriv' }],
   'arguments': 'GLuint sampler, GLenum pname, const GLint* params', },
 { 'return_type': 'void',
   'names': ['glScissor'],
@@ -984,8 +942,7 @@
       'GLsizei height, GLint border, GLenum format, GLenum type, '
       'const void* pixels', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glTexImage3D',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glTexImage3D' }],
   'arguments':
       'GLenum target, GLint level, GLint internalformat, GLsizei width, '
       'GLsizei height, GLsizei depth, GLint border, GLenum format, '
@@ -1005,16 +962,13 @@
 { 'return_type': 'void',
   'known_as': 'glTexStorage2DEXT',
   'versions': [{ 'name': 'glTexStorage2D',
-                 'gl_versions': ['es3'] },
-               { 'name': 'glTexStorage2D',
                  'extensions': ['GL_ARB_texture_storage'] },
                { 'name': 'glTexStorage2DEXT',
                  'extensions': ['GL_EXT_texture_storage'] }],
   'arguments': 'GLenum target, GLsizei levels, GLenum internalformat, '
                'GLsizei width, GLsizei height', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glTexStorage3D',
-                 'gl_versions': ['gl4', 'es3'] }],  # GL 4.2 or higher.
+  'versions': [{ 'name': 'glTexStorage3D' }],
   'arguments': 'GLenum target, GLsizei levels, GLenum internalformat, '
                'GLsizei width, GLsizei height, GLsizei depth', },
 { 'return_type': 'void',
@@ -1025,15 +979,13 @@
      'const void* pixels', },
 # TODO(zmo): wait for MOCK_METHOD11.
 # { 'return_type': 'void',
-#   'versions': [{ 'name': 'glTexSubImage3D',
-#                  'gl_versions': ['gl3', 'gl4', 'es3'] }],
+#   'versions': [{ 'name': 'glTexSubImage3D' }],
 #   'arguments':
 #       'GLenum target, GLint level, GLint xoffset, GLint yoffset, '
 #       'GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, '
 #       'GLenum format, GLenum type, const void* pixels', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glTransformFeedbackVaryings',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glTransformFeedbackVaryings' }],
   'arguments': 'GLuint program, GLsizei count, const char* const* varyings, '
                'GLenum bufferMode', },
 { 'return_type': 'void',
@@ -1049,12 +1001,10 @@
   'names': ['glUniform1iv'],
   'arguments': 'GLint location, GLsizei count, const GLint* v', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniform1ui',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniform1ui' }],
   'arguments': 'GLint location, GLuint v0', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniform1uiv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniform1uiv' }],
   'arguments': 'GLint location, GLsizei count, const GLuint* v', },
 { 'return_type': 'void',
   'names': ['glUniform2f'],
@@ -1069,12 +1019,10 @@
   'names': ['glUniform2iv'],
   'arguments': 'GLint location, GLsizei count, const GLint* v', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniform2ui',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniform2ui' }],
   'arguments': 'GLint location, GLuint v0, GLuint v1', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniform2uiv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniform2uiv' }],
   'arguments': 'GLint location, GLsizei count, const GLuint* v', },
 { 'return_type': 'void',
   'names': ['glUniform3f'],
@@ -1089,12 +1037,10 @@
   'names': ['glUniform3iv'],
   'arguments': 'GLint location, GLsizei count, const GLint* v', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniform3ui',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniform3ui' }],
   'arguments': 'GLint location, GLuint v0, GLuint v1, GLuint v2', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniform3uiv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniform3uiv' }],
   'arguments': 'GLint location, GLsizei count, const GLuint* v', },
 { 'return_type': 'void',
   'names': ['glUniform4f'],
@@ -1109,16 +1055,13 @@
   'names': ['glUniform4iv'],
   'arguments': 'GLint location, GLsizei count, const GLint* v', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniform4ui',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniform4ui' }],
   'arguments': 'GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniform4uiv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniform4uiv' }],
   'arguments': 'GLint location, GLsizei count, const GLuint* v', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniformBlockBinding',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],  # GL 3.1 or higher.
+  'versions': [{ 'name': 'glUniformBlockBinding' }],
   'arguments': 'GLuint program, GLuint uniformBlockIndex, '
                'GLuint uniformBlockBinding', },
 { 'return_type': 'void',
@@ -1126,13 +1069,11 @@
   'arguments': 'GLint location, GLsizei count, '
                'GLboolean transpose, const GLfloat* value', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniformMatrix2x3fv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniformMatrix2x3fv' }],
   'arguments': 'GLint location, GLsizei count, '
                'GLboolean transpose, const GLfloat* value', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniformMatrix2x4fv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniformMatrix2x4fv' }],
   'arguments': 'GLint location, GLsizei count, '
                'GLboolean transpose, const GLfloat* value', },
 { 'return_type': 'void',
@@ -1140,13 +1081,11 @@
   'arguments': 'GLint location, GLsizei count, '
                'GLboolean transpose, const GLfloat* value', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniformMatrix3x2fv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniformMatrix3x2fv' }],
   'arguments': 'GLint location, GLsizei count, '
                'GLboolean transpose, const GLfloat* value', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniformMatrix3x4fv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniformMatrix3x4fv' }],
   'arguments': 'GLint location, GLsizei count, '
                'GLboolean transpose, const GLfloat* value', },
 { 'return_type': 'void',
@@ -1154,13 +1093,11 @@
   'arguments': 'GLint location, GLsizei count, '
                'GLboolean transpose, const GLfloat* value', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniformMatrix4x2fv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniformMatrix4x2fv' }],
   'arguments': 'GLint location, GLsizei count, '
                'GLboolean transpose, const GLfloat* value', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glUniformMatrix4x3fv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glUniformMatrix4x3fv' }],
   'arguments': 'GLint location, GLsizei count, '
                'GLboolean transpose, const GLfloat* value', },
 { 'return_type': 'GLboolean',
@@ -1204,24 +1141,19 @@
   'arguments':
       'GLuint index, GLuint divisor', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glVertexAttribI4i',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glVertexAttribI4i' }],
   'arguments': 'GLuint indx, GLint x, GLint y, GLint z, GLint w', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glVertexAttribI4iv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glVertexAttribI4iv' }],
   'arguments': 'GLuint indx, const GLint* values', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glVertexAttribI4ui',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glVertexAttribI4ui' }],
   'arguments': 'GLuint indx, GLuint x, GLuint y, GLuint z, GLuint w', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glVertexAttribI4uiv',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glVertexAttribI4uiv' }],
   'arguments': 'GLuint indx, const GLuint* values', },
 { 'return_type': 'void',
-  'versions': [{ 'name': 'glVertexAttribIPointer',
-                 'gl_versions': ['gl3', 'gl4', 'es3'] }],
+  'versions': [{ 'name': 'glVertexAttribIPointer' }],
   'arguments': 'GLuint indx, GLint size, GLenum type, GLsizei stride, '
                'const void* ptr', },
 { 'return_type': 'void',
@@ -1232,7 +1164,8 @@
   'names': ['glViewport'],
   'arguments': 'GLint x, GLint y, GLsizei width, GLsizei height', },
 { 'return_type': 'GLenum',
-  'names': ['glWaitSync'],
+  'versions': [{ 'name': 'glWaitSync',
+                 'extensions': ['GL_ARB_sync'] }],
   'arguments':
     'GLsync sync, GLbitfield flags, GLuint64 timeout', },
 ]
@@ -1675,8 +1608,11 @@
 
 FUNCTION_SETS = [
   [GL_FUNCTIONS, 'gl', [
-      'GL/glext.h',
+      'GL/gl.h',
+      'noninclude/GL/glext.h',
       'GLES2/gl2ext.h',
+      'GLES3/gl3.h',
+      'GLES3/gl31.h',
       # Files below are Chromium-specific and shipped with Chromium sources.
       'GL/glextchromium.h',
       'GLES2/gl2chromium.h',
@@ -1693,8 +1629,8 @@
       'EGL_ANGLE_surface_d3d_texture_2d_share_handle',
     ],
   ],
-  [WGL_FUNCTIONS, 'wgl', ['GL/wglext.h'], []],
-  [GLX_FUNCTIONS, 'glx', ['GL/glx.h', 'GL/glxext.h'], []],
+  [WGL_FUNCTIONS, 'wgl', ['noninclude/GL/wglext.h'], []],
+  [GLX_FUNCTIONS, 'glx', ['GL/glx.h', 'noninclude/GL/glxext.h'], []],
 ]
 
 GLES2_HEADERS_WITH_ENUMS = [
@@ -1720,6 +1656,53 @@
 
 """
 
+GLVersion = namedtuple('GLVersion', 'is_es major_version minor_version')
+
+def GLVersionBindAlways(version):
+  return version.major_version <= 2
+
+
+def GetStaticBinding(func):
+  """If this function has a name assigned to it that should  be bound always,
+  then return this name.
+
+  This will be the case if either a function name is specified
+  that depends on an extension from UNCONDITIONALLY_BOUND_EXTENSIONS,
+  or if the GL version it depends on is assumed to be available (e.g. <=2.1).
+  There can only be one name that satisfies this condition (or the bindings
+  would be ambiguous)."""
+
+  static_bindings = set([])
+
+  for version in func['versions']:
+    if 'extensions' in version:
+      extensions = version['extensions']
+      num_unconditional_extensions = len(
+          extensions & UNCONDITIONALLY_BOUND_EXTENSIONS)
+      if num_unconditional_extensions:
+        static_bindings.add(version['name'])
+    elif 'gl_versions' in version:
+      versions = [v for v in version['gl_versions'] if GLVersionBindAlways(v)]
+      # It's only unconditional if it exists in GL and GLES
+      if len(versions) == 2:
+        assert versions[0].is_es != versions[1].is_es
+        static_bindings.add(version['name'])
+    else:
+        static_bindings.add(version['name'])
+
+  # Avoid ambiguous bindings (static binding with different names)
+  assert len(static_bindings) <= 1
+  if len(static_bindings):
+    static_name = static_bindings.pop()
+    # Avoid ambiguous bindings (static and dynamic bindings with
+    # different names)
+    assert len([v['name'] for v in func['versions']
+               if v['name'] != static_name]) == 0, func
+    return static_name
+  else:
+    return None
+
+
 def GenerateHeader(file, functions, set_name, used_extensions):
   """Generates gl_bindings_autogen_x.h"""
 
@@ -1824,13 +1807,14 @@
   """Generates gl_bindings_autogen_x.cc"""
 
   set_header_name = "ui/gl/gl_" + set_name.lower() + "_api_implementation.h"
-  include_list = [ 'base/debug/trace_event.h',
+  include_list = [ 'base/trace_event/trace_event.h',
                    'ui/gl/gl_enums.h',
                    'ui/gl/gl_bindings.h',
                    'ui/gl/gl_context.h',
                    'ui/gl/gl_implementation.h',
                    'ui/gl/gl_version_info.h',
                    set_header_name ]
+
   includes_string = "\n".join(["#include \"{0}\"".format(h)
                                for h in sorted(include_list)])
 
@@ -1854,17 +1838,16 @@
   # is initialized. This is done to provide clear asserts on debug build and to
   # avoid crashing in case of a bug on release build.
   file.write('\n')
+  num_dynamic = 0
   for func in functions:
-    unique_names = set([version['name'] for version in func['versions']])
-    if len(unique_names) > 1:
-      file.write('%s %sNotBound(%s) {\n' %
-          (func['return_type'], func['known_as'], func['arguments']))
-      file.write('  NOTREACHED();\n')
-      return_type = func['return_type'].lower()
-      # Returning 0 works for booleans, integers and pointers.
-      if return_type != 'void':
-        file.write('  return 0;\n')
-      file.write('}\n')
+    static_binding = GetStaticBinding(func)
+    if static_binding:
+      func['static_binding'] = static_binding
+    else:
+      num_dynamic = num_dynamic + 1
+
+  print "[%s] %d static bindings, %d dynamic bindings" % (
+      set_name, len(functions) - num_dynamic, num_dynamic)
 
   # Write function to initialize the function pointers that are always the same
   # and to initialize bindings where choice of the function depends on the
@@ -1879,100 +1862,81 @@
         (known_as, known_as, version_name))
 
   for func in functions:
-    unique_names = set([version['name'] for version in func['versions']])
-    if len(unique_names) == 1:
-      WriteFuncBinding(file, func['known_as'], func['known_as'])
+    if 'static_binding' in func:
+      WriteFuncBinding(file, func['known_as'], func['static_binding'])
     else:
-      file.write('  fn.%sFn = reinterpret_cast<%sProc>(%sNotBound);\n' %
-          (func['known_as'], func['known_as'], func['known_as']))
+      file.write('  fn.%sFn = 0;\n' % func['known_as'])
 
-  file.write('}\n')
-  file.write('\n')
-
-  # Write function to initialize bindings where choice of the function depends
-  # on the extension string or the GL version.
-  file.write("""void Driver%s::InitializeDynamicBindings(GLContext* context) {
+  if set_name == 'gl':
+    # Write the deferred bindings for GL that need a current context and depend
+    # on GL_VERSION and GL_EXTENSIONS.
+    file.write('}\n\n')
+    file.write("""void DriverGL::InitializeDynamicBindings(GLContext* context) {
   DCHECK(context && context->IsCurrent(NULL));
   const GLVersionInfo* ver = context->GetVersionInfo();
   ALLOW_UNUSED_LOCAL(ver);
   std::string extensions = context->GetExtensions() + " ";
   ALLOW_UNUSED_LOCAL(extensions);
 
-""" % set_name.upper())
+""")
+  else:
+    file.write("""std::string extensions(GetPlatformExtensions());
+  extensions += " ";
+  ALLOW_UNUSED_LOCAL(extensions);
+
+""")
+
   for extension in sorted(used_extensions):
     # Extra space at the end of the extension name is intentional, it is used
     # as a separator
     file.write('  ext.b_%s = extensions.find("%s ") != std::string::npos;\n' %
         (extension, extension))
 
-  def WrapOr(cond):
-    if ' || ' in cond:
-      return '(%s)' % cond
-    return cond
+  def GetGLVersionCondition(gl_version):
+    if GLVersionBindAlways(gl_version):
+      if gl_version.is_es:
+        return 'ver->is_es'
+      else:
+        return '!ver->is_es'
+    elif gl_version.is_es:
+      return 'ver->IsAtLeastGLES(%du, %du)' % (
+          gl_version.major_version, gl_version.minor_version)
+    else:
+      return 'ver->IsAtLeastGL(%du, %du)' % (
+          gl_version.major_version, gl_version.minor_version)
 
-  def WrapAnd(cond):
-    if ' && ' in cond:
-      return '(%s)' % cond
-    return cond
-
-  def VersionCondition(version):
+  def GetBindingCondition(version):
     conditions = []
     if 'gl_versions' in version:
-      gl_versions = version['gl_versions']
-      version_cond = ' || '.join(['ver->is_%s' % gl for gl in gl_versions])
-      conditions.append(WrapOr(version_cond))
+      conditions.extend(
+          [GetGLVersionCondition(v) for v in version['gl_versions']])
     if 'extensions' in version and version['extensions']:
-      ext_cond = ' || '.join(['ext.b_%s' % e for e in version['extensions']])
-      conditions.append(WrapOr(ext_cond))
-    return ' && '.join(conditions)
+      conditions.extend(
+          ['ext.b_%s' % e for e in version['extensions']])
+    return ' || '.join(conditions)
 
   def WriteConditionalFuncBinding(file, func):
-    # Functions with only one version are always bound unconditionally
-    assert len(func['versions']) > 1
+    assert len(func['versions']) > 0
     known_as = func['known_as']
     i = 0
     first_version = True
     while i < len(func['versions']):
       version = func['versions'][i]
-      cond = VersionCondition(version)
-      combined_conditions = [WrapAnd(cond)]
-      last_version = i + 1 == len(func['versions'])
-      while not last_version and \
-          func['versions'][i + 1]['name'] == version['name']:
-        i += 1
-        combinable_cond = VersionCondition(func['versions'][i])
-        combined_conditions.append(WrapAnd(combinable_cond))
-        last_version = i + 1 == len(func['versions'])
-      if len(combined_conditions) > 1:
-        if [1 for cond in combined_conditions if cond == '']:
-          cond = ''
-        else:
-          cond = ' || '.join(combined_conditions)
-      # Don't make the last possible binding conditional on anything else but
-      # that the function isn't already bound to avoid verbose specification
-      # of functions which have both ARB and core versions with the same name,
-      # and to be able to bind to mock extension functions in unit tests which
-      # call InitializeDynamicGLBindings with a stub context that doesn't have
-      # extensions in its extension string.
-      # TODO(oetuaho@nvidia.com): Get rid of the fallback.
-      # http://crbug.com/325668
-      if cond != '' and not last_version:
-        if not first_version:
-          file.write('  if (!fn.%sFn && (%s)) {\n  ' % (known_as, cond))
-        else:
-          file.write('  if (%s) {\n  ' % cond)
-      elif not first_version:
-        file.write('  if (!fn.%sFn) {\n  ' % known_as)
+      cond = GetBindingCondition(version)
+      if first_version:
+        file.write('  if (%s) {\n  ' % cond)
+      else:
+        file.write('  else if (%s) {\n  ' % (cond))
+
       WriteFuncBinding(file, known_as, version['name'])
+      file.write('DCHECK(fn.%sFn);\n' % known_as)
       file.write('}\n')
       i += 1
       first_version = False
 
   for func in functions:
-    unique_names = set([version['name'] for version in func['versions']])
-    if len(unique_names) > 1:
+    if not 'static_binding' in func:
       file.write('\n')
-      file.write('  fn.%sFn = 0;\n' % func['known_as'])
       file.write('  debug_fn.%sFn = 0;\n' % func['known_as'])
       WriteConditionalFuncBinding(file, func)
 
@@ -2275,15 +2239,18 @@
 """)
 
 
-def ParseExtensionFunctionsFromHeader(header_file):
+def ParseFunctionsFromHeader(header_file, extensions, versions):
   """Parse a C extension header file and return a map from extension names to
   a list of functions.
 
   Args:
     header_file: Line-iterable C header file.
   Returns:
-    Map of extension name => functions.
+    Map of extension name => functions, Map of gl version => functions.
+    Functions will only be in either one of the two maps.
   """
+  version_start = re.compile(
+      r'#ifndef GL_(ES_|)VERSION((?:_[0-9])+)$')
   extension_start = re.compile(
       r'#ifndef ((?:GL|EGL|WGL|GLX)_[A-Z]+_[a-zA-Z]\w+)')
   extension_function = re.compile(r'.+\s+([a-z]+\w+)\s*\(')
@@ -2291,59 +2258,109 @@
   macro_start = re.compile(r'^#(if|ifdef|ifndef).*')
   macro_end = re.compile(r'^#endif.*')
   macro_depth = 0
+  current_version = None
+  current_version_depth = 0
   current_extension = None
   current_extension_depth = 0
-  extensions = collections.defaultdict(lambda: [])
+
+  # Pick up all core functions here, since some of them are missing in the
+  # Khronos headers.
+  hdr = os.path.basename(header_file.name)
+  if hdr == "gl.h":
+    current_version = GLVersion(False, 1, 0)
+
+  line_num = 1
   for line in header_file:
+    version_match = version_start.match(line)
     if macro_start.match(line):
       macro_depth += 1
+      if version_match:
+        if current_version:
+          raise RuntimeError('Nested GL version macro in %s at line %d' % (
+              header_file.name, line_num))
+        current_version_depth = macro_depth
+        es = version_match.group(1)
+        major_version, minor_version =\
+            version_match.group(2).lstrip('_').split('_')
+        is_es = len(es) > 0
+        if (not is_es) and (major_version == '1'):
+          minor_version = 0
+        current_version = GLVersion(
+            is_es, int(major_version), int(minor_version))
     elif macro_end.match(line):
       macro_depth -= 1
       if macro_depth < current_extension_depth:
         current_extension = None
+      if macro_depth < current_version_depth:
+        current_version = None
+
     match = extension_start.match(line)
-    if match:
+    if match and not version_match:
+      if current_version and hdr != "gl.h":
+        raise RuntimeError('Nested GL version macro in %s at line %d' % (
+            header_file.name, line_num))
       current_extension = match.group(1)
       current_extension_depth = macro_depth
-      assert current_extension not in extensions, \
-          "Duplicate extension: " + current_extension
+
     match = extension_function.match(line)
-    if match and current_extension and not typedef.match(line):
-      extensions[current_extension].append(match.group(1))
-  return extensions
+    if match and not typedef.match(line):
+      if current_extension:
+        extensions[current_extension].add(match.group(1))
+      elif current_version:
+        versions[current_version].add(match.group(1))
+    line_num = line_num + 1
 
 
-def GetExtensionFunctions(extension_headers):
-  """Parse extension functions from a list of header files.
+def GetDynamicFunctions(extension_headers):
+  """Parse all optional functions from a list of header files.
 
   Args:
     extension_headers: List of header file names.
   Returns:
-    Map of extension name => list of functions.
+    Map of extension name => list of functions,
+    Map of gl version => list of functions.
   """
-  extensions = {}
+  extensions = collections.defaultdict(lambda: set([]))
+  gl_versions = collections.defaultdict(lambda: set([]))
   for header in extension_headers:
-    extensions.update(ParseExtensionFunctionsFromHeader(open(header)))
-  return extensions
+    ParseFunctionsFromHeader(open(header), extensions, gl_versions)
+  return extensions, gl_versions
 
 
-def GetFunctionToExtensionMap(extensions):
+def GetFunctionToExtensionsMap(extensions):
   """Construct map from a function names to extensions which define the
   function.
 
   Args:
     extensions: Map of extension name => functions.
   Returns:
-    Map of function name => extension name.
+    Map of function name => extension names.
   """
   function_to_extensions = {}
   for extension, functions in extensions.items():
     for function in functions:
       if not function in function_to_extensions:
-        function_to_extensions[function] = []
-      function_to_extensions[function].append(extension)
+        function_to_extensions[function] = set([])
+      function_to_extensions[function].add(extension)
   return function_to_extensions
 
+def GetFunctionToGLVersionsMap(gl_versions):
+  """Construct map from a function names to GL versions which define the
+  function.
+
+  Args:
+    extensions: Map of gl versions => functions.
+  Returns:
+    Map of function name => gl versions.
+  """
+  function_to_gl_versions = {}
+  for gl_version, functions in gl_versions.items():
+    for function in functions:
+      if not function in function_to_gl_versions:
+        function_to_gl_versions[function] = set([])
+      function_to_gl_versions[function].add(gl_version)
+  return function_to_gl_versions
+
 
 def LooksLikeExtensionFunction(function):
   """Heuristic to see if a function name is consistent with extension function
@@ -2352,6 +2369,13 @@
   return vendor is not None and not vendor.group(1) in ['GL', 'API', 'DC']
 
 
+def SortVersions(key):
+   # Prefer functions from the core for binding
+  if 'gl_versions' in key:
+    return 0
+  else:
+    return 1
+
 def FillExtensionsFromHeaders(functions, extension_headers, extra_extensions):
   """Determine which functions belong to extensions based on extension headers,
   and fill in this information to the functions table for functions that don't
@@ -2365,31 +2389,71 @@
     Set of used extensions.
   """
   # Parse known extensions.
-  extensions = GetExtensionFunctions(extension_headers)
-  functions_to_extensions = GetFunctionToExtensionMap(extensions)
+  extensions, gl_versions = GetDynamicFunctions(extension_headers)
+  functions_to_extensions = GetFunctionToExtensionsMap(extensions)
+  functions_to_gl_versions = GetFunctionToGLVersionsMap(gl_versions)
 
   # Fill in the extension information.
   used_extensions = set()
+  used_functions_by_version = collections.defaultdict(lambda: set([]))
   for func in functions:
     for version in func['versions']:
       name = version['name']
+
+      # There should only be one version entry per name string.
+      if len([v for v in func['versions'] if v['name'] == name]) > 1:
+        raise RuntimeError(
+            'Duplicate version entries with same name for %s' % name)
+
       # Make sure we know about all extensions and extension functions.
+      extensions_from_headers = set([])
+      if name in functions_to_extensions:
+        extensions_from_headers = set(functions_to_extensions[name])
+
+      explicit_extensions = set([])
       if 'extensions' in version:
+        explicit_extensions = set(version['extensions'])
+
+      in_both = explicit_extensions.intersection(extensions_from_headers)
+      if len(in_both):
+        print "[%s] Specified redundant extensions for binding: %s" % (
+            name, ', '.join(in_both))
+      diff = explicit_extensions - extensions_from_headers
+      if len(diff):
+        print "[%s] Specified extra extensions for binding: %s" % (
+            name, ', '.join(diff))
+
+      all_extensions = extensions_from_headers.union(explicit_extensions)
+      if len(all_extensions):
+        version['extensions'] = all_extensions
+
+      if 'extensions' in version:
+        assert len(version['extensions'])
         used_extensions.update(version['extensions'])
-      elif name in functions_to_extensions:
-        # If there are multiple versions with the same name, assume that they
-        # already have all the correct conditions, we can't just blindly add
-        # the same extension conditions to all of them
-        if len([v for v in func['versions'] if v['name'] == name]) == 1:
-          version['extensions'] = functions_to_extensions[name]
-          used_extensions.update(version['extensions'])
-      elif LooksLikeExtensionFunction(name):
+
+      if not 'extensions' in version and LooksLikeExtensionFunction(name):
         raise RuntimeError('%s looks like an extension function but does not '
             'belong to any of the known extensions.' % name)
 
+      if name in functions_to_gl_versions:
+        assert not 'gl_versions' in version
+        version['gl_versions'] = functions_to_gl_versions[name]
+        for v in version['gl_versions']:
+          used_functions_by_version[v].add(name)
+
+    func['versions'] = sorted(func['versions'], key=SortVersions)
+
   # Add extensions that do not have any functions.
   used_extensions.update(extra_extensions)
 
+  # Print out used function count by GL(ES) version.
+  for v in sorted([v for v in used_functions_by_version if v.is_es]):
+    print "OpenGL ES %d.%d: %d used functions" % (
+        v.major_version, v.minor_version, len(used_functions_by_version[v]))
+  for v in sorted([v for v in used_functions_by_version if not v.is_es]):
+    print "OpenGL %d.%d: %d used functions" % (
+        v.major_version, v.minor_version, len(used_functions_by_version[v]))
+
   return used_extensions
 
 
diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp
index 93c4d2b..7d97c66 100644
--- a/ui/gl/gl.gyp
+++ b/ui/gl/gl.gyp
@@ -40,6 +40,7 @@
         'android/surface_texture.h',
         'android/surface_texture_listener.cc',
         'android/surface_texture_listener.h',
+        'gl_bindings.cc',
         'gl_bindings.h',
         'gl_bindings_autogen_gl.cc',
         'gl_bindings_autogen_gl.h',
diff --git a/ui/gl/gl_bindings.cc b/ui/gl/gl_bindings.cc
new file mode 100644
index 0000000..43c84e2
--- /dev/null
+++ b/ui/gl/gl_bindings.cc
@@ -0,0 +1,68 @@
+// Copyright 2014 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.
+
+#if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || defined(USE_OZONE)
+#include <EGL/egl.h>
+#endif
+
+#include "ui/gl/gl_bindings.h"
+
+#if defined(USE_X11)
+#include "ui/gfx/x/x11_types.h"
+#endif
+
+#if defined(OS_WIN)
+#include "ui/gl/gl_surface_wgl.h"
+#endif
+
+#if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || defined(USE_OZONE)
+#include "ui/gl/gl_surface_egl.h"
+#endif
+
+namespace gfx {
+
+std::string DriverOSMESA::GetPlatformExtensions() {
+  return "";
+}
+
+#if defined(OS_WIN)
+std::string DriverWGL::GetPlatformExtensions() {
+  const char* str = nullptr;
+  if (g_driver_wgl.fn.wglGetExtensionsStringARBFn) {
+    str = g_driver_wgl.fn.wglGetExtensionsStringARBFn(
+        GLSurfaceWGL::GetDisplayDC());
+  } else if (g_driver_wgl.fn.wglGetExtensionsStringEXTFn) {
+    str = g_driver_wgl.fn.wglGetExtensionsStringEXTFn();
+  }
+  return str ? std::string(str) : "";
+}
+#endif
+
+#if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || defined(USE_OZONE)
+std::string DriverEGL::GetPlatformExtensions() {
+  EGLDisplay display =
+#if defined(OS_WIN)
+    GLSurfaceEGL::GetPlatformDisplay(GetPlatformDefaultEGLNativeDisplay());
+#else
+    g_driver_egl.fn.eglGetDisplayFn(GetPlatformDefaultEGLNativeDisplay());
+#endif
+
+  DCHECK(g_driver_egl.fn.eglInitializeFn);
+  g_driver_egl.fn.eglInitializeFn(display, NULL, NULL);
+  DCHECK(g_driver_egl.fn.eglQueryStringFn);
+  const char* str = g_driver_egl.fn.eglQueryStringFn(display, EGL_EXTENSIONS);
+  return str ? std::string(str) : "";
+}
+#endif
+
+#if defined(USE_X11)
+std::string DriverGLX::GetPlatformExtensions() {
+  DCHECK(g_driver_glx.fn.glXQueryExtensionsStringFn);
+  const char* str =
+      g_driver_glx.fn.glXQueryExtensionsStringFn(gfx::GetXDisplay(), 0);
+  return str ? std::string(str) : "";
+}
+#endif
+
+}  // namespace gfx
diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h
index 86f921b..0ddde77 100644
--- a/ui/gl/gl_bindings.h
+++ b/ui/gl/gl_bindings.h
@@ -5,6 +5,8 @@
 #ifndef UI_GL_GL_BINDINGS_H_
 #define UI_GL_GL_BINDINGS_H_
 
+#include <string>
+
 // Includes the platform independent and platform dependent GL headers.
 // Only include this in cc files. It pulls in system headers, including
 // the X11 headers on linux, which define all kinds of macros that are
@@ -345,51 +347,59 @@
 
 struct GL_EXPORT DriverOSMESA {
   void InitializeStaticBindings();
-  void InitializeDynamicBindings(GLContext* context);
   void InitializeDebugBindings();
   void ClearBindings();
 
   ProcsOSMESA fn;
   ProcsOSMESA debug_fn;
   ExtensionsOSMESA ext;
+
+ private:
+  static std::string GetPlatformExtensions();
 };
 
 #if defined(OS_WIN)
 struct GL_EXPORT DriverWGL {
   void InitializeStaticBindings();
-  void InitializeDynamicBindings(GLContext* context);
   void InitializeDebugBindings();
   void ClearBindings();
 
   ProcsWGL fn;
   ProcsWGL debug_fn;
   ExtensionsWGL ext;
+
+ private:
+  static std::string GetPlatformExtensions();
 };
 #endif
 
 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || defined(USE_OZONE)
 struct GL_EXPORT DriverEGL {
   void InitializeStaticBindings();
-  void InitializeDynamicBindings(GLContext* context);
   void InitializeDebugBindings();
   void ClearBindings();
 
   ProcsEGL fn;
   ProcsEGL debug_fn;
   ExtensionsEGL ext;
+
+ private:
+  static std::string GetPlatformExtensions();
 };
 #endif
 
 #if defined(USE_X11)
 struct GL_EXPORT DriverGLX {
   void InitializeStaticBindings();
-  void InitializeDynamicBindings(GLContext* context);
   void InitializeDebugBindings();
   void ClearBindings();
 
   ProcsGLX fn;
   ProcsGLX debug_fn;
   ExtensionsGLX ext;
+
+ private:
+  static std::string GetPlatformExtensions();
 };
 #endif
 
diff --git a/ui/gl/gl_bindings_autogen_egl.cc b/ui/gl/gl_bindings_autogen_egl.cc
index 051e1b3..e0de7f2 100644
--- a/ui/gl/gl_bindings_autogen_egl.cc
+++ b/ui/gl/gl_bindings_autogen_egl.cc
@@ -10,7 +10,7 @@
 
 #include <string>
 
-#include "base/debug/trace_event.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_egl_api_implementation.h"
@@ -30,14 +30,12 @@
       GetGLProcAddress("eglBindTexImage"));
   fn.eglChooseConfigFn = reinterpret_cast<eglChooseConfigProc>(
       GetGLProcAddress("eglChooseConfig"));
-  fn.eglClientWaitSyncKHRFn = reinterpret_cast<eglClientWaitSyncKHRProc>(
-      GetGLProcAddress("eglClientWaitSyncKHR"));
+  fn.eglClientWaitSyncKHRFn = 0;
   fn.eglCopyBuffersFn =
       reinterpret_cast<eglCopyBuffersProc>(GetGLProcAddress("eglCopyBuffers"));
   fn.eglCreateContextFn = reinterpret_cast<eglCreateContextProc>(
       GetGLProcAddress("eglCreateContext"));
-  fn.eglCreateImageKHRFn = reinterpret_cast<eglCreateImageKHRProc>(
-      GetGLProcAddress("eglCreateImageKHR"));
+  fn.eglCreateImageKHRFn = 0;
   fn.eglCreatePbufferFromClientBufferFn =
       reinterpret_cast<eglCreatePbufferFromClientBufferProc>(
           GetGLProcAddress("eglCreatePbufferFromClientBuffer"));
@@ -45,18 +43,15 @@
       GetGLProcAddress("eglCreatePbufferSurface"));
   fn.eglCreatePixmapSurfaceFn = reinterpret_cast<eglCreatePixmapSurfaceProc>(
       GetGLProcAddress("eglCreatePixmapSurface"));
-  fn.eglCreateSyncKHRFn = reinterpret_cast<eglCreateSyncKHRProc>(
-      GetGLProcAddress("eglCreateSyncKHR"));
+  fn.eglCreateSyncKHRFn = 0;
   fn.eglCreateWindowSurfaceFn = reinterpret_cast<eglCreateWindowSurfaceProc>(
       GetGLProcAddress("eglCreateWindowSurface"));
   fn.eglDestroyContextFn = reinterpret_cast<eglDestroyContextProc>(
       GetGLProcAddress("eglDestroyContext"));
-  fn.eglDestroyImageKHRFn = reinterpret_cast<eglDestroyImageKHRProc>(
-      GetGLProcAddress("eglDestroyImageKHR"));
+  fn.eglDestroyImageKHRFn = 0;
   fn.eglDestroySurfaceFn = reinterpret_cast<eglDestroySurfaceProc>(
       GetGLProcAddress("eglDestroySurface"));
-  fn.eglDestroySyncKHRFn = reinterpret_cast<eglDestroySyncKHRProc>(
-      GetGLProcAddress("eglDestroySyncKHR"));
+  fn.eglDestroySyncKHRFn = 0;
   fn.eglGetConfigAttribFn = reinterpret_cast<eglGetConfigAttribProc>(
       GetGLProcAddress("eglGetConfigAttrib"));
   fn.eglGetConfigsFn =
@@ -71,22 +66,16 @@
       reinterpret_cast<eglGetDisplayProc>(GetGLProcAddress("eglGetDisplay"));
   fn.eglGetErrorFn =
       reinterpret_cast<eglGetErrorProc>(GetGLProcAddress("eglGetError"));
-  fn.eglGetPlatformDisplayEXTFn =
-      reinterpret_cast<eglGetPlatformDisplayEXTProc>(
-          GetGLProcAddress("eglGetPlatformDisplayEXT"));
+  fn.eglGetPlatformDisplayEXTFn = 0;
   fn.eglGetProcAddressFn = reinterpret_cast<eglGetProcAddressProc>(
       GetGLProcAddress("eglGetProcAddress"));
-  fn.eglGetSyncAttribKHRFn = reinterpret_cast<eglGetSyncAttribKHRProc>(
-      GetGLProcAddress("eglGetSyncAttribKHR"));
-  fn.eglGetSyncValuesCHROMIUMFn =
-      reinterpret_cast<eglGetSyncValuesCHROMIUMProc>(
-          GetGLProcAddress("eglGetSyncValuesCHROMIUM"));
+  fn.eglGetSyncAttribKHRFn = 0;
+  fn.eglGetSyncValuesCHROMIUMFn = 0;
   fn.eglInitializeFn =
       reinterpret_cast<eglInitializeProc>(GetGLProcAddress("eglInitialize"));
   fn.eglMakeCurrentFn =
       reinterpret_cast<eglMakeCurrentProc>(GetGLProcAddress("eglMakeCurrent"));
-  fn.eglPostSubBufferNVFn = reinterpret_cast<eglPostSubBufferNVProc>(
-      GetGLProcAddress("eglPostSubBufferNV"));
+  fn.eglPostSubBufferNVFn = 0;
   fn.eglQueryAPIFn =
       reinterpret_cast<eglQueryAPIProc>(GetGLProcAddress("eglQueryAPI"));
   fn.eglQueryContextFn = reinterpret_cast<eglQueryContextProc>(
@@ -95,9 +84,7 @@
       reinterpret_cast<eglQueryStringProc>(GetGLProcAddress("eglQueryString"));
   fn.eglQuerySurfaceFn = reinterpret_cast<eglQuerySurfaceProc>(
       GetGLProcAddress("eglQuerySurface"));
-  fn.eglQuerySurfacePointerANGLEFn =
-      reinterpret_cast<eglQuerySurfacePointerANGLEProc>(
-          GetGLProcAddress("eglQuerySurfacePointerANGLE"));
+  fn.eglQuerySurfacePointerANGLEFn = 0;
   fn.eglReleaseTexImageFn = reinterpret_cast<eglReleaseTexImageProc>(
       GetGLProcAddress("eglReleaseTexImage"));
   fn.eglReleaseThreadFn = reinterpret_cast<eglReleaseThreadProc>(
@@ -116,15 +103,9 @@
       reinterpret_cast<eglWaitGLProc>(GetGLProcAddress("eglWaitGL"));
   fn.eglWaitNativeFn =
       reinterpret_cast<eglWaitNativeProc>(GetGLProcAddress("eglWaitNative"));
-  fn.eglWaitSyncKHRFn =
-      reinterpret_cast<eglWaitSyncKHRProc>(GetGLProcAddress("eglWaitSyncKHR"));
-}
-
-void DriverEGL::InitializeDynamicBindings(GLContext* context) {
-  DCHECK(context && context->IsCurrent(NULL));
-  const GLVersionInfo* ver = context->GetVersionInfo();
-  ALLOW_UNUSED_LOCAL(ver);
-  std::string extensions = context->GetExtensions() + " ";
+  fn.eglWaitSyncKHRFn = 0;
+  std::string extensions(GetPlatformExtensions());
+  extensions += " ";
   ALLOW_UNUSED_LOCAL(extensions);
 
   ext.b_EGL_ANGLE_d3d_share_handle_client_buffer =
@@ -143,13 +124,97 @@
       extensions.find("EGL_KHR_fence_sync ") != std::string::npos;
   ext.b_EGL_KHR_gl_texture_2D_image =
       extensions.find("EGL_KHR_gl_texture_2D_image ") != std::string::npos;
+  ext.b_EGL_KHR_image = extensions.find("EGL_KHR_image ") != std::string::npos;
   ext.b_EGL_KHR_image_base =
       extensions.find("EGL_KHR_image_base ") != std::string::npos;
+  ext.b_EGL_KHR_reusable_sync =
+      extensions.find("EGL_KHR_reusable_sync ") != std::string::npos;
   ext.b_EGL_KHR_wait_sync =
       extensions.find("EGL_KHR_wait_sync ") != std::string::npos;
   ext.b_EGL_NV_post_sub_buffer =
       extensions.find("EGL_NV_post_sub_buffer ") != std::string::npos;
 
+  debug_fn.eglClientWaitSyncKHRFn = 0;
+  if (ext.b_EGL_KHR_fence_sync || ext.b_EGL_KHR_reusable_sync) {
+    fn.eglClientWaitSyncKHRFn = reinterpret_cast<eglClientWaitSyncKHRProc>(
+        GetGLProcAddress("eglClientWaitSyncKHR"));
+    DCHECK(fn.eglClientWaitSyncKHRFn);
+  }
+
+  debug_fn.eglCreateImageKHRFn = 0;
+  if (ext.b_EGL_KHR_image || ext.b_EGL_KHR_image_base ||
+      ext.b_EGL_KHR_gl_texture_2D_image) {
+    fn.eglCreateImageKHRFn = reinterpret_cast<eglCreateImageKHRProc>(
+        GetGLProcAddress("eglCreateImageKHR"));
+    DCHECK(fn.eglCreateImageKHRFn);
+  }
+
+  debug_fn.eglCreateSyncKHRFn = 0;
+  if (ext.b_EGL_KHR_fence_sync || ext.b_EGL_KHR_reusable_sync) {
+    fn.eglCreateSyncKHRFn = reinterpret_cast<eglCreateSyncKHRProc>(
+        GetGLProcAddress("eglCreateSyncKHR"));
+    DCHECK(fn.eglCreateSyncKHRFn);
+  }
+
+  debug_fn.eglDestroyImageKHRFn = 0;
+  if (ext.b_EGL_KHR_image || ext.b_EGL_KHR_image_base) {
+    fn.eglDestroyImageKHRFn = reinterpret_cast<eglDestroyImageKHRProc>(
+        GetGLProcAddress("eglDestroyImageKHR"));
+    DCHECK(fn.eglDestroyImageKHRFn);
+  }
+
+  debug_fn.eglDestroySyncKHRFn = 0;
+  if (ext.b_EGL_KHR_fence_sync || ext.b_EGL_KHR_reusable_sync) {
+    fn.eglDestroySyncKHRFn = reinterpret_cast<eglDestroySyncKHRProc>(
+        GetGLProcAddress("eglDestroySyncKHR"));
+    DCHECK(fn.eglDestroySyncKHRFn);
+  }
+
+  debug_fn.eglGetPlatformDisplayEXTFn = 0;
+  if (ext.b_EGL_ANGLE_platform_angle) {
+    fn.eglGetPlatformDisplayEXTFn =
+        reinterpret_cast<eglGetPlatformDisplayEXTProc>(
+            GetGLProcAddress("eglGetPlatformDisplayEXT"));
+    DCHECK(fn.eglGetPlatformDisplayEXTFn);
+  }
+
+  debug_fn.eglGetSyncAttribKHRFn = 0;
+  if (ext.b_EGL_KHR_fence_sync || ext.b_EGL_KHR_reusable_sync) {
+    fn.eglGetSyncAttribKHRFn = reinterpret_cast<eglGetSyncAttribKHRProc>(
+        GetGLProcAddress("eglGetSyncAttribKHR"));
+    DCHECK(fn.eglGetSyncAttribKHRFn);
+  }
+
+  debug_fn.eglGetSyncValuesCHROMIUMFn = 0;
+  if (ext.b_EGL_CHROMIUM_sync_control) {
+    fn.eglGetSyncValuesCHROMIUMFn =
+        reinterpret_cast<eglGetSyncValuesCHROMIUMProc>(
+            GetGLProcAddress("eglGetSyncValuesCHROMIUM"));
+    DCHECK(fn.eglGetSyncValuesCHROMIUMFn);
+  }
+
+  debug_fn.eglPostSubBufferNVFn = 0;
+  if (ext.b_EGL_NV_post_sub_buffer) {
+    fn.eglPostSubBufferNVFn = reinterpret_cast<eglPostSubBufferNVProc>(
+        GetGLProcAddress("eglPostSubBufferNV"));
+    DCHECK(fn.eglPostSubBufferNVFn);
+  }
+
+  debug_fn.eglQuerySurfacePointerANGLEFn = 0;
+  if (ext.b_EGL_ANGLE_query_surface_pointer) {
+    fn.eglQuerySurfacePointerANGLEFn =
+        reinterpret_cast<eglQuerySurfacePointerANGLEProc>(
+            GetGLProcAddress("eglQuerySurfacePointerANGLE"));
+    DCHECK(fn.eglQuerySurfacePointerANGLEFn);
+  }
+
+  debug_fn.eglWaitSyncKHRFn = 0;
+  if (ext.b_EGL_KHR_fence_sync || ext.b_EGL_KHR_wait_sync) {
+    fn.eglWaitSyncKHRFn = reinterpret_cast<eglWaitSyncKHRProc>(
+        GetGLProcAddress("eglWaitSyncKHR"));
+    DCHECK(fn.eglWaitSyncKHRFn);
+  }
+
   if (g_debugBindingsInitialized)
     InitializeDebugBindings();
 }
diff --git a/ui/gl/gl_bindings_autogen_egl.h b/ui/gl/gl_bindings_autogen_egl.h
index a49935e..f184b6a 100644
--- a/ui/gl/gl_bindings_autogen_egl.h
+++ b/ui/gl/gl_bindings_autogen_egl.h
@@ -163,7 +163,9 @@
   bool b_EGL_CHROMIUM_sync_control;
   bool b_EGL_KHR_fence_sync;
   bool b_EGL_KHR_gl_texture_2D_image;
+  bool b_EGL_KHR_image;
   bool b_EGL_KHR_image_base;
+  bool b_EGL_KHR_reusable_sync;
   bool b_EGL_KHR_wait_sync;
   bool b_EGL_NV_post_sub_buffer;
 };
diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc
index 435758d..642190c 100644
--- a/ui/gl/gl_bindings_autogen_gl.cc
+++ b/ui/gl/gl_bindings_autogen_gl.cc
@@ -10,7 +10,7 @@
 
 #include <string>
 
-#include "base/debug/trace_event.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_enums.h"
@@ -23,258 +23,30 @@
 static bool g_debugBindingsInitialized;
 DriverGL g_driver_gl;
 
-void glBeginQueryARBNotBound(GLenum target, GLuint id) {
-  NOTREACHED();
-}
-void glBindFramebufferEXTNotBound(GLenum target, GLuint framebuffer) {
-  NOTREACHED();
-}
-void glBindRenderbufferEXTNotBound(GLenum target, GLuint renderbuffer) {
-  NOTREACHED();
-}
-void glBindVertexArrayOESNotBound(GLuint array) {
-  NOTREACHED();
-}
-void glBlendBarrierKHRNotBound(void) {
-  NOTREACHED();
-}
-void glBlitFramebufferANGLENotBound(GLint srcX0,
-                                    GLint srcY0,
-                                    GLint srcX1,
-                                    GLint srcY1,
-                                    GLint dstX0,
-                                    GLint dstY0,
-                                    GLint dstX1,
-                                    GLint dstY1,
-                                    GLbitfield mask,
-                                    GLenum filter) {
-  NOTREACHED();
-}
-void glBlitFramebufferEXTNotBound(GLint srcX0,
-                                  GLint srcY0,
-                                  GLint srcX1,
-                                  GLint srcY1,
-                                  GLint dstX0,
-                                  GLint dstY0,
-                                  GLint dstX1,
-                                  GLint dstY1,
-                                  GLbitfield mask,
-                                  GLenum filter) {
-  NOTREACHED();
-}
-GLenum glCheckFramebufferStatusEXTNotBound(GLenum target) {
-  NOTREACHED();
-  return 0;
-}
-void glDeleteBuffersARBNotBound(GLsizei n, const GLuint* buffers) {
-  NOTREACHED();
-}
-void glDeleteFramebuffersEXTNotBound(GLsizei n, const GLuint* framebuffers) {
-  NOTREACHED();
-}
-void glDeleteQueriesARBNotBound(GLsizei n, const GLuint* ids) {
-  NOTREACHED();
-}
-void glDeleteRenderbuffersEXTNotBound(GLsizei n, const GLuint* renderbuffers) {
-  NOTREACHED();
-}
-void glDeleteVertexArraysOESNotBound(GLsizei n, const GLuint* arrays) {
-  NOTREACHED();
-}
-void glDrawArraysInstancedANGLENotBound(GLenum mode,
-                                        GLint first,
-                                        GLsizei count,
-                                        GLsizei primcount) {
-  NOTREACHED();
-}
-void glDrawBuffersARBNotBound(GLsizei n, const GLenum* bufs) {
-  NOTREACHED();
-}
-void glDrawElementsInstancedANGLENotBound(GLenum mode,
-                                          GLsizei count,
-                                          GLenum type,
-                                          const void* indices,
-                                          GLsizei primcount) {
-  NOTREACHED();
-}
-void glEndQueryARBNotBound(GLenum target) {
-  NOTREACHED();
-}
-void glFramebufferRenderbufferEXTNotBound(GLenum target,
-                                          GLenum attachment,
-                                          GLenum renderbuffertarget,
-                                          GLuint renderbuffer) {
-  NOTREACHED();
-}
-void glFramebufferTexture2DEXTNotBound(GLenum target,
-                                       GLenum attachment,
-                                       GLenum textarget,
-                                       GLuint texture,
-                                       GLint level) {
-  NOTREACHED();
-}
-void glGenBuffersARBNotBound(GLsizei n, GLuint* buffers) {
-  NOTREACHED();
-}
-void glGenerateMipmapEXTNotBound(GLenum target) {
-  NOTREACHED();
-}
-void glGenFramebuffersEXTNotBound(GLsizei n, GLuint* framebuffers) {
-  NOTREACHED();
-}
-void glGenQueriesARBNotBound(GLsizei n, GLuint* ids) {
-  NOTREACHED();
-}
-void glGenRenderbuffersEXTNotBound(GLsizei n, GLuint* renderbuffers) {
-  NOTREACHED();
-}
-void glGenVertexArraysOESNotBound(GLsizei n, GLuint* arrays) {
-  NOTREACHED();
-}
-void glGetFramebufferAttachmentParameterivEXTNotBound(GLenum target,
-                                                      GLenum attachment,
-                                                      GLenum pname,
-                                                      GLint* params) {
-  NOTREACHED();
-}
-GLenum glGetGraphicsResetStatusARBNotBound(void) {
-  NOTREACHED();
-  return 0;
-}
-void glGetProgramBinaryNotBound(GLuint program,
-                                GLsizei bufSize,
-                                GLsizei* length,
-                                GLenum* binaryFormat,
-                                GLvoid* binary) {
-  NOTREACHED();
-}
-void glGetQueryivARBNotBound(GLenum target, GLenum pname, GLint* params) {
-  NOTREACHED();
-}
-void glGetQueryObjectivARBNotBound(GLuint id, GLenum pname, GLint* params) {
-  NOTREACHED();
-}
-void glGetQueryObjectui64vNotBound(GLuint id, GLenum pname, GLuint64* params) {
-  NOTREACHED();
-}
-void glGetQueryObjectuivARBNotBound(GLuint id, GLenum pname, GLuint* params) {
-  NOTREACHED();
-}
-void glGetRenderbufferParameterivEXTNotBound(GLenum target,
-                                             GLenum pname,
-                                             GLint* params) {
-  NOTREACHED();
-}
-GLboolean glIsFramebufferEXTNotBound(GLuint framebuffer) {
-  NOTREACHED();
-  return 0;
-}
-GLboolean glIsQueryARBNotBound(GLuint query) {
-  NOTREACHED();
-  return 0;
-}
-GLboolean glIsRenderbufferEXTNotBound(GLuint renderbuffer) {
-  NOTREACHED();
-  return 0;
-}
-GLboolean glIsVertexArrayOESNotBound(GLuint array) {
-  NOTREACHED();
-  return 0;
-}
-void* glMapBufferNotBound(GLenum target, GLenum access) {
-  NOTREACHED();
-  return 0;
-}
-void* glMapBufferRangeNotBound(GLenum target,
-                               GLintptr offset,
-                               GLsizeiptr length,
-                               GLbitfield access) {
-  NOTREACHED();
-  return 0;
-}
-void glProgramBinaryNotBound(GLuint program,
-                             GLenum binaryFormat,
-                             const GLvoid* binary,
-                             GLsizei length) {
-  NOTREACHED();
-}
-void glQueryCounterNotBound(GLuint id, GLenum target) {
-  NOTREACHED();
-}
-void glRenderbufferStorageEXTNotBound(GLenum target,
-                                      GLenum internalformat,
-                                      GLsizei width,
-                                      GLsizei height) {
-  NOTREACHED();
-}
-void glRenderbufferStorageMultisampleANGLENotBound(GLenum target,
-                                                   GLsizei samples,
-                                                   GLenum internalformat,
-                                                   GLsizei width,
-                                                   GLsizei height) {
-  NOTREACHED();
-}
-void glRenderbufferStorageMultisampleEXTNotBound(GLenum target,
-                                                 GLsizei samples,
-                                                 GLenum internalformat,
-                                                 GLsizei width,
-                                                 GLsizei height) {
-  NOTREACHED();
-}
-void glTexStorage2DEXTNotBound(GLenum target,
-                               GLsizei levels,
-                               GLenum internalformat,
-                               GLsizei width,
-                               GLsizei height) {
-  NOTREACHED();
-}
-GLboolean glUnmapBufferNotBound(GLenum target) {
-  NOTREACHED();
-  return 0;
-}
-void glVertexAttribDivisorANGLENotBound(GLuint index, GLuint divisor) {
-  NOTREACHED();
-}
-
 void DriverGL::InitializeStaticBindings() {
   fn.glActiveTextureFn = reinterpret_cast<glActiveTextureProc>(
       GetGLProcAddress("glActiveTexture"));
   fn.glAttachShaderFn =
       reinterpret_cast<glAttachShaderProc>(GetGLProcAddress("glAttachShader"));
-  fn.glBeginQueryFn =
-      reinterpret_cast<glBeginQueryProc>(GetGLProcAddress("glBeginQuery"));
-  fn.glBeginQueryARBFn =
-      reinterpret_cast<glBeginQueryARBProc>(glBeginQueryARBNotBound);
-  fn.glBeginTransformFeedbackFn =
-      reinterpret_cast<glBeginTransformFeedbackProc>(
-          GetGLProcAddress("glBeginTransformFeedback"));
+  fn.glBeginQueryFn = 0;
+  fn.glBeginQueryARBFn = 0;
+  fn.glBeginTransformFeedbackFn = 0;
   fn.glBindAttribLocationFn = reinterpret_cast<glBindAttribLocationProc>(
       GetGLProcAddress("glBindAttribLocation"));
   fn.glBindBufferFn =
       reinterpret_cast<glBindBufferProc>(GetGLProcAddress("glBindBuffer"));
-  fn.glBindBufferBaseFn = reinterpret_cast<glBindBufferBaseProc>(
-      GetGLProcAddress("glBindBufferBase"));
-  fn.glBindBufferRangeFn = reinterpret_cast<glBindBufferRangeProc>(
-      GetGLProcAddress("glBindBufferRange"));
-  fn.glBindFragDataLocationFn = reinterpret_cast<glBindFragDataLocationProc>(
-      GetGLProcAddress("glBindFragDataLocation"));
-  fn.glBindFragDataLocationIndexedFn =
-      reinterpret_cast<glBindFragDataLocationIndexedProc>(
-          GetGLProcAddress("glBindFragDataLocationIndexed"));
-  fn.glBindFramebufferEXTFn =
-      reinterpret_cast<glBindFramebufferEXTProc>(glBindFramebufferEXTNotBound);
-  fn.glBindRenderbufferEXTFn = reinterpret_cast<glBindRenderbufferEXTProc>(
-      glBindRenderbufferEXTNotBound);
-  fn.glBindSamplerFn =
-      reinterpret_cast<glBindSamplerProc>(GetGLProcAddress("glBindSampler"));
+  fn.glBindBufferBaseFn = 0;
+  fn.glBindBufferRangeFn = 0;
+  fn.glBindFragDataLocationFn = 0;
+  fn.glBindFragDataLocationIndexedFn = 0;
+  fn.glBindFramebufferEXTFn = 0;
+  fn.glBindRenderbufferEXTFn = 0;
+  fn.glBindSamplerFn = 0;
   fn.glBindTextureFn =
       reinterpret_cast<glBindTextureProc>(GetGLProcAddress("glBindTexture"));
-  fn.glBindTransformFeedbackFn = reinterpret_cast<glBindTransformFeedbackProc>(
-      GetGLProcAddress("glBindTransformFeedback"));
-  fn.glBindVertexArrayOESFn =
-      reinterpret_cast<glBindVertexArrayOESProc>(glBindVertexArrayOESNotBound);
-  fn.glBlendBarrierKHRFn =
-      reinterpret_cast<glBlendBarrierKHRProc>(glBlendBarrierKHRNotBound);
+  fn.glBindTransformFeedbackFn = 0;
+  fn.glBindVertexArrayOESFn = 0;
+  fn.glBlendBarrierKHRFn = 0;
   fn.glBlendColorFn =
       reinterpret_cast<glBlendColorProc>(GetGLProcAddress("glBlendColor"));
   fn.glBlendEquationFn = reinterpret_cast<glBlendEquationProc>(
@@ -285,101 +57,74 @@
       reinterpret_cast<glBlendFuncProc>(GetGLProcAddress("glBlendFunc"));
   fn.glBlendFuncSeparateFn = reinterpret_cast<glBlendFuncSeparateProc>(
       GetGLProcAddress("glBlendFuncSeparate"));
-  fn.glBlitFramebufferFn = reinterpret_cast<glBlitFramebufferProc>(
-      GetGLProcAddress("glBlitFramebuffer"));
-  fn.glBlitFramebufferANGLEFn = reinterpret_cast<glBlitFramebufferANGLEProc>(
-      glBlitFramebufferANGLENotBound);
-  fn.glBlitFramebufferEXTFn =
-      reinterpret_cast<glBlitFramebufferEXTProc>(glBlitFramebufferEXTNotBound);
+  fn.glBlitFramebufferFn = 0;
+  fn.glBlitFramebufferANGLEFn = 0;
+  fn.glBlitFramebufferEXTFn = 0;
   fn.glBufferDataFn =
       reinterpret_cast<glBufferDataProc>(GetGLProcAddress("glBufferData"));
   fn.glBufferSubDataFn = reinterpret_cast<glBufferSubDataProc>(
       GetGLProcAddress("glBufferSubData"));
-  fn.glCheckFramebufferStatusEXTFn =
-      reinterpret_cast<glCheckFramebufferStatusEXTProc>(
-          glCheckFramebufferStatusEXTNotBound);
+  fn.glCheckFramebufferStatusEXTFn = 0;
   fn.glClearFn = reinterpret_cast<glClearProc>(GetGLProcAddress("glClear"));
-  fn.glClearBufferfiFn = reinterpret_cast<glClearBufferfiProc>(
-      GetGLProcAddress("glClearBufferfi"));
-  fn.glClearBufferfvFn = reinterpret_cast<glClearBufferfvProc>(
-      GetGLProcAddress("glClearBufferfv"));
-  fn.glClearBufferivFn = reinterpret_cast<glClearBufferivProc>(
-      GetGLProcAddress("glClearBufferiv"));
-  fn.glClearBufferuivFn = reinterpret_cast<glClearBufferuivProc>(
-      GetGLProcAddress("glClearBufferuiv"));
+  fn.glClearBufferfiFn = 0;
+  fn.glClearBufferfvFn = 0;
+  fn.glClearBufferivFn = 0;
+  fn.glClearBufferuivFn = 0;
   fn.glClearColorFn =
       reinterpret_cast<glClearColorProc>(GetGLProcAddress("glClearColor"));
   fn.glClearDepthFn =
       reinterpret_cast<glClearDepthProc>(GetGLProcAddress("glClearDepth"));
-  fn.glClearDepthfFn =
-      reinterpret_cast<glClearDepthfProc>(GetGLProcAddress("glClearDepthf"));
+  fn.glClearDepthfFn = 0;
   fn.glClearStencilFn =
       reinterpret_cast<glClearStencilProc>(GetGLProcAddress("glClearStencil"));
-  fn.glClientWaitSyncFn = reinterpret_cast<glClientWaitSyncProc>(
-      GetGLProcAddress("glClientWaitSync"));
+  fn.glClientWaitSyncFn = 0;
   fn.glColorMaskFn =
       reinterpret_cast<glColorMaskProc>(GetGLProcAddress("glColorMask"));
   fn.glCompileShaderFn = reinterpret_cast<glCompileShaderProc>(
       GetGLProcAddress("glCompileShader"));
   fn.glCompressedTexImage2DFn = reinterpret_cast<glCompressedTexImage2DProc>(
       GetGLProcAddress("glCompressedTexImage2D"));
-  fn.glCompressedTexImage3DFn = reinterpret_cast<glCompressedTexImage3DProc>(
-      GetGLProcAddress("glCompressedTexImage3D"));
+  fn.glCompressedTexImage3DFn = 0;
   fn.glCompressedTexSubImage2DFn =
       reinterpret_cast<glCompressedTexSubImage2DProc>(
           GetGLProcAddress("glCompressedTexSubImage2D"));
-  fn.glCopyBufferSubDataFn = reinterpret_cast<glCopyBufferSubDataProc>(
-      GetGLProcAddress("glCopyBufferSubData"));
+  fn.glCopyBufferSubDataFn = 0;
   fn.glCopyTexImage2DFn = reinterpret_cast<glCopyTexImage2DProc>(
       GetGLProcAddress("glCopyTexImage2D"));
   fn.glCopyTexSubImage2DFn = reinterpret_cast<glCopyTexSubImage2DProc>(
       GetGLProcAddress("glCopyTexSubImage2D"));
-  fn.glCopyTexSubImage3DFn = reinterpret_cast<glCopyTexSubImage3DProc>(
-      GetGLProcAddress("glCopyTexSubImage3D"));
+  fn.glCopyTexSubImage3DFn = 0;
   fn.glCreateProgramFn = reinterpret_cast<glCreateProgramProc>(
       GetGLProcAddress("glCreateProgram"));
   fn.glCreateShaderFn =
       reinterpret_cast<glCreateShaderProc>(GetGLProcAddress("glCreateShader"));
   fn.glCullFaceFn =
       reinterpret_cast<glCullFaceProc>(GetGLProcAddress("glCullFace"));
-  fn.glDeleteBuffersARBFn =
-      reinterpret_cast<glDeleteBuffersARBProc>(glDeleteBuffersARBNotBound);
-  fn.glDeleteFencesAPPLEFn = reinterpret_cast<glDeleteFencesAPPLEProc>(
-      GetGLProcAddress("glDeleteFencesAPPLE"));
-  fn.glDeleteFencesNVFn = reinterpret_cast<glDeleteFencesNVProc>(
-      GetGLProcAddress("glDeleteFencesNV"));
-  fn.glDeleteFramebuffersEXTFn = reinterpret_cast<glDeleteFramebuffersEXTProc>(
-      glDeleteFramebuffersEXTNotBound);
+  fn.glDeleteBuffersARBFn = reinterpret_cast<glDeleteBuffersARBProc>(
+      GetGLProcAddress("glDeleteBuffers"));
+  fn.glDeleteFencesAPPLEFn = 0;
+  fn.glDeleteFencesNVFn = 0;
+  fn.glDeleteFramebuffersEXTFn = 0;
   fn.glDeleteProgramFn = reinterpret_cast<glDeleteProgramProc>(
       GetGLProcAddress("glDeleteProgram"));
-  fn.glDeleteQueriesFn = reinterpret_cast<glDeleteQueriesProc>(
-      GetGLProcAddress("glDeleteQueries"));
-  fn.glDeleteQueriesARBFn =
-      reinterpret_cast<glDeleteQueriesARBProc>(glDeleteQueriesARBNotBound);
-  fn.glDeleteRenderbuffersEXTFn =
-      reinterpret_cast<glDeleteRenderbuffersEXTProc>(
-          glDeleteRenderbuffersEXTNotBound);
-  fn.glDeleteSamplersFn = reinterpret_cast<glDeleteSamplersProc>(
-      GetGLProcAddress("glDeleteSamplers"));
+  fn.glDeleteQueriesFn = 0;
+  fn.glDeleteQueriesARBFn = 0;
+  fn.glDeleteRenderbuffersEXTFn = 0;
+  fn.glDeleteSamplersFn = 0;
   fn.glDeleteShaderFn =
       reinterpret_cast<glDeleteShaderProc>(GetGLProcAddress("glDeleteShader"));
-  fn.glDeleteSyncFn =
-      reinterpret_cast<glDeleteSyncProc>(GetGLProcAddress("glDeleteSync"));
+  fn.glDeleteSyncFn = 0;
   fn.glDeleteTexturesFn = reinterpret_cast<glDeleteTexturesProc>(
       GetGLProcAddress("glDeleteTextures"));
-  fn.glDeleteTransformFeedbacksFn =
-      reinterpret_cast<glDeleteTransformFeedbacksProc>(
-          GetGLProcAddress("glDeleteTransformFeedbacks"));
-  fn.glDeleteVertexArraysOESFn = reinterpret_cast<glDeleteVertexArraysOESProc>(
-      glDeleteVertexArraysOESNotBound);
+  fn.glDeleteTransformFeedbacksFn = 0;
+  fn.glDeleteVertexArraysOESFn = 0;
   fn.glDepthFuncFn =
       reinterpret_cast<glDepthFuncProc>(GetGLProcAddress("glDepthFunc"));
   fn.glDepthMaskFn =
       reinterpret_cast<glDepthMaskProc>(GetGLProcAddress("glDepthMask"));
   fn.glDepthRangeFn =
       reinterpret_cast<glDepthRangeProc>(GetGLProcAddress("glDepthRange"));
-  fn.glDepthRangefFn =
-      reinterpret_cast<glDepthRangefProc>(GetGLProcAddress("glDepthRangef"));
+  fn.glDepthRangefFn = 0;
   fn.glDetachShaderFn =
       reinterpret_cast<glDetachShaderProc>(GetGLProcAddress("glDetachShader"));
   fn.glDisableFn =
@@ -387,104 +132,59 @@
   fn.glDisableVertexAttribArrayFn =
       reinterpret_cast<glDisableVertexAttribArrayProc>(
           GetGLProcAddress("glDisableVertexAttribArray"));
-  fn.glDiscardFramebufferEXTFn = reinterpret_cast<glDiscardFramebufferEXTProc>(
-      GetGLProcAddress("glDiscardFramebufferEXT"));
+  fn.glDiscardFramebufferEXTFn = 0;
   fn.glDrawArraysFn =
       reinterpret_cast<glDrawArraysProc>(GetGLProcAddress("glDrawArrays"));
-  fn.glDrawArraysInstancedANGLEFn =
-      reinterpret_cast<glDrawArraysInstancedANGLEProc>(
-          glDrawArraysInstancedANGLENotBound);
-  fn.glDrawBufferFn =
-      reinterpret_cast<glDrawBufferProc>(GetGLProcAddress("glDrawBuffer"));
-  fn.glDrawBuffersARBFn =
-      reinterpret_cast<glDrawBuffersARBProc>(glDrawBuffersARBNotBound);
+  fn.glDrawArraysInstancedANGLEFn = 0;
+  fn.glDrawBufferFn = 0;
+  fn.glDrawBuffersARBFn = 0;
   fn.glDrawElementsFn =
       reinterpret_cast<glDrawElementsProc>(GetGLProcAddress("glDrawElements"));
-  fn.glDrawElementsInstancedANGLEFn =
-      reinterpret_cast<glDrawElementsInstancedANGLEProc>(
-          glDrawElementsInstancedANGLENotBound);
-  fn.glDrawRangeElementsFn = reinterpret_cast<glDrawRangeElementsProc>(
-      GetGLProcAddress("glDrawRangeElements"));
-  fn.glEGLImageTargetRenderbufferStorageOESFn =
-      reinterpret_cast<glEGLImageTargetRenderbufferStorageOESProc>(
-          GetGLProcAddress("glEGLImageTargetRenderbufferStorageOES"));
-  fn.glEGLImageTargetTexture2DOESFn =
-      reinterpret_cast<glEGLImageTargetTexture2DOESProc>(
-          GetGLProcAddress("glEGLImageTargetTexture2DOES"));
+  fn.glDrawElementsInstancedANGLEFn = 0;
+  fn.glDrawRangeElementsFn = 0;
+  fn.glEGLImageTargetRenderbufferStorageOESFn = 0;
+  fn.glEGLImageTargetTexture2DOESFn = 0;
   fn.glEnableFn = reinterpret_cast<glEnableProc>(GetGLProcAddress("glEnable"));
   fn.glEnableVertexAttribArrayFn =
       reinterpret_cast<glEnableVertexAttribArrayProc>(
           GetGLProcAddress("glEnableVertexAttribArray"));
-  fn.glEndQueryFn =
-      reinterpret_cast<glEndQueryProc>(GetGLProcAddress("glEndQuery"));
-  fn.glEndQueryARBFn =
-      reinterpret_cast<glEndQueryARBProc>(glEndQueryARBNotBound);
-  fn.glEndTransformFeedbackFn = reinterpret_cast<glEndTransformFeedbackProc>(
-      GetGLProcAddress("glEndTransformFeedback"));
-  fn.glFenceSyncFn =
-      reinterpret_cast<glFenceSyncProc>(GetGLProcAddress("glFenceSync"));
+  fn.glEndQueryFn = 0;
+  fn.glEndQueryARBFn = 0;
+  fn.glEndTransformFeedbackFn = 0;
+  fn.glFenceSyncFn = 0;
   fn.glFinishFn = reinterpret_cast<glFinishProc>(GetGLProcAddress("glFinish"));
-  fn.glFinishFenceAPPLEFn = reinterpret_cast<glFinishFenceAPPLEProc>(
-      GetGLProcAddress("glFinishFenceAPPLE"));
-  fn.glFinishFenceNVFn = reinterpret_cast<glFinishFenceNVProc>(
-      GetGLProcAddress("glFinishFenceNV"));
+  fn.glFinishFenceAPPLEFn = 0;
+  fn.glFinishFenceNVFn = 0;
   fn.glFlushFn = reinterpret_cast<glFlushProc>(GetGLProcAddress("glFlush"));
-  fn.glFlushMappedBufferRangeFn =
-      reinterpret_cast<glFlushMappedBufferRangeProc>(
-          GetGLProcAddress("glFlushMappedBufferRange"));
-  fn.glFramebufferRenderbufferEXTFn =
-      reinterpret_cast<glFramebufferRenderbufferEXTProc>(
-          glFramebufferRenderbufferEXTNotBound);
-  fn.glFramebufferTexture2DEXTFn =
-      reinterpret_cast<glFramebufferTexture2DEXTProc>(
-          glFramebufferTexture2DEXTNotBound);
-  fn.glFramebufferTexture2DMultisampleEXTFn =
-      reinterpret_cast<glFramebufferTexture2DMultisampleEXTProc>(
-          GetGLProcAddress("glFramebufferTexture2DMultisampleEXT"));
-  fn.glFramebufferTexture2DMultisampleIMGFn =
-      reinterpret_cast<glFramebufferTexture2DMultisampleIMGProc>(
-          GetGLProcAddress("glFramebufferTexture2DMultisampleIMG"));
-  fn.glFramebufferTextureLayerFn =
-      reinterpret_cast<glFramebufferTextureLayerProc>(
-          GetGLProcAddress("glFramebufferTextureLayer"));
+  fn.glFlushMappedBufferRangeFn = 0;
+  fn.glFramebufferRenderbufferEXTFn = 0;
+  fn.glFramebufferTexture2DEXTFn = 0;
+  fn.glFramebufferTexture2DMultisampleEXTFn = 0;
+  fn.glFramebufferTexture2DMultisampleIMGFn = 0;
+  fn.glFramebufferTextureLayerFn = 0;
   fn.glFrontFaceFn =
       reinterpret_cast<glFrontFaceProc>(GetGLProcAddress("glFrontFace"));
   fn.glGenBuffersARBFn =
-      reinterpret_cast<glGenBuffersARBProc>(glGenBuffersARBNotBound);
-  fn.glGenerateMipmapEXTFn =
-      reinterpret_cast<glGenerateMipmapEXTProc>(glGenerateMipmapEXTNotBound);
-  fn.glGenFencesAPPLEFn = reinterpret_cast<glGenFencesAPPLEProc>(
-      GetGLProcAddress("glGenFencesAPPLE"));
-  fn.glGenFencesNVFn =
-      reinterpret_cast<glGenFencesNVProc>(GetGLProcAddress("glGenFencesNV"));
-  fn.glGenFramebuffersEXTFn =
-      reinterpret_cast<glGenFramebuffersEXTProc>(glGenFramebuffersEXTNotBound);
-  fn.glGenQueriesFn =
-      reinterpret_cast<glGenQueriesProc>(GetGLProcAddress("glGenQueries"));
-  fn.glGenQueriesARBFn =
-      reinterpret_cast<glGenQueriesARBProc>(glGenQueriesARBNotBound);
-  fn.glGenRenderbuffersEXTFn = reinterpret_cast<glGenRenderbuffersEXTProc>(
-      glGenRenderbuffersEXTNotBound);
-  fn.glGenSamplersFn =
-      reinterpret_cast<glGenSamplersProc>(GetGLProcAddress("glGenSamplers"));
+      reinterpret_cast<glGenBuffersARBProc>(GetGLProcAddress("glGenBuffers"));
+  fn.glGenerateMipmapEXTFn = 0;
+  fn.glGenFencesAPPLEFn = 0;
+  fn.glGenFencesNVFn = 0;
+  fn.glGenFramebuffersEXTFn = 0;
+  fn.glGenQueriesFn = 0;
+  fn.glGenQueriesARBFn = 0;
+  fn.glGenRenderbuffersEXTFn = 0;
+  fn.glGenSamplersFn = 0;
   fn.glGenTexturesFn =
       reinterpret_cast<glGenTexturesProc>(GetGLProcAddress("glGenTextures"));
-  fn.glGenTransformFeedbacksFn = reinterpret_cast<glGenTransformFeedbacksProc>(
-      GetGLProcAddress("glGenTransformFeedbacks"));
-  fn.glGenVertexArraysOESFn =
-      reinterpret_cast<glGenVertexArraysOESProc>(glGenVertexArraysOESNotBound);
+  fn.glGenTransformFeedbacksFn = 0;
+  fn.glGenVertexArraysOESFn = 0;
   fn.glGetActiveAttribFn = reinterpret_cast<glGetActiveAttribProc>(
       GetGLProcAddress("glGetActiveAttrib"));
   fn.glGetActiveUniformFn = reinterpret_cast<glGetActiveUniformProc>(
       GetGLProcAddress("glGetActiveUniform"));
-  fn.glGetActiveUniformBlockivFn =
-      reinterpret_cast<glGetActiveUniformBlockivProc>(
-          GetGLProcAddress("glGetActiveUniformBlockiv"));
-  fn.glGetActiveUniformBlockNameFn =
-      reinterpret_cast<glGetActiveUniformBlockNameProc>(
-          GetGLProcAddress("glGetActiveUniformBlockName"));
-  fn.glGetActiveUniformsivFn = reinterpret_cast<glGetActiveUniformsivProc>(
-      GetGLProcAddress("glGetActiveUniformsiv"));
+  fn.glGetActiveUniformBlockivFn = 0;
+  fn.glGetActiveUniformBlockNameFn = 0;
+  fn.glGetActiveUniformsivFn = 0;
   fn.glGetAttachedShadersFn = reinterpret_cast<glGetAttachedShadersProc>(
       GetGLProcAddress("glGetAttachedShaders"));
   fn.glGetAttribLocationFn = reinterpret_cast<glGetAttribLocationProc>(
@@ -495,92 +195,56 @@
       GetGLProcAddress("glGetBufferParameteriv"));
   fn.glGetErrorFn =
       reinterpret_cast<glGetErrorProc>(GetGLProcAddress("glGetError"));
-  fn.glGetFenceivNVFn =
-      reinterpret_cast<glGetFenceivNVProc>(GetGLProcAddress("glGetFenceivNV"));
+  fn.glGetFenceivNVFn = 0;
   fn.glGetFloatvFn =
       reinterpret_cast<glGetFloatvProc>(GetGLProcAddress("glGetFloatv"));
-  fn.glGetFragDataLocationFn = reinterpret_cast<glGetFragDataLocationProc>(
-      GetGLProcAddress("glGetFragDataLocation"));
-  fn.glGetFramebufferAttachmentParameterivEXTFn =
-      reinterpret_cast<glGetFramebufferAttachmentParameterivEXTProc>(
-          glGetFramebufferAttachmentParameterivEXTNotBound);
-  fn.glGetGraphicsResetStatusARBFn =
-      reinterpret_cast<glGetGraphicsResetStatusARBProc>(
-          glGetGraphicsResetStatusARBNotBound);
-  fn.glGetInteger64i_vFn = reinterpret_cast<glGetInteger64i_vProc>(
-      GetGLProcAddress("glGetInteger64i_v"));
-  fn.glGetInteger64vFn = reinterpret_cast<glGetInteger64vProc>(
-      GetGLProcAddress("glGetInteger64v"));
-  fn.glGetIntegeri_vFn = reinterpret_cast<glGetIntegeri_vProc>(
-      GetGLProcAddress("glGetIntegeri_v"));
+  fn.glGetFragDataLocationFn = 0;
+  fn.glGetFramebufferAttachmentParameterivEXTFn = 0;
+  fn.glGetGraphicsResetStatusARBFn = 0;
+  fn.glGetInteger64i_vFn = 0;
+  fn.glGetInteger64vFn = 0;
+  fn.glGetIntegeri_vFn = 0;
   fn.glGetIntegervFn =
       reinterpret_cast<glGetIntegervProc>(GetGLProcAddress("glGetIntegerv"));
-  fn.glGetInternalformativFn = reinterpret_cast<glGetInternalformativProc>(
-      GetGLProcAddress("glGetInternalformativ"));
-  fn.glGetProgramBinaryFn =
-      reinterpret_cast<glGetProgramBinaryProc>(glGetProgramBinaryNotBound);
+  fn.glGetInternalformativFn = 0;
+  fn.glGetProgramBinaryFn = 0;
   fn.glGetProgramInfoLogFn = reinterpret_cast<glGetProgramInfoLogProc>(
       GetGLProcAddress("glGetProgramInfoLog"));
   fn.glGetProgramivFn =
       reinterpret_cast<glGetProgramivProc>(GetGLProcAddress("glGetProgramiv"));
-  fn.glGetQueryivFn =
-      reinterpret_cast<glGetQueryivProc>(GetGLProcAddress("glGetQueryiv"));
-  fn.glGetQueryivARBFn =
-      reinterpret_cast<glGetQueryivARBProc>(glGetQueryivARBNotBound);
-  fn.glGetQueryObjecti64vFn = reinterpret_cast<glGetQueryObjecti64vProc>(
-      GetGLProcAddress("glGetQueryObjecti64v"));
-  fn.glGetQueryObjectivFn = reinterpret_cast<glGetQueryObjectivProc>(
-      GetGLProcAddress("glGetQueryObjectiv"));
-  fn.glGetQueryObjectivARBFn = reinterpret_cast<glGetQueryObjectivARBProc>(
-      glGetQueryObjectivARBNotBound);
-  fn.glGetQueryObjectui64vFn = reinterpret_cast<glGetQueryObjectui64vProc>(
-      glGetQueryObjectui64vNotBound);
-  fn.glGetQueryObjectuivFn = reinterpret_cast<glGetQueryObjectuivProc>(
-      GetGLProcAddress("glGetQueryObjectuiv"));
-  fn.glGetQueryObjectuivARBFn = reinterpret_cast<glGetQueryObjectuivARBProc>(
-      glGetQueryObjectuivARBNotBound);
-  fn.glGetRenderbufferParameterivEXTFn =
-      reinterpret_cast<glGetRenderbufferParameterivEXTProc>(
-          glGetRenderbufferParameterivEXTNotBound);
-  fn.glGetSamplerParameterfvFn = reinterpret_cast<glGetSamplerParameterfvProc>(
-      GetGLProcAddress("glGetSamplerParameterfv"));
-  fn.glGetSamplerParameterivFn = reinterpret_cast<glGetSamplerParameterivProc>(
-      GetGLProcAddress("glGetSamplerParameteriv"));
+  fn.glGetQueryivFn = 0;
+  fn.glGetQueryivARBFn = 0;
+  fn.glGetQueryObjecti64vFn = 0;
+  fn.glGetQueryObjectivFn = 0;
+  fn.glGetQueryObjectivARBFn = 0;
+  fn.glGetQueryObjectui64vFn = 0;
+  fn.glGetQueryObjectuivFn = 0;
+  fn.glGetQueryObjectuivARBFn = 0;
+  fn.glGetRenderbufferParameterivEXTFn = 0;
+  fn.glGetSamplerParameterfvFn = 0;
+  fn.glGetSamplerParameterivFn = 0;
   fn.glGetShaderInfoLogFn = reinterpret_cast<glGetShaderInfoLogProc>(
       GetGLProcAddress("glGetShaderInfoLog"));
   fn.glGetShaderivFn =
       reinterpret_cast<glGetShaderivProc>(GetGLProcAddress("glGetShaderiv"));
-  fn.glGetShaderPrecisionFormatFn =
-      reinterpret_cast<glGetShaderPrecisionFormatProc>(
-          GetGLProcAddress("glGetShaderPrecisionFormat"));
+  fn.glGetShaderPrecisionFormatFn = 0;
   fn.glGetShaderSourceFn = reinterpret_cast<glGetShaderSourceProc>(
       GetGLProcAddress("glGetShaderSource"));
   fn.glGetStringFn =
       reinterpret_cast<glGetStringProc>(GetGLProcAddress("glGetString"));
-  fn.glGetSyncivFn =
-      reinterpret_cast<glGetSyncivProc>(GetGLProcAddress("glGetSynciv"));
-  fn.glGetTexLevelParameterfvFn =
-      reinterpret_cast<glGetTexLevelParameterfvProc>(
-          GetGLProcAddress("glGetTexLevelParameterfv"));
-  fn.glGetTexLevelParameterivFn =
-      reinterpret_cast<glGetTexLevelParameterivProc>(
-          GetGLProcAddress("glGetTexLevelParameteriv"));
+  fn.glGetSyncivFn = 0;
+  fn.glGetTexLevelParameterfvFn = 0;
+  fn.glGetTexLevelParameterivFn = 0;
   fn.glGetTexParameterfvFn = reinterpret_cast<glGetTexParameterfvProc>(
       GetGLProcAddress("glGetTexParameterfv"));
   fn.glGetTexParameterivFn = reinterpret_cast<glGetTexParameterivProc>(
       GetGLProcAddress("glGetTexParameteriv"));
-  fn.glGetTransformFeedbackVaryingFn =
-      reinterpret_cast<glGetTransformFeedbackVaryingProc>(
-          GetGLProcAddress("glGetTransformFeedbackVarying"));
-  fn.glGetTranslatedShaderSourceANGLEFn =
-      reinterpret_cast<glGetTranslatedShaderSourceANGLEProc>(
-          GetGLProcAddress("glGetTranslatedShaderSourceANGLE"));
-  fn.glGetUniformBlockIndexFn = reinterpret_cast<glGetUniformBlockIndexProc>(
-      GetGLProcAddress("glGetUniformBlockIndex"));
+  fn.glGetTransformFeedbackVaryingFn = 0;
+  fn.glGetTranslatedShaderSourceANGLEFn = 0;
+  fn.glGetUniformBlockIndexFn = 0;
   fn.glGetUniformfvFn =
       reinterpret_cast<glGetUniformfvProc>(GetGLProcAddress("glGetUniformfv"));
-  fn.glGetUniformIndicesFn = reinterpret_cast<glGetUniformIndicesProc>(
-      GetGLProcAddress("glGetUniformIndices"));
+  fn.glGetUniformIndicesFn = 0;
   fn.glGetUniformivFn =
       reinterpret_cast<glGetUniformivProc>(GetGLProcAddress("glGetUniformiv"));
   fn.glGetUniformLocationFn = reinterpret_cast<glGetUniformLocationProc>(
@@ -593,113 +257,69 @@
       reinterpret_cast<glGetVertexAttribPointervProc>(
           GetGLProcAddress("glGetVertexAttribPointerv"));
   fn.glHintFn = reinterpret_cast<glHintProc>(GetGLProcAddress("glHint"));
-  fn.glInsertEventMarkerEXTFn = reinterpret_cast<glInsertEventMarkerEXTProc>(
-      GetGLProcAddress("glInsertEventMarkerEXT"));
-  fn.glInvalidateFramebufferFn = reinterpret_cast<glInvalidateFramebufferProc>(
-      GetGLProcAddress("glInvalidateFramebuffer"));
-  fn.glInvalidateSubFramebufferFn =
-      reinterpret_cast<glInvalidateSubFramebufferProc>(
-          GetGLProcAddress("glInvalidateSubFramebuffer"));
+  fn.glInsertEventMarkerEXTFn = 0;
+  fn.glInvalidateFramebufferFn = 0;
+  fn.glInvalidateSubFramebufferFn = 0;
   fn.glIsBufferFn =
       reinterpret_cast<glIsBufferProc>(GetGLProcAddress("glIsBuffer"));
   fn.glIsEnabledFn =
       reinterpret_cast<glIsEnabledProc>(GetGLProcAddress("glIsEnabled"));
-  fn.glIsFenceAPPLEFn =
-      reinterpret_cast<glIsFenceAPPLEProc>(GetGLProcAddress("glIsFenceAPPLE"));
-  fn.glIsFenceNVFn =
-      reinterpret_cast<glIsFenceNVProc>(GetGLProcAddress("glIsFenceNV"));
-  fn.glIsFramebufferEXTFn =
-      reinterpret_cast<glIsFramebufferEXTProc>(glIsFramebufferEXTNotBound);
+  fn.glIsFenceAPPLEFn = 0;
+  fn.glIsFenceNVFn = 0;
+  fn.glIsFramebufferEXTFn = 0;
   fn.glIsProgramFn =
       reinterpret_cast<glIsProgramProc>(GetGLProcAddress("glIsProgram"));
-  fn.glIsQueryFn =
-      reinterpret_cast<glIsQueryProc>(GetGLProcAddress("glIsQuery"));
-  fn.glIsQueryARBFn = reinterpret_cast<glIsQueryARBProc>(glIsQueryARBNotBound);
-  fn.glIsRenderbufferEXTFn =
-      reinterpret_cast<glIsRenderbufferEXTProc>(glIsRenderbufferEXTNotBound);
-  fn.glIsSamplerFn =
-      reinterpret_cast<glIsSamplerProc>(GetGLProcAddress("glIsSampler"));
+  fn.glIsQueryFn = 0;
+  fn.glIsQueryARBFn = 0;
+  fn.glIsRenderbufferEXTFn = 0;
+  fn.glIsSamplerFn = 0;
   fn.glIsShaderFn =
       reinterpret_cast<glIsShaderProc>(GetGLProcAddress("glIsShader"));
-  fn.glIsSyncFn = reinterpret_cast<glIsSyncProc>(GetGLProcAddress("glIsSync"));
+  fn.glIsSyncFn = 0;
   fn.glIsTextureFn =
       reinterpret_cast<glIsTextureProc>(GetGLProcAddress("glIsTexture"));
-  fn.glIsTransformFeedbackFn = reinterpret_cast<glIsTransformFeedbackProc>(
-      GetGLProcAddress("glIsTransformFeedback"));
-  fn.glIsVertexArrayOESFn =
-      reinterpret_cast<glIsVertexArrayOESProc>(glIsVertexArrayOESNotBound);
+  fn.glIsTransformFeedbackFn = 0;
+  fn.glIsVertexArrayOESFn = 0;
   fn.glLineWidthFn =
       reinterpret_cast<glLineWidthProc>(GetGLProcAddress("glLineWidth"));
   fn.glLinkProgramFn =
       reinterpret_cast<glLinkProgramProc>(GetGLProcAddress("glLinkProgram"));
-  fn.glMapBufferFn = reinterpret_cast<glMapBufferProc>(glMapBufferNotBound);
-  fn.glMapBufferRangeFn =
-      reinterpret_cast<glMapBufferRangeProc>(glMapBufferRangeNotBound);
-  fn.glMatrixLoadfEXTFn = reinterpret_cast<glMatrixLoadfEXTProc>(
-      GetGLProcAddress("glMatrixLoadfEXT"));
-  fn.glMatrixLoadIdentityEXTFn = reinterpret_cast<glMatrixLoadIdentityEXTProc>(
-      GetGLProcAddress("glMatrixLoadIdentityEXT"));
-  fn.glPauseTransformFeedbackFn =
-      reinterpret_cast<glPauseTransformFeedbackProc>(
-          GetGLProcAddress("glPauseTransformFeedback"));
+  fn.glMapBufferFn = 0;
+  fn.glMapBufferRangeFn = 0;
+  fn.glMatrixLoadfEXTFn = 0;
+  fn.glMatrixLoadIdentityEXTFn = 0;
+  fn.glPauseTransformFeedbackFn = 0;
   fn.glPixelStoreiFn =
       reinterpret_cast<glPixelStoreiProc>(GetGLProcAddress("glPixelStorei"));
-  fn.glPointParameteriFn = reinterpret_cast<glPointParameteriProc>(
-      GetGLProcAddress("glPointParameteri"));
+  fn.glPointParameteriFn = 0;
   fn.glPolygonOffsetFn = reinterpret_cast<glPolygonOffsetProc>(
       GetGLProcAddress("glPolygonOffset"));
-  fn.glPopGroupMarkerEXTFn = reinterpret_cast<glPopGroupMarkerEXTProc>(
-      GetGLProcAddress("glPopGroupMarkerEXT"));
-  fn.glProgramBinaryFn =
-      reinterpret_cast<glProgramBinaryProc>(glProgramBinaryNotBound);
-  fn.glProgramParameteriFn = reinterpret_cast<glProgramParameteriProc>(
-      GetGLProcAddress("glProgramParameteri"));
-  fn.glPushGroupMarkerEXTFn = reinterpret_cast<glPushGroupMarkerEXTProc>(
-      GetGLProcAddress("glPushGroupMarkerEXT"));
-  fn.glQueryCounterFn =
-      reinterpret_cast<glQueryCounterProc>(glQueryCounterNotBound);
-  fn.glReadBufferFn =
-      reinterpret_cast<glReadBufferProc>(GetGLProcAddress("glReadBuffer"));
+  fn.glPopGroupMarkerEXTFn = 0;
+  fn.glProgramBinaryFn = 0;
+  fn.glProgramParameteriFn = 0;
+  fn.glPushGroupMarkerEXTFn = 0;
+  fn.glQueryCounterFn = 0;
+  fn.glReadBufferFn = 0;
   fn.glReadPixelsFn =
       reinterpret_cast<glReadPixelsProc>(GetGLProcAddress("glReadPixels"));
-  fn.glReleaseShaderCompilerFn = reinterpret_cast<glReleaseShaderCompilerProc>(
-      GetGLProcAddress("glReleaseShaderCompiler"));
-  fn.glRenderbufferStorageEXTFn =
-      reinterpret_cast<glRenderbufferStorageEXTProc>(
-          glRenderbufferStorageEXTNotBound);
-  fn.glRenderbufferStorageMultisampleFn =
-      reinterpret_cast<glRenderbufferStorageMultisampleProc>(
-          GetGLProcAddress("glRenderbufferStorageMultisample"));
-  fn.glRenderbufferStorageMultisampleANGLEFn =
-      reinterpret_cast<glRenderbufferStorageMultisampleANGLEProc>(
-          glRenderbufferStorageMultisampleANGLENotBound);
-  fn.glRenderbufferStorageMultisampleEXTFn =
-      reinterpret_cast<glRenderbufferStorageMultisampleEXTProc>(
-          glRenderbufferStorageMultisampleEXTNotBound);
-  fn.glRenderbufferStorageMultisampleIMGFn =
-      reinterpret_cast<glRenderbufferStorageMultisampleIMGProc>(
-          GetGLProcAddress("glRenderbufferStorageMultisampleIMG"));
-  fn.glResumeTransformFeedbackFn =
-      reinterpret_cast<glResumeTransformFeedbackProc>(
-          GetGLProcAddress("glResumeTransformFeedback"));
+  fn.glReleaseShaderCompilerFn = 0;
+  fn.glRenderbufferStorageEXTFn = 0;
+  fn.glRenderbufferStorageMultisampleFn = 0;
+  fn.glRenderbufferStorageMultisampleANGLEFn = 0;
+  fn.glRenderbufferStorageMultisampleEXTFn = 0;
+  fn.glRenderbufferStorageMultisampleIMGFn = 0;
+  fn.glResumeTransformFeedbackFn = 0;
   fn.glSampleCoverageFn = reinterpret_cast<glSampleCoverageProc>(
       GetGLProcAddress("glSampleCoverage"));
-  fn.glSamplerParameterfFn = reinterpret_cast<glSamplerParameterfProc>(
-      GetGLProcAddress("glSamplerParameterf"));
-  fn.glSamplerParameterfvFn = reinterpret_cast<glSamplerParameterfvProc>(
-      GetGLProcAddress("glSamplerParameterfv"));
-  fn.glSamplerParameteriFn = reinterpret_cast<glSamplerParameteriProc>(
-      GetGLProcAddress("glSamplerParameteri"));
-  fn.glSamplerParameterivFn = reinterpret_cast<glSamplerParameterivProc>(
-      GetGLProcAddress("glSamplerParameteriv"));
+  fn.glSamplerParameterfFn = 0;
+  fn.glSamplerParameterfvFn = 0;
+  fn.glSamplerParameteriFn = 0;
+  fn.glSamplerParameterivFn = 0;
   fn.glScissorFn =
       reinterpret_cast<glScissorProc>(GetGLProcAddress("glScissor"));
-  fn.glSetFenceAPPLEFn = reinterpret_cast<glSetFenceAPPLEProc>(
-      GetGLProcAddress("glSetFenceAPPLE"));
-  fn.glSetFenceNVFn =
-      reinterpret_cast<glSetFenceNVProc>(GetGLProcAddress("glSetFenceNV"));
-  fn.glShaderBinaryFn =
-      reinterpret_cast<glShaderBinaryProc>(GetGLProcAddress("glShaderBinary"));
+  fn.glSetFenceAPPLEFn = 0;
+  fn.glSetFenceNVFn = 0;
+  fn.glShaderBinaryFn = 0;
   fn.glShaderSourceFn =
       reinterpret_cast<glShaderSourceProc>(GetGLProcAddress("glShaderSource"));
   fn.glStencilFuncFn =
@@ -714,14 +334,11 @@
       reinterpret_cast<glStencilOpProc>(GetGLProcAddress("glStencilOp"));
   fn.glStencilOpSeparateFn = reinterpret_cast<glStencilOpSeparateProc>(
       GetGLProcAddress("glStencilOpSeparate"));
-  fn.glTestFenceAPPLEFn = reinterpret_cast<glTestFenceAPPLEProc>(
-      GetGLProcAddress("glTestFenceAPPLE"));
-  fn.glTestFenceNVFn =
-      reinterpret_cast<glTestFenceNVProc>(GetGLProcAddress("glTestFenceNV"));
+  fn.glTestFenceAPPLEFn = 0;
+  fn.glTestFenceNVFn = 0;
   fn.glTexImage2DFn =
       reinterpret_cast<glTexImage2DProc>(GetGLProcAddress("glTexImage2D"));
-  fn.glTexImage3DFn =
-      reinterpret_cast<glTexImage3DProc>(GetGLProcAddress("glTexImage3D"));
+  fn.glTexImage3DFn = 0;
   fn.glTexParameterfFn = reinterpret_cast<glTexParameterfProc>(
       GetGLProcAddress("glTexParameterf"));
   fn.glTexParameterfvFn = reinterpret_cast<glTexParameterfvProc>(
@@ -730,15 +347,11 @@
       GetGLProcAddress("glTexParameteri"));
   fn.glTexParameterivFn = reinterpret_cast<glTexParameterivProc>(
       GetGLProcAddress("glTexParameteriv"));
-  fn.glTexStorage2DEXTFn =
-      reinterpret_cast<glTexStorage2DEXTProc>(glTexStorage2DEXTNotBound);
-  fn.glTexStorage3DFn =
-      reinterpret_cast<glTexStorage3DProc>(GetGLProcAddress("glTexStorage3D"));
+  fn.glTexStorage2DEXTFn = 0;
+  fn.glTexStorage3DFn = 0;
   fn.glTexSubImage2DFn = reinterpret_cast<glTexSubImage2DProc>(
       GetGLProcAddress("glTexSubImage2D"));
-  fn.glTransformFeedbackVaryingsFn =
-      reinterpret_cast<glTransformFeedbackVaryingsProc>(
-          GetGLProcAddress("glTransformFeedbackVaryings"));
+  fn.glTransformFeedbackVaryingsFn = 0;
   fn.glUniform1fFn =
       reinterpret_cast<glUniform1fProc>(GetGLProcAddress("glUniform1f"));
   fn.glUniform1fvFn =
@@ -747,10 +360,8 @@
       reinterpret_cast<glUniform1iProc>(GetGLProcAddress("glUniform1i"));
   fn.glUniform1ivFn =
       reinterpret_cast<glUniform1ivProc>(GetGLProcAddress("glUniform1iv"));
-  fn.glUniform1uiFn =
-      reinterpret_cast<glUniform1uiProc>(GetGLProcAddress("glUniform1ui"));
-  fn.glUniform1uivFn =
-      reinterpret_cast<glUniform1uivProc>(GetGLProcAddress("glUniform1uiv"));
+  fn.glUniform1uiFn = 0;
+  fn.glUniform1uivFn = 0;
   fn.glUniform2fFn =
       reinterpret_cast<glUniform2fProc>(GetGLProcAddress("glUniform2f"));
   fn.glUniform2fvFn =
@@ -759,10 +370,8 @@
       reinterpret_cast<glUniform2iProc>(GetGLProcAddress("glUniform2i"));
   fn.glUniform2ivFn =
       reinterpret_cast<glUniform2ivProc>(GetGLProcAddress("glUniform2iv"));
-  fn.glUniform2uiFn =
-      reinterpret_cast<glUniform2uiProc>(GetGLProcAddress("glUniform2ui"));
-  fn.glUniform2uivFn =
-      reinterpret_cast<glUniform2uivProc>(GetGLProcAddress("glUniform2uiv"));
+  fn.glUniform2uiFn = 0;
+  fn.glUniform2uivFn = 0;
   fn.glUniform3fFn =
       reinterpret_cast<glUniform3fProc>(GetGLProcAddress("glUniform3f"));
   fn.glUniform3fvFn =
@@ -771,10 +380,8 @@
       reinterpret_cast<glUniform3iProc>(GetGLProcAddress("glUniform3i"));
   fn.glUniform3ivFn =
       reinterpret_cast<glUniform3ivProc>(GetGLProcAddress("glUniform3iv"));
-  fn.glUniform3uiFn =
-      reinterpret_cast<glUniform3uiProc>(GetGLProcAddress("glUniform3ui"));
-  fn.glUniform3uivFn =
-      reinterpret_cast<glUniform3uivProc>(GetGLProcAddress("glUniform3uiv"));
+  fn.glUniform3uiFn = 0;
+  fn.glUniform3uivFn = 0;
   fn.glUniform4fFn =
       reinterpret_cast<glUniform4fProc>(GetGLProcAddress("glUniform4f"));
   fn.glUniform4fvFn =
@@ -783,32 +390,22 @@
       reinterpret_cast<glUniform4iProc>(GetGLProcAddress("glUniform4i"));
   fn.glUniform4ivFn =
       reinterpret_cast<glUniform4ivProc>(GetGLProcAddress("glUniform4iv"));
-  fn.glUniform4uiFn =
-      reinterpret_cast<glUniform4uiProc>(GetGLProcAddress("glUniform4ui"));
-  fn.glUniform4uivFn =
-      reinterpret_cast<glUniform4uivProc>(GetGLProcAddress("glUniform4uiv"));
-  fn.glUniformBlockBindingFn = reinterpret_cast<glUniformBlockBindingProc>(
-      GetGLProcAddress("glUniformBlockBinding"));
+  fn.glUniform4uiFn = 0;
+  fn.glUniform4uivFn = 0;
+  fn.glUniformBlockBindingFn = 0;
   fn.glUniformMatrix2fvFn = reinterpret_cast<glUniformMatrix2fvProc>(
       GetGLProcAddress("glUniformMatrix2fv"));
-  fn.glUniformMatrix2x3fvFn = reinterpret_cast<glUniformMatrix2x3fvProc>(
-      GetGLProcAddress("glUniformMatrix2x3fv"));
-  fn.glUniformMatrix2x4fvFn = reinterpret_cast<glUniformMatrix2x4fvProc>(
-      GetGLProcAddress("glUniformMatrix2x4fv"));
+  fn.glUniformMatrix2x3fvFn = 0;
+  fn.glUniformMatrix2x4fvFn = 0;
   fn.glUniformMatrix3fvFn = reinterpret_cast<glUniformMatrix3fvProc>(
       GetGLProcAddress("glUniformMatrix3fv"));
-  fn.glUniformMatrix3x2fvFn = reinterpret_cast<glUniformMatrix3x2fvProc>(
-      GetGLProcAddress("glUniformMatrix3x2fv"));
-  fn.glUniformMatrix3x4fvFn = reinterpret_cast<glUniformMatrix3x4fvProc>(
-      GetGLProcAddress("glUniformMatrix3x4fv"));
+  fn.glUniformMatrix3x2fvFn = 0;
+  fn.glUniformMatrix3x4fvFn = 0;
   fn.glUniformMatrix4fvFn = reinterpret_cast<glUniformMatrix4fvProc>(
       GetGLProcAddress("glUniformMatrix4fv"));
-  fn.glUniformMatrix4x2fvFn = reinterpret_cast<glUniformMatrix4x2fvProc>(
-      GetGLProcAddress("glUniformMatrix4x2fv"));
-  fn.glUniformMatrix4x3fvFn = reinterpret_cast<glUniformMatrix4x3fvProc>(
-      GetGLProcAddress("glUniformMatrix4x3fv"));
-  fn.glUnmapBufferFn =
-      reinterpret_cast<glUnmapBufferProc>(glUnmapBufferNotBound);
+  fn.glUniformMatrix4x2fvFn = 0;
+  fn.glUniformMatrix4x3fvFn = 0;
+  fn.glUnmapBufferFn = 0;
   fn.glUseProgramFn =
       reinterpret_cast<glUseProgramProc>(GetGLProcAddress("glUseProgram"));
   fn.glValidateProgramFn = reinterpret_cast<glValidateProgramProc>(
@@ -829,25 +426,17 @@
       GetGLProcAddress("glVertexAttrib4f"));
   fn.glVertexAttrib4fvFn = reinterpret_cast<glVertexAttrib4fvProc>(
       GetGLProcAddress("glVertexAttrib4fv"));
-  fn.glVertexAttribDivisorANGLEFn =
-      reinterpret_cast<glVertexAttribDivisorANGLEProc>(
-          glVertexAttribDivisorANGLENotBound);
-  fn.glVertexAttribI4iFn = reinterpret_cast<glVertexAttribI4iProc>(
-      GetGLProcAddress("glVertexAttribI4i"));
-  fn.glVertexAttribI4ivFn = reinterpret_cast<glVertexAttribI4ivProc>(
-      GetGLProcAddress("glVertexAttribI4iv"));
-  fn.glVertexAttribI4uiFn = reinterpret_cast<glVertexAttribI4uiProc>(
-      GetGLProcAddress("glVertexAttribI4ui"));
-  fn.glVertexAttribI4uivFn = reinterpret_cast<glVertexAttribI4uivProc>(
-      GetGLProcAddress("glVertexAttribI4uiv"));
-  fn.glVertexAttribIPointerFn = reinterpret_cast<glVertexAttribIPointerProc>(
-      GetGLProcAddress("glVertexAttribIPointer"));
+  fn.glVertexAttribDivisorANGLEFn = 0;
+  fn.glVertexAttribI4iFn = 0;
+  fn.glVertexAttribI4ivFn = 0;
+  fn.glVertexAttribI4uiFn = 0;
+  fn.glVertexAttribI4uivFn = 0;
+  fn.glVertexAttribIPointerFn = 0;
   fn.glVertexAttribPointerFn = reinterpret_cast<glVertexAttribPointerProc>(
       GetGLProcAddress("glVertexAttribPointer"));
   fn.glViewportFn =
       reinterpret_cast<glViewportProc>(GetGLProcAddress("glViewport"));
-  fn.glWaitSyncFn =
-      reinterpret_cast<glWaitSyncProc>(GetGLProcAddress("glWaitSync"));
+  fn.glWaitSyncFn = 0;
 }
 
 void DriverGL::InitializeDynamicBindings(GLContext* context) {
@@ -870,47 +459,30 @@
       extensions.find("GL_APPLE_fence ") != std::string::npos;
   ext.b_GL_APPLE_vertex_array_object =
       extensions.find("GL_APPLE_vertex_array_object ") != std::string::npos;
-  ext.b_GL_ARB_ES2_compatibility =
-      extensions.find("GL_ARB_ES2_compatibility ") != std::string::npos;
-  ext.b_GL_ARB_blend_func_extended =
-      extensions.find("GL_ARB_blend_func_extended ") != std::string::npos;
-  ext.b_GL_ARB_copy_buffer =
-      extensions.find("GL_ARB_copy_buffer ") != std::string::npos;
   ext.b_GL_ARB_draw_buffers =
       extensions.find("GL_ARB_draw_buffers ") != std::string::npos;
   ext.b_GL_ARB_draw_instanced =
       extensions.find("GL_ARB_draw_instanced ") != std::string::npos;
-  ext.b_GL_ARB_framebuffer_object =
-      extensions.find("GL_ARB_framebuffer_object ") != std::string::npos;
   ext.b_GL_ARB_get_program_binary =
       extensions.find("GL_ARB_get_program_binary ") != std::string::npos;
   ext.b_GL_ARB_instanced_arrays =
       extensions.find("GL_ARB_instanced_arrays ") != std::string::npos;
-  ext.b_GL_ARB_internalformat_query =
-      extensions.find("GL_ARB_internalformat_query ") != std::string::npos;
-  ext.b_GL_ARB_invalidate_subdata =
-      extensions.find("GL_ARB_invalidate_subdata ") != std::string::npos;
   ext.b_GL_ARB_map_buffer_range =
       extensions.find("GL_ARB_map_buffer_range ") != std::string::npos;
   ext.b_GL_ARB_occlusion_query =
       extensions.find("GL_ARB_occlusion_query ") != std::string::npos;
   ext.b_GL_ARB_robustness =
       extensions.find("GL_ARB_robustness ") != std::string::npos;
-  ext.b_GL_ARB_sampler_objects =
-      extensions.find("GL_ARB_sampler_objects ") != std::string::npos;
   ext.b_GL_ARB_sync = extensions.find("GL_ARB_sync ") != std::string::npos;
   ext.b_GL_ARB_texture_storage =
       extensions.find("GL_ARB_texture_storage ") != std::string::npos;
   ext.b_GL_ARB_timer_query =
       extensions.find("GL_ARB_timer_query ") != std::string::npos;
-  ext.b_GL_ARB_transform_feedback2 =
-      extensions.find("GL_ARB_transform_feedback2 ") != std::string::npos;
-  ext.b_GL_ARB_uniform_buffer_object =
-      extensions.find("GL_ARB_uniform_buffer_object ") != std::string::npos;
   ext.b_GL_ARB_vertex_array_object =
       extensions.find("GL_ARB_vertex_array_object ") != std::string::npos;
-  ext.b_GL_ARB_vertex_buffer_object =
-      extensions.find("GL_ARB_vertex_buffer_object ") != std::string::npos;
+  ext.b_GL_CHROMIUM_gles_depth_binding_hack =
+      extensions.find("GL_CHROMIUM_gles_depth_binding_hack ") !=
+      std::string::npos;
   ext.b_GL_EXT_debug_marker =
       extensions.find("GL_EXT_debug_marker ") != std::string::npos;
   ext.b_GL_EXT_direct_state_access =
@@ -932,6 +504,8 @@
   ext.b_GL_EXT_multisampled_render_to_texture =
       extensions.find("GL_EXT_multisampled_render_to_texture ") !=
       std::string::npos;
+  ext.b_GL_EXT_occlusion_query_boolean =
+      extensions.find("GL_EXT_occlusion_query_boolean ") != std::string::npos;
   ext.b_GL_EXT_robustness =
       extensions.find("GL_EXT_robustness ") != std::string::npos;
   ext.b_GL_EXT_texture_storage =
@@ -959,603 +533,1479 @@
   ext.b_GL_OES_vertex_array_object =
       extensions.find("GL_OES_vertex_array_object ") != std::string::npos;
 
-  fn.glBeginQueryARBFn = 0;
+  debug_fn.glBeginQueryFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glBeginQueryFn =
+        reinterpret_cast<glBeginQueryProc>(GetGLProcAddress("glBeginQuery"));
+    DCHECK(fn.glBeginQueryFn);
+  }
+
   debug_fn.glBeginQueryARBFn = 0;
   if (ext.b_GL_ARB_occlusion_query) {
     fn.glBeginQueryARBFn = reinterpret_cast<glBeginQueryARBProc>(
         GetGLProcAddress("glBeginQueryARB"));
-  }
-  if (!fn.glBeginQueryARBFn) {
+    DCHECK(fn.glBeginQueryARBFn);
+  } else if (ext.b_GL_EXT_disjoint_timer_query ||
+             ext.b_GL_EXT_occlusion_query_boolean) {
     fn.glBeginQueryARBFn = reinterpret_cast<glBeginQueryARBProc>(
         GetGLProcAddress("glBeginQueryEXT"));
+    DCHECK(fn.glBeginQueryARBFn);
   }
 
-  fn.glBindFramebufferEXTFn = 0;
-  debug_fn.glBindFramebufferEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glBindFramebufferEXTFn = reinterpret_cast<glBindFramebufferEXTProc>(
-        GetGLProcAddress("glBindFramebufferEXT"));
+  debug_fn.glBeginTransformFeedbackFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glBeginTransformFeedbackFn =
+        reinterpret_cast<glBeginTransformFeedbackProc>(
+            GetGLProcAddress("glBeginTransformFeedback"));
+    DCHECK(fn.glBeginTransformFeedbackFn);
   }
-  if (!fn.glBindFramebufferEXTFn) {
+
+  debug_fn.glBindBufferBaseFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glBindBufferBaseFn = reinterpret_cast<glBindBufferBaseProc>(
+        GetGLProcAddress("glBindBufferBase"));
+    DCHECK(fn.glBindBufferBaseFn);
+  }
+
+  debug_fn.glBindBufferRangeFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glBindBufferRangeFn = reinterpret_cast<glBindBufferRangeProc>(
+        GetGLProcAddress("glBindBufferRange"));
+    DCHECK(fn.glBindBufferRangeFn);
+  }
+
+  debug_fn.glBindFragDataLocationFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u)) {
+    fn.glBindFragDataLocationFn = reinterpret_cast<glBindFragDataLocationProc>(
+        GetGLProcAddress("glBindFragDataLocation"));
+    DCHECK(fn.glBindFragDataLocationFn);
+  }
+
+  debug_fn.glBindFragDataLocationIndexedFn = 0;
+  if (ver->IsAtLeastGL(3u, 3u)) {
+    fn.glBindFragDataLocationIndexedFn =
+        reinterpret_cast<glBindFragDataLocationIndexedProc>(
+            GetGLProcAddress("glBindFragDataLocationIndexed"));
+    DCHECK(fn.glBindFragDataLocationIndexedFn);
+  }
+
+  debug_fn.glBindFramebufferEXTFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glBindFramebufferEXTFn = reinterpret_cast<glBindFramebufferEXTProc>(
         GetGLProcAddress("glBindFramebuffer"));
+    DCHECK(fn.glBindFramebufferEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glBindFramebufferEXTFn = reinterpret_cast<glBindFramebufferEXTProc>(
+        GetGLProcAddress("glBindFramebufferEXT"));
+    DCHECK(fn.glBindFramebufferEXTFn);
   }
 
-  fn.glBindRenderbufferEXTFn = 0;
   debug_fn.glBindRenderbufferEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glBindRenderbufferEXTFn = reinterpret_cast<glBindRenderbufferEXTProc>(
-        GetGLProcAddress("glBindRenderbufferEXT"));
-  }
-  if (!fn.glBindRenderbufferEXTFn) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glBindRenderbufferEXTFn = reinterpret_cast<glBindRenderbufferEXTProc>(
         GetGLProcAddress("glBindRenderbuffer"));
+    DCHECK(fn.glBindRenderbufferEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glBindRenderbufferEXTFn = reinterpret_cast<glBindRenderbufferEXTProc>(
+        GetGLProcAddress("glBindRenderbufferEXT"));
+    DCHECK(fn.glBindRenderbufferEXTFn);
   }
 
-  fn.glBindVertexArrayOESFn = 0;
+  debug_fn.glBindSamplerFn = 0;
+  if (ver->IsAtLeastGL(3u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glBindSamplerFn =
+        reinterpret_cast<glBindSamplerProc>(GetGLProcAddress("glBindSampler"));
+    DCHECK(fn.glBindSamplerFn);
+  }
+
+  debug_fn.glBindTransformFeedbackFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(4u, 0u)) {
+    fn.glBindTransformFeedbackFn =
+        reinterpret_cast<glBindTransformFeedbackProc>(
+            GetGLProcAddress("glBindTransformFeedback"));
+    DCHECK(fn.glBindTransformFeedbackFn);
+  }
+
   debug_fn.glBindVertexArrayOESFn = 0;
-  if ((ver->is_gl3 || ver->is_gl4 || ver->is_es3) ||
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u) ||
       ext.b_GL_ARB_vertex_array_object) {
     fn.glBindVertexArrayOESFn = reinterpret_cast<glBindVertexArrayOESProc>(
         GetGLProcAddress("glBindVertexArray"));
-  }
-  if (!fn.glBindVertexArrayOESFn && (ext.b_GL_OES_vertex_array_object)) {
+    DCHECK(fn.glBindVertexArrayOESFn);
+  } else if (ext.b_GL_OES_vertex_array_object) {
     fn.glBindVertexArrayOESFn = reinterpret_cast<glBindVertexArrayOESProc>(
         GetGLProcAddress("glBindVertexArrayOES"));
-  }
-  if (!fn.glBindVertexArrayOESFn) {
+    DCHECK(fn.glBindVertexArrayOESFn);
+  } else if (ext.b_GL_APPLE_vertex_array_object) {
     fn.glBindVertexArrayOESFn = reinterpret_cast<glBindVertexArrayOESProc>(
         GetGLProcAddress("glBindVertexArrayAPPLE"));
+    DCHECK(fn.glBindVertexArrayOESFn);
   }
 
-  fn.glBlendBarrierKHRFn = 0;
   debug_fn.glBlendBarrierKHRFn = 0;
   if (ext.b_GL_NV_blend_equation_advanced) {
     fn.glBlendBarrierKHRFn = reinterpret_cast<glBlendBarrierKHRProc>(
         GetGLProcAddress("glBlendBarrierNV"));
-  }
-  if (!fn.glBlendBarrierKHRFn) {
+    DCHECK(fn.glBlendBarrierKHRFn);
+  } else if (ext.b_GL_KHR_blend_equation_advanced) {
     fn.glBlendBarrierKHRFn = reinterpret_cast<glBlendBarrierKHRProc>(
         GetGLProcAddress("glBlendBarrierKHR"));
+    DCHECK(fn.glBlendBarrierKHRFn);
   }
 
-  fn.glBlitFramebufferANGLEFn = 0;
+  debug_fn.glBlitFramebufferFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glBlitFramebufferFn = reinterpret_cast<glBlitFramebufferProc>(
+        GetGLProcAddress("glBlitFramebuffer"));
+    DCHECK(fn.glBlitFramebufferFn);
+  }
+
   debug_fn.glBlitFramebufferANGLEFn = 0;
-  if (ext.b_GL_ANGLE_framebuffer_blit) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glBlitFramebufferANGLEFn = reinterpret_cast<glBlitFramebufferANGLEProc>(
+        GetGLProcAddress("glBlitFramebuffer"));
+    DCHECK(fn.glBlitFramebufferANGLEFn);
+  } else if (ext.b_GL_ANGLE_framebuffer_blit) {
     fn.glBlitFramebufferANGLEFn = reinterpret_cast<glBlitFramebufferANGLEProc>(
         GetGLProcAddress("glBlitFramebufferANGLE"));
-  }
-  if (!fn.glBlitFramebufferANGLEFn) {
-    fn.glBlitFramebufferANGLEFn = reinterpret_cast<glBlitFramebufferANGLEProc>(
-        GetGLProcAddress("glBlitFramebuffer"));
+    DCHECK(fn.glBlitFramebufferANGLEFn);
   }
 
-  fn.glBlitFramebufferEXTFn = 0;
   debug_fn.glBlitFramebufferEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_blit) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glBlitFramebufferEXTFn = reinterpret_cast<glBlitFramebufferEXTProc>(
+        GetGLProcAddress("glBlitFramebuffer"));
+    DCHECK(fn.glBlitFramebufferEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_blit) {
     fn.glBlitFramebufferEXTFn = reinterpret_cast<glBlitFramebufferEXTProc>(
         GetGLProcAddress("glBlitFramebufferEXT"));
-  }
-  if (!fn.glBlitFramebufferEXTFn) {
-    fn.glBlitFramebufferEXTFn = reinterpret_cast<glBlitFramebufferEXTProc>(
-        GetGLProcAddress("glBlitFramebuffer"));
+    DCHECK(fn.glBlitFramebufferEXTFn);
   }
 
-  fn.glCheckFramebufferStatusEXTFn = 0;
   debug_fn.glCheckFramebufferStatusEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glCheckFramebufferStatusEXTFn =
-        reinterpret_cast<glCheckFramebufferStatusEXTProc>(
-            GetGLProcAddress("glCheckFramebufferStatusEXT"));
-  }
-  if (!fn.glCheckFramebufferStatusEXTFn) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glCheckFramebufferStatusEXTFn =
         reinterpret_cast<glCheckFramebufferStatusEXTProc>(
             GetGLProcAddress("glCheckFramebufferStatus"));
+    DCHECK(fn.glCheckFramebufferStatusEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glCheckFramebufferStatusEXTFn =
+        reinterpret_cast<glCheckFramebufferStatusEXTProc>(
+            GetGLProcAddress("glCheckFramebufferStatusEXT"));
+    DCHECK(fn.glCheckFramebufferStatusEXTFn);
   }
 
-  fn.glDeleteBuffersARBFn = 0;
-  debug_fn.glDeleteBuffersARBFn = 0;
-  if (ext.b_GL_ARB_vertex_buffer_object) {
-    fn.glDeleteBuffersARBFn = reinterpret_cast<glDeleteBuffersARBProc>(
-        GetGLProcAddress("glDeleteBuffersARB"));
-  }
-  if (!fn.glDeleteBuffersARBFn) {
-    fn.glDeleteBuffersARBFn = reinterpret_cast<glDeleteBuffersARBProc>(
-        GetGLProcAddress("glDeleteBuffers"));
+  debug_fn.glClearBufferfiFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glClearBufferfiFn = reinterpret_cast<glClearBufferfiProc>(
+        GetGLProcAddress("glClearBufferfi"));
+    DCHECK(fn.glClearBufferfiFn);
   }
 
-  fn.glDeleteFramebuffersEXTFn = 0;
+  debug_fn.glClearBufferfvFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glClearBufferfvFn = reinterpret_cast<glClearBufferfvProc>(
+        GetGLProcAddress("glClearBufferfv"));
+    DCHECK(fn.glClearBufferfvFn);
+  }
+
+  debug_fn.glClearBufferivFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glClearBufferivFn = reinterpret_cast<glClearBufferivProc>(
+        GetGLProcAddress("glClearBufferiv"));
+    DCHECK(fn.glClearBufferivFn);
+  }
+
+  debug_fn.glClearBufferuivFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glClearBufferuivFn = reinterpret_cast<glClearBufferuivProc>(
+        GetGLProcAddress("glClearBufferuiv"));
+    DCHECK(fn.glClearBufferuivFn);
+  }
+
+  debug_fn.glClearDepthfFn = 0;
+  if (ver->IsAtLeastGL(4u, 1u) || ver->is_es) {
+    fn.glClearDepthfFn =
+        reinterpret_cast<glClearDepthfProc>(GetGLProcAddress("glClearDepthf"));
+    DCHECK(fn.glClearDepthfFn);
+  }
+
+  debug_fn.glClientWaitSyncFn = 0;
+  if (ver->IsAtLeastGL(3u, 2u) || ver->IsAtLeastGLES(3u, 0u) ||
+      ext.b_GL_ARB_sync) {
+    fn.glClientWaitSyncFn = reinterpret_cast<glClientWaitSyncProc>(
+        GetGLProcAddress("glClientWaitSync"));
+    DCHECK(fn.glClientWaitSyncFn);
+  }
+
+  debug_fn.glCompressedTexImage3DFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glCompressedTexImage3DFn = reinterpret_cast<glCompressedTexImage3DProc>(
+        GetGLProcAddress("glCompressedTexImage3D"));
+    DCHECK(fn.glCompressedTexImage3DFn);
+  }
+
+  debug_fn.glCopyBufferSubDataFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(3u, 1u)) {
+    fn.glCopyBufferSubDataFn = reinterpret_cast<glCopyBufferSubDataProc>(
+        GetGLProcAddress("glCopyBufferSubData"));
+    DCHECK(fn.glCopyBufferSubDataFn);
+  }
+
+  debug_fn.glCopyTexSubImage3DFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glCopyTexSubImage3DFn = reinterpret_cast<glCopyTexSubImage3DProc>(
+        GetGLProcAddress("glCopyTexSubImage3D"));
+    DCHECK(fn.glCopyTexSubImage3DFn);
+  }
+
+  debug_fn.glDeleteFencesAPPLEFn = 0;
+  if (ext.b_GL_APPLE_fence) {
+    fn.glDeleteFencesAPPLEFn = reinterpret_cast<glDeleteFencesAPPLEProc>(
+        GetGLProcAddress("glDeleteFencesAPPLE"));
+    DCHECK(fn.glDeleteFencesAPPLEFn);
+  }
+
+  debug_fn.glDeleteFencesNVFn = 0;
+  if (ext.b_GL_NV_fence) {
+    fn.glDeleteFencesNVFn = reinterpret_cast<glDeleteFencesNVProc>(
+        GetGLProcAddress("glDeleteFencesNV"));
+    DCHECK(fn.glDeleteFencesNVFn);
+  }
+
   debug_fn.glDeleteFramebuffersEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glDeleteFramebuffersEXTFn =
-        reinterpret_cast<glDeleteFramebuffersEXTProc>(
-            GetGLProcAddress("glDeleteFramebuffersEXT"));
-  }
-  if (!fn.glDeleteFramebuffersEXTFn) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glDeleteFramebuffersEXTFn =
         reinterpret_cast<glDeleteFramebuffersEXTProc>(
             GetGLProcAddress("glDeleteFramebuffers"));
+    DCHECK(fn.glDeleteFramebuffersEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glDeleteFramebuffersEXTFn =
+        reinterpret_cast<glDeleteFramebuffersEXTProc>(
+            GetGLProcAddress("glDeleteFramebuffersEXT"));
+    DCHECK(fn.glDeleteFramebuffersEXTFn);
   }
 
-  fn.glDeleteQueriesARBFn = 0;
+  debug_fn.glDeleteQueriesFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glDeleteQueriesFn = reinterpret_cast<glDeleteQueriesProc>(
+        GetGLProcAddress("glDeleteQueries"));
+    DCHECK(fn.glDeleteQueriesFn);
+  }
+
   debug_fn.glDeleteQueriesARBFn = 0;
   if (ext.b_GL_ARB_occlusion_query) {
     fn.glDeleteQueriesARBFn = reinterpret_cast<glDeleteQueriesARBProc>(
         GetGLProcAddress("glDeleteQueriesARB"));
-  }
-  if (!fn.glDeleteQueriesARBFn) {
+    DCHECK(fn.glDeleteQueriesARBFn);
+  } else if (ext.b_GL_EXT_disjoint_timer_query ||
+             ext.b_GL_EXT_occlusion_query_boolean) {
     fn.glDeleteQueriesARBFn = reinterpret_cast<glDeleteQueriesARBProc>(
         GetGLProcAddress("glDeleteQueriesEXT"));
+    DCHECK(fn.glDeleteQueriesARBFn);
   }
 
-  fn.glDeleteRenderbuffersEXTFn = 0;
   debug_fn.glDeleteRenderbuffersEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glDeleteRenderbuffersEXTFn =
-        reinterpret_cast<glDeleteRenderbuffersEXTProc>(
-            GetGLProcAddress("glDeleteRenderbuffersEXT"));
-  }
-  if (!fn.glDeleteRenderbuffersEXTFn) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glDeleteRenderbuffersEXTFn =
         reinterpret_cast<glDeleteRenderbuffersEXTProc>(
             GetGLProcAddress("glDeleteRenderbuffers"));
+    DCHECK(fn.glDeleteRenderbuffersEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glDeleteRenderbuffersEXTFn =
+        reinterpret_cast<glDeleteRenderbuffersEXTProc>(
+            GetGLProcAddress("glDeleteRenderbuffersEXT"));
+    DCHECK(fn.glDeleteRenderbuffersEXTFn);
   }
 
-  fn.glDeleteVertexArraysOESFn = 0;
+  debug_fn.glDeleteSamplersFn = 0;
+  if (ver->IsAtLeastGL(3u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glDeleteSamplersFn = reinterpret_cast<glDeleteSamplersProc>(
+        GetGLProcAddress("glDeleteSamplers"));
+    DCHECK(fn.glDeleteSamplersFn);
+  }
+
+  debug_fn.glDeleteSyncFn = 0;
+  if (ver->IsAtLeastGL(3u, 2u) || ver->IsAtLeastGLES(3u, 0u) ||
+      ext.b_GL_ARB_sync) {
+    fn.glDeleteSyncFn =
+        reinterpret_cast<glDeleteSyncProc>(GetGLProcAddress("glDeleteSync"));
+    DCHECK(fn.glDeleteSyncFn);
+  }
+
+  debug_fn.glDeleteTransformFeedbacksFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(4u, 0u)) {
+    fn.glDeleteTransformFeedbacksFn =
+        reinterpret_cast<glDeleteTransformFeedbacksProc>(
+            GetGLProcAddress("glDeleteTransformFeedbacks"));
+    DCHECK(fn.glDeleteTransformFeedbacksFn);
+  }
+
   debug_fn.glDeleteVertexArraysOESFn = 0;
-  if ((ver->is_gl3 || ver->is_gl4 || ver->is_es3) ||
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u) ||
       ext.b_GL_ARB_vertex_array_object) {
     fn.glDeleteVertexArraysOESFn =
         reinterpret_cast<glDeleteVertexArraysOESProc>(
             GetGLProcAddress("glDeleteVertexArrays"));
-  }
-  if (!fn.glDeleteVertexArraysOESFn && (ext.b_GL_OES_vertex_array_object)) {
+    DCHECK(fn.glDeleteVertexArraysOESFn);
+  } else if (ext.b_GL_OES_vertex_array_object) {
     fn.glDeleteVertexArraysOESFn =
         reinterpret_cast<glDeleteVertexArraysOESProc>(
             GetGLProcAddress("glDeleteVertexArraysOES"));
-  }
-  if (!fn.glDeleteVertexArraysOESFn) {
+    DCHECK(fn.glDeleteVertexArraysOESFn);
+  } else if (ext.b_GL_APPLE_vertex_array_object) {
     fn.glDeleteVertexArraysOESFn =
         reinterpret_cast<glDeleteVertexArraysOESProc>(
             GetGLProcAddress("glDeleteVertexArraysAPPLE"));
+    DCHECK(fn.glDeleteVertexArraysOESFn);
   }
 
-  fn.glDrawArraysInstancedANGLEFn = 0;
+  debug_fn.glDepthRangefFn = 0;
+  if (ver->IsAtLeastGL(4u, 1u) || ver->is_es) {
+    fn.glDepthRangefFn =
+        reinterpret_cast<glDepthRangefProc>(GetGLProcAddress("glDepthRangef"));
+    DCHECK(fn.glDepthRangefFn);
+  }
+
+  debug_fn.glDiscardFramebufferEXTFn = 0;
+  if (ext.b_GL_EXT_discard_framebuffer) {
+    fn.glDiscardFramebufferEXTFn =
+        reinterpret_cast<glDiscardFramebufferEXTProc>(
+            GetGLProcAddress("glDiscardFramebufferEXT"));
+    DCHECK(fn.glDiscardFramebufferEXTFn);
+  }
+
   debug_fn.glDrawArraysInstancedANGLEFn = 0;
-  if (ext.b_GL_ARB_draw_instanced) {
-    fn.glDrawArraysInstancedANGLEFn =
-        reinterpret_cast<glDrawArraysInstancedANGLEProc>(
-            GetGLProcAddress("glDrawArraysInstancedARB"));
-  }
-  if (!fn.glDrawArraysInstancedANGLEFn && (ext.b_GL_ANGLE_instanced_arrays)) {
-    fn.glDrawArraysInstancedANGLEFn =
-        reinterpret_cast<glDrawArraysInstancedANGLEProc>(
-            GetGLProcAddress("glDrawArraysInstancedANGLE"));
-  }
-  if (!fn.glDrawArraysInstancedANGLEFn) {
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(3u, 1u)) {
     fn.glDrawArraysInstancedANGLEFn =
         reinterpret_cast<glDrawArraysInstancedANGLEProc>(
             GetGLProcAddress("glDrawArraysInstanced"));
+    DCHECK(fn.glDrawArraysInstancedANGLEFn);
+  } else if (ext.b_GL_ARB_draw_instanced) {
+    fn.glDrawArraysInstancedANGLEFn =
+        reinterpret_cast<glDrawArraysInstancedANGLEProc>(
+            GetGLProcAddress("glDrawArraysInstancedARB"));
+    DCHECK(fn.glDrawArraysInstancedANGLEFn);
+  } else if (ext.b_GL_ANGLE_instanced_arrays) {
+    fn.glDrawArraysInstancedANGLEFn =
+        reinterpret_cast<glDrawArraysInstancedANGLEProc>(
+            GetGLProcAddress("glDrawArraysInstancedANGLE"));
+    DCHECK(fn.glDrawArraysInstancedANGLEFn);
   }
 
-  fn.glDrawBuffersARBFn = 0;
+  debug_fn.glDrawBufferFn = 0;
+  if (!ver->is_es) {
+    fn.glDrawBufferFn =
+        reinterpret_cast<glDrawBufferProc>(GetGLProcAddress("glDrawBuffer"));
+    DCHECK(fn.glDrawBufferFn);
+  }
+
   debug_fn.glDrawBuffersARBFn = 0;
-  if (ext.b_GL_ARB_draw_buffers) {
-    fn.glDrawBuffersARBFn = reinterpret_cast<glDrawBuffersARBProc>(
-        GetGLProcAddress("glDrawBuffersARB"));
-  }
-  if (!fn.glDrawBuffersARBFn && (ext.b_GL_EXT_draw_buffers)) {
-    fn.glDrawBuffersARBFn = reinterpret_cast<glDrawBuffersARBProc>(
-        GetGLProcAddress("glDrawBuffersEXT"));
-  }
-  if (!fn.glDrawBuffersARBFn) {
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
     fn.glDrawBuffersARBFn = reinterpret_cast<glDrawBuffersARBProc>(
         GetGLProcAddress("glDrawBuffers"));
+    DCHECK(fn.glDrawBuffersARBFn);
+  } else if (ext.b_GL_ARB_draw_buffers) {
+    fn.glDrawBuffersARBFn = reinterpret_cast<glDrawBuffersARBProc>(
+        GetGLProcAddress("glDrawBuffersARB"));
+    DCHECK(fn.glDrawBuffersARBFn);
+  } else if (ext.b_GL_EXT_draw_buffers) {
+    fn.glDrawBuffersARBFn = reinterpret_cast<glDrawBuffersARBProc>(
+        GetGLProcAddress("glDrawBuffersEXT"));
+    DCHECK(fn.glDrawBuffersARBFn);
   }
 
-  fn.glDrawElementsInstancedANGLEFn = 0;
   debug_fn.glDrawElementsInstancedANGLEFn = 0;
-  if (ext.b_GL_ARB_draw_instanced) {
-    fn.glDrawElementsInstancedANGLEFn =
-        reinterpret_cast<glDrawElementsInstancedANGLEProc>(
-            GetGLProcAddress("glDrawElementsInstancedARB"));
-  }
-  if (!fn.glDrawElementsInstancedANGLEFn && (ext.b_GL_ANGLE_instanced_arrays)) {
-    fn.glDrawElementsInstancedANGLEFn =
-        reinterpret_cast<glDrawElementsInstancedANGLEProc>(
-            GetGLProcAddress("glDrawElementsInstancedANGLE"));
-  }
-  if (!fn.glDrawElementsInstancedANGLEFn) {
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(3u, 1u)) {
     fn.glDrawElementsInstancedANGLEFn =
         reinterpret_cast<glDrawElementsInstancedANGLEProc>(
             GetGLProcAddress("glDrawElementsInstanced"));
+    DCHECK(fn.glDrawElementsInstancedANGLEFn);
+  } else if (ext.b_GL_ARB_draw_instanced) {
+    fn.glDrawElementsInstancedANGLEFn =
+        reinterpret_cast<glDrawElementsInstancedANGLEProc>(
+            GetGLProcAddress("glDrawElementsInstancedARB"));
+    DCHECK(fn.glDrawElementsInstancedANGLEFn);
+  } else if (ext.b_GL_ANGLE_instanced_arrays) {
+    fn.glDrawElementsInstancedANGLEFn =
+        reinterpret_cast<glDrawElementsInstancedANGLEProc>(
+            GetGLProcAddress("glDrawElementsInstancedANGLE"));
+    DCHECK(fn.glDrawElementsInstancedANGLEFn);
   }
 
-  fn.glEndQueryARBFn = 0;
+  debug_fn.glDrawRangeElementsFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glDrawRangeElementsFn = reinterpret_cast<glDrawRangeElementsProc>(
+        GetGLProcAddress("glDrawRangeElements"));
+    DCHECK(fn.glDrawRangeElementsFn);
+  }
+
+  debug_fn.glEGLImageTargetRenderbufferStorageOESFn = 0;
+  if (ext.b_GL_OES_EGL_image) {
+    fn.glEGLImageTargetRenderbufferStorageOESFn =
+        reinterpret_cast<glEGLImageTargetRenderbufferStorageOESProc>(
+            GetGLProcAddress("glEGLImageTargetRenderbufferStorageOES"));
+    DCHECK(fn.glEGLImageTargetRenderbufferStorageOESFn);
+  }
+
+  debug_fn.glEGLImageTargetTexture2DOESFn = 0;
+  if (ext.b_GL_OES_EGL_image) {
+    fn.glEGLImageTargetTexture2DOESFn =
+        reinterpret_cast<glEGLImageTargetTexture2DOESProc>(
+            GetGLProcAddress("glEGLImageTargetTexture2DOES"));
+    DCHECK(fn.glEGLImageTargetTexture2DOESFn);
+  }
+
+  debug_fn.glEndQueryFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glEndQueryFn =
+        reinterpret_cast<glEndQueryProc>(GetGLProcAddress("glEndQuery"));
+    DCHECK(fn.glEndQueryFn);
+  }
+
   debug_fn.glEndQueryARBFn = 0;
   if (ext.b_GL_ARB_occlusion_query) {
     fn.glEndQueryARBFn =
         reinterpret_cast<glEndQueryARBProc>(GetGLProcAddress("glEndQueryARB"));
-  }
-  if (!fn.glEndQueryARBFn) {
+    DCHECK(fn.glEndQueryARBFn);
+  } else if (ext.b_GL_EXT_disjoint_timer_query ||
+             ext.b_GL_EXT_occlusion_query_boolean) {
     fn.glEndQueryARBFn =
         reinterpret_cast<glEndQueryARBProc>(GetGLProcAddress("glEndQueryEXT"));
+    DCHECK(fn.glEndQueryARBFn);
   }
 
-  fn.glFramebufferRenderbufferEXTFn = 0;
-  debug_fn.glFramebufferRenderbufferEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glFramebufferRenderbufferEXTFn =
-        reinterpret_cast<glFramebufferRenderbufferEXTProc>(
-            GetGLProcAddress("glFramebufferRenderbufferEXT"));
+  debug_fn.glEndTransformFeedbackFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glEndTransformFeedbackFn = reinterpret_cast<glEndTransformFeedbackProc>(
+        GetGLProcAddress("glEndTransformFeedback"));
+    DCHECK(fn.glEndTransformFeedbackFn);
   }
-  if (!fn.glFramebufferRenderbufferEXTFn) {
+
+  debug_fn.glFenceSyncFn = 0;
+  if (ver->IsAtLeastGL(3u, 2u) || ver->IsAtLeastGLES(3u, 0u) ||
+      ext.b_GL_ARB_sync) {
+    fn.glFenceSyncFn =
+        reinterpret_cast<glFenceSyncProc>(GetGLProcAddress("glFenceSync"));
+    DCHECK(fn.glFenceSyncFn);
+  }
+
+  debug_fn.glFinishFenceAPPLEFn = 0;
+  if (ext.b_GL_APPLE_fence) {
+    fn.glFinishFenceAPPLEFn = reinterpret_cast<glFinishFenceAPPLEProc>(
+        GetGLProcAddress("glFinishFenceAPPLE"));
+    DCHECK(fn.glFinishFenceAPPLEFn);
+  }
+
+  debug_fn.glFinishFenceNVFn = 0;
+  if (ext.b_GL_NV_fence) {
+    fn.glFinishFenceNVFn = reinterpret_cast<glFinishFenceNVProc>(
+        GetGLProcAddress("glFinishFenceNV"));
+    DCHECK(fn.glFinishFenceNVFn);
+  }
+
+  debug_fn.glFlushMappedBufferRangeFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glFlushMappedBufferRangeFn =
+        reinterpret_cast<glFlushMappedBufferRangeProc>(
+            GetGLProcAddress("glFlushMappedBufferRange"));
+    DCHECK(fn.glFlushMappedBufferRangeFn);
+  }
+
+  debug_fn.glFramebufferRenderbufferEXTFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glFramebufferRenderbufferEXTFn =
         reinterpret_cast<glFramebufferRenderbufferEXTProc>(
             GetGLProcAddress("glFramebufferRenderbuffer"));
+    DCHECK(fn.glFramebufferRenderbufferEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glFramebufferRenderbufferEXTFn =
+        reinterpret_cast<glFramebufferRenderbufferEXTProc>(
+            GetGLProcAddress("glFramebufferRenderbufferEXT"));
+    DCHECK(fn.glFramebufferRenderbufferEXTFn);
   }
 
-  fn.glFramebufferTexture2DEXTFn = 0;
   debug_fn.glFramebufferTexture2DEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glFramebufferTexture2DEXTFn =
-        reinterpret_cast<glFramebufferTexture2DEXTProc>(
-            GetGLProcAddress("glFramebufferTexture2DEXT"));
-  }
-  if (!fn.glFramebufferTexture2DEXTFn) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glFramebufferTexture2DEXTFn =
         reinterpret_cast<glFramebufferTexture2DEXTProc>(
             GetGLProcAddress("glFramebufferTexture2D"));
+    DCHECK(fn.glFramebufferTexture2DEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glFramebufferTexture2DEXTFn =
+        reinterpret_cast<glFramebufferTexture2DEXTProc>(
+            GetGLProcAddress("glFramebufferTexture2DEXT"));
+    DCHECK(fn.glFramebufferTexture2DEXTFn);
   }
 
-  fn.glGenBuffersARBFn = 0;
-  debug_fn.glGenBuffersARBFn = 0;
-  if (ext.b_GL_ARB_vertex_buffer_object) {
-    fn.glGenBuffersARBFn = reinterpret_cast<glGenBuffersARBProc>(
-        GetGLProcAddress("glGenBuffersARB"));
-  }
-  if (!fn.glGenBuffersARBFn) {
-    fn.glGenBuffersARBFn =
-        reinterpret_cast<glGenBuffersARBProc>(GetGLProcAddress("glGenBuffers"));
+  debug_fn.glFramebufferTexture2DMultisampleEXTFn = 0;
+  if (ext.b_GL_EXT_multisampled_render_to_texture) {
+    fn.glFramebufferTexture2DMultisampleEXTFn =
+        reinterpret_cast<glFramebufferTexture2DMultisampleEXTProc>(
+            GetGLProcAddress("glFramebufferTexture2DMultisampleEXT"));
+    DCHECK(fn.glFramebufferTexture2DMultisampleEXTFn);
   }
 
-  fn.glGenerateMipmapEXTFn = 0;
+  debug_fn.glFramebufferTexture2DMultisampleIMGFn = 0;
+  if (ext.b_GL_IMG_multisampled_render_to_texture) {
+    fn.glFramebufferTexture2DMultisampleIMGFn =
+        reinterpret_cast<glFramebufferTexture2DMultisampleIMGProc>(
+            GetGLProcAddress("glFramebufferTexture2DMultisampleIMG"));
+    DCHECK(fn.glFramebufferTexture2DMultisampleIMGFn);
+  }
+
+  debug_fn.glFramebufferTextureLayerFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glFramebufferTextureLayerFn =
+        reinterpret_cast<glFramebufferTextureLayerProc>(
+            GetGLProcAddress("glFramebufferTextureLayer"));
+    DCHECK(fn.glFramebufferTextureLayerFn);
+  }
+
   debug_fn.glGenerateMipmapEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glGenerateMipmapEXTFn = reinterpret_cast<glGenerateMipmapEXTProc>(
-        GetGLProcAddress("glGenerateMipmapEXT"));
-  }
-  if (!fn.glGenerateMipmapEXTFn) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glGenerateMipmapEXTFn = reinterpret_cast<glGenerateMipmapEXTProc>(
         GetGLProcAddress("glGenerateMipmap"));
+    DCHECK(fn.glGenerateMipmapEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glGenerateMipmapEXTFn = reinterpret_cast<glGenerateMipmapEXTProc>(
+        GetGLProcAddress("glGenerateMipmapEXT"));
+    DCHECK(fn.glGenerateMipmapEXTFn);
   }
 
-  fn.glGenFramebuffersEXTFn = 0;
-  debug_fn.glGenFramebuffersEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glGenFramebuffersEXTFn = reinterpret_cast<glGenFramebuffersEXTProc>(
-        GetGLProcAddress("glGenFramebuffersEXT"));
+  debug_fn.glGenFencesAPPLEFn = 0;
+  if (ext.b_GL_APPLE_fence) {
+    fn.glGenFencesAPPLEFn = reinterpret_cast<glGenFencesAPPLEProc>(
+        GetGLProcAddress("glGenFencesAPPLE"));
+    DCHECK(fn.glGenFencesAPPLEFn);
   }
-  if (!fn.glGenFramebuffersEXTFn) {
+
+  debug_fn.glGenFencesNVFn = 0;
+  if (ext.b_GL_NV_fence) {
+    fn.glGenFencesNVFn =
+        reinterpret_cast<glGenFencesNVProc>(GetGLProcAddress("glGenFencesNV"));
+    DCHECK(fn.glGenFencesNVFn);
+  }
+
+  debug_fn.glGenFramebuffersEXTFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glGenFramebuffersEXTFn = reinterpret_cast<glGenFramebuffersEXTProc>(
         GetGLProcAddress("glGenFramebuffers"));
+    DCHECK(fn.glGenFramebuffersEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glGenFramebuffersEXTFn = reinterpret_cast<glGenFramebuffersEXTProc>(
+        GetGLProcAddress("glGenFramebuffersEXT"));
+    DCHECK(fn.glGenFramebuffersEXTFn);
   }
 
-  fn.glGenQueriesARBFn = 0;
+  debug_fn.glGenQueriesFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glGenQueriesFn =
+        reinterpret_cast<glGenQueriesProc>(GetGLProcAddress("glGenQueries"));
+    DCHECK(fn.glGenQueriesFn);
+  }
+
   debug_fn.glGenQueriesARBFn = 0;
   if (ext.b_GL_ARB_occlusion_query) {
     fn.glGenQueriesARBFn = reinterpret_cast<glGenQueriesARBProc>(
         GetGLProcAddress("glGenQueriesARB"));
-  }
-  if (!fn.glGenQueriesARBFn) {
+    DCHECK(fn.glGenQueriesARBFn);
+  } else if (ext.b_GL_EXT_disjoint_timer_query ||
+             ext.b_GL_EXT_occlusion_query_boolean) {
     fn.glGenQueriesARBFn = reinterpret_cast<glGenQueriesARBProc>(
         GetGLProcAddress("glGenQueriesEXT"));
+    DCHECK(fn.glGenQueriesARBFn);
   }
 
-  fn.glGenRenderbuffersEXTFn = 0;
   debug_fn.glGenRenderbuffersEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glGenRenderbuffersEXTFn = reinterpret_cast<glGenRenderbuffersEXTProc>(
-        GetGLProcAddress("glGenRenderbuffersEXT"));
-  }
-  if (!fn.glGenRenderbuffersEXTFn) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glGenRenderbuffersEXTFn = reinterpret_cast<glGenRenderbuffersEXTProc>(
         GetGLProcAddress("glGenRenderbuffers"));
+    DCHECK(fn.glGenRenderbuffersEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glGenRenderbuffersEXTFn = reinterpret_cast<glGenRenderbuffersEXTProc>(
+        GetGLProcAddress("glGenRenderbuffersEXT"));
+    DCHECK(fn.glGenRenderbuffersEXTFn);
   }
 
-  fn.glGenVertexArraysOESFn = 0;
+  debug_fn.glGenSamplersFn = 0;
+  if (ver->IsAtLeastGL(3u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glGenSamplersFn =
+        reinterpret_cast<glGenSamplersProc>(GetGLProcAddress("glGenSamplers"));
+    DCHECK(fn.glGenSamplersFn);
+  }
+
+  debug_fn.glGenTransformFeedbacksFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(4u, 0u)) {
+    fn.glGenTransformFeedbacksFn =
+        reinterpret_cast<glGenTransformFeedbacksProc>(
+            GetGLProcAddress("glGenTransformFeedbacks"));
+    DCHECK(fn.glGenTransformFeedbacksFn);
+  }
+
   debug_fn.glGenVertexArraysOESFn = 0;
-  if ((ver->is_gl3 || ver->is_gl4 || ver->is_es3) ||
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u) ||
       ext.b_GL_ARB_vertex_array_object) {
     fn.glGenVertexArraysOESFn = reinterpret_cast<glGenVertexArraysOESProc>(
         GetGLProcAddress("glGenVertexArrays"));
-  }
-  if (!fn.glGenVertexArraysOESFn && (ext.b_GL_OES_vertex_array_object)) {
+    DCHECK(fn.glGenVertexArraysOESFn);
+  } else if (ext.b_GL_OES_vertex_array_object) {
     fn.glGenVertexArraysOESFn = reinterpret_cast<glGenVertexArraysOESProc>(
         GetGLProcAddress("glGenVertexArraysOES"));
-  }
-  if (!fn.glGenVertexArraysOESFn) {
+    DCHECK(fn.glGenVertexArraysOESFn);
+  } else if (ext.b_GL_APPLE_vertex_array_object) {
     fn.glGenVertexArraysOESFn = reinterpret_cast<glGenVertexArraysOESProc>(
         GetGLProcAddress("glGenVertexArraysAPPLE"));
+    DCHECK(fn.glGenVertexArraysOESFn);
   }
 
-  fn.glGetFramebufferAttachmentParameterivEXTFn = 0;
-  debug_fn.glGetFramebufferAttachmentParameterivEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glGetFramebufferAttachmentParameterivEXTFn =
-        reinterpret_cast<glGetFramebufferAttachmentParameterivEXTProc>(
-            GetGLProcAddress("glGetFramebufferAttachmentParameterivEXT"));
+  debug_fn.glGetActiveUniformBlockivFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(3u, 1u)) {
+    fn.glGetActiveUniformBlockivFn =
+        reinterpret_cast<glGetActiveUniformBlockivProc>(
+            GetGLProcAddress("glGetActiveUniformBlockiv"));
+    DCHECK(fn.glGetActiveUniformBlockivFn);
   }
-  if (!fn.glGetFramebufferAttachmentParameterivEXTFn) {
+
+  debug_fn.glGetActiveUniformBlockNameFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(3u, 1u)) {
+    fn.glGetActiveUniformBlockNameFn =
+        reinterpret_cast<glGetActiveUniformBlockNameProc>(
+            GetGLProcAddress("glGetActiveUniformBlockName"));
+    DCHECK(fn.glGetActiveUniformBlockNameFn);
+  }
+
+  debug_fn.glGetActiveUniformsivFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(3u, 1u)) {
+    fn.glGetActiveUniformsivFn = reinterpret_cast<glGetActiveUniformsivProc>(
+        GetGLProcAddress("glGetActiveUniformsiv"));
+    DCHECK(fn.glGetActiveUniformsivFn);
+  }
+
+  debug_fn.glGetFenceivNVFn = 0;
+  if (ext.b_GL_NV_fence) {
+    fn.glGetFenceivNVFn = reinterpret_cast<glGetFenceivNVProc>(
+        GetGLProcAddress("glGetFenceivNV"));
+    DCHECK(fn.glGetFenceivNVFn);
+  }
+
+  debug_fn.glGetFragDataLocationFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glGetFragDataLocationFn = reinterpret_cast<glGetFragDataLocationProc>(
+        GetGLProcAddress("glGetFragDataLocation"));
+    DCHECK(fn.glGetFragDataLocationFn);
+  }
+
+  debug_fn.glGetFramebufferAttachmentParameterivEXTFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glGetFramebufferAttachmentParameterivEXTFn =
         reinterpret_cast<glGetFramebufferAttachmentParameterivEXTProc>(
             GetGLProcAddress("glGetFramebufferAttachmentParameteriv"));
+    DCHECK(fn.glGetFramebufferAttachmentParameterivEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glGetFramebufferAttachmentParameterivEXTFn =
+        reinterpret_cast<glGetFramebufferAttachmentParameterivEXTProc>(
+            GetGLProcAddress("glGetFramebufferAttachmentParameterivEXT"));
+    DCHECK(fn.glGetFramebufferAttachmentParameterivEXTFn);
   }
 
-  fn.glGetGraphicsResetStatusARBFn = 0;
   debug_fn.glGetGraphicsResetStatusARBFn = 0;
-  if (ext.b_GL_ARB_robustness) {
-    fn.glGetGraphicsResetStatusARBFn =
-        reinterpret_cast<glGetGraphicsResetStatusARBProc>(
-            GetGLProcAddress("glGetGraphicsResetStatusARB"));
-  }
-  if (!fn.glGetGraphicsResetStatusARBFn && (ext.b_GL_KHR_robustness)) {
-    fn.glGetGraphicsResetStatusARBFn =
-        reinterpret_cast<glGetGraphicsResetStatusARBProc>(
-            GetGLProcAddress("glGetGraphicsResetStatusKHR"));
-  }
-  if (!fn.glGetGraphicsResetStatusARBFn && (ext.b_GL_EXT_robustness)) {
-    fn.glGetGraphicsResetStatusARBFn =
-        reinterpret_cast<glGetGraphicsResetStatusARBProc>(
-            GetGLProcAddress("glGetGraphicsResetStatusEXT"));
-  }
-  if (!fn.glGetGraphicsResetStatusARBFn) {
+  if (ver->IsAtLeastGL(4u, 5u)) {
     fn.glGetGraphicsResetStatusARBFn =
         reinterpret_cast<glGetGraphicsResetStatusARBProc>(
             GetGLProcAddress("glGetGraphicsResetStatus"));
+    DCHECK(fn.glGetGraphicsResetStatusARBFn);
+  } else if (ext.b_GL_ARB_robustness) {
+    fn.glGetGraphicsResetStatusARBFn =
+        reinterpret_cast<glGetGraphicsResetStatusARBProc>(
+            GetGLProcAddress("glGetGraphicsResetStatusARB"));
+    DCHECK(fn.glGetGraphicsResetStatusARBFn);
+  } else if (ext.b_GL_KHR_robustness) {
+    fn.glGetGraphicsResetStatusARBFn =
+        reinterpret_cast<glGetGraphicsResetStatusARBProc>(
+            GetGLProcAddress("glGetGraphicsResetStatusKHR"));
+    DCHECK(fn.glGetGraphicsResetStatusARBFn);
+  } else if (ext.b_GL_EXT_robustness) {
+    fn.glGetGraphicsResetStatusARBFn =
+        reinterpret_cast<glGetGraphicsResetStatusARBProc>(
+            GetGLProcAddress("glGetGraphicsResetStatusEXT"));
+    DCHECK(fn.glGetGraphicsResetStatusARBFn);
   }
 
-  fn.glGetProgramBinaryFn = 0;
-  debug_fn.glGetProgramBinaryFn = 0;
-  if (ext.b_GL_OES_get_program_binary) {
-    fn.glGetProgramBinaryFn = reinterpret_cast<glGetProgramBinaryProc>(
-        GetGLProcAddress("glGetProgramBinaryOES"));
+  debug_fn.glGetInteger64i_vFn = 0;
+  if (ver->IsAtLeastGL(3u, 2u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glGetInteger64i_vFn = reinterpret_cast<glGetInteger64i_vProc>(
+        GetGLProcAddress("glGetInteger64i_v"));
+    DCHECK(fn.glGetInteger64i_vFn);
   }
-  if (!fn.glGetProgramBinaryFn) {
+
+  debug_fn.glGetInteger64vFn = 0;
+  if (ver->IsAtLeastGL(3u, 2u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glGetInteger64vFn = reinterpret_cast<glGetInteger64vProc>(
+        GetGLProcAddress("glGetInteger64v"));
+    DCHECK(fn.glGetInteger64vFn);
+  }
+
+  debug_fn.glGetIntegeri_vFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glGetIntegeri_vFn = reinterpret_cast<glGetIntegeri_vProc>(
+        GetGLProcAddress("glGetIntegeri_v"));
+    DCHECK(fn.glGetIntegeri_vFn);
+  }
+
+  debug_fn.glGetInternalformativFn = 0;
+  if (ver->IsAtLeastGL(4u, 2u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glGetInternalformativFn = reinterpret_cast<glGetInternalformativProc>(
+        GetGLProcAddress("glGetInternalformativ"));
+    DCHECK(fn.glGetInternalformativFn);
+  }
+
+  debug_fn.glGetProgramBinaryFn = 0;
+  if (ver->IsAtLeastGL(4u, 1u) || ver->IsAtLeastGLES(3u, 0u) ||
+      ext.b_GL_ARB_get_program_binary) {
     fn.glGetProgramBinaryFn = reinterpret_cast<glGetProgramBinaryProc>(
         GetGLProcAddress("glGetProgramBinary"));
+    DCHECK(fn.glGetProgramBinaryFn);
+  } else if (ext.b_GL_OES_get_program_binary) {
+    fn.glGetProgramBinaryFn = reinterpret_cast<glGetProgramBinaryProc>(
+        GetGLProcAddress("glGetProgramBinaryOES"));
+    DCHECK(fn.glGetProgramBinaryFn);
   }
 
-  fn.glGetQueryivARBFn = 0;
+  debug_fn.glGetQueryivFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glGetQueryivFn =
+        reinterpret_cast<glGetQueryivProc>(GetGLProcAddress("glGetQueryiv"));
+    DCHECK(fn.glGetQueryivFn);
+  }
+
   debug_fn.glGetQueryivARBFn = 0;
   if (ext.b_GL_ARB_occlusion_query) {
     fn.glGetQueryivARBFn = reinterpret_cast<glGetQueryivARBProc>(
         GetGLProcAddress("glGetQueryivARB"));
-  }
-  if (!fn.glGetQueryivARBFn) {
+    DCHECK(fn.glGetQueryivARBFn);
+  } else if (ext.b_GL_EXT_disjoint_timer_query ||
+             ext.b_GL_EXT_occlusion_query_boolean) {
     fn.glGetQueryivARBFn = reinterpret_cast<glGetQueryivARBProc>(
         GetGLProcAddress("glGetQueryivEXT"));
+    DCHECK(fn.glGetQueryivARBFn);
   }
 
-  fn.glGetQueryObjectivARBFn = 0;
+  debug_fn.glGetQueryObjecti64vFn = 0;
+  if (ver->IsAtLeastGL(3u, 3u) || ext.b_GL_ARB_timer_query) {
+    fn.glGetQueryObjecti64vFn = reinterpret_cast<glGetQueryObjecti64vProc>(
+        GetGLProcAddress("glGetQueryObjecti64v"));
+    DCHECK(fn.glGetQueryObjecti64vFn);
+  } else if (ext.b_GL_EXT_timer_query || ext.b_GL_EXT_disjoint_timer_query) {
+    fn.glGetQueryObjecti64vFn = reinterpret_cast<glGetQueryObjecti64vProc>(
+        GetGLProcAddress("glGetQueryObjecti64vEXT"));
+    DCHECK(fn.glGetQueryObjecti64vFn);
+  }
+
+  debug_fn.glGetQueryObjectivFn = 0;
+  if (!ver->is_es) {
+    fn.glGetQueryObjectivFn = reinterpret_cast<glGetQueryObjectivProc>(
+        GetGLProcAddress("glGetQueryObjectiv"));
+    DCHECK(fn.glGetQueryObjectivFn);
+  }
+
   debug_fn.glGetQueryObjectivARBFn = 0;
   if (ext.b_GL_ARB_occlusion_query) {
     fn.glGetQueryObjectivARBFn = reinterpret_cast<glGetQueryObjectivARBProc>(
         GetGLProcAddress("glGetQueryObjectivARB"));
-  }
-  if (!fn.glGetQueryObjectivARBFn) {
+    DCHECK(fn.glGetQueryObjectivARBFn);
+  } else if (ext.b_GL_EXT_disjoint_timer_query) {
     fn.glGetQueryObjectivARBFn = reinterpret_cast<glGetQueryObjectivARBProc>(
         GetGLProcAddress("glGetQueryObjectivEXT"));
+    DCHECK(fn.glGetQueryObjectivARBFn);
   }
 
-  fn.glGetQueryObjectui64vFn = 0;
   debug_fn.glGetQueryObjectui64vFn = 0;
-  if (ext.b_GL_ARB_timer_query) {
+  if (ver->IsAtLeastGL(3u, 3u) || ext.b_GL_ARB_timer_query) {
     fn.glGetQueryObjectui64vFn = reinterpret_cast<glGetQueryObjectui64vProc>(
         GetGLProcAddress("glGetQueryObjectui64v"));
-  }
-  if (!fn.glGetQueryObjectui64vFn) {
+    DCHECK(fn.glGetQueryObjectui64vFn);
+  } else if (ext.b_GL_EXT_timer_query || ext.b_GL_EXT_disjoint_timer_query) {
     fn.glGetQueryObjectui64vFn = reinterpret_cast<glGetQueryObjectui64vProc>(
         GetGLProcAddress("glGetQueryObjectui64vEXT"));
+    DCHECK(fn.glGetQueryObjectui64vFn);
   }
 
-  fn.glGetQueryObjectuivARBFn = 0;
+  debug_fn.glGetQueryObjectuivFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glGetQueryObjectuivFn = reinterpret_cast<glGetQueryObjectuivProc>(
+        GetGLProcAddress("glGetQueryObjectuiv"));
+    DCHECK(fn.glGetQueryObjectuivFn);
+  }
+
   debug_fn.glGetQueryObjectuivARBFn = 0;
   if (ext.b_GL_ARB_occlusion_query) {
     fn.glGetQueryObjectuivARBFn = reinterpret_cast<glGetQueryObjectuivARBProc>(
         GetGLProcAddress("glGetQueryObjectuivARB"));
-  }
-  if (!fn.glGetQueryObjectuivARBFn) {
+    DCHECK(fn.glGetQueryObjectuivARBFn);
+  } else if (ext.b_GL_EXT_disjoint_timer_query ||
+             ext.b_GL_EXT_occlusion_query_boolean) {
     fn.glGetQueryObjectuivARBFn = reinterpret_cast<glGetQueryObjectuivARBProc>(
         GetGLProcAddress("glGetQueryObjectuivEXT"));
+    DCHECK(fn.glGetQueryObjectuivARBFn);
   }
 
-  fn.glGetRenderbufferParameterivEXTFn = 0;
   debug_fn.glGetRenderbufferParameterivEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glGetRenderbufferParameterivEXTFn =
-        reinterpret_cast<glGetRenderbufferParameterivEXTProc>(
-            GetGLProcAddress("glGetRenderbufferParameterivEXT"));
-  }
-  if (!fn.glGetRenderbufferParameterivEXTFn) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glGetRenderbufferParameterivEXTFn =
         reinterpret_cast<glGetRenderbufferParameterivEXTProc>(
             GetGLProcAddress("glGetRenderbufferParameteriv"));
+    DCHECK(fn.glGetRenderbufferParameterivEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glGetRenderbufferParameterivEXTFn =
+        reinterpret_cast<glGetRenderbufferParameterivEXTProc>(
+            GetGLProcAddress("glGetRenderbufferParameterivEXT"));
+    DCHECK(fn.glGetRenderbufferParameterivEXTFn);
   }
 
-  fn.glIsFramebufferEXTFn = 0;
-  debug_fn.glIsFramebufferEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glIsFramebufferEXTFn = reinterpret_cast<glIsFramebufferEXTProc>(
-        GetGLProcAddress("glIsFramebufferEXT"));
+  debug_fn.glGetSamplerParameterfvFn = 0;
+  if (ver->IsAtLeastGL(3u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glGetSamplerParameterfvFn =
+        reinterpret_cast<glGetSamplerParameterfvProc>(
+            GetGLProcAddress("glGetSamplerParameterfv"));
+    DCHECK(fn.glGetSamplerParameterfvFn);
   }
-  if (!fn.glIsFramebufferEXTFn) {
+
+  debug_fn.glGetSamplerParameterivFn = 0;
+  if (ver->IsAtLeastGL(3u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glGetSamplerParameterivFn =
+        reinterpret_cast<glGetSamplerParameterivProc>(
+            GetGLProcAddress("glGetSamplerParameteriv"));
+    DCHECK(fn.glGetSamplerParameterivFn);
+  }
+
+  debug_fn.glGetShaderPrecisionFormatFn = 0;
+  if (ver->IsAtLeastGL(4u, 1u) || ver->is_es) {
+    fn.glGetShaderPrecisionFormatFn =
+        reinterpret_cast<glGetShaderPrecisionFormatProc>(
+            GetGLProcAddress("glGetShaderPrecisionFormat"));
+    DCHECK(fn.glGetShaderPrecisionFormatFn);
+  }
+
+  debug_fn.glGetSyncivFn = 0;
+  if (ver->IsAtLeastGL(3u, 2u) || ver->IsAtLeastGLES(3u, 0u) ||
+      ext.b_GL_ARB_sync) {
+    fn.glGetSyncivFn =
+        reinterpret_cast<glGetSyncivProc>(GetGLProcAddress("glGetSynciv"));
+    DCHECK(fn.glGetSyncivFn);
+  }
+
+  debug_fn.glGetTexLevelParameterfvFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 1u)) {
+    fn.glGetTexLevelParameterfvFn =
+        reinterpret_cast<glGetTexLevelParameterfvProc>(
+            GetGLProcAddress("glGetTexLevelParameterfv"));
+    DCHECK(fn.glGetTexLevelParameterfvFn);
+  }
+
+  debug_fn.glGetTexLevelParameterivFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 1u)) {
+    fn.glGetTexLevelParameterivFn =
+        reinterpret_cast<glGetTexLevelParameterivProc>(
+            GetGLProcAddress("glGetTexLevelParameteriv"));
+    DCHECK(fn.glGetTexLevelParameterivFn);
+  }
+
+  debug_fn.glGetTransformFeedbackVaryingFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glGetTransformFeedbackVaryingFn =
+        reinterpret_cast<glGetTransformFeedbackVaryingProc>(
+            GetGLProcAddress("glGetTransformFeedbackVarying"));
+    DCHECK(fn.glGetTransformFeedbackVaryingFn);
+  }
+
+  debug_fn.glGetTranslatedShaderSourceANGLEFn = 0;
+  if (ext.b_GL_ANGLE_translated_shader_source) {
+    fn.glGetTranslatedShaderSourceANGLEFn =
+        reinterpret_cast<glGetTranslatedShaderSourceANGLEProc>(
+            GetGLProcAddress("glGetTranslatedShaderSourceANGLE"));
+    DCHECK(fn.glGetTranslatedShaderSourceANGLEFn);
+  }
+
+  debug_fn.glGetUniformBlockIndexFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(3u, 1u)) {
+    fn.glGetUniformBlockIndexFn = reinterpret_cast<glGetUniformBlockIndexProc>(
+        GetGLProcAddress("glGetUniformBlockIndex"));
+    DCHECK(fn.glGetUniformBlockIndexFn);
+  }
+
+  debug_fn.glGetUniformIndicesFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(3u, 1u)) {
+    fn.glGetUniformIndicesFn = reinterpret_cast<glGetUniformIndicesProc>(
+        GetGLProcAddress("glGetUniformIndices"));
+    DCHECK(fn.glGetUniformIndicesFn);
+  }
+
+  debug_fn.glInsertEventMarkerEXTFn = 0;
+  if (ext.b_GL_EXT_debug_marker) {
+    fn.glInsertEventMarkerEXTFn = reinterpret_cast<glInsertEventMarkerEXTProc>(
+        GetGLProcAddress("glInsertEventMarkerEXT"));
+    DCHECK(fn.glInsertEventMarkerEXTFn);
+  }
+
+  debug_fn.glInvalidateFramebufferFn = 0;
+  if (ver->IsAtLeastGL(4u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glInvalidateFramebufferFn =
+        reinterpret_cast<glInvalidateFramebufferProc>(
+            GetGLProcAddress("glInvalidateFramebuffer"));
+    DCHECK(fn.glInvalidateFramebufferFn);
+  }
+
+  debug_fn.glInvalidateSubFramebufferFn = 0;
+  if (ver->IsAtLeastGL(4u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glInvalidateSubFramebufferFn =
+        reinterpret_cast<glInvalidateSubFramebufferProc>(
+            GetGLProcAddress("glInvalidateSubFramebuffer"));
+    DCHECK(fn.glInvalidateSubFramebufferFn);
+  }
+
+  debug_fn.glIsFenceAPPLEFn = 0;
+  if (ext.b_GL_APPLE_fence) {
+    fn.glIsFenceAPPLEFn = reinterpret_cast<glIsFenceAPPLEProc>(
+        GetGLProcAddress("glIsFenceAPPLE"));
+    DCHECK(fn.glIsFenceAPPLEFn);
+  }
+
+  debug_fn.glIsFenceNVFn = 0;
+  if (ext.b_GL_NV_fence) {
+    fn.glIsFenceNVFn =
+        reinterpret_cast<glIsFenceNVProc>(GetGLProcAddress("glIsFenceNV"));
+    DCHECK(fn.glIsFenceNVFn);
+  }
+
+  debug_fn.glIsFramebufferEXTFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glIsFramebufferEXTFn = reinterpret_cast<glIsFramebufferEXTProc>(
         GetGLProcAddress("glIsFramebuffer"));
+    DCHECK(fn.glIsFramebufferEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glIsFramebufferEXTFn = reinterpret_cast<glIsFramebufferEXTProc>(
+        GetGLProcAddress("glIsFramebufferEXT"));
+    DCHECK(fn.glIsFramebufferEXTFn);
   }
 
-  fn.glIsQueryARBFn = 0;
+  debug_fn.glIsQueryFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glIsQueryFn =
+        reinterpret_cast<glIsQueryProc>(GetGLProcAddress("glIsQuery"));
+    DCHECK(fn.glIsQueryFn);
+  }
+
   debug_fn.glIsQueryARBFn = 0;
   if (ext.b_GL_ARB_occlusion_query) {
     fn.glIsQueryARBFn =
         reinterpret_cast<glIsQueryARBProc>(GetGLProcAddress("glIsQueryARB"));
-  }
-  if (!fn.glIsQueryARBFn) {
+    DCHECK(fn.glIsQueryARBFn);
+  } else if (ext.b_GL_EXT_disjoint_timer_query ||
+             ext.b_GL_EXT_occlusion_query_boolean) {
     fn.glIsQueryARBFn =
         reinterpret_cast<glIsQueryARBProc>(GetGLProcAddress("glIsQueryEXT"));
+    DCHECK(fn.glIsQueryARBFn);
   }
 
-  fn.glIsRenderbufferEXTFn = 0;
   debug_fn.glIsRenderbufferEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glIsRenderbufferEXTFn = reinterpret_cast<glIsRenderbufferEXTProc>(
-        GetGLProcAddress("glIsRenderbufferEXT"));
-  }
-  if (!fn.glIsRenderbufferEXTFn) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glIsRenderbufferEXTFn = reinterpret_cast<glIsRenderbufferEXTProc>(
         GetGLProcAddress("glIsRenderbuffer"));
+    DCHECK(fn.glIsRenderbufferEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glIsRenderbufferEXTFn = reinterpret_cast<glIsRenderbufferEXTProc>(
+        GetGLProcAddress("glIsRenderbufferEXT"));
+    DCHECK(fn.glIsRenderbufferEXTFn);
   }
 
-  fn.glIsVertexArrayOESFn = 0;
+  debug_fn.glIsSamplerFn = 0;
+  if (ver->IsAtLeastGL(3u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glIsSamplerFn =
+        reinterpret_cast<glIsSamplerProc>(GetGLProcAddress("glIsSampler"));
+    DCHECK(fn.glIsSamplerFn);
+  }
+
+  debug_fn.glIsSyncFn = 0;
+  if (ver->IsAtLeastGL(3u, 2u) || ver->IsAtLeastGLES(3u, 0u) ||
+      ext.b_GL_ARB_sync) {
+    fn.glIsSyncFn =
+        reinterpret_cast<glIsSyncProc>(GetGLProcAddress("glIsSync"));
+    DCHECK(fn.glIsSyncFn);
+  }
+
+  debug_fn.glIsTransformFeedbackFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(4u, 0u)) {
+    fn.glIsTransformFeedbackFn = reinterpret_cast<glIsTransformFeedbackProc>(
+        GetGLProcAddress("glIsTransformFeedback"));
+    DCHECK(fn.glIsTransformFeedbackFn);
+  }
+
   debug_fn.glIsVertexArrayOESFn = 0;
-  if ((ver->is_gl3 || ver->is_gl4 || ver->is_es3) ||
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u) ||
       ext.b_GL_ARB_vertex_array_object) {
     fn.glIsVertexArrayOESFn = reinterpret_cast<glIsVertexArrayOESProc>(
         GetGLProcAddress("glIsVertexArray"));
-  }
-  if (!fn.glIsVertexArrayOESFn && (ext.b_GL_OES_vertex_array_object)) {
+    DCHECK(fn.glIsVertexArrayOESFn);
+  } else if (ext.b_GL_OES_vertex_array_object) {
     fn.glIsVertexArrayOESFn = reinterpret_cast<glIsVertexArrayOESProc>(
         GetGLProcAddress("glIsVertexArrayOES"));
-  }
-  if (!fn.glIsVertexArrayOESFn) {
+    DCHECK(fn.glIsVertexArrayOESFn);
+  } else if (ext.b_GL_APPLE_vertex_array_object) {
     fn.glIsVertexArrayOESFn = reinterpret_cast<glIsVertexArrayOESProc>(
         GetGLProcAddress("glIsVertexArrayAPPLE"));
+    DCHECK(fn.glIsVertexArrayOESFn);
   }
 
-  fn.glMapBufferFn = 0;
   debug_fn.glMapBufferFn = 0;
-  if (ext.b_GL_OES_mapbuffer) {
-    fn.glMapBufferFn =
-        reinterpret_cast<glMapBufferProc>(GetGLProcAddress("glMapBufferOES"));
-  }
-  if (!fn.glMapBufferFn) {
+  if (!ver->is_es) {
     fn.glMapBufferFn =
         reinterpret_cast<glMapBufferProc>(GetGLProcAddress("glMapBuffer"));
+    DCHECK(fn.glMapBufferFn);
+  } else if (ext.b_GL_OES_mapbuffer) {
+    fn.glMapBufferFn =
+        reinterpret_cast<glMapBufferProc>(GetGLProcAddress("glMapBufferOES"));
+    DCHECK(fn.glMapBufferFn);
   }
 
-  fn.glMapBufferRangeFn = 0;
   debug_fn.glMapBufferRangeFn = 0;
-  if ((ver->is_gl3 || ver->is_gl4 || ver->is_es3) ||
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u) ||
       ext.b_GL_ARB_map_buffer_range) {
     fn.glMapBufferRangeFn = reinterpret_cast<glMapBufferRangeProc>(
         GetGLProcAddress("glMapBufferRange"));
-  }
-  if (!fn.glMapBufferRangeFn) {
+    DCHECK(fn.glMapBufferRangeFn);
+  } else if (ext.b_GL_EXT_map_buffer_range) {
     fn.glMapBufferRangeFn = reinterpret_cast<glMapBufferRangeProc>(
         GetGLProcAddress("glMapBufferRangeEXT"));
+    DCHECK(fn.glMapBufferRangeFn);
   }
 
-  fn.glProgramBinaryFn = 0;
-  debug_fn.glProgramBinaryFn = 0;
-  if (ext.b_GL_OES_get_program_binary) {
-    fn.glProgramBinaryFn = reinterpret_cast<glProgramBinaryProc>(
-        GetGLProcAddress("glProgramBinaryOES"));
+  debug_fn.glMatrixLoadfEXTFn = 0;
+  if (ext.b_GL_EXT_direct_state_access || ext.b_GL_NV_path_rendering) {
+    fn.glMatrixLoadfEXTFn = reinterpret_cast<glMatrixLoadfEXTProc>(
+        GetGLProcAddress("glMatrixLoadfEXT"));
+    DCHECK(fn.glMatrixLoadfEXTFn);
   }
-  if (!fn.glProgramBinaryFn) {
+
+  debug_fn.glMatrixLoadIdentityEXTFn = 0;
+  if (ext.b_GL_EXT_direct_state_access || ext.b_GL_NV_path_rendering) {
+    fn.glMatrixLoadIdentityEXTFn =
+        reinterpret_cast<glMatrixLoadIdentityEXTProc>(
+            GetGLProcAddress("glMatrixLoadIdentityEXT"));
+    DCHECK(fn.glMatrixLoadIdentityEXTFn);
+  }
+
+  debug_fn.glPauseTransformFeedbackFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(4u, 0u)) {
+    fn.glPauseTransformFeedbackFn =
+        reinterpret_cast<glPauseTransformFeedbackProc>(
+            GetGLProcAddress("glPauseTransformFeedback"));
+    DCHECK(fn.glPauseTransformFeedbackFn);
+  }
+
+  debug_fn.glPointParameteriFn = 0;
+  if (!ver->is_es) {
+    fn.glPointParameteriFn = reinterpret_cast<glPointParameteriProc>(
+        GetGLProcAddress("glPointParameteri"));
+    DCHECK(fn.glPointParameteriFn);
+  }
+
+  debug_fn.glPopGroupMarkerEXTFn = 0;
+  if (ext.b_GL_EXT_debug_marker) {
+    fn.glPopGroupMarkerEXTFn = reinterpret_cast<glPopGroupMarkerEXTProc>(
+        GetGLProcAddress("glPopGroupMarkerEXT"));
+    DCHECK(fn.glPopGroupMarkerEXTFn);
+  }
+
+  debug_fn.glProgramBinaryFn = 0;
+  if (ver->IsAtLeastGL(4u, 1u) || ver->IsAtLeastGLES(3u, 0u) ||
+      ext.b_GL_ARB_get_program_binary) {
     fn.glProgramBinaryFn = reinterpret_cast<glProgramBinaryProc>(
         GetGLProcAddress("glProgramBinary"));
+    DCHECK(fn.glProgramBinaryFn);
+  } else if (ext.b_GL_OES_get_program_binary) {
+    fn.glProgramBinaryFn = reinterpret_cast<glProgramBinaryProc>(
+        GetGLProcAddress("glProgramBinaryOES"));
+    DCHECK(fn.glProgramBinaryFn);
   }
 
-  fn.glQueryCounterFn = 0;
+  debug_fn.glProgramParameteriFn = 0;
+  if (ver->IsAtLeastGL(4u, 1u) || ver->IsAtLeastGLES(3u, 0u) ||
+      ext.b_GL_ARB_get_program_binary) {
+    fn.glProgramParameteriFn = reinterpret_cast<glProgramParameteriProc>(
+        GetGLProcAddress("glProgramParameteri"));
+    DCHECK(fn.glProgramParameteriFn);
+  }
+
+  debug_fn.glPushGroupMarkerEXTFn = 0;
+  if (ext.b_GL_EXT_debug_marker) {
+    fn.glPushGroupMarkerEXTFn = reinterpret_cast<glPushGroupMarkerEXTProc>(
+        GetGLProcAddress("glPushGroupMarkerEXT"));
+    DCHECK(fn.glPushGroupMarkerEXTFn);
+  }
+
   debug_fn.glQueryCounterFn = 0;
-  if (ext.b_GL_ARB_timer_query) {
+  if (ver->IsAtLeastGL(3u, 3u) || ext.b_GL_ARB_timer_query) {
     fn.glQueryCounterFn = reinterpret_cast<glQueryCounterProc>(
         GetGLProcAddress("glQueryCounter"));
-  }
-  if (!fn.glQueryCounterFn) {
+    DCHECK(fn.glQueryCounterFn);
+  } else if (ext.b_GL_EXT_disjoint_timer_query) {
     fn.glQueryCounterFn = reinterpret_cast<glQueryCounterProc>(
         GetGLProcAddress("glQueryCounterEXT"));
+    DCHECK(fn.glQueryCounterFn);
   }
 
-  fn.glRenderbufferStorageEXTFn = 0;
-  debug_fn.glRenderbufferStorageEXTFn = 0;
-  if (ext.b_GL_EXT_framebuffer_object) {
-    fn.glRenderbufferStorageEXTFn =
-        reinterpret_cast<glRenderbufferStorageEXTProc>(
-            GetGLProcAddress("glRenderbufferStorageEXT"));
+  debug_fn.glReadBufferFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glReadBufferFn =
+        reinterpret_cast<glReadBufferProc>(GetGLProcAddress("glReadBuffer"));
+    DCHECK(fn.glReadBufferFn);
   }
-  if (!fn.glRenderbufferStorageEXTFn) {
+
+  debug_fn.glReleaseShaderCompilerFn = 0;
+  if (ver->IsAtLeastGL(4u, 1u) || ver->is_es) {
+    fn.glReleaseShaderCompilerFn =
+        reinterpret_cast<glReleaseShaderCompilerProc>(
+            GetGLProcAddress("glReleaseShaderCompiler"));
+    DCHECK(fn.glReleaseShaderCompilerFn);
+  }
+
+  debug_fn.glRenderbufferStorageEXTFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) {
     fn.glRenderbufferStorageEXTFn =
         reinterpret_cast<glRenderbufferStorageEXTProc>(
             GetGLProcAddress("glRenderbufferStorage"));
+    DCHECK(fn.glRenderbufferStorageEXTFn);
+  } else if (ext.b_GL_EXT_framebuffer_object) {
+    fn.glRenderbufferStorageEXTFn =
+        reinterpret_cast<glRenderbufferStorageEXTProc>(
+            GetGLProcAddress("glRenderbufferStorageEXT"));
+    DCHECK(fn.glRenderbufferStorageEXTFn);
   }
 
-  fn.glRenderbufferStorageMultisampleANGLEFn = 0;
+  debug_fn.glRenderbufferStorageMultisampleFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glRenderbufferStorageMultisampleFn =
+        reinterpret_cast<glRenderbufferStorageMultisampleProc>(
+            GetGLProcAddress("glRenderbufferStorageMultisample"));
+    DCHECK(fn.glRenderbufferStorageMultisampleFn);
+  }
+
   debug_fn.glRenderbufferStorageMultisampleANGLEFn = 0;
-  if (ext.b_GL_ANGLE_framebuffer_multisample) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glRenderbufferStorageMultisampleANGLEFn =
+        reinterpret_cast<glRenderbufferStorageMultisampleANGLEProc>(
+            GetGLProcAddress("glRenderbufferStorageMultisample"));
+    DCHECK(fn.glRenderbufferStorageMultisampleANGLEFn);
+  } else if (ext.b_GL_ANGLE_framebuffer_multisample) {
     fn.glRenderbufferStorageMultisampleANGLEFn =
         reinterpret_cast<glRenderbufferStorageMultisampleANGLEProc>(
             GetGLProcAddress("glRenderbufferStorageMultisampleANGLE"));
-  }
-  if (!fn.glRenderbufferStorageMultisampleANGLEFn) {
-    fn.glRenderbufferStorageMultisampleANGLEFn =
-        reinterpret_cast<glRenderbufferStorageMultisampleANGLEProc>(
-            GetGLProcAddress("glRenderbufferStorageMultisample"));
+    DCHECK(fn.glRenderbufferStorageMultisampleANGLEFn);
   }
 
-  fn.glRenderbufferStorageMultisampleEXTFn = 0;
   debug_fn.glRenderbufferStorageMultisampleEXTFn = 0;
-  if ((ext.b_GL_EXT_framebuffer_multisample ||
-       ext.b_GL_EXT_multisampled_render_to_texture)) {
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glRenderbufferStorageMultisampleEXTFn =
+        reinterpret_cast<glRenderbufferStorageMultisampleEXTProc>(
+            GetGLProcAddress("glRenderbufferStorageMultisample"));
+    DCHECK(fn.glRenderbufferStorageMultisampleEXTFn);
+  } else if (ext.b_GL_EXT_multisampled_render_to_texture ||
+             ext.b_GL_EXT_framebuffer_multisample) {
     fn.glRenderbufferStorageMultisampleEXTFn =
         reinterpret_cast<glRenderbufferStorageMultisampleEXTProc>(
             GetGLProcAddress("glRenderbufferStorageMultisampleEXT"));
-  }
-  if (!fn.glRenderbufferStorageMultisampleEXTFn) {
-    fn.glRenderbufferStorageMultisampleEXTFn =
-        reinterpret_cast<glRenderbufferStorageMultisampleEXTProc>(
-            GetGLProcAddress("glRenderbufferStorageMultisample"));
+    DCHECK(fn.glRenderbufferStorageMultisampleEXTFn);
   }
 
-  fn.glTexStorage2DEXTFn = 0;
+  debug_fn.glRenderbufferStorageMultisampleIMGFn = 0;
+  if (ext.b_GL_IMG_multisampled_render_to_texture) {
+    fn.glRenderbufferStorageMultisampleIMGFn =
+        reinterpret_cast<glRenderbufferStorageMultisampleIMGProc>(
+            GetGLProcAddress("glRenderbufferStorageMultisampleIMG"));
+    DCHECK(fn.glRenderbufferStorageMultisampleIMGFn);
+  }
+
+  debug_fn.glResumeTransformFeedbackFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(4u, 0u)) {
+    fn.glResumeTransformFeedbackFn =
+        reinterpret_cast<glResumeTransformFeedbackProc>(
+            GetGLProcAddress("glResumeTransformFeedback"));
+    DCHECK(fn.glResumeTransformFeedbackFn);
+  }
+
+  debug_fn.glSamplerParameterfFn = 0;
+  if (ver->IsAtLeastGL(3u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glSamplerParameterfFn = reinterpret_cast<glSamplerParameterfProc>(
+        GetGLProcAddress("glSamplerParameterf"));
+    DCHECK(fn.glSamplerParameterfFn);
+  }
+
+  debug_fn.glSamplerParameterfvFn = 0;
+  if (ver->IsAtLeastGL(3u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glSamplerParameterfvFn = reinterpret_cast<glSamplerParameterfvProc>(
+        GetGLProcAddress("glSamplerParameterfv"));
+    DCHECK(fn.glSamplerParameterfvFn);
+  }
+
+  debug_fn.glSamplerParameteriFn = 0;
+  if (ver->IsAtLeastGL(3u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glSamplerParameteriFn = reinterpret_cast<glSamplerParameteriProc>(
+        GetGLProcAddress("glSamplerParameteri"));
+    DCHECK(fn.glSamplerParameteriFn);
+  }
+
+  debug_fn.glSamplerParameterivFn = 0;
+  if (ver->IsAtLeastGL(3u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glSamplerParameterivFn = reinterpret_cast<glSamplerParameterivProc>(
+        GetGLProcAddress("glSamplerParameteriv"));
+    DCHECK(fn.glSamplerParameterivFn);
+  }
+
+  debug_fn.glSetFenceAPPLEFn = 0;
+  if (ext.b_GL_APPLE_fence) {
+    fn.glSetFenceAPPLEFn = reinterpret_cast<glSetFenceAPPLEProc>(
+        GetGLProcAddress("glSetFenceAPPLE"));
+    DCHECK(fn.glSetFenceAPPLEFn);
+  }
+
+  debug_fn.glSetFenceNVFn = 0;
+  if (ext.b_GL_NV_fence) {
+    fn.glSetFenceNVFn =
+        reinterpret_cast<glSetFenceNVProc>(GetGLProcAddress("glSetFenceNV"));
+    DCHECK(fn.glSetFenceNVFn);
+  }
+
+  debug_fn.glShaderBinaryFn = 0;
+  if (ver->IsAtLeastGL(4u, 1u) || ver->is_es) {
+    fn.glShaderBinaryFn = reinterpret_cast<glShaderBinaryProc>(
+        GetGLProcAddress("glShaderBinary"));
+    DCHECK(fn.glShaderBinaryFn);
+  }
+
+  debug_fn.glTestFenceAPPLEFn = 0;
+  if (ext.b_GL_APPLE_fence) {
+    fn.glTestFenceAPPLEFn = reinterpret_cast<glTestFenceAPPLEProc>(
+        GetGLProcAddress("glTestFenceAPPLE"));
+    DCHECK(fn.glTestFenceAPPLEFn);
+  }
+
+  debug_fn.glTestFenceNVFn = 0;
+  if (ext.b_GL_NV_fence) {
+    fn.glTestFenceNVFn =
+        reinterpret_cast<glTestFenceNVProc>(GetGLProcAddress("glTestFenceNV"));
+    DCHECK(fn.glTestFenceNVFn);
+  }
+
+  debug_fn.glTexImage3DFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glTexImage3DFn =
+        reinterpret_cast<glTexImage3DProc>(GetGLProcAddress("glTexImage3D"));
+    DCHECK(fn.glTexImage3DFn);
+  }
+
   debug_fn.glTexStorage2DEXTFn = 0;
-  if (ver->is_es3 || ext.b_GL_ARB_texture_storage) {
+  if (ver->IsAtLeastGL(4u, 2u) || ver->IsAtLeastGLES(3u, 0u) ||
+      ext.b_GL_ARB_texture_storage) {
     fn.glTexStorage2DEXTFn = reinterpret_cast<glTexStorage2DEXTProc>(
         GetGLProcAddress("glTexStorage2D"));
-  }
-  if (!fn.glTexStorage2DEXTFn) {
+    DCHECK(fn.glTexStorage2DEXTFn);
+  } else if (ext.b_GL_EXT_texture_storage) {
     fn.glTexStorage2DEXTFn = reinterpret_cast<glTexStorage2DEXTProc>(
         GetGLProcAddress("glTexStorage2DEXT"));
+    DCHECK(fn.glTexStorage2DEXTFn);
   }
 
-  fn.glUnmapBufferFn = 0;
-  debug_fn.glUnmapBufferFn = 0;
-  if (ext.b_GL_OES_mapbuffer) {
-    fn.glUnmapBufferFn = reinterpret_cast<glUnmapBufferProc>(
-        GetGLProcAddress("glUnmapBufferOES"));
+  debug_fn.glTexStorage3DFn = 0;
+  if (ver->IsAtLeastGL(4u, 2u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glTexStorage3DFn = reinterpret_cast<glTexStorage3DProc>(
+        GetGLProcAddress("glTexStorage3D"));
+    DCHECK(fn.glTexStorage3DFn);
   }
-  if (!fn.glUnmapBufferFn) {
+
+  debug_fn.glTransformFeedbackVaryingsFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glTransformFeedbackVaryingsFn =
+        reinterpret_cast<glTransformFeedbackVaryingsProc>(
+            GetGLProcAddress("glTransformFeedbackVaryings"));
+    DCHECK(fn.glTransformFeedbackVaryingsFn);
+  }
+
+  debug_fn.glUniform1uiFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniform1uiFn =
+        reinterpret_cast<glUniform1uiProc>(GetGLProcAddress("glUniform1ui"));
+    DCHECK(fn.glUniform1uiFn);
+  }
+
+  debug_fn.glUniform1uivFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniform1uivFn =
+        reinterpret_cast<glUniform1uivProc>(GetGLProcAddress("glUniform1uiv"));
+    DCHECK(fn.glUniform1uivFn);
+  }
+
+  debug_fn.glUniform2uiFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniform2uiFn =
+        reinterpret_cast<glUniform2uiProc>(GetGLProcAddress("glUniform2ui"));
+    DCHECK(fn.glUniform2uiFn);
+  }
+
+  debug_fn.glUniform2uivFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniform2uivFn =
+        reinterpret_cast<glUniform2uivProc>(GetGLProcAddress("glUniform2uiv"));
+    DCHECK(fn.glUniform2uivFn);
+  }
+
+  debug_fn.glUniform3uiFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniform3uiFn =
+        reinterpret_cast<glUniform3uiProc>(GetGLProcAddress("glUniform3ui"));
+    DCHECK(fn.glUniform3uiFn);
+  }
+
+  debug_fn.glUniform3uivFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniform3uivFn =
+        reinterpret_cast<glUniform3uivProc>(GetGLProcAddress("glUniform3uiv"));
+    DCHECK(fn.glUniform3uivFn);
+  }
+
+  debug_fn.glUniform4uiFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniform4uiFn =
+        reinterpret_cast<glUniform4uiProc>(GetGLProcAddress("glUniform4ui"));
+    DCHECK(fn.glUniform4uiFn);
+  }
+
+  debug_fn.glUniform4uivFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniform4uivFn =
+        reinterpret_cast<glUniform4uivProc>(GetGLProcAddress("glUniform4uiv"));
+    DCHECK(fn.glUniform4uivFn);
+  }
+
+  debug_fn.glUniformBlockBindingFn = 0;
+  if (ver->IsAtLeastGLES(3u, 0u) || ver->IsAtLeastGL(3u, 1u)) {
+    fn.glUniformBlockBindingFn = reinterpret_cast<glUniformBlockBindingProc>(
+        GetGLProcAddress("glUniformBlockBinding"));
+    DCHECK(fn.glUniformBlockBindingFn);
+  }
+
+  debug_fn.glUniformMatrix2x3fvFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniformMatrix2x3fvFn = reinterpret_cast<glUniformMatrix2x3fvProc>(
+        GetGLProcAddress("glUniformMatrix2x3fv"));
+    DCHECK(fn.glUniformMatrix2x3fvFn);
+  }
+
+  debug_fn.glUniformMatrix2x4fvFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniformMatrix2x4fvFn = reinterpret_cast<glUniformMatrix2x4fvProc>(
+        GetGLProcAddress("glUniformMatrix2x4fv"));
+    DCHECK(fn.glUniformMatrix2x4fvFn);
+  }
+
+  debug_fn.glUniformMatrix3x2fvFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniformMatrix3x2fvFn = reinterpret_cast<glUniformMatrix3x2fvProc>(
+        GetGLProcAddress("glUniformMatrix3x2fv"));
+    DCHECK(fn.glUniformMatrix3x2fvFn);
+  }
+
+  debug_fn.glUniformMatrix3x4fvFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniformMatrix3x4fvFn = reinterpret_cast<glUniformMatrix3x4fvProc>(
+        GetGLProcAddress("glUniformMatrix3x4fv"));
+    DCHECK(fn.glUniformMatrix3x4fvFn);
+  }
+
+  debug_fn.glUniformMatrix4x2fvFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniformMatrix4x2fvFn = reinterpret_cast<glUniformMatrix4x2fvProc>(
+        GetGLProcAddress("glUniformMatrix4x2fv"));
+    DCHECK(fn.glUniformMatrix4x2fvFn);
+  }
+
+  debug_fn.glUniformMatrix4x3fvFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glUniformMatrix4x3fvFn = reinterpret_cast<glUniformMatrix4x3fvProc>(
+        GetGLProcAddress("glUniformMatrix4x3fv"));
+    DCHECK(fn.glUniformMatrix4x3fvFn);
+  }
+
+  debug_fn.glUnmapBufferFn = 0;
+  if (!ver->is_es || ver->IsAtLeastGLES(3u, 0u)) {
     fn.glUnmapBufferFn =
         reinterpret_cast<glUnmapBufferProc>(GetGLProcAddress("glUnmapBuffer"));
+    DCHECK(fn.glUnmapBufferFn);
+  } else if (ext.b_GL_OES_mapbuffer) {
+    fn.glUnmapBufferFn = reinterpret_cast<glUnmapBufferProc>(
+        GetGLProcAddress("glUnmapBufferOES"));
+    DCHECK(fn.glUnmapBufferFn);
   }
 
-  fn.glVertexAttribDivisorANGLEFn = 0;
   debug_fn.glVertexAttribDivisorANGLEFn = 0;
-  if (ext.b_GL_ARB_instanced_arrays) {
-    fn.glVertexAttribDivisorANGLEFn =
-        reinterpret_cast<glVertexAttribDivisorANGLEProc>(
-            GetGLProcAddress("glVertexAttribDivisorARB"));
-  }
-  if (!fn.glVertexAttribDivisorANGLEFn && (ext.b_GL_ANGLE_instanced_arrays)) {
-    fn.glVertexAttribDivisorANGLEFn =
-        reinterpret_cast<glVertexAttribDivisorANGLEProc>(
-            GetGLProcAddress("glVertexAttribDivisorANGLE"));
-  }
-  if (!fn.glVertexAttribDivisorANGLEFn) {
+  if (ver->IsAtLeastGL(3u, 3u) || ver->IsAtLeastGLES(3u, 0u)) {
     fn.glVertexAttribDivisorANGLEFn =
         reinterpret_cast<glVertexAttribDivisorANGLEProc>(
             GetGLProcAddress("glVertexAttribDivisor"));
+    DCHECK(fn.glVertexAttribDivisorANGLEFn);
+  } else if (ext.b_GL_ARB_instanced_arrays) {
+    fn.glVertexAttribDivisorANGLEFn =
+        reinterpret_cast<glVertexAttribDivisorANGLEProc>(
+            GetGLProcAddress("glVertexAttribDivisorARB"));
+    DCHECK(fn.glVertexAttribDivisorANGLEFn);
+  } else if (ext.b_GL_ANGLE_instanced_arrays) {
+    fn.glVertexAttribDivisorANGLEFn =
+        reinterpret_cast<glVertexAttribDivisorANGLEProc>(
+            GetGLProcAddress("glVertexAttribDivisorANGLE"));
+    DCHECK(fn.glVertexAttribDivisorANGLEFn);
+  }
+
+  debug_fn.glVertexAttribI4iFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glVertexAttribI4iFn = reinterpret_cast<glVertexAttribI4iProc>(
+        GetGLProcAddress("glVertexAttribI4i"));
+    DCHECK(fn.glVertexAttribI4iFn);
+  }
+
+  debug_fn.glVertexAttribI4ivFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glVertexAttribI4ivFn = reinterpret_cast<glVertexAttribI4ivProc>(
+        GetGLProcAddress("glVertexAttribI4iv"));
+    DCHECK(fn.glVertexAttribI4ivFn);
+  }
+
+  debug_fn.glVertexAttribI4uiFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glVertexAttribI4uiFn = reinterpret_cast<glVertexAttribI4uiProc>(
+        GetGLProcAddress("glVertexAttribI4ui"));
+    DCHECK(fn.glVertexAttribI4uiFn);
+  }
+
+  debug_fn.glVertexAttribI4uivFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glVertexAttribI4uivFn = reinterpret_cast<glVertexAttribI4uivProc>(
+        GetGLProcAddress("glVertexAttribI4uiv"));
+    DCHECK(fn.glVertexAttribI4uivFn);
+  }
+
+  debug_fn.glVertexAttribIPointerFn = 0;
+  if (ver->IsAtLeastGL(3u, 0u) || ver->IsAtLeastGLES(3u, 0u)) {
+    fn.glVertexAttribIPointerFn = reinterpret_cast<glVertexAttribIPointerProc>(
+        GetGLProcAddress("glVertexAttribIPointer"));
+    DCHECK(fn.glVertexAttribIPointerFn);
+  }
+
+  debug_fn.glWaitSyncFn = 0;
+  if (ver->IsAtLeastGL(3u, 2u) || ver->IsAtLeastGLES(3u, 0u) ||
+      ext.b_GL_ARB_sync) {
+    fn.glWaitSyncFn =
+        reinterpret_cast<glWaitSyncProc>(GetGLProcAddress("glWaitSync"));
+    DCHECK(fn.glWaitSyncFn);
   }
 
   if (g_debugBindingsInitialized)
diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h
index eb66b4a..b38ba3f 100644
--- a/ui/gl/gl_bindings_autogen_gl.h
+++ b/ui/gl/gl_bindings_autogen_gl.h
@@ -894,27 +894,18 @@
   bool b_GL_ANGLE_translated_shader_source;
   bool b_GL_APPLE_fence;
   bool b_GL_APPLE_vertex_array_object;
-  bool b_GL_ARB_ES2_compatibility;
-  bool b_GL_ARB_blend_func_extended;
-  bool b_GL_ARB_copy_buffer;
   bool b_GL_ARB_draw_buffers;
   bool b_GL_ARB_draw_instanced;
-  bool b_GL_ARB_framebuffer_object;
   bool b_GL_ARB_get_program_binary;
   bool b_GL_ARB_instanced_arrays;
-  bool b_GL_ARB_internalformat_query;
-  bool b_GL_ARB_invalidate_subdata;
   bool b_GL_ARB_map_buffer_range;
   bool b_GL_ARB_occlusion_query;
   bool b_GL_ARB_robustness;
-  bool b_GL_ARB_sampler_objects;
   bool b_GL_ARB_sync;
   bool b_GL_ARB_texture_storage;
   bool b_GL_ARB_timer_query;
-  bool b_GL_ARB_transform_feedback2;
-  bool b_GL_ARB_uniform_buffer_object;
   bool b_GL_ARB_vertex_array_object;
-  bool b_GL_ARB_vertex_buffer_object;
+  bool b_GL_CHROMIUM_gles_depth_binding_hack;
   bool b_GL_EXT_debug_marker;
   bool b_GL_EXT_direct_state_access;
   bool b_GL_EXT_discard_framebuffer;
@@ -925,6 +916,7 @@
   bool b_GL_EXT_framebuffer_object;
   bool b_GL_EXT_map_buffer_range;
   bool b_GL_EXT_multisampled_render_to_texture;
+  bool b_GL_EXT_occlusion_query_boolean;
   bool b_GL_EXT_robustness;
   bool b_GL_EXT_texture_storage;
   bool b_GL_EXT_timer_query;
diff --git a/ui/gl/gl_bindings_autogen_glx.cc b/ui/gl/gl_bindings_autogen_glx.cc
index 617ff5f..ca36b7a 100644
--- a/ui/gl/gl_bindings_autogen_glx.cc
+++ b/ui/gl/gl_bindings_autogen_glx.cc
@@ -10,7 +10,7 @@
 
 #include <string>
 
-#include "base/debug/trace_event.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_enums.h"
@@ -24,21 +24,17 @@
 DriverGLX g_driver_glx;
 
 void DriverGLX::InitializeStaticBindings() {
-  fn.glXBindTexImageEXTFn = reinterpret_cast<glXBindTexImageEXTProc>(
-      GetGLProcAddress("glXBindTexImageEXT"));
+  fn.glXBindTexImageEXTFn = 0;
   fn.glXChooseFBConfigFn = reinterpret_cast<glXChooseFBConfigProc>(
       GetGLProcAddress("glXChooseFBConfig"));
   fn.glXChooseVisualFn = reinterpret_cast<glXChooseVisualProc>(
       GetGLProcAddress("glXChooseVisual"));
   fn.glXCopyContextFn =
       reinterpret_cast<glXCopyContextProc>(GetGLProcAddress("glXCopyContext"));
-  fn.glXCopySubBufferMESAFn = reinterpret_cast<glXCopySubBufferMESAProc>(
-      GetGLProcAddress("glXCopySubBufferMESA"));
+  fn.glXCopySubBufferMESAFn = 0;
   fn.glXCreateContextFn = reinterpret_cast<glXCreateContextProc>(
       GetGLProcAddress("glXCreateContext"));
-  fn.glXCreateContextAttribsARBFn =
-      reinterpret_cast<glXCreateContextAttribsARBProc>(
-          GetGLProcAddress("glXCreateContextAttribsARB"));
+  fn.glXCreateContextAttribsARBFn = 0;
   fn.glXCreateGLXPixmapFn = reinterpret_cast<glXCreateGLXPixmapProc>(
       GetGLProcAddress("glXCreateGLXPixmap"));
   fn.glXCreateNewContextFn = reinterpret_cast<glXCreateNewContextProc>(
@@ -74,17 +70,13 @@
           GetGLProcAddress("glXGetCurrentReadDrawable"));
   fn.glXGetFBConfigAttribFn = reinterpret_cast<glXGetFBConfigAttribProc>(
       GetGLProcAddress("glXGetFBConfigAttrib"));
-  fn.glXGetFBConfigFromVisualSGIXFn =
-      reinterpret_cast<glXGetFBConfigFromVisualSGIXProc>(
-          GetGLProcAddress("glXGetFBConfigFromVisualSGIX"));
+  fn.glXGetFBConfigFromVisualSGIXFn = 0;
   fn.glXGetFBConfigsFn = reinterpret_cast<glXGetFBConfigsProc>(
       GetGLProcAddress("glXGetFBConfigs"));
-  fn.glXGetMscRateOMLFn = reinterpret_cast<glXGetMscRateOMLProc>(
-      GetGLProcAddress("glXGetMscRateOML"));
+  fn.glXGetMscRateOMLFn = 0;
   fn.glXGetSelectedEventFn = reinterpret_cast<glXGetSelectedEventProc>(
       GetGLProcAddress("glXGetSelectedEvent"));
-  fn.glXGetSyncValuesOMLFn = reinterpret_cast<glXGetSyncValuesOMLProc>(
-      GetGLProcAddress("glXGetSyncValuesOML"));
+  fn.glXGetSyncValuesOMLFn = 0;
   fn.glXGetVisualFromFBConfigFn =
       reinterpret_cast<glXGetVisualFromFBConfigProc>(
           GetGLProcAddress("glXGetVisualFromFBConfig"));
@@ -107,30 +99,21 @@
       GetGLProcAddress("glXQueryServerString"));
   fn.glXQueryVersionFn = reinterpret_cast<glXQueryVersionProc>(
       GetGLProcAddress("glXQueryVersion"));
-  fn.glXReleaseTexImageEXTFn = reinterpret_cast<glXReleaseTexImageEXTProc>(
-      GetGLProcAddress("glXReleaseTexImageEXT"));
+  fn.glXReleaseTexImageEXTFn = 0;
   fn.glXSelectEventFn =
       reinterpret_cast<glXSelectEventProc>(GetGLProcAddress("glXSelectEvent"));
   fn.glXSwapBuffersFn =
       reinterpret_cast<glXSwapBuffersProc>(GetGLProcAddress("glXSwapBuffers"));
-  fn.glXSwapIntervalEXTFn = reinterpret_cast<glXSwapIntervalEXTProc>(
-      GetGLProcAddress("glXSwapIntervalEXT"));
-  fn.glXSwapIntervalMESAFn = reinterpret_cast<glXSwapIntervalMESAProc>(
-      GetGLProcAddress("glXSwapIntervalMESA"));
+  fn.glXSwapIntervalEXTFn = 0;
+  fn.glXSwapIntervalMESAFn = 0;
   fn.glXUseXFontFn =
       reinterpret_cast<glXUseXFontProc>(GetGLProcAddress("glXUseXFont"));
   fn.glXWaitGLFn =
       reinterpret_cast<glXWaitGLProc>(GetGLProcAddress("glXWaitGL"));
-  fn.glXWaitVideoSyncSGIFn = reinterpret_cast<glXWaitVideoSyncSGIProc>(
-      GetGLProcAddress("glXWaitVideoSyncSGI"));
+  fn.glXWaitVideoSyncSGIFn = 0;
   fn.glXWaitXFn = reinterpret_cast<glXWaitXProc>(GetGLProcAddress("glXWaitX"));
-}
-
-void DriverGLX::InitializeDynamicBindings(GLContext* context) {
-  DCHECK(context && context->IsCurrent(NULL));
-  const GLVersionInfo* ver = context->GetVersionInfo();
-  ALLOW_UNUSED_LOCAL(ver);
-  std::string extensions = context->GetExtensions() + " ";
+  std::string extensions(GetPlatformExtensions());
+  extensions += " ";
   ALLOW_UNUSED_LOCAL(extensions);
 
   ext.b_GLX_ARB_create_context =
@@ -150,6 +133,78 @@
   ext.b_GLX_SGI_video_sync =
       extensions.find("GLX_SGI_video_sync ") != std::string::npos;
 
+  debug_fn.glXBindTexImageEXTFn = 0;
+  if (ext.b_GLX_EXT_texture_from_pixmap) {
+    fn.glXBindTexImageEXTFn = reinterpret_cast<glXBindTexImageEXTProc>(
+        GetGLProcAddress("glXBindTexImageEXT"));
+    DCHECK(fn.glXBindTexImageEXTFn);
+  }
+
+  debug_fn.glXCopySubBufferMESAFn = 0;
+  if (ext.b_GLX_MESA_copy_sub_buffer) {
+    fn.glXCopySubBufferMESAFn = reinterpret_cast<glXCopySubBufferMESAProc>(
+        GetGLProcAddress("glXCopySubBufferMESA"));
+    DCHECK(fn.glXCopySubBufferMESAFn);
+  }
+
+  debug_fn.glXCreateContextAttribsARBFn = 0;
+  if (ext.b_GLX_ARB_create_context) {
+    fn.glXCreateContextAttribsARBFn =
+        reinterpret_cast<glXCreateContextAttribsARBProc>(
+            GetGLProcAddress("glXCreateContextAttribsARB"));
+    DCHECK(fn.glXCreateContextAttribsARBFn);
+  }
+
+  debug_fn.glXGetFBConfigFromVisualSGIXFn = 0;
+  if (ext.b_GLX_SGIX_fbconfig) {
+    fn.glXGetFBConfigFromVisualSGIXFn =
+        reinterpret_cast<glXGetFBConfigFromVisualSGIXProc>(
+            GetGLProcAddress("glXGetFBConfigFromVisualSGIX"));
+    DCHECK(fn.glXGetFBConfigFromVisualSGIXFn);
+  }
+
+  debug_fn.glXGetMscRateOMLFn = 0;
+  if (ext.b_GLX_OML_sync_control) {
+    fn.glXGetMscRateOMLFn = reinterpret_cast<glXGetMscRateOMLProc>(
+        GetGLProcAddress("glXGetMscRateOML"));
+    DCHECK(fn.glXGetMscRateOMLFn);
+  }
+
+  debug_fn.glXGetSyncValuesOMLFn = 0;
+  if (ext.b_GLX_OML_sync_control) {
+    fn.glXGetSyncValuesOMLFn = reinterpret_cast<glXGetSyncValuesOMLProc>(
+        GetGLProcAddress("glXGetSyncValuesOML"));
+    DCHECK(fn.glXGetSyncValuesOMLFn);
+  }
+
+  debug_fn.glXReleaseTexImageEXTFn = 0;
+  if (ext.b_GLX_EXT_texture_from_pixmap) {
+    fn.glXReleaseTexImageEXTFn = reinterpret_cast<glXReleaseTexImageEXTProc>(
+        GetGLProcAddress("glXReleaseTexImageEXT"));
+    DCHECK(fn.glXReleaseTexImageEXTFn);
+  }
+
+  debug_fn.glXSwapIntervalEXTFn = 0;
+  if (ext.b_GLX_EXT_swap_control) {
+    fn.glXSwapIntervalEXTFn = reinterpret_cast<glXSwapIntervalEXTProc>(
+        GetGLProcAddress("glXSwapIntervalEXT"));
+    DCHECK(fn.glXSwapIntervalEXTFn);
+  }
+
+  debug_fn.glXSwapIntervalMESAFn = 0;
+  if (ext.b_GLX_MESA_swap_control) {
+    fn.glXSwapIntervalMESAFn = reinterpret_cast<glXSwapIntervalMESAProc>(
+        GetGLProcAddress("glXSwapIntervalMESA"));
+    DCHECK(fn.glXSwapIntervalMESAFn);
+  }
+
+  debug_fn.glXWaitVideoSyncSGIFn = 0;
+  if (ext.b_GLX_SGI_video_sync) {
+    fn.glXWaitVideoSyncSGIFn = reinterpret_cast<glXWaitVideoSyncSGIProc>(
+        GetGLProcAddress("glXWaitVideoSyncSGI"));
+    DCHECK(fn.glXWaitVideoSyncSGIFn);
+  }
+
   if (g_debugBindingsInitialized)
     InitializeDebugBindings();
 }
diff --git a/ui/gl/gl_bindings_autogen_mock.cc b/ui/gl/gl_bindings_autogen_mock.cc
index f424696..185d809 100644
--- a/ui/gl/gl_bindings_autogen_mock.cc
+++ b/ui/gl/gl_bindings_autogen_mock.cc
@@ -479,12 +479,6 @@
 }
 
 void GL_BINDING_CALL
-MockGLInterface::Mock_glDeleteBuffersARB(GLsizei n, const GLuint* buffers) {
-  MakeFunctionUnique("glDeleteBuffersARB");
-  interface_->DeleteBuffersARB(n, buffers);
-}
-
-void GL_BINDING_CALL
 MockGLInterface::Mock_glDeleteFencesAPPLE(GLsizei n, const GLuint* fences) {
   MakeFunctionUnique("glDeleteFencesAPPLE");
   interface_->DeleteFencesAPPLE(n, fences);
@@ -915,12 +909,6 @@
 }
 
 void GL_BINDING_CALL
-MockGLInterface::Mock_glGenBuffersARB(GLsizei n, GLuint* buffers) {
-  MakeFunctionUnique("glGenBuffersARB");
-  interface_->GenBuffersARB(n, buffers);
-}
-
-void GL_BINDING_CALL
 MockGLInterface::Mock_glGenFencesAPPLE(GLsizei n, GLuint* fences) {
   MakeFunctionUnique("glGenFencesAPPLE");
   interface_->GenFencesAPPLE(n, fences);
@@ -1250,6 +1238,14 @@
   interface_->GetQueryObjecti64v(id, pname, params);
 }
 
+void GL_BINDING_CALL
+MockGLInterface::Mock_glGetQueryObjecti64vEXT(GLuint id,
+                                              GLenum pname,
+                                              GLint64* params) {
+  MakeFunctionUnique("glGetQueryObjecti64vEXT");
+  interface_->GetQueryObjecti64v(id, pname, params);
+}
+
 void GL_BINDING_CALL MockGLInterface::Mock_glGetQueryObjectiv(GLuint id,
                                                               GLenum pname,
                                                               GLint* params) {
@@ -2650,8 +2646,6 @@
     return reinterpret_cast<void*>(Mock_glCullFace);
   if (strcmp(name, "glDeleteBuffers") == 0)
     return reinterpret_cast<void*>(Mock_glDeleteBuffers);
-  if (strcmp(name, "glDeleteBuffersARB") == 0)
-    return reinterpret_cast<void*>(Mock_glDeleteBuffersARB);
   if (strcmp(name, "glDeleteFencesAPPLE") == 0)
     return reinterpret_cast<void*>(Mock_glDeleteFencesAPPLE);
   if (strcmp(name, "glDeleteFencesNV") == 0)
@@ -2776,8 +2770,6 @@
     return reinterpret_cast<void*>(Mock_glFrontFace);
   if (strcmp(name, "glGenBuffers") == 0)
     return reinterpret_cast<void*>(Mock_glGenBuffers);
-  if (strcmp(name, "glGenBuffersARB") == 0)
-    return reinterpret_cast<void*>(Mock_glGenBuffersARB);
   if (strcmp(name, "glGenFencesAPPLE") == 0)
     return reinterpret_cast<void*>(Mock_glGenFencesAPPLE);
   if (strcmp(name, "glGenFencesNV") == 0)
@@ -2871,6 +2863,8 @@
     return reinterpret_cast<void*>(Mock_glGetProgramiv);
   if (strcmp(name, "glGetQueryObjecti64v") == 0)
     return reinterpret_cast<void*>(Mock_glGetQueryObjecti64v);
+  if (strcmp(name, "glGetQueryObjecti64vEXT") == 0)
+    return reinterpret_cast<void*>(Mock_glGetQueryObjecti64vEXT);
   if (strcmp(name, "glGetQueryObjectiv") == 0)
     return reinterpret_cast<void*>(Mock_glGetQueryObjectiv);
   if (strcmp(name, "glGetQueryObjectivARB") == 0)
diff --git a/ui/gl/gl_bindings_autogen_mock.h b/ui/gl/gl_bindings_autogen_mock.h
index 2ed1095..4b1ff4b 100644
--- a/ui/gl/gl_bindings_autogen_mock.h
+++ b/ui/gl/gl_bindings_autogen_mock.h
@@ -184,8 +184,6 @@
 static void GL_BINDING_CALL
 Mock_glDeleteBuffers(GLsizei n, const GLuint* buffers);
 static void GL_BINDING_CALL
-Mock_glDeleteBuffersARB(GLsizei n, const GLuint* buffers);
-static void GL_BINDING_CALL
 Mock_glDeleteFencesAPPLE(GLsizei n, const GLuint* fences);
 static void GL_BINDING_CALL
 Mock_glDeleteFencesNV(GLsizei n, const GLuint* fences);
@@ -334,7 +332,6 @@
                                                            GLint layer);
 static void GL_BINDING_CALL Mock_glFrontFace(GLenum mode);
 static void GL_BINDING_CALL Mock_glGenBuffers(GLsizei n, GLuint* buffers);
-static void GL_BINDING_CALL Mock_glGenBuffersARB(GLsizei n, GLuint* buffers);
 static void GL_BINDING_CALL Mock_glGenFencesAPPLE(GLsizei n, GLuint* fences);
 static void GL_BINDING_CALL Mock_glGenFencesNV(GLsizei n, GLuint* fences);
 static void GL_BINDING_CALL
@@ -449,6 +446,8 @@
 static void GL_BINDING_CALL
 Mock_glGetQueryObjecti64v(GLuint id, GLenum pname, GLint64* params);
 static void GL_BINDING_CALL
+Mock_glGetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64* params);
+static void GL_BINDING_CALL
 Mock_glGetQueryObjectiv(GLuint id, GLenum pname, GLint* params);
 static void GL_BINDING_CALL
 Mock_glGetQueryObjectivARB(GLuint id, GLenum pname, GLint* params);
diff --git a/ui/gl/gl_bindings_autogen_osmesa.cc b/ui/gl/gl_bindings_autogen_osmesa.cc
index c0c3ed2..299f9f2 100644
--- a/ui/gl/gl_bindings_autogen_osmesa.cc
+++ b/ui/gl/gl_bindings_autogen_osmesa.cc
@@ -10,7 +10,7 @@
 
 #include <string>
 
-#include "base/debug/trace_event.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_enums.h"
@@ -46,13 +46,8 @@
       GetGLProcAddress("OSMesaMakeCurrent"));
   fn.OSMesaPixelStoreFn = reinterpret_cast<OSMesaPixelStoreProc>(
       GetGLProcAddress("OSMesaPixelStore"));
-}
-
-void DriverOSMESA::InitializeDynamicBindings(GLContext* context) {
-  DCHECK(context && context->IsCurrent(NULL));
-  const GLVersionInfo* ver = context->GetVersionInfo();
-  ALLOW_UNUSED_LOCAL(ver);
-  std::string extensions = context->GetExtensions() + " ";
+  std::string extensions(GetPlatformExtensions());
+  extensions += " ";
   ALLOW_UNUSED_LOCAL(extensions);
 
   if (g_debugBindingsInitialized)
diff --git a/ui/gl/gl_bindings_autogen_wgl.cc b/ui/gl/gl_bindings_autogen_wgl.cc
index a28aaf6..b70f929 100644
--- a/ui/gl/gl_bindings_autogen_wgl.cc
+++ b/ui/gl/gl_bindings_autogen_wgl.cc
@@ -10,7 +10,7 @@
 
 #include <string>
 
-#include "base/debug/trace_event.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_enums.h"
@@ -24,20 +24,17 @@
 DriverWGL g_driver_wgl;
 
 void DriverWGL::InitializeStaticBindings() {
-  fn.wglChoosePixelFormatARBFn = reinterpret_cast<wglChoosePixelFormatARBProc>(
-      GetGLProcAddress("wglChoosePixelFormatARB"));
+  fn.wglChoosePixelFormatARBFn = 0;
   fn.wglCopyContextFn =
       reinterpret_cast<wglCopyContextProc>(GetGLProcAddress("wglCopyContext"));
   fn.wglCreateContextFn = reinterpret_cast<wglCreateContextProc>(
       GetGLProcAddress("wglCreateContext"));
   fn.wglCreateLayerContextFn = reinterpret_cast<wglCreateLayerContextProc>(
       GetGLProcAddress("wglCreateLayerContext"));
-  fn.wglCreatePbufferARBFn = reinterpret_cast<wglCreatePbufferARBProc>(
-      GetGLProcAddress("wglCreatePbufferARB"));
+  fn.wglCreatePbufferARBFn = 0;
   fn.wglDeleteContextFn = reinterpret_cast<wglDeleteContextProc>(
       GetGLProcAddress("wglDeleteContext"));
-  fn.wglDestroyPbufferARBFn = reinterpret_cast<wglDestroyPbufferARBProc>(
-      GetGLProcAddress("wglDestroyPbufferARB"));
+  fn.wglDestroyPbufferARBFn = 0;
   fn.wglGetCurrentContextFn = reinterpret_cast<wglGetCurrentContextProc>(
       GetGLProcAddress("wglGetCurrentContext"));
   fn.wglGetCurrentDCFn = reinterpret_cast<wglGetCurrentDCProc>(
@@ -48,27 +45,18 @@
   fn.wglGetExtensionsStringEXTFn =
       reinterpret_cast<wglGetExtensionsStringEXTProc>(
           GetGLProcAddress("wglGetExtensionsStringEXT"));
-  fn.wglGetPbufferDCARBFn = reinterpret_cast<wglGetPbufferDCARBProc>(
-      GetGLProcAddress("wglGetPbufferDCARB"));
+  fn.wglGetPbufferDCARBFn = 0;
   fn.wglMakeCurrentFn =
       reinterpret_cast<wglMakeCurrentProc>(GetGLProcAddress("wglMakeCurrent"));
-  fn.wglQueryPbufferARBFn = reinterpret_cast<wglQueryPbufferARBProc>(
-      GetGLProcAddress("wglQueryPbufferARB"));
-  fn.wglReleasePbufferDCARBFn = reinterpret_cast<wglReleasePbufferDCARBProc>(
-      GetGLProcAddress("wglReleasePbufferDCARB"));
+  fn.wglQueryPbufferARBFn = 0;
+  fn.wglReleasePbufferDCARBFn = 0;
   fn.wglShareListsFn =
       reinterpret_cast<wglShareListsProc>(GetGLProcAddress("wglShareLists"));
-  fn.wglSwapIntervalEXTFn = reinterpret_cast<wglSwapIntervalEXTProc>(
-      GetGLProcAddress("wglSwapIntervalEXT"));
+  fn.wglSwapIntervalEXTFn = 0;
   fn.wglSwapLayerBuffersFn = reinterpret_cast<wglSwapLayerBuffersProc>(
       GetGLProcAddress("wglSwapLayerBuffers"));
-}
-
-void DriverWGL::InitializeDynamicBindings(GLContext* context) {
-  DCHECK(context && context->IsCurrent(NULL));
-  const GLVersionInfo* ver = context->GetVersionInfo();
-  ALLOW_UNUSED_LOCAL(ver);
-  std::string extensions = context->GetExtensions() + " ";
+  std::string extensions(GetPlatformExtensions());
+  extensions += " ";
   ALLOW_UNUSED_LOCAL(extensions);
 
   ext.b_WGL_ARB_extensions_string =
@@ -82,6 +70,56 @@
   ext.b_WGL_EXT_swap_control =
       extensions.find("WGL_EXT_swap_control ") != std::string::npos;
 
+  debug_fn.wglChoosePixelFormatARBFn = 0;
+  if (ext.b_WGL_ARB_pixel_format) {
+    fn.wglChoosePixelFormatARBFn =
+        reinterpret_cast<wglChoosePixelFormatARBProc>(
+            GetGLProcAddress("wglChoosePixelFormatARB"));
+    DCHECK(fn.wglChoosePixelFormatARBFn);
+  }
+
+  debug_fn.wglCreatePbufferARBFn = 0;
+  if (ext.b_WGL_ARB_pbuffer) {
+    fn.wglCreatePbufferARBFn = reinterpret_cast<wglCreatePbufferARBProc>(
+        GetGLProcAddress("wglCreatePbufferARB"));
+    DCHECK(fn.wglCreatePbufferARBFn);
+  }
+
+  debug_fn.wglDestroyPbufferARBFn = 0;
+  if (ext.b_WGL_ARB_pbuffer) {
+    fn.wglDestroyPbufferARBFn = reinterpret_cast<wglDestroyPbufferARBProc>(
+        GetGLProcAddress("wglDestroyPbufferARB"));
+    DCHECK(fn.wglDestroyPbufferARBFn);
+  }
+
+  debug_fn.wglGetPbufferDCARBFn = 0;
+  if (ext.b_WGL_ARB_pbuffer) {
+    fn.wglGetPbufferDCARBFn = reinterpret_cast<wglGetPbufferDCARBProc>(
+        GetGLProcAddress("wglGetPbufferDCARB"));
+    DCHECK(fn.wglGetPbufferDCARBFn);
+  }
+
+  debug_fn.wglQueryPbufferARBFn = 0;
+  if (ext.b_WGL_ARB_pbuffer) {
+    fn.wglQueryPbufferARBFn = reinterpret_cast<wglQueryPbufferARBProc>(
+        GetGLProcAddress("wglQueryPbufferARB"));
+    DCHECK(fn.wglQueryPbufferARBFn);
+  }
+
+  debug_fn.wglReleasePbufferDCARBFn = 0;
+  if (ext.b_WGL_ARB_pbuffer) {
+    fn.wglReleasePbufferDCARBFn = reinterpret_cast<wglReleasePbufferDCARBProc>(
+        GetGLProcAddress("wglReleasePbufferDCARB"));
+    DCHECK(fn.wglReleasePbufferDCARBFn);
+  }
+
+  debug_fn.wglSwapIntervalEXTFn = 0;
+  if (ext.b_WGL_EXT_swap_control) {
+    fn.wglSwapIntervalEXTFn = reinterpret_cast<wglSwapIntervalEXTProc>(
+        GetGLProcAddress("wglSwapIntervalEXT"));
+    DCHECK(fn.wglSwapIntervalEXTFn);
+  }
+
   if (g_debugBindingsInitialized)
     InitializeDebugBindings();
 }
diff --git a/ui/gl/gl_context_cgl.cc b/ui/gl/gl_context_cgl.cc
index 723e97e..d4bc780 100644
--- a/ui/gl/gl_context_cgl.cc
+++ b/ui/gl/gl_context_cgl.cc
@@ -8,9 +8,9 @@
 #include <OpenGL/CGLTypes.h>
 #include <vector>
 
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_implementation.h"
 #include "ui/gl/gl_surface.h"
diff --git a/ui/gl/gl_context_egl.cc b/ui/gl/gl_context_egl.cc
index 076de98..5fa2c44 100644
--- a/ui/gl/gl_context_egl.cc
+++ b/ui/gl/gl_context_egl.cc
@@ -4,9 +4,9 @@
 
 #include "ui/gl/gl_context_egl.h"
 
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
 #include "third_party/khronos/EGL/egl.h"
 #include "third_party/khronos/EGL/eglext.h"
diff --git a/ui/gl/gl_context_glx.cc b/ui/gl/gl_context_glx.cc
index a16daf3..e5b1cc1 100644
--- a/ui/gl/gl_context_glx.cc
+++ b/ui/gl/gl_context_glx.cc
@@ -8,9 +8,9 @@
 
 #include "ui/gl/gl_context_glx.h"
 
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/GL/glextchromium.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_implementation.h"
diff --git a/ui/gl/gl_context_mac.mm b/ui/gl/gl_context_mac.mm
index 8cd58b1..aa5516f 100644
--- a/ui/gl/gl_context_mac.mm
+++ b/ui/gl/gl_context_mac.mm
@@ -3,9 +3,9 @@
 // found in the LICENSE file.
 
 #include "base/basictypes.h"
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_context_cgl.h"
 #include "ui/gl/gl_context_osmesa.h"
 #include "ui/gl/gl_context_stub.h"
diff --git a/ui/gl/gl_context_wgl.cc b/ui/gl/gl_context_wgl.cc
index 2f34cd3..fa7f706 100644
--- a/ui/gl/gl_context_wgl.cc
+++ b/ui/gl/gl_context_wgl.cc
@@ -6,8 +6,8 @@
 
 #include "ui/gl/gl_context_wgl.h"
 
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_implementation.h"
 #include "ui/gl/gl_surface_wgl.h"
diff --git a/ui/gl/gl_context_win.cc b/ui/gl/gl_context_win.cc
index a69fcd2..dc2e20c 100644
--- a/ui/gl/gl_context_win.cc
+++ b/ui/gl/gl_context_win.cc
@@ -4,9 +4,9 @@
 
 #include "ui/gl/gl_context.h"
 
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context_egl.h"
 #include "ui/gl/gl_context_osmesa.h"
diff --git a/ui/gl/gl_context_x11.cc b/ui/gl/gl_context_x11.cc
index 7aff48c..b17364d 100644
--- a/ui/gl/gl_context_x11.cc
+++ b/ui/gl/gl_context_x11.cc
@@ -4,9 +4,9 @@
 
 #include "ui/gl/gl_context.h"
 
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context_egl.h"
 #include "ui/gl/gl_context_glx.h"
diff --git a/ui/gl/gl_egl_api_implementation.cc b/ui/gl/gl_egl_api_implementation.cc
index b3b55b8..53a1bf6 100644
--- a/ui/gl/gl_egl_api_implementation.cc
+++ b/ui/gl/gl_egl_api_implementation.cc
@@ -10,16 +10,12 @@
 RealEGLApi* g_real_egl;
 
 void InitializeStaticGLBindingsEGL() {
-  g_driver_egl.InitializeStaticBindings();
   if (!g_real_egl) {
     g_real_egl = new RealEGLApi();
   }
   g_real_egl->Initialize(&g_driver_egl);
   g_current_egl_context = g_real_egl;
-}
-
-void InitializeDynamicGLBindingsEGL(GLContext* context) {
-  g_driver_egl.InitializeDynamicBindings(context);
+  g_driver_egl.InitializeStaticBindings();
 }
 
 void InitializeDebugGLBindingsEGL() {
diff --git a/ui/gl/gl_egl_api_implementation.h b/ui/gl/gl_egl_api_implementation.h
index e58860c..a2ff28d 100644
--- a/ui/gl/gl_egl_api_implementation.h
+++ b/ui/gl/gl_egl_api_implementation.h
@@ -15,7 +15,6 @@
 struct GLWindowSystemBindingInfo;
 
 void InitializeStaticGLBindingsEGL();
-void InitializeDynamicGLBindingsEGL(GLContext* context);
 void InitializeDebugGLBindingsEGL();
 void ClearGLBindingsEGL();
 bool GetGLWindowSystemBindingInfoEGL(GLWindowSystemBindingInfo* info);
diff --git a/ui/gl/gl_gl_api_implementation.cc b/ui/gl/gl_gl_api_implementation.cc
index 3b8c534..fada5e3 100644
--- a/ui/gl/gl_gl_api_implementation.cc
+++ b/ui/gl/gl_gl_api_implementation.cc
@@ -85,7 +85,7 @@
   }
 
   if (type == GL_FLOAT && gfx::g_version_info->is_angle &&
-      gfx::g_version_info->is_es2) {
+      gfx::g_version_info->is_es && gfx::g_version_info->major_version == 2) {
     // It's possible that the texture is using a sized internal format, and
     // ANGLE exposing GLES2 API doesn't support those.
     // TODO(oetuaho@nvidia.com): Remove these conversions once ANGLE has the
diff --git a/ui/gl/gl_glx_api_implementation.cc b/ui/gl/gl_glx_api_implementation.cc
index 0392c39..cd38fd8 100644
--- a/ui/gl/gl_glx_api_implementation.cc
+++ b/ui/gl/gl_glx_api_implementation.cc
@@ -18,10 +18,6 @@
   g_current_glx_context = g_real_glx;
 }
 
-void InitializeDynamicGLBindingsGLX(GLContext* context) {
-  g_driver_glx.InitializeDynamicBindings(context);
-}
-
 void InitializeDebugGLBindingsGLX() {
   g_driver_glx.InitializeDebugBindings();
 }
diff --git a/ui/gl/gl_glx_api_implementation.h b/ui/gl/gl_glx_api_implementation.h
index 30a70cf..c83f478 100644
--- a/ui/gl/gl_glx_api_implementation.h
+++ b/ui/gl/gl_glx_api_implementation.h
@@ -15,7 +15,6 @@
 struct GLWindowSystemBindingInfo;
 
 void InitializeStaticGLBindingsGLX();
-void InitializeDynamicGLBindingsGLX(GLContext* context);
 void InitializeDebugGLBindingsGLX();
 void ClearGLBindingsGLX();
 bool GetGLWindowSystemBindingInfoGLX(GLWindowSystemBindingInfo* info);
diff --git a/ui/gl/gl_image_memory.cc b/ui/gl/gl_image_memory.cc
index 5e23d30..e92cc1f 100644
--- a/ui/gl/gl_image_memory.cc
+++ b/ui/gl/gl_image_memory.cc
@@ -4,8 +4,8 @@
 
 #include "ui/gl/gl_image_memory.h"
 
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/scoped_binders.h"
 
diff --git a/ui/gl/gl_image_surface_texture.cc b/ui/gl/gl_image_surface_texture.cc
index 27c9f64..a321c4d 100644
--- a/ui/gl/gl_image_surface_texture.cc
+++ b/ui/gl/gl_image_surface_texture.cc
@@ -4,7 +4,7 @@
 
 #include "ui/gl/gl_image_surface_texture.h"
 
-#include "base/debug/trace_event.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/android/surface_texture.h"
 
 namespace gfx {
diff --git a/ui/gl/gl_implementation_android.cc b/ui/gl/gl_implementation_android.cc
index 1486a6d..176cf28 100644
--- a/ui/gl/gl_implementation_android.cc
+++ b/ui/gl/gl_implementation_android.cc
@@ -99,11 +99,6 @@
   switch (implementation) {
     case kGLImplementationEGLGLES2:
       InitializeDynamicGLBindingsGL(context);
-      InitializeDynamicGLBindingsEGL(context);
-      break;
-    case kGLImplementationOSMesaGL:
-      InitializeDynamicGLBindingsGL(context);
-      InitializeDynamicGLBindingsOSMESA(context);
       break;
     case kGLImplementationMockGL:
       if (!context) {
diff --git a/ui/gl/gl_implementation_mac.cc b/ui/gl/gl_implementation_mac.cc
index 1011406..d818f05 100644
--- a/ui/gl/gl_implementation_mac.cc
+++ b/ui/gl/gl_implementation_mac.cc
@@ -112,9 +112,6 @@
     GLContext* context) {
   switch (implementation) {
     case kGLImplementationOSMesaGL:
-      InitializeDynamicGLBindingsGL(context);
-      InitializeDynamicGLBindingsOSMESA(context);
-      break;
     case kGLImplementationDesktopGL:
     case kGLImplementationAppleGL:
       InitializeDynamicGLBindingsGL(context);
diff --git a/ui/gl/gl_implementation_ozone.cc b/ui/gl/gl_implementation_ozone.cc
index 43b3b04..2a85720 100644
--- a/ui/gl/gl_implementation_ozone.cc
+++ b/ui/gl/gl_implementation_ozone.cc
@@ -75,12 +75,8 @@
                                  GLContext* context) {
   switch (implementation) {
     case kGLImplementationOSMesaGL:
-      InitializeDynamicGLBindingsGL(context);
-      InitializeDynamicGLBindingsOSMESA(context);
-      break;
     case kGLImplementationEGLGLES2:
       InitializeDynamicGLBindingsGL(context);
-      InitializeDynamicGLBindingsEGL(context);
       break;
     case kGLImplementationMockGL:
       if (!context) {
diff --git a/ui/gl/gl_implementation_win.cc b/ui/gl/gl_implementation_win.cc
index ff7d1d1..477f5a5 100644
--- a/ui/gl/gl_implementation_win.cc
+++ b/ui/gl/gl_implementation_win.cc
@@ -8,13 +8,13 @@
 #include "base/base_paths.h"
 #include "base/bind.h"
 #include "base/command_line.h"
-#include "base/debug/trace_event.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
 #include "base/native_library.h"
 #include "base/path_service.h"
 #include "base/strings/stringprintf.h"
 #include "base/threading/thread_restrictions.h"
+#include "base/trace_event/trace_event.h"
 #include "base/win/windows_version.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context_stub_with_extensions.h"
@@ -320,16 +320,9 @@
     GLContext* context) {
   switch (implementation) {
     case kGLImplementationOSMesaGL:
-      InitializeDynamicGLBindingsGL(context);
-      InitializeDynamicGLBindingsOSMESA(context);
-      break;
     case kGLImplementationEGLGLES2:
-      InitializeDynamicGLBindingsGL(context);
-      InitializeDynamicGLBindingsEGL(context);
-      break;
     case kGLImplementationDesktopGL:
       InitializeDynamicGLBindingsGL(context);
-      InitializeDynamicGLBindingsWGL(context);
       break;
     case kGLImplementationMockGL:
       if (!context) {
diff --git a/ui/gl/gl_implementation_x11.cc b/ui/gl/gl_implementation_x11.cc
index 28c1a3e..b8a7246 100644
--- a/ui/gl/gl_implementation_x11.cc
+++ b/ui/gl/gl_implementation_x11.cc
@@ -151,16 +151,9 @@
     GLContext* context) {
   switch (implementation) {
     case kGLImplementationOSMesaGL:
-      InitializeDynamicGLBindingsGL(context);
-      InitializeDynamicGLBindingsOSMESA(context);
-      break;
-    case kGLImplementationDesktopGL:
-      InitializeDynamicGLBindingsGL(context);
-      InitializeDynamicGLBindingsGLX(context);
-      break;
+   case kGLImplementationDesktopGL:
     case kGLImplementationEGLGLES2:
       InitializeDynamicGLBindingsGL(context);
-      InitializeDynamicGLBindingsEGL(context);
       break;
     case kGLImplementationMockGL:
       if (!context) {
diff --git a/ui/gl/gl_osmesa_api_implementation.cc b/ui/gl/gl_osmesa_api_implementation.cc
index f23c299..4fa33c6 100644
--- a/ui/gl/gl_osmesa_api_implementation.cc
+++ b/ui/gl/gl_osmesa_api_implementation.cc
@@ -17,10 +17,6 @@
   g_current_osmesa_context = g_real_osmesa;
 }
 
-void InitializeDynamicGLBindingsOSMESA(GLContext* context) {
-  g_driver_osmesa.InitializeDynamicBindings(context);
-}
-
 void InitializeDebugGLBindingsOSMESA() {
   g_driver_osmesa.InitializeDebugBindings();
 }
diff --git a/ui/gl/gl_osmesa_api_implementation.h b/ui/gl/gl_osmesa_api_implementation.h
index 9d4dbe1..c740e1a 100644
--- a/ui/gl/gl_osmesa_api_implementation.h
+++ b/ui/gl/gl_osmesa_api_implementation.h
@@ -14,7 +14,6 @@
 class GLContext;
 
 void InitializeStaticGLBindingsOSMESA();
-void InitializeDynamicGLBindingsOSMESA(GLContext* context);
 void InitializeDebugGLBindingsOSMESA();
 void ClearGLBindingsOSMESA();
 
diff --git a/ui/gl/gl_surface.cc b/ui/gl/gl_surface.cc
index 1ae458a..a827503 100644
--- a/ui/gl/gl_surface.cc
+++ b/ui/gl/gl_surface.cc
@@ -8,10 +8,10 @@
 #include <vector>
 
 #include "base/command_line.h"
-#include "base/debug/trace_event.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/threading/thread_local.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_implementation.h"
 #include "ui/gl/gl_switches.h"
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc
index 02c19e8..98a3a23 100644
--- a/ui/gl/gl_surface_egl.cc
+++ b/ui/gl/gl_surface_egl.cc
@@ -9,10 +9,10 @@
 #endif
 
 #include "base/command_line.h"
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
+#include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gl/egl_util.h"
diff --git a/ui/gl/gl_surface_egl.h b/ui/gl/gl_surface_egl.h
index b05f9bf..21669d7 100644
--- a/ui/gl/gl_surface_egl.h
+++ b/ui/gl/gl_surface_egl.h
@@ -49,6 +49,7 @@
 
  private:
 #if defined(OS_WIN)
+  friend struct DriverEGL;
   static EGLDisplay GetPlatformDisplay(EGLNativeDisplayType native_display);
 #endif
 
diff --git a/ui/gl/gl_surface_glx.cc b/ui/gl/gl_surface_glx.cc
index de888e5..5a3eafd 100644
--- a/ui/gl/gl_surface_glx.cc
+++ b/ui/gl/gl_surface_glx.cc
@@ -9,7 +9,6 @@
 #include "ui/gl/gl_surface_glx.h"
 
 #include "base/basictypes.h"
-#include "base/debug/trace_event.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
@@ -22,6 +21,7 @@
 #include "base/threading/non_thread_safe.h"
 #include "base/threading/thread.h"
 #include "base/time/time.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/events/platform/platform_event_source.h"
 #include "ui/gfx/x/x11_connection.h"
 #include "ui/gfx/x/x11_types.h"
diff --git a/ui/gl/gl_surface_mac.cc b/ui/gl/gl_surface_mac.cc
index 4b46244..4ba560d 100644
--- a/ui/gl/gl_surface_mac.cc
+++ b/ui/gl/gl_surface_mac.cc
@@ -7,9 +7,9 @@
 #include <OpenGL/CGLRenderers.h>
 
 #include "base/basictypes.h"
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_implementation.h"
diff --git a/ui/gl/gl_surface_wgl.cc b/ui/gl/gl_surface_wgl.cc
index 66cef26..698539f 100644
--- a/ui/gl/gl_surface_wgl.cc
+++ b/ui/gl/gl_surface_wgl.cc
@@ -4,9 +4,9 @@
 
 #include "ui/gl/gl_surface_wgl.h"
 
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_gl_api_implementation.h"
 #include "ui/gl/gl_wgl_api_implementation.h"
diff --git a/ui/gl/gl_surface_win.cc b/ui/gl/gl_surface_win.cc
index 0e10bac..1e509c9 100644
--- a/ui/gl/gl_surface_win.cc
+++ b/ui/gl/gl_surface_win.cc
@@ -7,9 +7,9 @@
 #include <dwmapi.h>
 
 #include "base/command_line.h"
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
+#include "base/trace_event/trace_event.h"
 #include "base/win/windows_version.h"
 #include "ui/gfx/frame_time.h"
 #include "ui/gfx/native_widget_types.h"
diff --git a/ui/gl/gl_surface_x11.cc b/ui/gl/gl_surface_x11.cc
index 895eb93..a384147 100644
--- a/ui/gl/gl_surface_x11.cc
+++ b/ui/gl/gl_surface_x11.cc
@@ -4,10 +4,10 @@
 
 #include "ui/gl/gl_surface.h"
 
-#include "base/debug/trace_event.h"
 #include "base/logging.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/message_loop.h"
+#include "base/trace_event/trace_event.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gfx/x/x11_types.h"
 #include "ui/gl/gl_bindings.h"
diff --git a/ui/gl/gl_version_info.cc b/ui/gl/gl_version_info.cc
index 0d052b5..e2aa0de 100644
--- a/ui/gl/gl_version_info.cc
+++ b/ui/gl/gl_version_info.cc
@@ -4,35 +4,35 @@
 
 #include "ui/gl/gl_version_info.h"
 
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_tokenizer.h"
 #include "base/strings/string_util.h"
 
 namespace gfx {
 
 GLVersionInfo::GLVersionInfo(const char* version_str, const char* renderer_str)
     : is_es(false),
-      is_es1(false),
-      is_es2(false),
-      is_es3(false),
-      is_gl1(false),
-      is_gl2(false),
-      is_gl3(false),
-      is_gl4(false),
-      is_angle(false) {
+      is_angle(false),
+      major_version(0),
+      minor_version(0),
+      is_es3(false) {
   if (version_str) {
     std::string lstr(base::StringToLowerASCII(std::string(version_str)));
-    is_es = (lstr.substr(0, 9) == "opengl es");
-    if (is_es) {
-      is_es1 = (lstr.substr(9, 2) == "-c" && lstr.substr(13, 2) == "1.");
-      is_es2 = (lstr.substr(9, 3) == " 2.");
-      is_es3 = (lstr.substr(9, 3) == " 3.");
-    } else {
-      is_gl2 = (lstr.substr(0, 2) == "2.");
-      is_gl3 = (lstr.substr(0, 2) == "3.");
-      is_gl4 = (lstr.substr(0, 2) == "4.");
-      // In early GL versions, GetString output format is implementation
-      // dependent.
-      is_gl1 = !is_gl2 && !is_gl3 && !is_gl4;
+    is_es = (lstr.length() > 12) && (lstr.substr(0, 9) == "opengl es");
+    if (is_es)
+      lstr = lstr.substr(10, 3);
+    base::StringTokenizer tokenizer(lstr.begin(), lstr.end(), ".");
+    unsigned major, minor;
+    if (tokenizer.GetNext() &&
+        base::StringToUint(tokenizer.token_piece(), &major)) {
+      major_version = major;
+      if (tokenizer.GetNext() &&
+          base::StringToUint(tokenizer.token_piece(), &minor)) {
+        minor_version = minor;
+      }
     }
+    if (is_es && major_version == 3)
+      is_es3 = true;
   }
   if (renderer_str) {
     is_angle = StartsWithASCII(renderer_str, "ANGLE", true);
diff --git a/ui/gl/gl_version_info.h b/ui/gl/gl_version_info.h
index 21ca07a..d8f2730 100644
--- a/ui/gl/gl_version_info.h
+++ b/ui/gl/gl_version_info.h
@@ -14,19 +14,21 @@
 struct GL_EXPORT GLVersionInfo {
   GLVersionInfo(const char* version_str, const char* renderer_str);
 
-  // New flags, such as is_gl4_4 could be introduced as needed.
-  // For now, this level of granularity is enough.
+  bool IsAtLeastGL(unsigned major, unsigned minor) const {
+    return !is_es && (major_version > major ||
+                      (major_version == major && minor_version >= minor));
+  }
+
+  bool IsAtLeastGLES(unsigned major, unsigned minor) const {
+    return is_es && (major_version > major ||
+                     (major_version == major && minor_version >= minor));
+  }
+
   bool is_es;
-  bool is_es1;
-  bool is_es2;
-  bool is_es3;
-
-  bool is_gl1;
-  bool is_gl2;
-  bool is_gl3;
-  bool is_gl4;
-
   bool is_angle;
+  unsigned major_version;
+  unsigned minor_version;
+  bool is_es3;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(GLVersionInfo);
diff --git a/ui/gl/gl_wgl_api_implementation.cc b/ui/gl/gl_wgl_api_implementation.cc
index 889a53f..3b92d98 100644
--- a/ui/gl/gl_wgl_api_implementation.cc
+++ b/ui/gl/gl_wgl_api_implementation.cc
@@ -18,10 +18,6 @@
   g_current_wgl_context = g_real_wgl;
 }
 
-void InitializeDynamicGLBindingsWGL(GLContext* context) {
-  g_driver_wgl.InitializeDynamicBindings(context);
-}
-
 void InitializeDebugGLBindingsWGL() {
   g_driver_wgl.InitializeDebugBindings();
 }
diff --git a/ui/gl/gl_wgl_api_implementation.h b/ui/gl/gl_wgl_api_implementation.h
index 07a5275..dbef51a 100644
--- a/ui/gl/gl_wgl_api_implementation.h
+++ b/ui/gl/gl_wgl_api_implementation.h
@@ -15,7 +15,6 @@
 struct GLWindowSystemBindingInfo;
 
 void InitializeStaticGLBindingsWGL();
-void InitializeDynamicGLBindingsWGL(GLContext* context);
 void InitializeDebugGLBindingsWGL();
 void ClearGLBindingsWGL();
 bool GetGLWindowSystemBindingInfoWGL(GLWindowSystemBindingInfo* info);