180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gl/GrGLInterface.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "../GrGLUtil.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GL_GLEXT_PROTOTYPES
14d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "osmesa_wrapper.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GR_GL_GET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) \
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        OSMesaGetProcAddress("gl" #F);
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GR_GL_GET_PROC_SUFFIX(F, S) interface->f ## F = (GrGL ## F ## Proc) \
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        OSMesaGetProcAddress("gl" #F #S);
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// We use OSMesaGetProcAddress for every gl function to avoid accidentally using
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// non-Mesa gl functions.
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst GrGLInterface* GrGLCreateMesaInterface() {
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL != OSMesaGetCurrentContext()) {
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GrGLGetStringProc getString = (GrGLGetStringProc) OSMesaGetProcAddress("glGetString");
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const char* versionString = (const char*) getString(GL_VERSION);
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const char* extString = (const char*) getString(GL_EXTENSIONS);
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GrGLVersion glVer = GrGLGetVersionFromString(versionString);
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (glVer < GR_GL_VER(1,5)) {
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            // We must have array and element_array buffer objects.
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return NULL;
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GrGLInterface* interface = new GrGLInterface();
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(ActiveTexture);
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(BeginQuery);
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(AttachShader);
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(BindAttribLocation);
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(BindBuffer);
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(BindFragDataLocation);
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(BindTexture);
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(BlendFunc);
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (glVer >= GR_GL_VER(1,4) ||
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrGLHasExtensionFromString("GL_ARB_imaging", extString) ||
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrGLHasExtensionFromString("GL_EXT_blend_color", extString)) {
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(BlendColor);
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(BufferData);
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(BufferSubData);
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Clear);
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(ClearColor);
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(ClearStencil);
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(ColorMask);
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(CompileShader);
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(CompressedTexImage2D);
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(CreateProgram);
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(CreateShader);
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(CullFace);
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(DeleteBuffers);
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(DeleteProgram);
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(DeleteQueries);
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(DeleteShader);
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(DeleteTextures);
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(DepthMask);
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Disable);
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(DisableVertexAttribArray);
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(DrawArrays);
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(DrawBuffer);
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(DrawBuffers);
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(DrawElements);
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Enable);
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(EnableVertexAttribArray);
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(EndQuery);
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Finish);
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Flush);
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(FrontFace);
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GenBuffers);
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GenQueries);
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetBufferParameteriv);
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetError);
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetIntegerv);
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetProgramInfoLog);
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetProgramiv);
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (glVer >= GR_GL_VER(3,3) ||
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrGLHasExtensionFromString("GL_ARB_timer_query", extString)) {
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(GetQueryObjecti64v);
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(GetQueryObjectui64v)
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(QueryCounter);
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extString)) {
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetQueryObjectiv);
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetQueryObjectuiv);
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetQueryiv);
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetShaderInfoLog);
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetShaderiv);
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetString);
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetTexLevelParameteriv);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GenTextures);
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(GetUniformLocation);
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(LineWidth);
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(LinkProgram);
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(MapBuffer);
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(PixelStorei);
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(ReadBuffer);
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(ReadPixels);
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Scissor);
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(ShaderSource);
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(StencilFunc);
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(StencilFuncSeparate);
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(StencilMask);
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(StencilMaskSeparate);
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(StencilOp);
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(StencilOpSeparate);
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(TexImage2D)
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(TexParameteri);
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(TexParameteriv);
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(TexStorage2D);
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL == interface->fTexStorage2D) {
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(TexStorage2D, EXT);
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(TexSubImage2D);
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform1f);
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform1i);
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform1fv);
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform1iv);
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform2f);
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform2i);
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform2fv);
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform2iv);
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform3f);
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform3i);
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform3fv);
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform3iv);
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform4f);
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform4i);
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform4fv);
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Uniform4iv);
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(UniformMatrix2fv);
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(UniformMatrix3fv);
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(UniformMatrix4fv);
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(UnmapBuffer);
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(UseProgram);
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(VertexAttrib4fv);
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(VertexAttribPointer);
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(Viewport);
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // GL_ARB_framebuffer_object doesn't use ARB suffix.)
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (glVer >= GR_GL_VER(3,0) ||
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrGLHasExtensionFromString("GL_ARB_framebuffer_object",
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        extString)) {
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(GenFramebuffers);
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(GetFramebufferAttachmentParameteriv);
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(GetRenderbufferParameteriv);
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(BindFramebuffer);
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(FramebufferTexture2D);
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(CheckFramebufferStatus);
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(DeleteFramebuffers);
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(RenderbufferStorage);
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(GenRenderbuffers);
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(DeleteRenderbuffers);
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(FramebufferRenderbuffer);
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(BindRenderbuffer);
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(RenderbufferStorageMultisample);
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC(BlitFramebuffer);
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object",
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                              extString)) {
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(GenFramebuffers, EXT);
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(BindFramebuffer, EXT);
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(FramebufferTexture2D, EXT);
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(DeleteFramebuffers, EXT);
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(RenderbufferStorage, EXT);
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(GenRenderbuffers, EXT);
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GR_GL_GET_PROC_SUFFIX(BindRenderbuffer, EXT);
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample",
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                           extString)) {
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                GR_GL_GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit",
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                           extString)) {
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                GR_GL_GET_PROC_SUFFIX(BlitFramebuffer, EXT);
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            // we must have FBOs
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            delete interface;
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return NULL;
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_GET_PROC(BindFragDataLocationIndexed);
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        interface->fBindingsExported = kDesktop_GrGLBinding;
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return interface;
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return NULL;
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
206