blob: 66aea63b5c48931e8c916900fb3bd417af7d5bf4 [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.comc82b8892011-09-22 14:10:33 +000022GrGLVersion GrGLGetVersionFromString(const char* versionString) {
bsalomon@google.comedfe1aa2011-09-29 14:40:26 +000023 if (NULL == versionString) {
24 GrAssert(!"NULL GL version string.");
25 return 0;
26 }
27
bsalomon@google.comc82b8892011-09-22 14:10:33 +000028 int major, minor;
twiz@google.com0f31ca72011-03-18 17:38:11 +000029
bsalomon@google.comc82b8892011-09-22 14:10:33 +000030 int n = sscanf(versionString, "%d.%d", &major, &minor);
twiz@google.com0f31ca72011-03-18 17:38:11 +000031 if (2 == n) {
bsalomon@google.comc82b8892011-09-22 14:10:33 +000032 return GR_GL_VER(major, minor);
twiz@google.com59a190b2011-03-14 21:23:01 +000033 }
twiz@google.com0f31ca72011-03-18 17:38:11 +000034
twiz@google.com59a190b2011-03-14 21:23:01 +000035 char profile[2];
twiz@google.com0f31ca72011-03-18 17:38:11 +000036 n = sscanf(versionString, "OpenGL ES-%c%c %d.%d", profile, profile+1,
bsalomon@google.comc82b8892011-09-22 14:10:33 +000037 &major, &minor);
38 if (4 == n) {
39 return GR_GL_VER(major, minor);
40 }
41
42 n = sscanf(versionString, "OpenGL ES %d.%d", &major, &minor);
43 if (2 == n) {
44 return GR_GL_VER(major, minor);
twiz@google.com59a190b2011-03-14 21:23:01 +000045 }
twiz@google.com0f31ca72011-03-18 17:38:11 +000046
bsalomon@google.comc82b8892011-09-22 14:10:33 +000047 return 0;
twiz@google.com59a190b2011-03-14 21:23:01 +000048}
49
bsalomon@google.comedfe1aa2011-09-29 14:40:26 +000050GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString) {
51 if (NULL == versionString) {
52 GrAssert(!"NULL GLSL version string.");
53 return 0;
54 }
55
56 int major, minor;
57
58 int n = sscanf(versionString, "%d.%d", &major, &minor);
59 if (2 == n) {
60 return GR_GLSL_VER(major, minor);
61 }
62
63 n = sscanf(versionString, "OpenGL ES GLSL ES %d.%d", &major, &minor);
64 if (2 == n) {
65 return GR_GLSL_VER(major, minor);
66 }
67 return 0;
68}
69
bsalomon@google.comc82b8892011-09-22 14:10:33 +000070bool GrGLHasExtensionFromString(const char* ext, const char* extensionString) {
twiz@google.com59a190b2011-03-14 21:23:01 +000071 int extLength = strlen(ext);
72
73 while (true) {
74 int n = strcspn(extensionString, " ");
75 if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
76 return true;
77 }
78 if (0 == extensionString[n]) {
79 return false;
80 }
81 extensionString += n+1;
82 }
83
84 return false;
85}
86
bsalomon@google.comc82b8892011-09-22 14:10:33 +000087bool GrGLHasExtension(const GrGLInterface* gl, const char* ext) {
bsalomon@google.comdca4aab2011-09-06 19:05:24 +000088 const GrGLubyte* glstr;
89 GR_GL_CALL_RET(gl, glstr, GetString(GR_GL_EXTENSIONS));
bsalomon@google.comc82b8892011-09-22 14:10:33 +000090 return GrGLHasExtensionFromString(ext, (const char*) glstr);
twiz@google.com59a190b2011-03-14 21:23:01 +000091}
92
bsalomon@google.comc82b8892011-09-22 14:10:33 +000093GrGLVersion GrGLGetVersion(const GrGLInterface* gl) {
bsalomon@google.comdca4aab2011-09-06 19:05:24 +000094 const GrGLubyte* v;
95 GR_GL_CALL_RET(gl, v, GetString(GR_GL_VERSION));
bsalomon@google.comc82b8892011-09-22 14:10:33 +000096 return GrGLGetVersionFromString((const char*) v);
bsalomon@google.com2c17fcd2011-07-06 17:47:02 +000097}
98
bsalomon@google.comedfe1aa2011-09-29 14:40:26 +000099GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface* gl) {
100 const GrGLubyte* v;
101 GR_GL_CALL_RET(gl, v, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
102 return GrGLGetGLSLVersionFromString((const char*) v);
103}
104
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000105GrGLInterface::GrGLInterface() {
106 fBindingsExported = (GrGLBinding)0;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000107
108 fActiveTexture = NULL;
109 fAttachShader = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000110 fBeginQuery = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000111 fBindAttribLocation = NULL;
112 fBindBuffer = NULL;
bsalomon@google.combc5cf512011-09-21 16:21:07 +0000113 fBindFragDataLocation = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000114 fBindTexture = NULL;
115 fBlendColor = NULL;
116 fBlendFunc = NULL;
117 fBufferData = NULL;
118 fBufferSubData = NULL;
119 fClear = NULL;
120 fClearColor = NULL;
121 fClearStencil = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000122 fColorMask = NULL;
123 fColorPointer = NULL;
124 fCompileShader = NULL;
125 fCompressedTexImage2D = NULL;
126 fCreateProgram = NULL;
127 fCreateShader = NULL;
128 fCullFace = NULL;
129 fDeleteBuffers = NULL;
130 fDeleteProgram = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000131 fDeleteQueries = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000132 fDeleteShader = NULL;
133 fDeleteTextures = NULL;
134 fDepthMask = NULL;
135 fDisable = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000136 fDisableVertexAttribArray = NULL;
137 fDrawArrays = NULL;
138 fDrawBuffer = NULL;
139 fDrawBuffers = NULL;
140 fDrawElements = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000141 fEndQuery = NULL;
142 fFinish = NULL;
143 fFlush = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000144 fEnable = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000145 fEnableVertexAttribArray = NULL;
146 fFrontFace = NULL;
147 fGenBuffers = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000148 fGenQueries = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000149 fGenTextures = NULL;
150 fGetBufferParameteriv = NULL;
151 fGetError = NULL;
152 fGetIntegerv = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000153 fGetQueryiv = NULL;
154 fGetQueryObjecti64v = NULL;
155 fGetQueryObjectiv = NULL;
156 fGetQueryObjectui64v = NULL;
157 fGetQueryObjectuiv = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000158 fGetProgramInfoLog = NULL;
159 fGetProgramiv = NULL;
160 fGetShaderInfoLog = NULL;
161 fGetShaderiv = NULL;
162 fGetString = NULL;
163 fGetTexLevelParameteriv = NULL;
164 fGetUniformLocation = NULL;
165 fLineWidth = NULL;
166 fLinkProgram = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000167 fPixelStorei = NULL;
bsalomon@google.comf97c1942011-10-19 21:35:26 +0000168 fQueryCounter = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000169 fReadBuffer = NULL;
170 fReadPixels = NULL;
171 fScissor = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000172 fShaderSource = NULL;
173 fStencilFunc = NULL;
174 fStencilFuncSeparate = NULL;
175 fStencilMask = NULL;
176 fStencilMaskSeparate = NULL;
177 fStencilOp = NULL;
178 fStencilOpSeparate = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000179 fTexImage2D = NULL;
180 fTexParameteri = NULL;
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000181 fTexStorage2D = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000182 fTexSubImage2D = NULL;
183 fUniform1f = NULL;
184 fUniform1i = NULL;
185 fUniform1fv = NULL;
186 fUniform1iv = NULL;
187 fUniform2f = NULL;
188 fUniform2i = NULL;
189 fUniform2fv = NULL;
190 fUniform2iv = NULL;
191 fUniform3f = NULL;
192 fUniform3i = NULL;
193 fUniform3fv = NULL;
194 fUniform3iv = NULL;
195 fUniform4f = NULL;
196 fUniform4i = NULL;
197 fUniform4fv = NULL;
198 fUniform4iv = NULL;
199 fUniformMatrix2fv = NULL;
200 fUniformMatrix3fv = NULL;
201 fUniformMatrix4fv = NULL;
202 fUseProgram = NULL;
203 fVertexAttrib4fv = NULL;
204 fVertexAttribPointer = NULL;
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000205 fViewport = NULL;
206 fBindFramebuffer = NULL;
207 fBindRenderbuffer = NULL;
208 fCheckFramebufferStatus = NULL;
209 fDeleteFramebuffers = NULL;
210 fDeleteRenderbuffers = NULL;
211 fFramebufferRenderbuffer = NULL;
212 fFramebufferTexture2D = NULL;
213 fGenFramebuffers = NULL;
214 fGenRenderbuffers = NULL;
215 fGetFramebufferAttachmentParameteriv = NULL;
216 fGetRenderbufferParameteriv = NULL;
217 fRenderbufferStorage = NULL;
218 fRenderbufferStorageMultisample = NULL;
219 fBlitFramebuffer = NULL;
220 fResolveMultisampleFramebuffer = NULL;
221 fMapBuffer = NULL;
222 fUnmapBuffer = NULL;
223 fBindFragDataLocationIndexed = NULL;
bsalomon@google.com56bfc5a2011-09-01 13:28:16 +0000224
225#if GR_GL_PER_GL_FUNC_CALLBACK
226 fCallback = GrGLDefaultInterfaceCallback;
227 fCallbackData = 0;
228#endif
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000229}
230
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000231bool GrGLInterface::validate() const {
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000232
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000233 bool isDesktop = this->supportsDesktop();
234
235 bool isES2 = this->supportsES2();
236
237 if (isDesktop == isES2) {
238 // must have one, don't support both in same interface
239 return false;
240 }
241
242 // functions that are always required
243 if (NULL == fActiveTexture ||
244 NULL == fAttachShader ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000245 NULL == fBindAttribLocation ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000246 NULL == fBindBuffer ||
247 NULL == fBindTexture ||
248 NULL == fBlendFunc ||
249 NULL == fBufferData ||
250 NULL == fBufferSubData ||
251 NULL == fClear ||
252 NULL == fClearColor ||
253 NULL == fClearStencil ||
254 NULL == fColorMask ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000255 NULL == fCompileShader ||
256 NULL == fCreateProgram ||
257 NULL == fCreateShader ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000258 NULL == fCullFace ||
259 NULL == fDeleteBuffers ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000260 NULL == fDeleteProgram ||
261 NULL == fDeleteShader ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000262 NULL == fDeleteTextures ||
263 NULL == fDepthMask ||
264 NULL == fDisable ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000265 NULL == fDisableVertexAttribArray ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000266 NULL == fDrawArrays ||
267 NULL == fDrawElements ||
268 NULL == fEnable ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000269 NULL == fEnableVertexAttribArray ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000270 NULL == fFrontFace ||
271 NULL == fGenBuffers ||
272 NULL == fGenTextures ||
273 NULL == fGetBufferParameteriv ||
274 NULL == fGetError ||
275 NULL == fGetIntegerv ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000276 NULL == fGetProgramInfoLog ||
277 NULL == fGetProgramiv ||
278 NULL == fGetShaderInfoLog ||
279 NULL == fGetShaderiv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000280 NULL == fGetString ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000281 NULL == fGetUniformLocation ||
282 NULL == fLinkProgram ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000283 NULL == fPixelStorei ||
284 NULL == fReadPixels ||
285 NULL == fScissor ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000286 NULL == fShaderSource ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000287 NULL == fStencilFunc ||
288 NULL == fStencilMask ||
289 NULL == fStencilOp ||
290 NULL == fTexImage2D ||
291 NULL == fTexParameteri ||
292 NULL == fTexSubImage2D ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000293 NULL == fUniform1f ||
294 NULL == fUniform1i ||
295 NULL == fUniform1fv ||
296 NULL == fUniform1iv ||
297 NULL == fUniform2f ||
298 NULL == fUniform2i ||
299 NULL == fUniform2fv ||
300 NULL == fUniform2iv ||
301 NULL == fUniform3f ||
302 NULL == fUniform3i ||
303 NULL == fUniform3fv ||
304 NULL == fUniform3iv ||
305 NULL == fUniform4f ||
306 NULL == fUniform4i ||
307 NULL == fUniform4fv ||
308 NULL == fUniform4iv ||
309 NULL == fUniformMatrix2fv ||
310 NULL == fUniformMatrix3fv ||
311 NULL == fUniformMatrix4fv ||
312 NULL == fUseProgram ||
313 NULL == fVertexAttrib4fv ||
bsalomon@google.com1dcf5062011-11-14 19:29:53 +0000314 NULL == fVertexAttribPointer ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000315 NULL == fViewport ||
316 NULL == fBindFramebuffer ||
317 NULL == fBindRenderbuffer ||
318 NULL == fCheckFramebufferStatus ||
319 NULL == fDeleteFramebuffers ||
320 NULL == fDeleteRenderbuffers ||
bsalomon@google.com373a6632011-10-19 20:43:20 +0000321 NULL == fFinish ||
322 NULL == fFlush ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000323 NULL == fFramebufferRenderbuffer ||
324 NULL == fFramebufferTexture2D ||
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000325 NULL == fGetFramebufferAttachmentParameteriv ||
326 NULL == fGetRenderbufferParameteriv ||
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000327 NULL == fGenFramebuffers ||
328 NULL == fGenRenderbuffers ||
329 NULL == fRenderbufferStorage) {
330 return false;
331 }
332
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000333 const char* ext;
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000334 GrGLVersion glVer = GrGLGetVersion(this);
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000335 ext = (const char*)fGetString(GR_GL_EXTENSIONS);
336
337 // Now check that baseline ES/Desktop fns not covered above are present
338 // and that we have fn pointers for any advertised extensions that we will
339 // try to use.
340
341 // these functions are part of ES2, we assume they are available
342 // On the desktop we assume they are available if the extension
343 // is present or GL version is high enough.
344 if ((kES2_GrGLBinding & fBindingsExported)) {
345 if (NULL == fBlendColor ||
346 NULL == fStencilFuncSeparate ||
347 NULL == fStencilMaskSeparate ||
348 NULL == fStencilOpSeparate) {
349 return false;
350 }
351 } else if (kDesktop_GrGLBinding == fBindingsExported) {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000352 if (glVer >= GR_GL_VER(2,0)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000353 if (NULL == fStencilFuncSeparate ||
354 NULL == fStencilMaskSeparate ||
355 NULL == fStencilOpSeparate) {
356 return false;
357 }
358 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000359 if (glVer >= GR_GL_VER(3,0) && NULL == fBindFragDataLocation) {
bsalomon@google.combc5cf512011-09-21 16:21:07 +0000360 return false;
361 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000362 if (glVer >= GR_GL_VER(2,0) ||
363 GrGLHasExtensionFromString("GL_ARB_draw_buffers", ext)) {
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000364 if (NULL == fDrawBuffers) {
365 return false;
366 }
367 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000368 if (glVer >= GR_GL_VER(1,4) ||
369 GrGLHasExtensionFromString("GL_EXT_blend_color", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000370 if (NULL == fBlendColor) {
371 return false;
372 }
373 }
bsalomon@google.com373a6632011-10-19 20:43:20 +0000374 if (glVer >= GR_GL_VER(1,5) ||
375 GrGLHasExtensionFromString("GL_ARB_occlusion_query", ext)) {
376 if (NULL == fGenQueries ||
377 NULL == fDeleteQueries ||
378 NULL == fBeginQuery ||
379 NULL == fEndQuery ||
380 NULL == fGetQueryiv ||
381 NULL == fGetQueryObjectiv ||
382 NULL == fGetQueryObjectuiv) {
383 return false;
384 }
385 }
386 if (glVer >= GR_GL_VER(3,3) ||
387 GrGLHasExtensionFromString("GL_ARB_timer_query", ext) ||
388 GrGLHasExtensionFromString("GL_EXT_timer_query", ext)) {
389 if (NULL == fGetQueryObjecti64v ||
390 NULL == fGetQueryObjectui64v) {
391 return false;
392 }
393 }
394 if (glVer >= GR_GL_VER(3,3) ||
395 GrGLHasExtensionFromString("GL_ARB_timer_query", ext)) {
396 if (NULL == fQueryCounter) {
397 return false;
398 }
399 }
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000400 }
401
402 // optional function on desktop before 1.3
403 if (kDesktop_GrGLBinding != fBindingsExported ||
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000404 (glVer >= GR_GL_VER(1,3) ||
405 GrGLHasExtensionFromString("GL_ARB_texture_compression", ext))) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000406 if (NULL == fCompressedTexImage2D) {
407 return false;
408 }
409 }
410
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000411 // part of desktop GL, but not ES
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000412 if (kDesktop_GrGLBinding == fBindingsExported &&
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000413 (NULL == fLineWidth ||
bsalomon@google.comd32c5f52011-08-02 19:29:03 +0000414 NULL == fGetTexLevelParameteriv ||
bsalomon@google.comc49d66b2011-08-03 14:22:30 +0000415 NULL == fDrawBuffer ||
416 NULL == fReadBuffer)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000417 return false;
418 }
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000419
bsalomon@google.com280e99f2012-01-05 16:17:38 +0000420 // GL_EXT_texture_storage is part of desktop 4.2
421 // There is a desktop ARB extension and an ES+desktop EXT extension
422 if ((kDesktop_GrGLBinding == fBindingsExported &&
423 (glVer >= GR_GL_VER(4,2)) ||
424 GrGLHasExtensionFromString("GL_ARB_texture_storage", ext)) ||
425 GrGLHasExtensionFromString("GL_EXT_texture_storage", ext)) {
426 }
427
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000428 // FBO MSAA
429 if (kDesktop_GrGLBinding == fBindingsExported) {
430 // GL 3.0 and the ARB extension have multisample + blit
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000431 if (glVer >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_framebuffer_object", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000432 if (NULL == fRenderbufferStorageMultisample ||
433 NULL == fBlitFramebuffer) {
434 return false;
435 }
436 } else {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000437 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_blit", ext) &&
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000438 NULL == fBlitFramebuffer) {
439 return false;
440 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000441 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", ext) &&
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000442 NULL == fRenderbufferStorageMultisample) {
443 return false;
444 }
445 }
446 } else {
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000447 if (GrGLHasExtensionFromString("GL_CHROMIUM_framebuffer_multisample", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000448 if (NULL == fRenderbufferStorageMultisample ||
449 NULL == fBlitFramebuffer) {
450 return false;
451 }
452 }
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000453 if (GrGLHasExtensionFromString("GL_APPLE_framebuffer_multisample", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000454 if (NULL == fRenderbufferStorageMultisample ||
455 NULL == fResolveMultisampleFramebuffer) {
456 return false;
457 }
458 }
459 }
460
461 // On ES buffer mapping is an extension. On Desktop
462 // buffer mapping was part of original VBO extension
463 // which we require.
464 if (kDesktop_GrGLBinding == fBindingsExported ||
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000465 GrGLHasExtensionFromString("GL_OES_mapbuffer", ext)) {
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000466 if (NULL == fMapBuffer ||
467 NULL == fUnmapBuffer) {
468 return false;
469 }
470 }
471
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000472 // Dual source blending
473 if (kDesktop_GrGLBinding == fBindingsExported &&
bsalomon@google.comc82b8892011-09-22 14:10:33 +0000474 (glVer >= GR_GL_VER(3,3) ||
475 GrGLHasExtensionFromString("GL_ARB_blend_func_extended", ext))) {
bsalomon@google.com271cffc2011-05-20 14:13:56 +0000476 if (NULL == fBindFragDataLocationIndexed) {
477 return false;
478 }
479 }
480
bsalomon@google.combf2a4692011-05-04 12:35:39 +0000481 return true;
482}
483