GrGLCreateNativeInterface_win.cpp revision 4d063dea5ee9d5a62e3566a07cb8386cb1a59585
1f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com */
8f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
106c8c34e65ff8248ec7374e0d662d7f5684d800fatomhudson@google.com#include "gl/GrGLInterface.h"
119c1f1ac5d399c73f5f331bdf7b392ea7f0c44dafbsalomon@google.com#include "../GrGLUtil.h"
12373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com#define WIN32_LEAN_AND_MEAN
13f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com#include <Windows.h>
14f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com#include <GL/GL.h>
15f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
16f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com/*
17f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com * Windows makes the GL funcs all be __stdcall instead of __cdecl :(
18f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com * This implementation will only work if GR_GL_FUNCTION_TYPE is __stdcall.
19f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com * Otherwise, a springboard would be needed that hides the calling convention.
20f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com */
21f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
226fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com#define GR_GL_GET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F);
236fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com#define GR_GL_GET_PROC_SUFFIX(F, S) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F #S);
24747bf293d47d7437791caed8e8990370b57a7766tomhudson@google.com
25373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.comconst GrGLInterface* GrGLCreateNativeInterface() {
260b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com    // wglGetProcAddress requires a context.
276fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com    // GL Function pointers retrieved in one context may not be valid in another
286fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com    // context. For that reason we create a new GrGLInterface each time we're
296fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com    // called.
300b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com    if (NULL != wglGetCurrentContext()) {
310b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        const char* versionString = (const char*) glGetString(GL_VERSION);
320b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        const char* extString = (const char*) glGetString(GL_EXTENSIONS);
33c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com        GrGLVersion glVer = GrGLGetVersionFromString(versionString);
34f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
35c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com        if (glVer < GR_GL_VER(1,5)) {
360b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            // We must have array and element_array buffer objects.
376fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com            return NULL;
380b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        }
396fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        GrGLInterface* interface = new GrGLInterface();
40f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
410b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        // Functions that are part of GL 1.1 will return NULL in
420b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        // wglGetProcAddress
437d1276ff67bc8a03f1c62c10ed05dae87349f782bsalomon@google.com        interface->fBindTexture = glBindTexture;
446fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fBlendFunc = glBlendFunc;
45e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com
46e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com        if (glVer >= GR_GL_VER(1,4) ||
47e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com            GrGLHasExtensionFromString("GL_ARB_imaging", extString)) {
48e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com            GR_GL_GET_PROC(BlendColor);
49e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com            GR_GL_GET_PROC(BlendEquation);
50e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com        } else {
51e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com            if (GrGLHasExtensionFromString("GL_EXT_blend_color", extString)) {
52e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com                GR_GL_GET_PROC_SUFFIX(BlendColor, EXT);
53e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com            }
54e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com            if (GrGLHasExtensionFromString("GL_EXT_blend_minmax", extString) ||
55e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com                GrGLHasExtensionFromString("GL_EXT_blend_subtract", extString)) {
56e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com                GR_GL_GET_PROC_SUFFIX(BlendEquation, EXT);
57e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com            }
58e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com        }
59e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com
606fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fClear = glClear;
616fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fClearColor = glClearColor;
626fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fClearStencil = glClearStencil;
636fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fColorMask = glColorMask;
646fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fColorPointer = glColorPointer;
656fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fCullFace = glCullFace;
666fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fDeleteTextures = glDeleteTextures;
676fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fDepthMask = glDepthMask;
686fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fDisable = glDisable;
696fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fDrawArrays = glDrawArrays;
706fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fDrawElements = glDrawElements;
716fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fDrawBuffer = glDrawBuffer;
726fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fEnable = glEnable;
736fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fFrontFace = glFrontFace;
74373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        interface->fFinish = glFinish;
75373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        interface->fFlush = glFlush;
766fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fGenTextures = glGenTextures;
776fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fGetError = glGetError;
786fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fGetIntegerv = glGetIntegerv;
796fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fGetString = glGetString;
806fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv;
816fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fLineWidth = glLineWidth;
826fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fPixelStorei = glPixelStorei;
836fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fReadBuffer = glReadBuffer;
846fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fReadPixels = glReadPixels;
856fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fScissor = glScissor;
866fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fStencilFunc = glStencilFunc;
876fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fStencilMask = glStencilMask;
886fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fStencilOp = glStencilOp;
896fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fTexImage2D = glTexImage2D;
906fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fTexParameteri = glTexParameteri;
914d063dea5ee9d5a62e3566a07cb8386cb1a59585bsalomon@google.com        interface->fTexParameteriv = glTexParameteriv;
92280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com        if (glVer >= GR_GL_VER(4,2) ||
93280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com            GrGLHasExtensionFromString("GL_ARB_texture_storage", extString)) {
94280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com            GR_GL_GET_PROC(TexStorage2D);
95280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com        } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", extString)) {
96280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(TexStorage2D, EXT);
97280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com        }
986fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fTexSubImage2D = glTexSubImage2D;
996fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fViewport = glViewport;
100f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
1010b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(ActiveTexture);
1020b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(AttachShader);
103f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(BeginQuery);
1040b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(BindAttribLocation);
1050b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(BindBuffer);
106bc5cf51627505f763586100675aa60b66d743c7ebsalomon@google.com        GR_GL_GET_PROC(BindFragDataLocation);
1070b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(BufferData);
1080b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(BufferSubData);
1090b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(CompileShader);
1100b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(CompressedTexImage2D);
1110b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(CreateProgram);
1120b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(CreateShader);
1130b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(DeleteBuffers);
114f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(DeleteQueries);
1150b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(DeleteProgram);
1160b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(DeleteShader);
1170b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(DisableVertexAttribArray);
1180b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(DrawBuffers);
1190b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(EnableVertexAttribArray);
120f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(EndQuery);
1210b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GenBuffers);
122f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(GenQueries);
1230b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GetBufferParameteriv);
124f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(GetQueryiv);
125f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(GetQueryObjectiv);
126f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(GetQueryObjectuiv);
127f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        if (glVer > GR_GL_VER(3,3) ||
128f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com            GrGLHasExtensionFromString("GL_ARB_timer_query", extString)) {
129f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com            GR_GL_GET_PROC(GetQueryObjecti64v);
130f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com            GR_GL_GET_PROC(GetQueryObjectui64v);
131f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com            GR_GL_GET_PROC(QueryCounter);
132f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extString)) {
133f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com            GR_GL_GET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
134e173992c2319205fdc263ccd10d7a9018c23013cbsalomon@google.com            GR_GL_GET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
135f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        }
1360b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GetProgramInfoLog);
1370b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GetProgramiv);
1380b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GetShaderInfoLog);
1390b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GetShaderiv);
1400b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GetUniformLocation);
1410b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(LinkProgram);
142c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com        if (GrGLHasExtensionFromString("GL_NV_framebuffer_multisample_coverage", extString)) {
143c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisampleCoverage, NV);
144c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com        }
1450b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(ShaderSource);
1460b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(StencilFuncSeparate);
1470b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(StencilMaskSeparate);
1480b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(StencilOpSeparate);
1490b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform1f);
1500b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform1i);
1510b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform1fv);
1520b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform1iv);
1530b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform2f);
1540b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform2i);
1550b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform2fv);
1560b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform2iv);
1570b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform3f);
1580b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform3i);
1590b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform3fv);
1600b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform3iv);
1610b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform4f);
1620b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform4i);
1630b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform4fv);
1640b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform4iv);
1650b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(UniformMatrix2fv);
1660b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(UniformMatrix3fv);
1670b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(UniformMatrix4fv);
1680b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(UseProgram);
1690b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(VertexAttrib4fv);
1700b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(VertexAttribPointer);
1710b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(BindFragDataLocationIndexed);
172f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
1730b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
1740b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        // GL_ARB_framebuffer_object doesn't use ARB suffix.)
175c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com        if (glVer > GR_GL_VER(3,0) ||
176c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com            GrGLHasExtensionFromString("GL_ARB_framebuffer_object", extString)) {
1770b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(GenFramebuffers);
1780b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(GetFramebufferAttachmentParameteriv);
1790b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(GetRenderbufferParameteriv);
1800b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(BindFramebuffer);
1810b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(FramebufferTexture2D);
1820b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(CheckFramebufferStatus);
1830b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(DeleteFramebuffers);
1840b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(RenderbufferStorage);
1850b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(GenRenderbuffers);
1860b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(DeleteRenderbuffers);
1870b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(FramebufferRenderbuffer);
1880b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(BindRenderbuffer);
1890b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(RenderbufferStorageMultisample);
1900b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(BlitFramebuffer);
191c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com        } else if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object",
192c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com                   extString)) {
1930b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT);
1940b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
1950b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
1960b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT);
1970b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, EXT);
1980b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
1990b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, EXT);
2000b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT);
2010b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT);
2020b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
2030b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
2040b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT);
205c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com            if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", extString)) {
2060b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com                GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
2070b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            }
208c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com            if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", extString)) {
2090b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com                GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT);
210f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com            }
2110b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        } else {
2120b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            // we must have FBOs
2136fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com            delete interface;
2146fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com            return NULL;
2150b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        }
2160b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(MapBuffer);
2170b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(UnmapBuffer);
218f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
2196fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fBindingsExported = kDesktop_GrGLBinding;
220f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
2216fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        return interface;
2226fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com    } else {
2236fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        return NULL;
224f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com    }
225f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com}
226