blob: c1ac088b5f11f0ae30fe8afab81f943c38d768e6 [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"
bsalomon@google.comf987d1b2011-04-04 17:13:52 +000011#include "GrGLInterface.h"
12#include "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 }
98 return 0;
99}
100
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000101bool GrGLHasExtensionFromString(const char* ext, const char* extensionString) {
twiz@google.com59a190b2011-03-14 21:23:01 +0000102 int extLength = strlen(ext);
103
104 while (true) {
105 int n = strcspn(extensionString, " ");
106 if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
107 return true;
108 }
109 if (0 == extensionString[n]) {
110 return false;
111 }
112 extensionString += n+1;
113 }
114
115 return false;
116}
117
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000118bool GrGLHasExtension(const GrGLInterface* gl, const char* ext) {
bsalomon@google.comdca4aab2011-09-06 19:05:24 +0000119 const GrGLubyte* glstr;
120 GR_GL_CALL_RET(gl, glstr, GetString(GR_GL_EXTENSIONS));
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000121 return GrGLHasExtensionFromString(ext, (const char*) glstr);
twiz@google.com59a190b2011-03-14 21:23:01 +0000122}
123
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000124GrGLBinding GrGLGetBindingInUse(const GrGLInterface* gl) {
125 const GrGLubyte* v;
126 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
127 return GrGLGetBindingInUseFromString((const char*) v);
128}
129
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000130GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
bsalomon@google.comdca4aab2011-09-06 19:05:24 +0000131 const GrGLubyte* v;
132 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000133 return GrGLGetVersionFromString((const char*) v);
bsalomon@google.com2c17fcd2011-07-06 17:47:02 +0000134}
135
bsalomon@google.comedfe1aa2011-09-29 14:40:26 +0000136GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
137 const GrGLubyte* v;
138 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
139 return GrGLGetGLSLVersionFromString((const char*) v);
140}
141
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000142GrGLInterface::GrGLInterface() {
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000143 fBindingsExported = kNone_GrGLBinding;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000144
145 fActiveTexture = NULL;
146 fAttachShader = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000147 fBeginQuery = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000148 fBindAttribLocation = NULL;
149 fBindBuffer = NULL;
bsalomon@google.combc5cf512011-09-21 16:21:07 +0000150 fBindFragDataLocation = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000151 fBindTexture = NULL;
152 fBlendColor = NULL;
153 fBlendFunc = NULL;
154 fBufferData = NULL;
155 fBufferSubData = NULL;
156 fClear = NULL;
157 fClearColor = NULL;
158 fClearStencil = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000159 fColorMask = NULL;
160 fColorPointer = NULL;
161 fCompileShader = NULL;
162 fCompressedTexImage2D = NULL;
163 fCreateProgram = NULL;
164 fCreateShader = NULL;
165 fCullFace = NULL;
166 fDeleteBuffers = NULL;
167 fDeleteProgram = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000168 fDeleteQueries = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000169 fDeleteShader = NULL;
170 fDeleteTextures = NULL;
171 fDepthMask = NULL;
172 fDisable = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000173 fDisableVertexAttribArray = NULL;
174 fDrawArrays = NULL;
175 fDrawBuffer = NULL;
176 fDrawBuffers = NULL;
177 fDrawElements = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000178 fEndQuery = NULL;
179 fFinish = NULL;
180 fFlush = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000181 fEnable = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000182 fEnableVertexAttribArray = NULL;
183 fFrontFace = NULL;
184 fGenBuffers = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000185 fGenQueries = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000186 fGenTextures = NULL;
187 fGetBufferParameteriv = NULL;
188 fGetError = NULL;
189 fGetIntegerv = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000190 fGetQueryiv = NULL;
191 fGetQueryObjecti64v = NULL;
192 fGetQueryObjectiv = NULL;
193 fGetQueryObjectui64v = NULL;
194 fGetQueryObjectuiv = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000195 fGetProgramInfoLog = NULL;
196 fGetProgramiv = NULL;
197 fGetShaderInfoLog = NULL;
198 fGetShaderiv = NULL;
199 fGetString = NULL;
200 fGetTexLevelParameteriv = NULL;
201 fGetUniformLocation = NULL;
202 fLineWidth = NULL;
203 fLinkProgram = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000204 fPixelStorei = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000205 fQueryCounter = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000206 fReadBuffer = NULL;
207 fReadPixels = NULL;
208 fScissor = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000209 fShaderSource = NULL;
210 fStencilFunc = NULL;
211 fStencilFuncSeparate = NULL;
212 fStencilMask = NULL;
213 fStencilMaskSeparate = NULL;
214 fStencilOp = NULL;
215 fStencilOpSeparate = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000216 fTexImage2D = NULL;
217 fTexParameteri = NULL;
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000218 fTexStorage2D = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000219 fTexSubImage2D = NULL;
220 fUniform1f = NULL;
221 fUniform1i = NULL;
222 fUniform1fv = NULL;
223 fUniform1iv = NULL;
224 fUniform2f = NULL;
225 fUniform2i = NULL;
226 fUniform2fv = NULL;
227 fUniform2iv = NULL;
228 fUniform3f = NULL;
229 fUniform3i = NULL;
230 fUniform3fv = NULL;
231 fUniform3iv = NULL;
232 fUniform4f = NULL;
233 fUniform4i = NULL;
234 fUniform4fv = NULL;
235 fUniform4iv = NULL;
236 fUniformMatrix2fv = NULL;
237 fUniformMatrix3fv = NULL;
238 fUniformMatrix4fv = NULL;
239 fUseProgram = NULL;
240 fVertexAttrib4fv = NULL;
241 fVertexAttribPointer = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000242 fViewport = NULL;
243 fBindFramebuffer = NULL;
244 fBindRenderbuffer = NULL;
245 fCheckFramebufferStatus = NULL;
246 fDeleteFramebuffers = NULL;
247 fDeleteRenderbuffers = NULL;
248 fFramebufferRenderbuffer = NULL;
249 fFramebufferTexture2D = NULL;
250 fGenFramebuffers = NULL;
251 fGenRenderbuffers = NULL;
252 fGetFramebufferAttachmentParameteriv = NULL;
253 fGetRenderbufferParameteriv = NULL;
254 fRenderbufferStorage = NULL;
255 fRenderbufferStorageMultisample = NULL;
256 fBlitFramebuffer = NULL;
257 fResolveMultisampleFramebuffer = NULL;
258 fMapBuffer = NULL;
259 fUnmapBuffer = NULL;
260 fBindFragDataLocationIndexed = NULL;
bsalomon@google.com56bfc5a2011-09-01 13:28:16 +0000261
262#if GR_GL_PER_GL_FUNC_CALLBACK
263 fCallback = GrGLDefaultInterfaceCallback;
264 fCallbackData = 0;
265#endif
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000266}
267
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000268bool GrGLInterface::validate(GrGLBinding binding) const {
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000269
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000270 // kNone must be 0 so that the check we're about to do can never succeed if
271 // binding == kNone.
272 GR_STATIC_ASSERT(kNone_GrGLBinding == 0);
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000273
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000274 if (0 == (binding & fBindingsExported)) {
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000275 return false;
276 }
277
278 // functions that are always required
279 if (NULL == fActiveTexture ||
280 NULL == fAttachShader ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000281 NULL == fBindAttribLocation ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000282 NULL == fBindBuffer ||
283 NULL == fBindTexture ||
284 NULL == fBlendFunc ||
285 NULL == fBufferData ||
286 NULL == fBufferSubData ||
287 NULL == fClear ||
288 NULL == fClearColor ||
289 NULL == fClearStencil ||
290 NULL == fColorMask ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000291 NULL == fCompileShader ||
292 NULL == fCreateProgram ||
293 NULL == fCreateShader ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000294 NULL == fCullFace ||
295 NULL == fDeleteBuffers ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000296 NULL == fDeleteProgram ||
297 NULL == fDeleteShader ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000298 NULL == fDeleteTextures ||
299 NULL == fDepthMask ||
300 NULL == fDisable ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000301 NULL == fDisableVertexAttribArray ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000302 NULL == fDrawArrays ||
303 NULL == fDrawElements ||
304 NULL == fEnable ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000305 NULL == fEnableVertexAttribArray ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000306 NULL == fFrontFace ||
307 NULL == fGenBuffers ||
308 NULL == fGenTextures ||
309 NULL == fGetBufferParameteriv ||
310 NULL == fGetError ||
311 NULL == fGetIntegerv ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000312 NULL == fGetProgramInfoLog ||
313 NULL == fGetProgramiv ||
314 NULL == fGetShaderInfoLog ||
315 NULL == fGetShaderiv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000316 NULL == fGetString ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000317 NULL == fGetUniformLocation ||
318 NULL == fLinkProgram ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000319 NULL == fPixelStorei ||
320 NULL == fReadPixels ||
321 NULL == fScissor ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000322 NULL == fShaderSource ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000323 NULL == fStencilFunc ||
324 NULL == fStencilMask ||
325 NULL == fStencilOp ||
326 NULL == fTexImage2D ||
327 NULL == fTexParameteri ||
328 NULL == fTexSubImage2D ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000329 NULL == fUniform1f ||
330 NULL == fUniform1i ||
331 NULL == fUniform1fv ||
332 NULL == fUniform1iv ||
333 NULL == fUniform2f ||
334 NULL == fUniform2i ||
335 NULL == fUniform2fv ||
336 NULL == fUniform2iv ||
337 NULL == fUniform3f ||
338 NULL == fUniform3i ||
339 NULL == fUniform3fv ||
340 NULL == fUniform3iv ||
341 NULL == fUniform4f ||
342 NULL == fUniform4i ||
343 NULL == fUniform4fv ||
344 NULL == fUniform4iv ||
345 NULL == fUniformMatrix2fv ||
346 NULL == fUniformMatrix3fv ||
347 NULL == fUniformMatrix4fv ||
348 NULL == fUseProgram ||
349 NULL == fVertexAttrib4fv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000350 NULL == fVertexAttribPointer ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000351 NULL == fViewport ||
352 NULL == fBindFramebuffer ||
353 NULL == fBindRenderbuffer ||
354 NULL == fCheckFramebufferStatus ||
355 NULL == fDeleteFramebuffers ||
356 NULL == fDeleteRenderbuffers ||
bsalomon@google.com373a6632011-10-19 20:43:20 +0000357 NULL == fFinish ||
358 NULL == fFlush ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000359 NULL == fFramebufferRenderbuffer ||
360 NULL == fFramebufferTexture2D ||
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000361 NULL == fGetFramebufferAttachmentParameteriv ||
362 NULL == fGetRenderbufferParameteriv ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000363 NULL == fGenFramebuffers ||
364 NULL == fGenRenderbuffers ||
365 NULL == fRenderbufferStorage) {
366 return false;
367 }
368
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000369 const char* ext;
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000370 GrGLVersion glVer = GrGLGetVersion(this);
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000371 ext = (const char*)fGetString(GR_GL_EXTENSIONS);
372
373 // Now check that baseline ES/Desktop fns not covered above are present
374 // and that we have fn pointers for any advertised extensions that we will
375 // try to use.
376
377 // these functions are part of ES2, we assume they are available
378 // On the desktop we assume they are available if the extension
379 // is present or GL version is high enough.
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000380 if (kES2_GrGLBinding == binding) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000381 if (NULL == fBlendColor ||
382 NULL == fStencilFuncSeparate ||
383 NULL == fStencilMaskSeparate ||
384 NULL == fStencilOpSeparate) {
385 return false;
386 }
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000387 } else if (kDesktop_GrGLBinding == binding) {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000388 if (glVer >= GR_GL_VER(2,0)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000389 if (NULL == fStencilFuncSeparate ||
390 NULL == fStencilMaskSeparate ||
391 NULL == fStencilOpSeparate) {
392 return false;
393 }
394 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000395 if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) {
bsalomon@google.combc5cf512011-09-21 16:21:07 +0000396 return false;
397 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000398 if (glVer >= GR_GL_VER(2,0) ||
399 GrGLHasExtensionFromString("GL_ARB_draw_buffers", ext)) {
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000400 if (NULL == fDrawBuffers) {
401 return false;
402 }
403 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000404 if (glVer >= GR_GL_VER(1,4) ||
405 GrGLHasExtensionFromString("GL_EXT_blend_color", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000406 if (NULL == fBlendColor) {
407 return false;
408 }
409 }
bsalomon@google.com373a6632011-10-19 20:43:20 +0000410 if (glVer >= GR_GL_VER(1,5) ||
411 GrGLHasExtensionFromString("GL_ARB_occlusion_query", ext)) {
412 if (NULL == fGenQueries ||
413 NULL == fDeleteQueries ||
414 NULL == fBeginQuery ||
415 NULL == fEndQuery ||
416 NULL == fGetQueryiv ||
417 NULL == fGetQueryObjectiv ||
418 NULL == fGetQueryObjectuiv) {
419 return false;
420 }
421 }
422 if (glVer >= GR_GL_VER(3,3) ||
423 GrGLHasExtensionFromString("GL_ARB_timer_query", ext) ||
424 GrGLHasExtensionFromString("GL_EXT_timer_query", ext)) {
425 if (NULL == fGetQueryObjecti64v ||
426 NULL == fGetQueryObjectui64v) {
427 return false;
428 }
429 }
430 if (glVer >= GR_GL_VER(3,3) ||
431 GrGLHasExtensionFromString("GL_ARB_timer_query", ext)) {
432 if (NULL == fQueryCounter) {
433 return false;
434 }
435 }
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000436 }
437
438 // optional function on desktop before 1.3
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000439 if (kDesktop_GrGLBinding != binding ||
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000440 (glVer >= GR_GL_VER(1,3) ||
441 GrGLHasExtensionFromString("GL_ARB_texture_compression", ext))) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000442 if (NULL == fCompressedTexImage2D) {
443 return false;
444 }
445 }
446
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000447 // part of desktop GL, but not ES
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000448 if (kDesktop_GrGLBinding == binding &&
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000449 (NULL == fLineWidth ||
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000450 NULL == fGetTexLevelParameteriv ||
bsalomon@google.comc49d66b2011-08-03 14:22:30 +0000451 NULL == fDrawBuffer ||
452 NULL == fReadBuffer)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000453 return false;
454 }
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000455
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000456 // GL_EXT_texture_storage is part of desktop 4.2
457 // There is a desktop ARB extension and an ES+desktop EXT extension
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000458 if (kDesktop_GrGLBinding == binding) {
bsalomon@google.combaa9ea12012-01-06 19:05:43 +0000459 if (glVer >= GR_GL_VER(4,2) ||
460 GrGLHasExtensionFromString("GL_ARB_texture_storage", ext) ||
461 GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) {
462 if (NULL == fTexStorage2D) {
463 return false;
464 }
465 }
466 } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) {
467 if (NULL == fTexStorage2D) {
468 return false;
469 }
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000470 }
471
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000472 // FBO MSAA
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000473 if (kDesktop_GrGLBinding == binding) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000474 // GL 3.0 and the ARB extension have multisample + blit
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000475 if (glVer >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_framebuffer_object", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000476 if (NULL == fRenderbufferStorageMultisample ||
477 NULL == fBlitFramebuffer) {
478 return false;
479 }
480 } else {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000481 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", ext) &&
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000482 NULL == fBlitFramebuffer) {
483 return false;
484 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000485 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", ext) &&
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000486 NULL == fRenderbufferStorageMultisample) {
487 return false;
488 }
489 }
490 } else {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000491 if (GrGLHasExtensionFromString("GL_CHROMIUM_framebuffer_multisample", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000492 if (NULL == fRenderbufferStorageMultisample ||
493 NULL == fBlitFramebuffer) {
494 return false;
495 }
496 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000497 if (GrGLHasExtensionFromString("GL_APPLE_framebuffer_multisample", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000498 if (NULL == fRenderbufferStorageMultisample ||
499 NULL == fResolveMultisampleFramebuffer) {
500 return false;
501 }
502 }
503 }
504
505 // On ES buffer mapping is an extension. On Desktop
506 // buffer mapping was part of original VBO extension
507 // which we require.
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000508 if (kDesktop_GrGLBinding == binding ||
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000509 GrGLHasExtensionFromString("GL_OES_mapbuffer", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000510 if (NULL == fMapBuffer ||
511 NULL == fUnmapBuffer) {
512 return false;
513 }
514 }
515
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000516 // Dual source blending
bsalomon@google.com89ec61e2012-02-10 20:05:18 +0000517 if (kDesktop_GrGLBinding == binding &&
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000518 (glVer >= GR_GL_VER(3,3) ||
519 GrGLHasExtensionFromString("GL_ARB_blend_func_extended", ext))) {
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000520 if (NULL == fBindFragDataLocationIndexed) {
521 return false;
522 }
523 }
524
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000525 return true;
526}
527