GrGLInterface.cpp revision 096defe64d408e54474fe19f418c95bf1a554fc7
180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "gl/GrGLInterface.h"
10096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "gl/GrGLExtensions.h"
11096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#include "gl/GrGLUtil.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <stdio.h>
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_DEFINE_INST_COUNT(GrGLInterface)
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_GL_PER_GL_FUNC_CALLBACK
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace {
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrGLDefaultInterfaceCallback(const GrGLInterface*) {}
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrGLInterface::GrGLInterface() {
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fBindingsExported = kNone_GrGLBinding;
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_GL_PER_GL_FUNC_CALLBACK
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fCallback = GrGLDefaultInterfaceCallback;
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fCallbackData = 0;
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool GrGLInterface::validate(GrGLBinding binding) const {
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // kNone must be 0 so that the check we're about to do can never succeed if
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // binding == kNone.
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GR_STATIC_ASSERT(kNone_GrGLBinding == 0);
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (0 == (binding & fBindingsExported)) {
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
42096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    GrGLExtensions extensions;
43096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (!extensions.init(binding, this)) {
44096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        return false;
45096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
46096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // functions that are always required
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL == fActiveTexture ||
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fAttachShader ||
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fBindAttribLocation ||
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fBindBuffer ||
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fBindTexture ||
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fBlendFunc ||
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fBlendColor ||      // -> GL >= 1.4, ES >= 2.0 or extension
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fBufferData ||
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fBufferSubData ||
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fClear ||
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fClearColor ||
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fClearStencil ||
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fColorMask ||
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fCompileShader ||
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fCreateProgram ||
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fCreateShader ||
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fCullFace ||
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fDeleteBuffers ||
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fDeleteProgram ||
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fDeleteShader ||
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fDeleteTextures ||
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fDepthMask ||
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fDisable ||
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fDisableVertexAttribArray ||
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fDrawArrays ||
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fDrawElements ||
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fEnable ||
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fEnableVertexAttribArray ||
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fFrontFace ||
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGenBuffers ||
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGenTextures ||
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGetBufferParameteriv ||
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGetError ||
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGetIntegerv ||
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGetProgramInfoLog ||
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGetProgramiv ||
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGetShaderInfoLog ||
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGetShaderiv ||
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGetString ||
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGetUniformLocation ||
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fLinkProgram ||
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fPixelStorei ||
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fReadPixels ||
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fScissor ||
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fShaderSource ||
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fStencilFunc ||
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fStencilMask ||
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fStencilOp ||
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fTexImage2D ||
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fTexParameteri ||
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fTexParameteriv ||
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fTexSubImage2D ||
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform1f ||
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform1i ||
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform1fv ||
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform1iv ||
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform2f ||
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform2i ||
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform2fv ||
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform2iv ||
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform3f ||
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform3i ||
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform3fv ||
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform3iv ||
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform4f ||
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform4i ||
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform4fv ||
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniform4iv ||
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniformMatrix2fv ||
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniformMatrix3fv ||
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUniformMatrix4fv ||
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fUseProgram ||
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fVertexAttrib4fv ||
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fVertexAttribPointer ||
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fViewport ||
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fBindFramebuffer ||
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fBindRenderbuffer ||
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fCheckFramebufferStatus ||
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fDeleteFramebuffers ||
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fDeleteRenderbuffers ||
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fFinish ||
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fFlush ||
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fFramebufferRenderbuffer ||
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fFramebufferTexture2D ||
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGetFramebufferAttachmentParameteriv ||
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGetRenderbufferParameteriv ||
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGenFramebuffers ||
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fGenRenderbuffers ||
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        NULL == fRenderbufferStorage) {
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrGLVersion glVer = GrGLGetVersion(this);
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // Now check that baseline ES/Desktop fns not covered above are present
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // and that we have fn pointers for any advertised extensions that we will
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // try to use.
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // these functions are part of ES2, we assume they are available
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // On the desktop we assume they are available if the extension
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // is present or GL version is high enough.
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (kES2_GrGLBinding == binding) {
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL == fStencilFuncSeparate ||
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            NULL == fStencilMaskSeparate ||
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            NULL == fStencilOpSeparate) {
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else if (kDesktop_GrGLBinding == binding) {
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (glVer >= GR_GL_VER(2,0)) {
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (NULL == fStencilFuncSeparate ||
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fStencilMaskSeparate ||
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fStencilOpSeparate) {
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) {
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
167096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (glVer >= GR_GL_VER(2,0) || extensions.has("GL_ARB_draw_buffers")) {
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (NULL == fDrawBuffers) {
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
173096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (glVer >= GR_GL_VER(1,5) || extensions.has("GL_ARB_occlusion_query")) {
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (NULL == fGenQueries ||
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fDeleteQueries ||
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fBeginQuery ||
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fEndQuery ||
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetQueryiv ||
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetQueryObjectiv ||
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetQueryObjectuiv) {
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (glVer >= GR_GL_VER(3,3) ||
185096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            extensions.has("GL_ARB_timer_query") ||
186096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            extensions.has("GL_EXT_timer_query")) {
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (NULL == fGetQueryObjecti64v ||
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetQueryObjectui64v) {
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
192096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) {
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (NULL == fQueryCounter) {
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // The below two blocks are checks for functions used with
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // GL_NV_path_rendering. We're not enforcing that they be non-NULL
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // because they aren't actually called at this time.
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (false &&
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (NULL == fMatrixMode ||
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             NULL == fLoadIdentity ||
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru             NULL == fLoadMatrixf)) {
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
206096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (false && extensions.has("GL_NV_path_rendering")) {
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (NULL == fPathCommands ||
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathCoords ||
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathSubCommands ||
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathSubCoords ||
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathString ||
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathGlyphs ||
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathGlyphRange ||
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fWeightPaths ||
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fCopyPath ||
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fInterpolatePaths ||
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fTransformPath ||
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathParameteriv ||
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathParameteri ||
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathParameterfv ||
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathParameterf ||
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathDashArray ||
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGenPaths ||
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fDeletePaths ||
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fIsPath ||
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathStencilFunc ||
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathStencilDepthOffset ||
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fStencilFillPath ||
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fStencilStrokePath ||
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fStencilFillPathInstanced ||
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fStencilStrokePathInstanced ||
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathCoverDepthFunc ||
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathColorGen ||
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathTexGen ||
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPathFogGen ||
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fCoverFillPath ||
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fCoverStrokePath ||
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fCoverFillPathInstanced ||
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fCoverStrokePathInstanced ||
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathParameteriv ||
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathParameterfv ||
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathCommands ||
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathCoords ||
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathDashArray ||
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathMetrics ||
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathMetricRange ||
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathSpacing ||
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathColorGeniv ||
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathColorGenfv ||
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathTexGeniv ||
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathTexGenfv ||
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fIsPointInFillPath ||
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fIsPointInStrokePath ||
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fGetPathLength ||
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fPointAlongPath) {
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // optional function on desktop before 1.3
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (kDesktop_GrGLBinding != binding ||
263096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        (glVer >= GR_GL_VER(1,3)) ||
264096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        extensions.has("GL_ARB_texture_compression")) {
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL == fCompressedTexImage2D) {
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // part of desktop GL, but not ES
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (kDesktop_GrGLBinding == binding &&
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        (NULL == fLineWidth ||
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         NULL == fGetTexLevelParameteriv ||
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         NULL == fDrawBuffer ||
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru         NULL == fReadBuffer)) {
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // GL_EXT_texture_storage is part of desktop 4.2
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // There is a desktop ARB extension and an ES+desktop EXT extension
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (kDesktop_GrGLBinding == binding) {
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (glVer >= GR_GL_VER(4,2) ||
283096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            extensions.has("GL_ARB_texture_storage") ||
284096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            extensions.has("GL_EXT_texture_storage")) {
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (NULL == fTexStorage2D) {
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
289096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    } else if (extensions.has("GL_EXT_texture_storage")) {
29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL == fTexStorage2D) {
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // FBO MSAA
29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (kDesktop_GrGLBinding == binding) {
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // GL 3.0 and the ARB extension have multisample + blit
298096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) {
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (NULL == fRenderbufferStorageMultisample ||
30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fBlitFramebuffer) {
30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
304096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            if (extensions.has("GL_EXT_framebuffer_blit") &&
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fBlitFramebuffer) {
30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
308096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            if (extensions.has("GL_EXT_framebuffer_multisample") &&
30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fRenderbufferStorageMultisample) {
31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
314096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (extensions.has("GL_CHROMIUM_framebuffer_multisample")) {
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (NULL == fRenderbufferStorageMultisample ||
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fBlitFramebuffer) {
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
320096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (extensions.has("GL_APPLE_framebuffer_multisample")) {
32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (NULL == fRenderbufferStorageMultisample ||
32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                NULL == fResolveMultisampleFramebuffer) {
32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                return false;
32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
326096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (extensions.has("GL_IMG_multisampled_render_to_texture")) {
327096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            if (NULL == fRenderbufferStorageMultisample ||
328096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                NULL == fFramebufferTexture2DMultisample) {
329096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                return false;
330096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            }
331096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        }
33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // On ES buffer mapping is an extension. On Desktop
33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // buffer mapping was part of original VBO extension
33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // which we require.
337096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (kDesktop_GrGLBinding == binding || extensions.has("GL_OES_mapbuffer")) {
33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL == fMapBuffer ||
33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            NULL == fUnmapBuffer) {
34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // Dual source blending
34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (kDesktop_GrGLBinding == binding &&
346096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        (glVer >= GR_GL_VER(3,3) || extensions.has("GL_ARB_blend_func_extended"))) {
34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL == fBindFragDataLocationIndexed) {
34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
352096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (kDesktop_GrGLBinding == binding && glVer >= GR_GL_VER(3, 0)) {
353096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (NULL == fGetStringi) {
354096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            return false;
355096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        }
356096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
357096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
358096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (kDesktop_GrGLBinding == binding) {
359096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (glVer >= GR_GL_VER(3, 0) || extensions.has("GL_ARB_vertex_array_object")) {
360096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            if (NULL == fBindVertexArray ||
361096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                NULL == fDeleteVertexArrays ||
362096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                NULL == fGenVertexArrays) {
363096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                return false;
364096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            }
365096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        }
366096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    } else {
367096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (extensions.has("GL_OES_vertex_array_object")) {
368096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            if (NULL == fBindVertexArray ||
369096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                NULL == fDeleteVertexArrays ||
370096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                NULL == fGenVertexArrays) {
371096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                return false;
372096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            }
373096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        }
374096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    }
375096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
378