GrGLCreateNativeInterface_win.cpp revision c9668ecdb7188a90b050771727da899c54dc7013
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"
11373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com#define WIN32_LEAN_AND_MEAN
12f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com#include <Windows.h>
13f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com#include <GL/GL.h>
14f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
15f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com/*
16f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com * Windows makes the GL funcs all be __stdcall instead of __cdecl :(
17f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com * This implementation will only work if GR_GL_FUNCTION_TYPE is __stdcall.
18f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com * Otherwise, a springboard would be needed that hides the calling convention.
19f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com */
20f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
216fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com#define GR_GL_GET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F);
226fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com#define GR_GL_GET_PROC_SUFFIX(F, S) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F #S);
23747bf293d47d7437791caed8e8990370b57a7766tomhudson@google.com
24373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.comconst GrGLInterface* GrGLCreateNativeInterface() {
250b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com    // wglGetProcAddress requires a context.
266fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com    // GL Function pointers retrieved in one context may not be valid in another
276fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com    // context. For that reason we create a new GrGLInterface each time we're
286fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com    // called.
290b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com    if (NULL != wglGetCurrentContext()) {
300b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        const char* versionString = (const char*) glGetString(GL_VERSION);
310b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        const char* extString = (const char*) glGetString(GL_EXTENSIONS);
32c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com        GrGLVersion glVer = GrGLGetVersionFromString(versionString);
33f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
34c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com        if (glVer < GR_GL_VER(1,5)) {
350b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            // We must have array and element_array buffer objects.
366fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com            return NULL;
370b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        }
386fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        GrGLInterface* interface = new GrGLInterface();
39f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
400b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        // Functions that are part of GL 1.1 will return NULL in
410b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        // wglGetProcAddress
427d1276ff67bc8a03f1c62c10ed05dae87349f782bsalomon@google.com        interface->fBindTexture = glBindTexture;
436fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fBlendFunc = glBlendFunc;
446fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fClear = glClear;
456fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fClearColor = glClearColor;
466fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fClearStencil = glClearStencil;
476fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fColorMask = glColorMask;
486fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fColorPointer = glColorPointer;
496fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fCullFace = glCullFace;
506fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fDeleteTextures = glDeleteTextures;
516fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fDepthMask = glDepthMask;
526fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fDisable = glDisable;
536fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fDrawArrays = glDrawArrays;
546fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fDrawElements = glDrawElements;
556fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fDrawBuffer = glDrawBuffer;
566fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fEnable = glEnable;
576fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fFrontFace = glFrontFace;
58373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        interface->fFinish = glFinish;
59373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        interface->fFlush = glFlush;
606fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fGenTextures = glGenTextures;
616fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fGetError = glGetError;
626fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fGetIntegerv = glGetIntegerv;
636fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fGetString = glGetString;
646fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv;
656fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fLineWidth = glLineWidth;
666fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fPixelStorei = glPixelStorei;
676fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fReadBuffer = glReadBuffer;
686fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fReadPixels = glReadPixels;
696fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fScissor = glScissor;
706fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fStencilFunc = glStencilFunc;
716fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fStencilMask = glStencilMask;
726fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fStencilOp = glStencilOp;
736fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fTexImage2D = glTexImage2D;
746fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fTexParameteri = glTexParameteri;
75280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com        if (glVer >= GR_GL_VER(4,2) ||
76280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com            GrGLHasExtensionFromString("GL_ARB_texture_storage", extString)) {
77280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com            GR_GL_GET_PROC(TexStorage2D);
78280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com        } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", extString)) {
79280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(TexStorage2D, EXT);
80280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com        }
816fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fTexSubImage2D = glTexSubImage2D;
826fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fViewport = glViewport;
83f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
840b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(ActiveTexture);
850b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(AttachShader);
86f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(BeginQuery);
870b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(BindAttribLocation);
880b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(BindBuffer);
89bc5cf51627505f763586100675aa60b66d743c7ebsalomon@google.com        GR_GL_GET_PROC(BindFragDataLocation);
900b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(BlendColor);
910b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(BufferData);
920b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(BufferSubData);
930b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(CompileShader);
940b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(CompressedTexImage2D);
950b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(CreateProgram);
960b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(CreateShader);
970b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(DeleteBuffers);
98f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(DeleteQueries);
990b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(DeleteProgram);
1000b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(DeleteShader);
1010b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(DisableVertexAttribArray);
1020b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(DrawBuffers);
1030b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(EnableVertexAttribArray);
104f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(EndQuery);
1050b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GenBuffers);
106f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(GenQueries);
1070b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GetBufferParameteriv);
108f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(GetQueryiv);
109f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(GetQueryObjectiv);
110f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        GR_GL_GET_PROC(GetQueryObjectuiv);
111f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        if (glVer > GR_GL_VER(3,3) ||
112f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com            GrGLHasExtensionFromString("GL_ARB_timer_query", extString)) {
113f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com            GR_GL_GET_PROC(GetQueryObjecti64v);
114f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com            GR_GL_GET_PROC(GetQueryObjectui64v);
115f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com            GR_GL_GET_PROC(QueryCounter);
116f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extString)) {
117f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com            GR_GL_GET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
118e173992c2319205fdc263ccd10d7a9018c23013cbsalomon@google.com            GR_GL_GET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
119f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        }
1200b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GetProgramInfoLog);
1210b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GetProgramiv);
1220b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GetShaderInfoLog);
1230b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GetShaderiv);
1240b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(GetUniformLocation);
1250b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(LinkProgram);
126c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com        if (GrGLHasExtensionFromString("GL_NV_framebuffer_multisample_coverage", extString)) {
127c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisampleCoverage, NV);
128c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com        }
1290b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(ShaderSource);
1300b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(StencilFuncSeparate);
1310b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(StencilMaskSeparate);
1320b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(StencilOpSeparate);
1330b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform1f);
1340b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform1i);
1350b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform1fv);
1360b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform1iv);
1370b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform2f);
1380b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform2i);
1390b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform2fv);
1400b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform2iv);
1410b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform3f);
1420b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform3i);
1430b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform3fv);
1440b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform3iv);
1450b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform4f);
1460b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform4i);
1470b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform4fv);
1480b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(Uniform4iv);
1490b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(UniformMatrix2fv);
1500b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(UniformMatrix3fv);
1510b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(UniformMatrix4fv);
1520b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(UseProgram);
1530b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(VertexAttrib4fv);
1540b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(VertexAttribPointer);
1550b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(BindFragDataLocationIndexed);
156f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
1570b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
1580b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        // GL_ARB_framebuffer_object doesn't use ARB suffix.)
159c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com        if (glVer > GR_GL_VER(3,0) ||
160c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com            GrGLHasExtensionFromString("GL_ARB_framebuffer_object", extString)) {
1610b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(GenFramebuffers);
1620b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(GetFramebufferAttachmentParameteriv);
1630b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(GetRenderbufferParameteriv);
1640b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(BindFramebuffer);
1650b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(FramebufferTexture2D);
1660b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(CheckFramebufferStatus);
1670b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(DeleteFramebuffers);
1680b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(RenderbufferStorage);
1690b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(GenRenderbuffers);
1700b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(DeleteRenderbuffers);
1710b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(FramebufferRenderbuffer);
1720b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(BindRenderbuffer);
1730b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(RenderbufferStorageMultisample);
1740b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC(BlitFramebuffer);
175c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com        } else if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object",
176c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com                   extString)) {
1770b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT);
1780b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
1790b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
1800b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT);
1810b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, EXT);
1820b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
1830b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, EXT);
1840b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT);
1850b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT);
1860b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
1870b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
1880b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT);
189c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com            if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", extString)) {
1900b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com                GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
1910b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            }
192c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com            if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", extString)) {
1930b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com                GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT);
194f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com            }
1950b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        } else {
1960b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            // we must have FBOs
1976fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com            delete interface;
1986fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com            return NULL;
1990b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        }
2000b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(MapBuffer);
2010b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        GR_GL_GET_PROC(UnmapBuffer);
202f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
2036fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fBindingsExported = kDesktop_GrGLBinding;
204f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
2056fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        return interface;
2066fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com    } else {
2076fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        return NULL;
208f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com    }
209f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com}
210