blob: 75047cac4fc89617667d62db1d9dead8f2b500cf [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
twiz@google.com59a190b2011-03-14 21:23:01 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
twiz@google.com59a190b2011-03-14 21:23:01 +00007 */
8
9
twiz@google.com59a190b2011-03-14 21:23:01 +000010#include "GrTypes.h"
tomhudson@google.com6bf38b52012-02-14 15:11:59 +000011#include "gl/GrGLInterface.h"
12#include "gl/GrGLDefines.h"
twiz@google.com59a190b2011-03-14 21:23:01 +000013
14#include <stdio.h>
15
bsalomon@google.com56bfc5a2011-09-01 13:28:16 +000016#if GR_GL_PER_GL_FUNC_CALLBACK
17namespace {
18void GrGLDefaultInterfaceCallback(const GrGLInterface*) {}
19}
20#endif
21
bsalomon@google.com89ec61e2012-02-10 20:05:18 +000022GrGLBinding GrGLGetBindingInUseFromString(const char* versionString) {
23 if (NULL == versionString) {
24 GrAssert(!"NULL GL version string.");
25 return kNone_GrGLBinding;
26 }
27
28 int major, minor;
29
30 // check for desktop
31 int n = sscanf(versionString, "%d.%d", &major, &minor);
32 if (2 == n) {
33 return kDesktop_GrGLBinding;
34 }
35
36 // check for ES 1
37 char profile[2];
38 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
39 &major, &minor);
40 if (4 == n) {
41 // we no longer support ES1.
42 return kNone_GrGLBinding;
43 }
44
45 // check for ES2
46 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
47 if (2 == n) {
48 return kES2_GrGLBinding;
49 }
50 return kNone_GrGLBinding;
51}
52
bsalomon@google.comc82b8892011-09-22 14:10:33 +000053GrGLVersion GrGLGetVersionFromString(const char* versionString) {
bsalomon@google.comedfe1aa2011-09-29 14:40:26 +000054 if (NULL == versionString) {
55 GrAssert(!"NULL GL version string.");
56 return 0;
57 }
58
bsalomon@google.comc82b8892011-09-22 14:10:33 +000059 int major, minor;
twiz@google.com0f31ca72011-03-18 17:38:11 +000060
bsalomon@google.comc82b8892011-09-22 14:10:33 +000061 int n = sscanf(versionString, "%d.%d", &major, &minor);
twiz@google.com0f31ca72011-03-18 17:38:11 +000062 if (2 == n) {
bsalomon@google.comc82b8892011-09-22 14:10:33 +000063 return GR_GL_VER(major, minor);
twiz@google.com59a190b2011-03-14 21:23:01 +000064 }
twiz@google.com0f31ca72011-03-18 17:38:11 +000065
twiz@google.com59a190b2011-03-14 21:23:01 +000066 char profile[2];
twiz@google.com0f31ca72011-03-18 17:38:11 +000067 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
bsalomon@google.comc82b8892011-09-22 14:10:33 +000068 &major, &minor);
69 if (4 == n) {
70 return GR_GL_VER(major, minor);
71 }
72
73 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
74 if (2 == n) {
75 return GR_GL_VER(major, minor);
twiz@google.com59a190b2011-03-14 21:23:01 +000076 }
twiz@google.com0f31ca72011-03-18 17:38:11 +000077
bsalomon@google.comc82b8892011-09-22 14:10:33 +000078 return 0;
twiz@google.com59a190b2011-03-14 21:23:01 +000079}
80
bsalomon@google.comedfe1aa2011-09-29 14:40:26 +000081GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
82 if (NULL == versionString) {
83 GrAssert(!"NULL GLSL version string.");
84 return 0;
85 }
86
87 int major, minor;
88
89 int n = sscanf(versionString, "%d.%d", &major, &minor);
90 if (2 == n) {
91 return GR_GLSL_VER(major, minor);
92 }
93
94 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
95 if (2 == n) {
96 return GR_GLSL_VER(major, minor);
97 }
djsollen@google.com55e713c2012-03-20 15:28:14 +000098
99#ifdef SK_BUILD_FOR_ANDROID
100 // android hack until the gpu vender updates their drivers
101 n = sscanf(versionString, "OpenGL ES GLSL %d.%d", &major, &minor);
102 if (2 == n) {
103 return GR_GLSL_VER(major, minor);
104 }
105#endif
106
bsalomon@google.comedfe1aa2011-09-29 14:40:26 +0000107 return 0;
108}
109
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000110bool GrGLHasExtensionFromString(const char* ext, const char* extensionString) {
twiz@google.com59a190b2011-03-14 21:23:01 +0000111 int extLength = strlen(ext);
112
113 while (true) {
114 int n = strcspn(extensionString, " ");
115 if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
116 return true;
117 }
118 if (0 == extensionString[n]) {
119 return false;
120 }
121 extensionString += n+1;
122 }
123
124 return false;
125}
126
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000127bool GrGLHasExtension(const GrGLInterface* gl, const char* ext) {
bsalomon@google.comdca4aab2011-09-06 19:05:24 +0000128 const GrGLubyte* glstr;
129 GR_GL_CALL_RET(gl, glstr, GetString(GR_GL_EXTENSIONS));
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000130 return GrGLHasExtensionFromString(ext, (const char*) glstr);
twiz@google.com59a190b2011-03-14 21:23:01 +0000131}
132
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000133GrGLBinding GrGLGetBindingInUse(const GrGLInterface* gl) {
134 const GrGLubyte* v;
135 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
136 return GrGLGetBindingInUseFromString((const char*) v);
137}
138
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000139GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
bsalomon@google.comdca4aab2011-09-06 19:05:24 +0000140 const GrGLubyte* v;
141 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000142 return GrGLGetVersionFromString((const char*) v);
bsalomon@google.com2c17fcd2011-07-06 17:47:02 +0000143}
144
bsalomon@google.comedfe1aa2011-09-29 14:40:26 +0000145GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
146 const GrGLubyte* v;
147 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
148 return GrGLGetGLSLVersionFromString((const char*) v);
149}
150
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000151GrGLInterface::GrGLInterface() {
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000152 fBindingsExported = kNone_GrGLBinding;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000153
154 fActiveTexture = NULL;
155 fAttachShader = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000156 fBeginQuery = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000157 fBindAttribLocation = NULL;
158 fBindBuffer = NULL;
bsalomon@google.combc5cf512011-09-21 16:21:07 +0000159 fBindFragDataLocation = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000160 fBindTexture = NULL;
161 fBlendColor = NULL;
162 fBlendFunc = NULL;
163 fBufferData = NULL;
164 fBufferSubData = NULL;
165 fClear = NULL;
166 fClearColor = NULL;
167 fClearStencil = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000168 fColorMask = NULL;
169 fColorPointer = NULL;
170 fCompileShader = NULL;
171 fCompressedTexImage2D = NULL;
172 fCreateProgram = NULL;
173 fCreateShader = NULL;
174 fCullFace = NULL;
175 fDeleteBuffers = NULL;
176 fDeleteProgram = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000177 fDeleteQueries = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000178 fDeleteShader = NULL;
179 fDeleteTextures = NULL;
180 fDepthMask = NULL;
181 fDisable = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000182 fDisableVertexAttribArray = NULL;
183 fDrawArrays = NULL;
184 fDrawBuffer = NULL;
185 fDrawBuffers = NULL;
186 fDrawElements = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000187 fEndQuery = NULL;
188 fFinish = NULL;
189 fFlush = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000190 fEnable = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000191 fEnableVertexAttribArray = NULL;
192 fFrontFace = NULL;
193 fGenBuffers = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000194 fGenQueries = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000195 fGenTextures = NULL;
196 fGetBufferParameteriv = NULL;
197 fGetError = NULL;
198 fGetIntegerv = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000199 fGetQueryiv = NULL;
200 fGetQueryObjecti64v = NULL;
201 fGetQueryObjectiv = NULL;
202 fGetQueryObjectui64v = NULL;
203 fGetQueryObjectuiv = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000204 fGetProgramInfoLog = NULL;
205 fGetProgramiv = NULL;
206 fGetShaderInfoLog = NULL;
207 fGetShaderiv = NULL;
208 fGetString = NULL;
209 fGetTexLevelParameteriv = NULL;
210 fGetUniformLocation = NULL;
211 fLineWidth = NULL;
212 fLinkProgram = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000213 fPixelStorei = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000214 fQueryCounter = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000215 fReadBuffer = NULL;
216 fReadPixels = NULL;
217 fScissor = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000218 fShaderSource = NULL;
219 fStencilFunc = NULL;
220 fStencilFuncSeparate = NULL;
221 fStencilMask = NULL;
222 fStencilMaskSeparate = NULL;
223 fStencilOp = NULL;
224 fStencilOpSeparate = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000225 fTexImage2D = NULL;
226 fTexParameteri = NULL;
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000227 fTexStorage2D = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000228 fTexSubImage2D = NULL;
229 fUniform1f = NULL;
230 fUniform1i = NULL;
231 fUniform1fv = NULL;
232 fUniform1iv = NULL;
233 fUniform2f = NULL;
234 fUniform2i = NULL;
235 fUniform2fv = NULL;
236 fUniform2iv = NULL;
237 fUniform3f = NULL;
238 fUniform3i = NULL;
239 fUniform3fv = NULL;
240 fUniform3iv = NULL;
241 fUniform4f = NULL;
242 fUniform4i = NULL;
243 fUniform4fv = NULL;
244 fUniform4iv = NULL;
245 fUniformMatrix2fv = NULL;
246 fUniformMatrix3fv = NULL;
247 fUniformMatrix4fv = NULL;
248 fUseProgram = NULL;
249 fVertexAttrib4fv = NULL;
250 fVertexAttribPointer = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000251 fViewport = NULL;
252 fBindFramebuffer = NULL;
253 fBindRenderbuffer = NULL;
254 fCheckFramebufferStatus = NULL;
255 fDeleteFramebuffers = NULL;
256 fDeleteRenderbuffers = NULL;
257 fFramebufferRenderbuffer = NULL;
258 fFramebufferTexture2D = NULL;
259 fGenFramebuffers = NULL;
260 fGenRenderbuffers = NULL;
261 fGetFramebufferAttachmentParameteriv = NULL;
262 fGetRenderbufferParameteriv = NULL;
263 fRenderbufferStorage = NULL;
264 fRenderbufferStorageMultisample = NULL;
265 fBlitFramebuffer = NULL;
266 fResolveMultisampleFramebuffer = NULL;
267 fMapBuffer = NULL;
268 fUnmapBuffer = NULL;
269 fBindFragDataLocationIndexed = NULL;
bsalomon@google.com56bfc5a2011-09-01 13:28:16 +0000270
271#if GR_GL_PER_GL_FUNC_CALLBACK
272 fCallback = GrGLDefaultInterfaceCallback;
273 fCallbackData = 0;
274#endif
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000275}
276
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000277bool GrGLInterface::validate(GrGLBinding binding) const {
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000278
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000279 // kNone must be 0 so that the check we're about to do can never succeed if
280 // binding == kNone.
281 GR_STATIC_ASSERT(kNone_GrGLBinding == 0);
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000282
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000283 if (0 == (binding & fBindingsExported)) {
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000284 return false;
285 }
286
287 // functions that are always required
288 if (NULL == fActiveTexture ||
289 NULL == fAttachShader ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000290 NULL == fBindAttribLocation ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000291 NULL == fBindBuffer ||
292 NULL == fBindTexture ||
293 NULL == fBlendFunc ||
294 NULL == fBufferData ||
295 NULL == fBufferSubData ||
296 NULL == fClear ||
297 NULL == fClearColor ||
298 NULL == fClearStencil ||
299 NULL == fColorMask ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000300 NULL == fCompileShader ||
301 NULL == fCreateProgram ||
302 NULL == fCreateShader ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000303 NULL == fCullFace ||
304 NULL == fDeleteBuffers ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000305 NULL == fDeleteProgram ||
306 NULL == fDeleteShader ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000307 NULL == fDeleteTextures ||
308 NULL == fDepthMask ||
309 NULL == fDisable ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000310 NULL == fDisableVertexAttribArray ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000311 NULL == fDrawArrays ||
312 NULL == fDrawElements ||
313 NULL == fEnable ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000314 NULL == fEnableVertexAttribArray ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000315 NULL == fFrontFace ||
316 NULL == fGenBuffers ||
317 NULL == fGenTextures ||
318 NULL == fGetBufferParameteriv ||
319 NULL == fGetError ||
320 NULL == fGetIntegerv ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000321 NULL == fGetProgramInfoLog ||
322 NULL == fGetProgramiv ||
323 NULL == fGetShaderInfoLog ||
324 NULL == fGetShaderiv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000325 NULL == fGetString ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000326 NULL == fGetUniformLocation ||
327 NULL == fLinkProgram ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000328 NULL == fPixelStorei ||
329 NULL == fReadPixels ||
330 NULL == fScissor ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000331 NULL == fShaderSource ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000332 NULL == fStencilFunc ||
333 NULL == fStencilMask ||
334 NULL == fStencilOp ||
335 NULL == fTexImage2D ||
336 NULL == fTexParameteri ||
337 NULL == fTexSubImage2D ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000338 NULL == fUniform1f ||
339 NULL == fUniform1i ||
340 NULL == fUniform1fv ||
341 NULL == fUniform1iv ||
342 NULL == fUniform2f ||
343 NULL == fUniform2i ||
344 NULL == fUniform2fv ||
345 NULL == fUniform2iv ||
346 NULL == fUniform3f ||
347 NULL == fUniform3i ||
348 NULL == fUniform3fv ||
349 NULL == fUniform3iv ||
350 NULL == fUniform4f ||
351 NULL == fUniform4i ||
352 NULL == fUniform4fv ||
353 NULL == fUniform4iv ||
354 NULL == fUniformMatrix2fv ||
355 NULL == fUniformMatrix3fv ||
356 NULL == fUniformMatrix4fv ||
357 NULL == fUseProgram ||
358 NULL == fVertexAttrib4fv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000359 NULL == fVertexAttribPointer ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000360 NULL == fViewport ||
361 NULL == fBindFramebuffer ||
362 NULL == fBindRenderbuffer ||
363 NULL == fCheckFramebufferStatus ||
364 NULL == fDeleteFramebuffers ||
365 NULL == fDeleteRenderbuffers ||
bsalomon@google.com373a6632011-10-19 20:43:20 +0000366 NULL == fFinish ||
367 NULL == fFlush ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000368 NULL == fFramebufferRenderbuffer ||
369 NULL == fFramebufferTexture2D ||
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000370 NULL == fGetFramebufferAttachmentParameteriv ||
371 NULL == fGetRenderbufferParameteriv ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000372 NULL == fGenFramebuffers ||
373 NULL == fGenRenderbuffers ||
374 NULL == fRenderbufferStorage) {
375 return false;
376 }
377
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000378 const char* ext;
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000379 GrGLVersion glVer = GrGLGetVersion(this);
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000380 ext = (const char*)fGetString(GR_GL_EXTENSIONS);
381
382 // Now check that baseline ES/Desktop fns not covered above are present
383 // and that we have fn pointers for any advertised extensions that we will
384 // try to use.
385
386 // these functions are part of ES2, we assume they are available
387 // On the desktop we assume they are available if the extension
388 // is present or GL version is high enough.
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000389 if (kES2_GrGLBinding == binding) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000390 if (NULL == fBlendColor ||
391 NULL == fStencilFuncSeparate ||
392 NULL == fStencilMaskSeparate ||
393 NULL == fStencilOpSeparate) {
394 return false;
395 }
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000396 } else if (kDesktop_GrGLBinding == binding) {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000397 if (glVer >= GR_GL_VER(2,0)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000398 if (NULL == fStencilFuncSeparate ||
399 NULL == fStencilMaskSeparate ||
400 NULL == fStencilOpSeparate) {
401 return false;
402 }
403 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000404 if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) {
bsalomon@google.combc5cf512011-09-21 16:21:07 +0000405 return false;
406 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000407 if (glVer >= GR_GL_VER(2,0) ||
408 GrGLHasExtensionFromString("GL_ARB_draw_buffers", ext)) {
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000409 if (NULL == fDrawBuffers) {
410 return false;
411 }
412 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000413 if (glVer >= GR_GL_VER(1,4) ||
414 GrGLHasExtensionFromString("GL_EXT_blend_color", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000415 if (NULL == fBlendColor) {
416 return false;
417 }
418 }
bsalomon@google.com373a6632011-10-19 20:43:20 +0000419 if (glVer >= GR_GL_VER(1,5) ||
420 GrGLHasExtensionFromString("GL_ARB_occlusion_query", ext)) {
421 if (NULL == fGenQueries ||
422 NULL == fDeleteQueries ||
423 NULL == fBeginQuery ||
424 NULL == fEndQuery ||
425 NULL == fGetQueryiv ||
426 NULL == fGetQueryObjectiv ||
427 NULL == fGetQueryObjectuiv) {
428 return false;
429 }
430 }
431 if (glVer >= GR_GL_VER(3,3) ||
432 GrGLHasExtensionFromString("GL_ARB_timer_query", ext) ||
433 GrGLHasExtensionFromString("GL_EXT_timer_query", ext)) {
434 if (NULL == fGetQueryObjecti64v ||
435 NULL == fGetQueryObjectui64v) {
436 return false;
437 }
438 }
439 if (glVer >= GR_GL_VER(3,3) ||
440 GrGLHasExtensionFromString("GL_ARB_timer_query", ext)) {
441 if (NULL == fQueryCounter) {
442 return false;
443 }
444 }
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000445 }
446
447 // optional function on desktop before 1.3
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000448 if (kDesktop_GrGLBinding != binding ||
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000449 (glVer >= GR_GL_VER(1,3) ||
450 GrGLHasExtensionFromString("GL_ARB_texture_compression", ext))) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000451 if (NULL == fCompressedTexImage2D) {
452 return false;
453 }
454 }
455
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000456 // part of desktop GL, but not ES
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000457 if (kDesktop_GrGLBinding == binding &&
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000458 (NULL == fLineWidth ||
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000459 NULL == fGetTexLevelParameteriv ||
bsalomon@google.comc49d66b2011-08-03 14:22:30 +0000460 NULL == fDrawBuffer ||
461 NULL == fReadBuffer)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000462 return false;
463 }
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000464
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000465 // GL_EXT_texture_storage is part of desktop 4.2
466 // There is a desktop ARB extension and an ES+desktop EXT extension
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000467 if (kDesktop_GrGLBinding == binding) {
bsalomon@google.combaa9ea12012-01-06 19:05:43 +0000468 if (glVer >= GR_GL_VER(4,2) ||
469 GrGLHasExtensionFromString("GL_ARB_texture_storage", ext) ||
470 GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) {
471 if (NULL == fTexStorage2D) {
472 return false;
473 }
474 }
475 } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) {
476 if (NULL == fTexStorage2D) {
477 return false;
478 }
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000479 }
480
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000481 // FBO MSAA
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000482 if (kDesktop_GrGLBinding == binding) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000483 // GL 3.0 and the ARB extension have multisample + blit
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000484 if (glVer >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_framebuffer_object", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000485 if (NULL == fRenderbufferStorageMultisample ||
486 NULL == fBlitFramebuffer) {
487 return false;
488 }
489 } else {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000490 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", ext) &&
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000491 NULL == fBlitFramebuffer) {
492 return false;
493 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000494 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", ext) &&
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000495 NULL == fRenderbufferStorageMultisample) {
496 return false;
497 }
498 }
499 } else {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000500 if (GrGLHasExtensionFromString("GL_CHROMIUM_framebuffer_multisample", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000501 if (NULL == fRenderbufferStorageMultisample ||
502 NULL == fBlitFramebuffer) {
503 return false;
504 }
505 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000506 if (GrGLHasExtensionFromString("GL_APPLE_framebuffer_multisample", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000507 if (NULL == fRenderbufferStorageMultisample ||
508 NULL == fResolveMultisampleFramebuffer) {
509 return false;
510 }
511 }
512 }
513
514 // On ES buffer mapping is an extension. On Desktop
515 // buffer mapping was part of original VBO extension
516 // which we require.
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000517 if (kDesktop_GrGLBinding == binding ||
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000518 GrGLHasExtensionFromString("GL_OES_mapbuffer", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000519 if (NULL == fMapBuffer ||
520 NULL == fUnmapBuffer) {
521 return false;
522 }
523 }
524
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000525 // Dual source blending
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000526 if (kDesktop_GrGLBinding == binding &&
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000527 (glVer >= GR_GL_VER(3,3) ||
528 GrGLHasExtensionFromString("GL_ARB_blend_func_extended", ext))) {
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000529 if (NULL == fBindFragDataLocationIndexed) {
530 return false;
531 }
532 }
533
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000534 return true;
535}
536