13f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
23f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com/*
33f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * Copyright 2011 Google Inc.
43f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com *
53f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
63f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * found in the LICENSE file.
73f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com */
83f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
93f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
1086c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com#include "gl/GrGLExtensions.h"
1139ef825ac6dff4eb2a165b15dbdccdbfb5887984tomhudson@google.com#include "gl/GrGLInterface.h"
1286c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com#include "gl/GrGLUtil.h"
13d9f609a66ab7192670bf0ccbbc878ab2b398dab8bsalomon@google.com#define WIN32_LEAN_AND_MEAN
143f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com#include <Windows.h>
153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com/*
173f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * Windows makes the GL funcs all be __stdcall instead of __cdecl :(
183f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * This implementation will only work if GR_GL_FUNCTION_TYPE is __stdcall.
193f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com * Otherwise, a springboard would be needed that hides the calling convention.
203f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com */
213f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
2299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com#define SET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) GetProcAddress(alu.get(), "gl" #F);
2399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com#define WGL_SET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F);
2499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com#define WGL_SET_PROC_SUFFIX(F, S) interface->f ## F = \
2599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com                                  (GrGL ## F ## Proc) wglGetProcAddress("gl" #F #S);
2699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com
2799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.comclass AutoLibraryUnload {
2899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.compublic:
2999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com    AutoLibraryUnload(const char* moduleName) {
3099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        fModule = LoadLibrary(moduleName);
3199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com    }
3299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com    ~AutoLibraryUnload() {
3399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        if (NULL != fModule) {
3499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            FreeLibrary(fModule);
3599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        }
3699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com    }
3799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com    HMODULE get() const { return fModule; }
3899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com
3999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.comprivate:
4099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com    HMODULE fModule;
4199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com};
423f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
43d9f609a66ab7192670bf0ccbbc878ab2b398dab8bsalomon@google.comconst GrGLInterface* GrGLCreateNativeInterface() {
443f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    // wglGetProcAddress requires a context.
453f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    // GL Function pointers retrieved in one context may not be valid in another
46dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com    // context. For that reason we create a new GrGLInterface each time we're
473f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    // called.
4899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com    AutoLibraryUnload alu("opengl32.dll");
4999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com    if (NULL == alu.get()) {
5099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        return NULL;
5199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com    }
52f767ef027a3298fff43ea96239eff4c04b8d214dskia.committer@gmail.com
533f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    if (NULL != wglGetCurrentContext()) {
5486c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com
5586c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        // These should always be present and don't require wglGetProcAddress
5686c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        GrGLGetStringProc glGetString =
5786c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com            (GrGLGetStringProc) GetProcAddress(alu.get(), "glGetString");
5886c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        GrGLGetIntegervProc glGetIntegerv =
5986c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com            (GrGLGetIntegervProc) GetProcAddress(alu.get(), "glGetIntegerv");
6086c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        if (NULL == glGetString || NULL == glGetIntegerv) {
6186c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com            return NULL;
6286c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        }
6386c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com
6486c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        // This may or may not succeed depending on the gl version.
6586c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc)  wglGetProcAddress("glGetStringi");
6686c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com
6786c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        GrGLExtensions extensions;
6886c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        if (!extensions.init(kDesktop_GrGLBinding, glGetString, glGetStringi, glGetIntegerv)) {
6986c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com            return NULL;
7086c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        }
7199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        const char* versionString = (const char*) glGetString(GR_GL_VERSION);
723f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        GrGLVersion glVer = GrGLGetVersionFromString(versionString);
733f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
743f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        if (glVer < GR_GL_VER(1,5)) {
753f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            // We must have array and element_array buffer objects.
763f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            return NULL;
773f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        }
783f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        GrGLInterface* interface = new GrGLInterface();
793f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
803f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        // Functions that are part of GL 1.1 will return NULL in
813f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        // wglGetProcAddress
8299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(BindTexture)
8399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(BlendFunc)
84d26439670a7010ba518af5bb81f4d94d94ce8108robertphillips@google.com
85d26439670a7010ba518af5bb81f4d94d94ce8108robertphillips@google.com        if (glVer >= GR_GL_VER(1,4) ||
8686c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com            extensions.has("GL_ARB_imaging") ||
8786c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com            extensions.has("GL_EXT_blend_color")) {
8899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(BlendColor);
89aaefb11b6a32b499c47002326a8cae33f9468241bsalomon@google.com        }
90d26439670a7010ba518af5bb81f4d94d94ce8108robertphillips@google.com
9199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(Clear)
9299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(ClearColor)
9399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(ClearStencil)
9499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(ColorMask)
9588672fbe426b68b6981a96204de8aff8201dd29ccommit-bot@chromium.org        SET_PROC(CopyTexSubImage2D)
9699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(CullFace)
9799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(DeleteTextures)
9899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(DepthMask)
9999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(Disable)
10099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(DrawArrays)
10199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(DrawElements)
10299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(DrawBuffer)
10399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(Enable)
10499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(FrontFace)
10599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(Finish)
10699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(Flush)
10799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(GenTextures)
10899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(GetError)
10999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(GetIntegerv)
11099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(GetString)
11199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(GetTexLevelParameteriv)
11299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(LineWidth)
11399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(LoadIdentity)
11499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(LoadMatrixf)
11599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(MatrixMode)
11699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(PixelStorei)
11799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(ReadBuffer)
11899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(ReadPixels)
11999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(Scissor)
12099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(StencilFunc)
12199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(StencilMask)
12299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(StencilOp)
12399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(TexImage2D)
12499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(TexParameteri)
12599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(TexParameteriv)
12686c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) {
12799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(TexStorage2D);
12886c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        } else if (extensions.has("GL_EXT_texture_storage")) {
12999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(TexStorage2D, EXT);
130919a1375ba60823b849c648646af9326fbba87f7bsalomon@google.com        }
13199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(TexSubImage2D)
13299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        SET_PROC(Viewport)
1333f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
13499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(ActiveTexture);
13599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(AttachShader);
13699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(BeginQuery);
13799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(BindAttribLocation);
13899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(BindBuffer);
13999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(BindFragDataLocation);
14099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(BufferData);
14199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(BufferSubData);
14299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(CompileShader);
14399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(CompressedTexImage2D);
14499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(CreateProgram);
14599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(CreateShader);
14699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(DeleteBuffers);
14799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(DeleteQueries);
14899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(DeleteProgram);
14999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(DeleteShader);
15099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(DisableVertexAttribArray);
15199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(DrawBuffers);
15299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(EnableVertexAttribArray);
15399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(EndQuery);
15499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(GenBuffers);
155a67b348f7f66678e392b0f9e70cc738cc0c69007commit-bot@chromium.org        WGL_SET_PROC(GenerateMipmap);
15699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(GenQueries);
15799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(GetBufferParameteriv);
15899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(GetQueryiv);
15999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(GetQueryObjectiv);
16099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(GetQueryObjectuiv);
16186c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        if (glVer > GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) {
16299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(GetQueryObjecti64v);
16399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(GetQueryObjectui64v);
16499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(QueryCounter);
16586c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        } else if (extensions.has("GL_EXT_timer_query")) {
16699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
16799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
168e8db0d07b73867274b63ce25efbb1bdd0b8096b7bsalomon@google.com        }
16999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(GetProgramInfoLog);
17099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(GetProgramiv);
17199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(GetShaderInfoLog);
17299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(GetShaderiv);
17386c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        WGL_SET_PROC(GetStringi)
17499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(GetUniformLocation);
17599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(LinkProgram);
17686c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        if (extensions.has("GL_NV_framebuffer_multisample_coverage")) {
17799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisampleCoverage, NV);
17803269653c5444dd14eca80f51d16c700b864863fbsalomon@google.com        }
17999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(ShaderSource);
18099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(StencilFuncSeparate);
18199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(StencilMaskSeparate);
18299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(StencilOpSeparate);
18399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform1f);
18499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform1i);
18599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform1fv);
18699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform1iv);
18799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform2f);
18899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform2i);
18999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform2fv);
19099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform2iv);
19199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform3f);
19299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform3i);
19399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform3fv);
19499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform3iv);
19599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform4f);
19699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform4i);
19799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform4fv);
19899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(Uniform4iv);
19999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(UniformMatrix2fv);
20099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(UniformMatrix3fv);
20199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(UniformMatrix4fv);
20299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(UseProgram);
20399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(VertexAttrib4fv);
20499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(VertexAttribPointer);
20599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(BindFragDataLocationIndexed);
2063f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
2076ccccc065b1122fec12480699d10e7e7482a8b76bsalomon@google.com        if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_object")) {
2086ccccc065b1122fec12480699d10e7e7482a8b76bsalomon@google.com            // no ARB suffix for GL_ARB_vertex_array_object
2096ccccc065b1122fec12480699d10e7e7482a8b76bsalomon@google.com            WGL_SET_PROC(BindVertexArray);
2106ccccc065b1122fec12480699d10e7e7482a8b76bsalomon@google.com            WGL_SET_PROC(DeleteVertexArrays);
2116ccccc065b1122fec12480699d10e7e7482a8b76bsalomon@google.com            WGL_SET_PROC(GenVertexArrays);
2126ccccc065b1122fec12480699d10e7e7482a8b76bsalomon@google.com        }
2136ccccc065b1122fec12480699d10e7e7482a8b76bsalomon@google.com
2143f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
2153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        // GL_ARB_framebuffer_object doesn't use ARB suffix.)
2166ccccc065b1122fec12480699d10e7e7482a8b76bsalomon@google.com        if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) {
21799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(GenFramebuffers);
21899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(GetFramebufferAttachmentParameteriv);
21999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(GetRenderbufferParameteriv);
22099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(BindFramebuffer);
22199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(FramebufferTexture2D);
22299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(CheckFramebufferStatus);
22399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(DeleteFramebuffers);
22499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(RenderbufferStorage);
22599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(GenRenderbuffers);
22699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(DeleteRenderbuffers);
22799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(FramebufferRenderbuffer);
22899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(BindRenderbuffer);
22999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(RenderbufferStorageMultisample);
23099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC(BlitFramebuffer);
23186c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        } else if (extensions.has("GL_EXT_framebuffer_object")) {
23299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GenFramebuffers, EXT);
23399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
23499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
23599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(BindFramebuffer, EXT);
23699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(FramebufferTexture2D, EXT);
23799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
23899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(DeleteFramebuffers, EXT);
23999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(RenderbufferStorage, EXT);
24099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GenRenderbuffers, EXT);
24199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
24299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
24399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(BindRenderbuffer, EXT);
24486c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com            if (extensions.has("GL_EXT_framebuffer_multisample")) {
24599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com                WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
2463f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            }
24786c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com            if (extensions.has("GL_EXT_framebuffer_blit")) {
24899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com                WGL_SET_PROC_SUFFIX(BlitFramebuffer, EXT);
2493f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            }
2503f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        } else {
2513f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            // we must have FBOs
2523f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            delete interface;
2533f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com            return NULL;
2543f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        }
25599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(MapBuffer);
25699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com        WGL_SET_PROC(UnmapBuffer);
2573f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
25886c972c88eedf604db60ec44e32cefe9baf70243bsalomon@google.com        if (extensions.has("GL_NV_path_rendering")) {
25999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathCommands, NV);
26099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathCoords, NV);
26199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathSubCommands, NV);
26299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathSubCoords, NV);
26399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathString, NV);
26499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathGlyphs, NV);
26599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathGlyphRange, NV);
26699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(WeightPaths, NV);
26799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(CopyPath, NV);
26899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(InterpolatePaths, NV);
26999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(TransformPath, NV);
27099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathParameteriv, NV);
27199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathParameteri, NV);
27299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathParameterfv, NV);
27399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathParameterf, NV);
27499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathDashArray, NV);
27599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GenPaths, NV);
27699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(DeletePaths, NV);
27799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(IsPath, NV);
27899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathStencilFunc, NV);
27999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathStencilDepthOffset, NV);
28099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(StencilFillPath, NV);
28199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(StencilStrokePath, NV);
28299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(StencilFillPathInstanced, NV);
28399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(StencilStrokePathInstanced, NV);
28499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathCoverDepthFunc, NV);
28599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathColorGen, NV);
28699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathTexGen, NV);
28799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PathFogGen, NV);
28899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(CoverFillPath, NV);
28999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(CoverStrokePath, NV);
29099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(CoverFillPathInstanced, NV);
29199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(CoverStrokePathInstanced, NV);
29299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathParameteriv, NV);
29399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathParameterfv, NV);
29499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathCommands, NV);
29599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathCoords, NV);
29699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathDashArray, NV);
29799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathMetrics, NV);
29899e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathMetricRange, NV);
29999e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathSpacing, NV);
30099e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathColorGeniv, NV);
30199e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathColorGenfv, NV);
30299e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathTexGeniv, NV);
30399e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathTexGenfv, NV);
30499e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(IsPointInFillPath, NV);
30599e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(IsPointInStrokePath, NV);
30699e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(GetPathLength, NV);
30799e028d307c7e295ac0ba4c7c57d4152dc8dd579bsalomon@google.com            WGL_SET_PROC_SUFFIX(PointAlongPath, NV);
3081d6dfbd00d46e24d52fe06385effc7dd1d0d9aeabsalomon@google.com        }
3091d6dfbd00d46e24d52fe06385effc7dd1d0d9aeabsalomon@google.com
3103f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        interface->fBindingsExported = kDesktop_GrGLBinding;
3113f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com
3123f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        return interface;
3133f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    } else {
3143f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com        return NULL;
3153f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com    }
3163f30e3a41fc16816105e28e0d4c241eff6d391b4bsalomon@google.com}
317