GrGLInterface.cpp revision 271cffc77bd2fcb3458559e509634442517ca1e9
159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com/*
259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    Copyright 2011 Google Inc.
359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    Licensed under the Apache License, Version 2.0 (the "License");
559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    you may not use this file except in compliance with the License.
659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    You may obtain a copy of the License at
759a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com         http://www.apache.org/licenses/LICENSE-2.0
959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
1059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    Unless required by applicable law or agreed to in writing, software
1159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    distributed under the License is distributed on an "AS IS" BASIS,
1259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    See the License for the specific language governing permissions and
1459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    limitations under the License.
1559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com */
1659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
1759a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
1859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com#include "GrTypes.h"
19f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com#include "GrGLInterface.h"
20f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com#include "GrGLDefines.h"
2159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
2259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com#include <stdio.h>
2359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
24f987d1b2348258970cae675135b6dedda079de48bsalomon@google.comGrGLInterface* gGLInterface = NULL;
2559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
2659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.comvoid gl_version_from_string(int* major, int* minor,
2759a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com                            const char* versionString) {
2859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    if (NULL == versionString) {
2959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        GrAssert(0);
3059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        *major = 0;
3159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        *minor = 0;
3259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        return;
3359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    }
340f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com
3559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    int n = sscanf(versionString, "%d.%d", major, minor);
360f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    if (2 == n) {
370f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com      return;
3859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    }
390f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com
4059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    char profile[2];
410f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com    n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
420f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com               major, minor);
4359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    bool ok = 4 == n;
4459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    if (!ok) {
450f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com        n = sscanf(versionString, "OpenGL ES %d.%d", major, minor);
4659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        ok = 2 == n;
4759a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    }
480f31ca79bde088e6caac219734c35c1ae3e9e8b9twiz@google.com
4959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    if (!ok) {
5059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        GrAssert(0);
5159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        *major = 0;
5259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        *minor = 0;
5359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        return;
5459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    }
5559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com}
5659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
5759a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.combool has_gl_extension_from_string(const char* ext,
5859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com                                  const char* extensionString) {
5959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    int extLength = strlen(ext);
6059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
6159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    while (true) {
6259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        int n = strcspn(extensionString, " ");
6359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
6459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com            return true;
6559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        }
6659a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        if (0 == extensionString[n]) {
6759a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com            return false;
6859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        }
6959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com        extensionString += n+1;
7059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    }
7159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
7259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    return false;
7359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com}
7459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
7559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
76918261018f7a7754a5e7f0fbb6ec96f9b269fd26bsalomon@google.comGR_API void GrGLSetGLInterface(GrGLInterface* gl_interface) {
7759a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    gGLInterface = gl_interface;
7859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com}
7959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
80918261018f7a7754a5e7f0fbb6ec96f9b269fd26bsalomon@google.comGR_API GrGLInterface* GrGLGetGLInterface() {
8159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    return gGLInterface;
8259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com}
8359a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
8459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.combool has_gl_extension(const char* ext) {
8559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    const char* glstr = reinterpret_cast<const char*>(
86f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com                GrGLGetGLInterface()->fGetString(GR_GL_EXTENSIONS));
8759a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
8859a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    return has_gl_extension_from_string(ext, glstr);
8959a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com}
9059a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com
9159a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.comvoid gl_version(int* major, int* minor) {
9259a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    const char* v = reinterpret_cast<const char*>(
93f987d1b2348258970cae675135b6dedda079de48bsalomon@google.com                GrGLGetGLInterface()->fGetString(GR_GL_VERSION));
9459a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com    gl_version_from_string(major, minor, v);
9559a190bcab5d4b2bf03f8f10cb6a581d19fed403twiz@google.com}
96bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
97bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.combool GrGLInterface::validateShaderFunctions() const {
98bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // required for GrGpuGLShaders
99bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (NULL == fAttachShader ||
100bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBindAttribLocation ||
101bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fCompileShader ||
102bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fCreateProgram ||
103bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fCreateShader ||
104bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDeleteProgram ||
105bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDeleteShader ||
106bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDisableVertexAttribArray ||
107bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fEnableVertexAttribArray ||
108bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetProgramInfoLog ||
109bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetProgramiv ||
110bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetShaderInfoLog ||
111bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetShaderiv ||
112bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetUniformLocation ||
113bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fLinkProgram ||
114bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fShaderSource ||
115bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform1f ||
116bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform1i ||
117bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform1fv ||
118bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform1iv ||
119bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform2f ||
120bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform2i ||
121bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform2fv ||
122bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform2iv ||
123bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform3f ||
124bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform3i ||
125bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform3fv ||
126bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform3iv ||
127bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform4f ||
128bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform4i ||
129bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform4fv ||
130bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniform4iv ||
131bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniformMatrix2fv ||
132bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniformMatrix3fv ||
133bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUniformMatrix4fv ||
134bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fUseProgram ||
135bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fVertexAttrib4fv ||
136bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fVertexAttribPointer) {
137bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        return false;
138bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
139bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    return true;
140bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com}
141bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
142bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.combool GrGLInterface::validateFixedFunctions() const {
143bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (NULL == fClientActiveTexture ||
144bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fColor4ub ||
145bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fColorPointer ||
146bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDisableClientState ||
147bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fEnableClientState ||
148bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fLoadMatrixf ||
149bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fMatrixMode ||
150bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fPointSize ||
151bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fShadeModel ||
152bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fTexCoordPointer ||
1534b9b6a20d4bc3147c7ab8b755264f3ddda0e0e04bsalomon@google.com        NULL == fTexEnvi ||
154bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fVertexPointer) {
155bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        return false;
156bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
157bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    return true;
158bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com}
159bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
160bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.combool GrGLInterface::validate(GrEngine engine) const {
161bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
162bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    bool isDesktop = kDesktop_GrGLBinding == fBindingsExported;
163bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
164bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // ES1 and 2 can be supported in the same interface
165bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    bool isES = ((kES1_GrGLBinding | kES2_GrGLBinding) & fBindingsExported &&
166bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                 !(~(kES1_GrGLBinding | kES2_GrGLBinding) & fBindingsExported));
167bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
168bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (!isDesktop && !isES) {
169bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        return false;
170bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
171bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
172bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // functions that are always required
173bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (NULL == fActiveTexture ||
174bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBindBuffer ||
175bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBindTexture ||
176bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBlendFunc ||
177bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBufferData ||
178bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBufferSubData ||
179bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fClear ||
180bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fClearColor ||
181bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fClearStencil ||
182bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fColorMask ||
183bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fCullFace ||
184bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDeleteBuffers ||
185bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDeleteTextures ||
186bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDepthMask ||
187bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDisable ||
188bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDrawArrays ||
189bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDrawElements ||
190bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fEnable ||
191bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fFrontFace ||
192bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGenBuffers ||
193bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGenTextures ||
194bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetBufferParameteriv ||
195bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetError ||
196bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetIntegerv ||
197bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGetString ||
198bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fPixelStorei ||
199bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fReadPixels ||
200bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fScissor ||
201bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fStencilFunc ||
202bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fStencilMask ||
203bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fStencilOp ||
204bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fTexImage2D ||
205bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fTexParameteri ||
206bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fTexSubImage2D ||
207bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fViewport ||
208bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBindFramebuffer ||
209bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fBindRenderbuffer ||
210bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fCheckFramebufferStatus ||
211bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDeleteFramebuffers ||
212bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fDeleteRenderbuffers ||
213bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fFramebufferRenderbuffer ||
214bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fFramebufferTexture2D ||
215bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGenFramebuffers ||
216bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fGenRenderbuffers ||
217bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fRenderbufferStorage) {
218bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        return false;
219bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
220bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
221bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    switch (engine) {
222bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        case kOpenGL_Shaders_GrEngine:
223bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (kES1_GrGLBinding == fBindingsExported) {
224bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
225bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
226bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (!this->validateShaderFunctions()) {
227bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
228bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
229bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            break;
230bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        case kOpenGL_Fixed_GrEngine:
231bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (kES1_GrGLBinding == fBindingsExported) {
232bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
233bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
234bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (!this->validateFixedFunctions()) {
235bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
236bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
237bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            break;
238bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        default:
239bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            return false;
240bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
241bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
242bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    int major, minor;
243bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    const char* ext;
244bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
245bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    gl_version(&major, &minor);
246bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    ext = (const char*)fGetString(GR_GL_EXTENSIONS);
247bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
248bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // Now check that baseline ES/Desktop fns not covered above are present
249bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // and that we have fn pointers for any advertised extensions that we will
250bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // try to use.
251bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
252bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // these functions are part of ES2, we assume they are available
253bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // On the desktop we assume they are available if the extension
254bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // is present or GL version is high enough.
255bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if ((kES2_GrGLBinding & fBindingsExported)) {
256bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (NULL == fBlendColor ||
257bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            NULL == fStencilFuncSeparate ||
258bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            NULL == fStencilMaskSeparate ||
259bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            NULL == fStencilOpSeparate) {
260bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            return false;
261bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
262bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    } else if (kDesktop_GrGLBinding == fBindingsExported) {
263bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (major >= 2) {
264bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (NULL == fStencilFuncSeparate ||
265bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fStencilMaskSeparate ||
266bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fStencilOpSeparate) {
267bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
268bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
269bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
270bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (1 < major || (1 == major && 4 <= minor) ||
271bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            has_gl_extension_from_string("GL_EXT_blend_color", ext)) {
272bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (NULL == fBlendColor) {
273bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
274bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
275bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
276bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
277bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
278bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // optional function on desktop before 1.3
279bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (kDesktop_GrGLBinding != fBindingsExported ||
280bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        (1 < major || (1 == major && 3 <= minor)) ||
281bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        has_gl_extension_from_string("GL_ARB_texture_compression", ext)) {
282bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (NULL == fCompressedTexImage2D) {
283bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            return false;
284bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
285bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
286bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
287bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // part of desktop GL
288bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (kDesktop_GrGLBinding == fBindingsExported &&
289bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        NULL == fLineWidth) {
290bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        return false;
291bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
292bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // FBO MSAA
293bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (kDesktop_GrGLBinding == fBindingsExported) {
294bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        // GL 3.0 and the ARB extension have multisample + blit
295bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if ((major >= 3) || has_gl_extension_from_string("GL_ARB_framebuffer_object", ext)) {
296bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (NULL == fRenderbufferStorageMultisample ||
297bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fBlitFramebuffer) {
298bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
299bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
300bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        } else {
301bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (has_gl_extension_from_string("GL_EXT_framebuffer_blit", ext) &&
302bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fBlitFramebuffer) {
303bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
304bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
305bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (has_gl_extension_from_string("GL_EXT_framebuffer_multisample", ext) &&
306bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fRenderbufferStorageMultisample) {
307bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
308bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
309bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
310bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    } else {
311bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (has_gl_extension_from_string("GL_CHROMIUM_framebuffer_multisample", ext)) {
312bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (NULL == fRenderbufferStorageMultisample ||
313bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fBlitFramebuffer) {
314bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
315bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
316bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
317bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (has_gl_extension_from_string("GL_APPLE_framebuffer_multisample", ext)) {
318bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            if (NULL == fRenderbufferStorageMultisample ||
319bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                NULL == fResolveMultisampleFramebuffer) {
320bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com                return false;
321bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            }
322bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
323bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
324bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
325bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // On ES buffer mapping is an extension. On Desktop
326bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // buffer mapping was part of original VBO extension
327bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    // which we require.
328bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    if (kDesktop_GrGLBinding == fBindingsExported  ||
329bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        has_gl_extension_from_string("GL_OES_mapbuffer", ext)) {
330bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        if (NULL == fMapBuffer ||
331bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            NULL == fUnmapBuffer) {
332bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com            return false;
333bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com        }
334bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    }
335bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
336271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    // Dual source blending
337271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    if (kDesktop_GrGLBinding == fBindingsExported  &&
338271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        (has_gl_extension_from_string("GL_ARB_blend_func_extended", ext) ||
339271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com         (3 < major) || (3 == major && 3 <= minor))) {
340271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        if (NULL == fBindFragDataLocationIndexed) {
341271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com            return false;
342271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com        }
343271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com    }
344271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com
345bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com    return true;
346bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com}
347bf2a46941e8fdebfcd24ea8f7184779021898225bsalomon@google.com
348