GrGLInterface.cpp revision d32c5f564e4aa9ada2650e07d3856d5b21cd2138
159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@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.
759a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com */
859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
10ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
1159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com#include "GrTypes.h"
12f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com#include "GrGLInterface.h"
13f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com#include "GrGLDefines.h"
1459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
1559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com#include <stdio.h>
1659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
17f987d1b2348258970cae675135b6dedda079de48bsalomon@google.comGrGLInterface* gGLInterface = NULL;
1859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
1959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.comvoid gl_version_from_string(int* major, int* minor,
2059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com                            const char* versionString) {
2159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    if (NULL == versionString) {
2259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        GrAssert(0);
2359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        *major = 0;
2459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        *minor = 0;
2559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        return;
2659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    }
270f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com
2859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    int n = sscanf(versionString, "%d.%d", major, minor);
290f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    if (2 == n) {
300f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com      return;
3159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    }
320f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com
3359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    char profile[2];
340f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
350f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com               major, minor);
3659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    bool ok = 4 == n;
3759a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    if (!ok) {
380f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com        n = sscanf(versionString, "OpenGL ES %d.%d", major, minor);
3959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        ok = 2 == n;
4059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    }
410f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com
4259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    if (!ok) {
4359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        GrAssert(0);
4459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        *major = 0;
4559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        *minor = 0;
4659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        return;
4759a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    }
4859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com}
4959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
502c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.comfloat gl_version_as_float_from_string(const char* versionString) {
512c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com    int major, minor;
522c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com    gl_version_from_string(&major, &minor, versionString);
532c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com    GrAssert(minor >= 0);
542c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com    // AFAIK there are only single digit minor numbers
552c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com    if (minor < 10) {
562c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com        return major + minor / 10.f;
572c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com    } else if (minor < 100) {
582c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com        return major + minor / 100.f;
592c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com    } else if (minor < 1000) {
602c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com        return major + minor / 1000.f;
612c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com    } else {
622c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com        GrAssert(!"Why so many digits in minor revision number?");
632c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com        char temp[32];
642c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com        sprintf(temp, "%d.%d", major, minor);
652c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com        return (float) atof(temp);
662c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com    }
672c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com}
682c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com
6959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.combool has_gl_extension_from_string(const char* ext,
7059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com                                  const char* extensionString) {
7159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    int extLength = strlen(ext);
7259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
7359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    while (true) {
7459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        int n = strcspn(extensionString, " ");
7559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
7659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com            return true;
7759a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        }
7859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        if (0 == extensionString[n]) {
7959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com            return false;
8059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        }
8159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        extensionString += n+1;
8259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    }
8359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
8459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    return false;
8559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com}
8659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
87918261018f7a7754a5e7f0fbb6ec96f9b269fd26bsalomon@google.comGR_API void GrGLSetGLInterface(GrGLInterface* gl_interface) {
8859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    gGLInterface = gl_interface;
8959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com}
9059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
91918261018f7a7754a5e7f0fbb6ec96f9b269fd26bsalomon@google.comGR_API GrGLInterface* GrGLGetGLInterface() {
9259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    return gGLInterface;
9359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com}
9459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
9559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.combool has_gl_extension(const char* ext) {
9659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    const char* glstr = reinterpret_cast<const char*>(
97f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com                GrGLGetGLInterface()->fGetString(GR_GL_EXTENSIONS));
9859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
9959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    return has_gl_extension_from_string(ext, glstr);
10059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com}
10159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
10259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.comvoid gl_version(int* major, int* minor) {
10359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    const char* v = reinterpret_cast<const char*>(
104f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com                GrGLGetGLInterface()->fGetString(GR_GL_VERSION));
10559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    gl_version_from_string(major, minor, v);
10659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com}
107bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
1082c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.comfloat gl_version_as_float() {
1092c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com    const char* v = reinterpret_cast<const char*>(
1102c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com                GrGLGetGLInterface()->fGetString(GR_GL_VERSION));
1112c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com    return gl_version_as_float_from_string(v);
1122c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com}
1132c17fcdc45f9fa9a2dc785786347040fbe30928bbsalomon@google.com
114bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.combool GrGLInterface::validateShaderFunctions() const {
115bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // required for GrGpuGLShaders
116bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (NULL == fAttachShader ||
117bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBindAttribLocation ||
118bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fCompileShader ||
119bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fCreateProgram ||
120bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fCreateShader ||
121bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDeleteProgram ||
122bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDeleteShader ||
123bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDisableVertexAttribArray ||
124bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fEnableVertexAttribArray ||
125bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetProgramInfoLog ||
126bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetProgramiv ||
127bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetShaderInfoLog ||
128bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetShaderiv ||
129bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetUniformLocation ||
130bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fLinkProgram ||
131bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fShaderSource ||
132bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform1f ||
133bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform1i ||
134bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform1fv ||
135bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform1iv ||
136bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform2f ||
137bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform2i ||
138bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform2fv ||
139bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform2iv ||
140bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform3f ||
141bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform3i ||
142bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform3fv ||
143bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform3iv ||
144bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform4f ||
145bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform4i ||
146bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform4fv ||
147bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform4iv ||
148bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniformMatrix2fv ||
149bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniformMatrix3fv ||
150bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniformMatrix4fv ||
151bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUseProgram ||
152bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fVertexAttrib4fv ||
153bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fVertexAttribPointer) {
154bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        return false;
155bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
156bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    return true;
157bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com}
158bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
159bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.combool GrGLInterface::validateFixedFunctions() const {
160bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (NULL == fClientActiveTexture ||
161bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fColor4ub ||
162bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fColorPointer ||
163bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDisableClientState ||
164bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fEnableClientState ||
165bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fLoadMatrixf ||
166bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fMatrixMode ||
167bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fPointSize ||
168bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fShadeModel ||
169bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fTexCoordPointer ||
1704b9b6a20d4bc3147c7ab8b755264f3ddda0e0e04bsalomon@google.com        NULL == fTexEnvi ||
171bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fVertexPointer) {
172bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        return false;
173bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
174bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    return true;
175bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com}
176bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
177bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.combool GrGLInterface::validate(GrEngine engine) const {
178bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
179bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    bool isDesktop = kDesktop_GrGLBinding == fBindingsExported;
180bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
181bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // ES1 and 2 can be supported in the same interface
182bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    bool isES = ((kES1_GrGLBinding | kES2_GrGLBinding) & fBindingsExported &&
183bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                 !(~(kES1_GrGLBinding | kES2_GrGLBinding) & fBindingsExported));
184bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
185bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (!isDesktop && !isES) {
186bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        return false;
187bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
188bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
189bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // functions that are always required
190bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (NULL == fActiveTexture ||
191bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBindBuffer ||
192bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBindTexture ||
193bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBlendFunc ||
194bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBufferData ||
195bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBufferSubData ||
196bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fClear ||
197bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fClearColor ||
198bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fClearStencil ||
199bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fColorMask ||
200bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fCullFace ||
201bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDeleteBuffers ||
202bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDeleteTextures ||
203bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDepthMask ||
204bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDisable ||
205bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDrawArrays ||
206bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDrawElements ||
207bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fEnable ||
208bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fFrontFace ||
209bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGenBuffers ||
210bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGenTextures ||
211bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetBufferParameteriv ||
212bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetError ||
213bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetIntegerv ||
214bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetString ||
215bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fPixelStorei ||
216bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fReadPixels ||
217bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fScissor ||
218bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fStencilFunc ||
219bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fStencilMask ||
220bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fStencilOp ||
221bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fTexImage2D ||
222bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fTexParameteri ||
223bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fTexSubImage2D ||
224bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fViewport ||
225bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBindFramebuffer ||
226bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBindRenderbuffer ||
227bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fCheckFramebufferStatus ||
228bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDeleteFramebuffers ||
229bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDeleteRenderbuffers ||
230bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fFramebufferRenderbuffer ||
231bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fFramebufferTexture2D ||
232cee661af926cc977addc6e039b7022975a448acebsalomon@google.com        NULL == fGetFramebufferAttachmentParameteriv ||
233cee661af926cc977addc6e039b7022975a448acebsalomon@google.com        NULL == fGetRenderbufferParameteriv ||
234bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGenFramebuffers ||
235bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGenRenderbuffers ||
236bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fRenderbufferStorage) {
237bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        return false;
238bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
239bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
240bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    switch (engine) {
241bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        case kOpenGL_Shaders_GrEngine:
242bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (kES1_GrGLBinding == fBindingsExported) {
243bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
244bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
245bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (!this->validateShaderFunctions()) {
246bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
247bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
248bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            break;
249bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        case kOpenGL_Fixed_GrEngine:
250bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (kES1_GrGLBinding == fBindingsExported) {
251bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
252bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
253bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (!this->validateFixedFunctions()) {
254bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
255bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
256bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            break;
257bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        default:
258bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            return false;
259bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
260bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
261bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    int major, minor;
262bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    const char* ext;
263bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
264bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    gl_version(&major, &minor);
265bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    ext = (const char*)fGetString(GR_GL_EXTENSIONS);
266bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
267bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // Now check that baseline ES/Desktop fns not covered above are present
268bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // and that we have fn pointers for any advertised extensions that we will
269bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // try to use.
270bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
271bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // these functions are part of ES2, we assume they are available
272bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // On the desktop we assume they are available if the extension
273bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // is present or GL version is high enough.
274bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if ((kES2_GrGLBinding & fBindingsExported)) {
275bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (NULL == fBlendColor ||
276bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            NULL == fStencilFuncSeparate ||
277bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            NULL == fStencilMaskSeparate ||
278bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            NULL == fStencilOpSeparate) {
279bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            return false;
280bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
281bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    } else if (kDesktop_GrGLBinding == fBindingsExported) {
282bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (major >= 2) {
283bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (NULL == fStencilFuncSeparate ||
284bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fStencilMaskSeparate ||
285bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fStencilOpSeparate) {
286bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
287bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
288bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
289d32c5f564e4aa9ada2650e07d3856d5b21cd2138bsalomon@google.com        if (major >= 2 ||
290d32c5f564e4aa9ada2650e07d3856d5b21cd2138bsalomon@google.com            has_gl_extension_from_string("GL_ARB_draw_buffers", ext)) {
291d32c5f564e4aa9ada2650e07d3856d5b21cd2138bsalomon@google.com            if (NULL == fDrawBuffers) {
292d32c5f564e4aa9ada2650e07d3856d5b21cd2138bsalomon@google.com                return false;
293d32c5f564e4aa9ada2650e07d3856d5b21cd2138bsalomon@google.com            }
294d32c5f564e4aa9ada2650e07d3856d5b21cd2138bsalomon@google.com        }
295bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (1 < major || (1 == major && 4 <= minor) ||
296bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            has_gl_extension_from_string("GL_EXT_blend_color", ext)) {
297bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (NULL == fBlendColor) {
298bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
299bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
300bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
301bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
302bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
303bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // optional function on desktop before 1.3
304bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (kDesktop_GrGLBinding != fBindingsExported ||
305bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        (1 < major || (1 == major && 3 <= minor)) ||
306bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        has_gl_extension_from_string("GL_ARB_texture_compression", ext)) {
307bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (NULL == fCompressedTexImage2D) {
308bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            return false;
309bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
310bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
311bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
312d32c5f564e4aa9ada2650e07d3856d5b21cd2138bsalomon@google.com    // part of desktop GL, but not ES
313bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (kDesktop_GrGLBinding == fBindingsExported &&
314cee661af926cc977addc6e039b7022975a448acebsalomon@google.com        (NULL == fLineWidth ||
315d32c5f564e4aa9ada2650e07d3856d5b21cd2138bsalomon@google.com         NULL == fGetTexLevelParameteriv ||
316d32c5f564e4aa9ada2650e07d3856d5b21cd2138bsalomon@google.com         NULL == fDrawBuffer)) {
317bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        return false;
318bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
319cee661af926cc977addc6e039b7022975a448acebsalomon@google.com
320bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // FBO MSAA
321bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (kDesktop_GrGLBinding == fBindingsExported) {
322bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        // GL 3.0 and the ARB extension have multisample + blit
323bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if ((major >= 3) || has_gl_extension_from_string("GL_ARB_framebuffer_object", ext)) {
324bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (NULL == fRenderbufferStorageMultisample ||
325bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fBlitFramebuffer) {
326bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
327bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
328bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        } else {
329bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (has_gl_extension_from_string("GL_EXT_framebuffer_blit", ext) &&
330bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fBlitFramebuffer) {
331bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
332bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
333bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (has_gl_extension_from_string("GL_EXT_framebuffer_multisample", ext) &&
334bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fRenderbufferStorageMultisample) {
335bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
336bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
337bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
338bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    } else {
339bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (has_gl_extension_from_string("GL_CHROMIUM_framebuffer_multisample", ext)) {
340bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (NULL == fRenderbufferStorageMultisample ||
341bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fBlitFramebuffer) {
342bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
343bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
344bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
345bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (has_gl_extension_from_string("GL_APPLE_framebuffer_multisample", ext)) {
346bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (NULL == fRenderbufferStorageMultisample ||
347bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fResolveMultisampleFramebuffer) {
348bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
349bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
350bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
351bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
352bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
353bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // On ES buffer mapping is an extension. On Desktop
354bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // buffer mapping was part of original VBO extension
355bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // which we require.
356bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (kDesktop_GrGLBinding == fBindingsExported  ||
357bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        has_gl_extension_from_string("GL_OES_mapbuffer", ext)) {
358bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (NULL == fMapBuffer ||
359bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            NULL == fUnmapBuffer) {
360bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            return false;
361bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
362bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
363bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
364271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    // Dual source blending
365271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    if (kDesktop_GrGLBinding == fBindingsExported  &&
366271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        (has_gl_extension_from_string("GL_ARB_blend_func_extended", ext) ||
367271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com         (3 < major) || (3 == major && 3 <= minor))) {
368271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        if (NULL == fBindFragDataLocationIndexed) {
369271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com            return false;
370271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        }
371271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    }
372271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com
373bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    return true;
374bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com}
375bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
376