GrGLCreateNativeInterface_win.cpp revision ecd84842b3f65918eb040c53391172b6413fd7ad
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
101744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com#include "gl/GrGLExtensions.h"
116c8c34e65ff8248ec7374e0d662d7f5684d800fatomhudson@google.com#include "gl/GrGLInterface.h"
121744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com#include "gl/GrGLUtil.h"
13373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com#define WIN32_LEAN_AND_MEAN
14f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com#include <Windows.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
22bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com#define SET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) GetProcAddress(alu.get(), "gl" #F);
23bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com#define WGL_SET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F);
24bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com#define WGL_SET_PROC_SUFFIX(F, S) interface->f ## F = \
25bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com                                  (GrGL ## F ## Proc) wglGetProcAddress("gl" #F #S);
26bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com
27bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.comclass AutoLibraryUnload {
28bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.compublic:
29bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com    AutoLibraryUnload(const char* moduleName) {
30bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        fModule = LoadLibrary(moduleName);
31bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com    }
32bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com    ~AutoLibraryUnload() {
33bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        if (NULL != fModule) {
34bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            FreeLibrary(fModule);
35bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        }
36bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com    }
37bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com    HMODULE get() const { return fModule; }
38bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com
39bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.comprivate:
40bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com    HMODULE fModule;
41bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com};
42747bf293d47d7437791caed8e8990370b57a7766tomhudson@google.com
43373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.comconst GrGLInterface* GrGLCreateNativeInterface() {
440b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com    // wglGetProcAddress requires a context.
456fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com    // GL Function pointers retrieved in one context may not be valid in another
46d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    // context. For that reason we create a new GrGLInterface each time we're
476fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com    // called.
48bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com    AutoLibraryUnload alu("opengl32.dll");
49bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com    if (NULL == alu.get()) {
50bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        return NULL;
51bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com    }
52ae683921ffda9108147a29da7319c7eee4dc9245skia.committer@gmail.com
530b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com    if (NULL != wglGetCurrentContext()) {
541744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com
551744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        // These should always be present and don't require wglGetProcAddress
561744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        GrGLGetStringProc glGetString =
571744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            (GrGLGetStringProc) GetProcAddress(alu.get(), "glGetString");
581744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        GrGLGetIntegervProc glGetIntegerv =
591744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            (GrGLGetIntegervProc) GetProcAddress(alu.get(), "glGetIntegerv");
601744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        if (NULL == glGetString || NULL == glGetIntegerv) {
611744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            return NULL;
621744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        }
631744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com
641744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        // This may or may not succeed depending on the gl version.
651744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc)  wglGetProcAddress("glGetStringi");
661744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com
671744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        GrGLExtensions extensions;
681744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        if (!extensions.init(kDesktop_GrGLBinding, glGetString, glGetStringi, glGetIntegerv)) {
691744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            return NULL;
701744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        }
71bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        const char* versionString = (const char*) glGetString(GR_GL_VERSION);
72c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com        GrGLVersion glVer = GrGLGetVersionFromString(versionString);
73f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
74c82b8899d97c2a26f5991bc771ad3beb8257edaebsalomon@google.com        if (glVer < GR_GL_VER(1,5)) {
750b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            // We must have array and element_array buffer objects.
766fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com            return NULL;
770b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        }
786fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        GrGLInterface* interface = new GrGLInterface();
79f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
800b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        // Functions that are part of GL 1.1 will return NULL in
810b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        // wglGetProcAddress
82bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(BindTexture)
83bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(BlendFunc)
84e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com
85e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com        if (glVer >= GR_GL_VER(1,4) ||
861744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            extensions.has("GL_ARB_imaging") ||
871744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            extensions.has("GL_EXT_blend_color")) {
88bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(BlendColor);
890efcc37952afb7629a5c905cc597f1cb837b987cbsalomon@google.com        }
90e788430144d1474329878abd1ddb39cc0ca52a0arobertphillips@google.com
91bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(Clear)
92bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(ClearColor)
93bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(ClearStencil)
94bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(ColorMask)
95bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(CullFace)
96bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(DeleteTextures)
97bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(DepthMask)
98bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(Disable)
99bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(DrawArrays)
100bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(DrawElements)
101bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(DrawBuffer)
102bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(Enable)
103bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(FrontFace)
104bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(Finish)
105bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(Flush)
106bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(GenTextures)
107bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(GetError)
108bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(GetIntegerv)
109bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(GetString)
110bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(GetTexLevelParameteriv)
111bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(LineWidth)
112bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(LoadIdentity)
113bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(LoadMatrixf)
114bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(MatrixMode)
115bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(PixelStorei)
116bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(ReadBuffer)
117bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(ReadPixels)
118bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(Scissor)
119bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(StencilFunc)
120bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(StencilMask)
121bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(StencilOp)
122bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(TexImage2D)
123bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(TexParameteri)
124bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(TexParameteriv)
1251744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) {
126bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(TexStorage2D);
1271744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        } else if (extensions.has("GL_EXT_texture_storage")) {
128bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(TexStorage2D, EXT);
129280e99f1a61f2cf66a8ee9b9e6c517f3d2290de7bsalomon@google.com        }
130bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(TexSubImage2D)
131bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        SET_PROC(Viewport)
132f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
133bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(ActiveTexture);
134bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(AttachShader);
135bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(BeginQuery);
136bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(BindAttribLocation);
137bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(BindBuffer);
138bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(BindFragDataLocation);
139bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(BufferData);
140bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(BufferSubData);
141bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(CompileShader);
142bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(CompressedTexImage2D);
143bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(CreateProgram);
144bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(CreateShader);
145bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(DeleteBuffers);
146bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(DeleteQueries);
147bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(DeleteProgram);
148bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(DeleteShader);
149bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(DisableVertexAttribArray);
150bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(DrawBuffers);
151bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(EnableVertexAttribArray);
152bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(EndQuery);
153bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(GenBuffers);
154bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(GenQueries);
155bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(GetBufferParameteriv);
156bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(GetQueryiv);
157bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(GetQueryObjectiv);
158bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(GetQueryObjectuiv);
1591744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        if (glVer > GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) {
160bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(GetQueryObjecti64v);
161bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(GetQueryObjectui64v);
162bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(QueryCounter);
1631744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        } else if (extensions.has("GL_EXT_timer_query")) {
164bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
165bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
166f97c194df7d38e45ae8bf03e276141c914ff6d8ebsalomon@google.com        }
167bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(GetProgramInfoLog);
168bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(GetProgramiv);
169bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(GetShaderInfoLog);
170bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(GetShaderiv);
1711744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        WGL_SET_PROC(GetStringi)
172bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(GetUniformLocation);
173bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(LinkProgram);
1741744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        if (extensions.has("GL_NV_framebuffer_multisample_coverage")) {
175bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisampleCoverage, NV);
176c9668ecdb7188a90b050771727da899c54dc7013bsalomon@google.com        }
177bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(ShaderSource);
178bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(StencilFuncSeparate);
179bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(StencilMaskSeparate);
180bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(StencilOpSeparate);
181bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform1f);
182bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform1i);
183bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform1fv);
184bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform1iv);
185bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform2f);
186bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform2i);
187bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform2fv);
188bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform2iv);
189bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform3f);
190bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform3i);
191bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform3fv);
192bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform3iv);
193bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform4f);
194bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform4i);
195bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform4fv);
196bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(Uniform4iv);
197bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(UniformMatrix2fv);
198bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(UniformMatrix3fv);
199bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(UniformMatrix4fv);
200bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(UseProgram);
201bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(VertexAttrib4fv);
202bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(VertexAttribPointer);
203bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(BindFragDataLocationIndexed);
204f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
205ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com        if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_object")) {
206ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com            // no ARB suffix for GL_ARB_vertex_array_object
207ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com            WGL_SET_PROC(BindVertexArray);
208ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com            WGL_SET_PROC(DeleteVertexArrays);
209ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com            WGL_SET_PROC(GenVertexArrays);
210ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com        }
211ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com
2120b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
2130b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        // GL_ARB_framebuffer_object doesn't use ARB suffix.)
214ecd84842b3f65918eb040c53391172b6413fd7adbsalomon@google.com        if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) {
215bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(GenFramebuffers);
216bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(GetFramebufferAttachmentParameteriv);
217bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(GetRenderbufferParameteriv);
218bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(BindFramebuffer);
219bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(FramebufferTexture2D);
220bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(CheckFramebufferStatus);
221bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(DeleteFramebuffers);
222bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(RenderbufferStorage);
223bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(GenRenderbuffers);
224bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(DeleteRenderbuffers);
225bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(FramebufferRenderbuffer);
226bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(BindRenderbuffer);
227bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(RenderbufferStorageMultisample);
228bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC(BlitFramebuffer);
2291744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        } else if (extensions.has("GL_EXT_framebuffer_object")) {
230bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GenFramebuffers, EXT);
231bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
232bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
233bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(BindFramebuffer, EXT);
234bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(FramebufferTexture2D, EXT);
235bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
236bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(DeleteFramebuffers, EXT);
237bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(RenderbufferStorage, EXT);
238bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GenRenderbuffers, EXT);
239bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
240bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
241bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(BindRenderbuffer, EXT);
2421744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            if (extensions.has("GL_EXT_framebuffer_multisample")) {
243bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com                WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
2440b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            }
2451744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com            if (extensions.has("GL_EXT_framebuffer_blit")) {
246bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com                WGL_SET_PROC_SUFFIX(BlitFramebuffer, EXT);
247f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com            }
2480b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        } else {
2490b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com            // we must have FBOs
2506fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com            delete interface;
2516fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com            return NULL;
2520b77d6892b067ad402c9678b0226bff70599fbe2bsalomon@google.com        }
253bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(MapBuffer);
254bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com        WGL_SET_PROC(UnmapBuffer);
255f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
2561744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        if (extensions.has("GL_NV_path_rendering")) {
257bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathCommands, NV);
258bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathCoords, NV);
259bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathSubCommands, NV);
260bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathSubCoords, NV);
261bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathString, NV);
262bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathGlyphs, NV);
263bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathGlyphRange, NV);
264bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(WeightPaths, NV);
265bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(CopyPath, NV);
266bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(InterpolatePaths, NV);
267bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(TransformPath, NV);
268bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathParameteriv, NV);
269bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathParameteri, NV);
270bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathParameterfv, NV);
271bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathParameterf, NV);
272bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathDashArray, NV);
273bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GenPaths, NV);
274bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(DeletePaths, NV);
275bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(IsPath, NV);
276bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathStencilFunc, NV);
277bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathStencilDepthOffset, NV);
278bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(StencilFillPath, NV);
279bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(StencilStrokePath, NV);
280bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(StencilFillPathInstanced, NV);
281bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(StencilStrokePathInstanced, NV);
282bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathCoverDepthFunc, NV);
283bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathColorGen, NV);
284bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathTexGen, NV);
285bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathFogGen, NV);
286bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(CoverFillPath, NV);
287bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(CoverStrokePath, NV);
288bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(CoverFillPathInstanced, NV);
289bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(CoverStrokePathInstanced, NV);
290bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathParameteriv, NV);
291bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathParameterfv, NV);
292bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathCommands, NV);
293bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathCoords, NV);
294bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathDashArray, NV);
295bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathMetrics, NV);
296bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathMetricRange, NV);
297bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathSpacing, NV);
298bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathColorGeniv, NV);
299bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathColorGenfv, NV);
300bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathTexGeniv, NV);
301bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathTexGenfv, NV);
302bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(IsPointInFillPath, NV);
303bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(IsPointInStrokePath, NV);
304bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathLength, NV);
305bc2f0e857a007bb645958aeed9d7e6a49ade0e66bsalomon@google.com            WGL_SET_PROC_SUFFIX(PointAlongPath, NV);
306fe11cb6486adfccc1a9ca9658ae25907192a8642bsalomon@google.com        }
307fe11cb6486adfccc1a9ca9658ae25907192a8642bsalomon@google.com
3086fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        interface->fBindingsExported = kDesktop_GrGLBinding;
309f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com
3106fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        return interface;
3116fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com    } else {
3126fb736fc2ea5f3f7ac44494211cc6755180ca192bsalomon@google.com        return NULL;
313f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com    }
314f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com}
315