1 /*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8
9 #include "gl/GrGLInterface.h"
10 #include "gl/GrGLExtensions.h"
11 #include "gl/GrGLUtil.h"
12
13 #include <stdio.h>
14
GrGLInterface()15 GrGLInterface::GrGLInterface() {
16 fStandard = kNone_GrGLStandard;
17 }
18
19 #ifdef SK_DEBUG
20 static int kIsDebug = 1;
21 #else
22 static int kIsDebug = 0;
23 #endif
24
25 #define RETURN_FALSE_INTERFACE \
26 if (kIsDebug) { SkDebugf("%s:%d GrGLInterface::validate() failed.\n", __FILE__, __LINE__); } \
27 return false
28
validate() const29 bool GrGLInterface::validate() const {
30
31 if (kNone_GrGLStandard == fStandard) {
32 RETURN_FALSE_INTERFACE;
33 }
34
35 if (!fExtensions.isInitialized()) {
36 RETURN_FALSE_INTERFACE;
37 }
38
39 // functions that are always required
40 if (!fFunctions.fActiveTexture ||
41 !fFunctions.fAttachShader ||
42 !fFunctions.fBindAttribLocation ||
43 !fFunctions.fBindBuffer ||
44 !fFunctions.fBindTexture ||
45 !fFunctions.fBlendColor || // -> GL >= 1.4 or extension, ES >= 2.0
46 !fFunctions.fBlendEquation || // -> GL >= 1.4 or extension, ES >= 2.0
47 !fFunctions.fBlendFunc ||
48 !fFunctions.fBufferData ||
49 !fFunctions.fBufferSubData ||
50 !fFunctions.fClear ||
51 !fFunctions.fClearColor ||
52 !fFunctions.fClearStencil ||
53 !fFunctions.fColorMask ||
54 !fFunctions.fCompileShader ||
55 !fFunctions.fCompressedTexImage2D ||
56 !fFunctions.fCompressedTexSubImage2D ||
57 !fFunctions.fCopyTexSubImage2D ||
58 !fFunctions.fCreateProgram ||
59 !fFunctions.fCreateShader ||
60 !fFunctions.fCullFace ||
61 !fFunctions.fDeleteBuffers ||
62 !fFunctions.fDeleteProgram ||
63 !fFunctions.fDeleteShader ||
64 !fFunctions.fDeleteTextures ||
65 !fFunctions.fDepthMask ||
66 !fFunctions.fDisable ||
67 !fFunctions.fDisableVertexAttribArray ||
68 !fFunctions.fDrawArrays ||
69 !fFunctions.fDrawElements ||
70 !fFunctions.fEnable ||
71 !fFunctions.fEnableVertexAttribArray ||
72 !fFunctions.fFrontFace ||
73 !fFunctions.fGenBuffers ||
74 !fFunctions.fGenTextures ||
75 !fFunctions.fGetBufferParameteriv ||
76 !fFunctions.fGenerateMipmap ||
77 !fFunctions.fGetError ||
78 !fFunctions.fGetIntegerv ||
79 !fFunctions.fGetProgramInfoLog ||
80 !fFunctions.fGetProgramiv ||
81 !fFunctions.fGetShaderInfoLog ||
82 !fFunctions.fGetShaderiv ||
83 !fFunctions.fGetString ||
84 !fFunctions.fGetUniformLocation ||
85 !fFunctions.fIsTexture ||
86 !fFunctions.fLinkProgram ||
87 !fFunctions.fLineWidth ||
88 !fFunctions.fPixelStorei ||
89 !fFunctions.fReadPixels ||
90 !fFunctions.fScissor ||
91 !fFunctions.fShaderSource ||
92 !fFunctions.fStencilFunc ||
93 !fFunctions.fStencilFuncSeparate ||
94 !fFunctions.fStencilMask ||
95 !fFunctions.fStencilMaskSeparate ||
96 !fFunctions.fStencilOp ||
97 !fFunctions.fStencilOpSeparate ||
98 !fFunctions.fTexImage2D ||
99 !fFunctions.fTexParameterf ||
100 !fFunctions.fTexParameterfv ||
101 !fFunctions.fTexParameteri ||
102 !fFunctions.fTexParameteriv ||
103 !fFunctions.fTexSubImage2D ||
104 !fFunctions.fUniform1f ||
105 !fFunctions.fUniform1i ||
106 !fFunctions.fUniform1fv ||
107 !fFunctions.fUniform1iv ||
108 !fFunctions.fUniform2f ||
109 !fFunctions.fUniform2i ||
110 !fFunctions.fUniform2fv ||
111 !fFunctions.fUniform2iv ||
112 !fFunctions.fUniform3f ||
113 !fFunctions.fUniform3i ||
114 !fFunctions.fUniform3fv ||
115 !fFunctions.fUniform3iv ||
116 !fFunctions.fUniform4f ||
117 !fFunctions.fUniform4i ||
118 !fFunctions.fUniform4fv ||
119 !fFunctions.fUniform4iv ||
120 !fFunctions.fUniformMatrix2fv ||
121 !fFunctions.fUniformMatrix3fv ||
122 !fFunctions.fUniformMatrix4fv ||
123 !fFunctions.fUseProgram ||
124 !fFunctions.fVertexAttrib1f ||
125 !fFunctions.fVertexAttrib2fv ||
126 !fFunctions.fVertexAttrib3fv ||
127 !fFunctions.fVertexAttrib4fv ||
128 !fFunctions.fVertexAttribPointer ||
129 !fFunctions.fViewport ||
130 !fFunctions.fBindFramebuffer ||
131 !fFunctions.fBindRenderbuffer ||
132 !fFunctions.fCheckFramebufferStatus ||
133 !fFunctions.fDeleteFramebuffers ||
134 !fFunctions.fDeleteRenderbuffers ||
135 !fFunctions.fFinish ||
136 !fFunctions.fFlush ||
137 !fFunctions.fFramebufferRenderbuffer ||
138 !fFunctions.fFramebufferTexture2D ||
139 !fFunctions.fGetFramebufferAttachmentParameteriv ||
140 !fFunctions.fGetRenderbufferParameteriv ||
141 !fFunctions.fGenFramebuffers ||
142 !fFunctions.fGenRenderbuffers ||
143 !fFunctions.fRenderbufferStorage) {
144 RETURN_FALSE_INTERFACE;
145 }
146
147 GrGLVersion glVer = GrGLGetVersion(this);
148 if (GR_GL_INVALID_VER == glVer) {
149 RETURN_FALSE_INTERFACE;
150 }
151
152 // Now check that baseline ES/Desktop fns not covered above are present
153 // and that we have fn pointers for any advertised fExtensions that we will
154 // try to use.
155
156 // these functions are part of ES2, we assume they are available
157 // On the desktop we assume they are available if the extension
158 // is present or GL version is high enough.
159 if (kGL_GrGLStandard == fStandard) {
160 if (glVer >= GR_GL_VER(3,0) && !fFunctions.fBindFragDataLocation) {
161 RETURN_FALSE_INTERFACE;
162 }
163
164 if (glVer >= GR_GL_VER(3,3) ||
165 fExtensions.has("GL_ARB_timer_query") ||
166 fExtensions.has("GL_EXT_timer_query")) {
167 if (!fFunctions.fGetQueryObjecti64v ||
168 !fFunctions.fGetQueryObjectui64v) {
169 RETURN_FALSE_INTERFACE;
170 }
171 }
172 if (glVer >= GR_GL_VER(3,3) || fExtensions.has("GL_ARB_timer_query")) {
173 if (!fFunctions.fQueryCounter) {
174 RETURN_FALSE_INTERFACE;
175 }
176 }
177 }
178
179 // part of desktop GL, but not ES
180 if (kGL_GrGLStandard == fStandard &&
181 (!fFunctions.fDrawBuffer ||
182 !fFunctions.fPolygonMode)) {
183 RETURN_FALSE_INTERFACE;
184 }
185
186 // ES 3.0 (or ES 2.0 extended) has glDrawBuffers but not glDrawBuffer
187 if (kGL_GrGLStandard == fStandard || glVer >= GR_GL_VER(3,0)) {
188 if (!fFunctions.fDrawBuffers) {
189 RETURN_FALSE_INTERFACE;
190 }
191 }
192
193 if (kGL_GrGLStandard == fStandard || glVer >= GR_GL_VER(3,0)) {
194 if (!fFunctions.fReadBuffer) {
195 RETURN_FALSE_INTERFACE;
196 }
197 }
198
199 // glGetTexLevelParameteriv was added to ES in 3.1.
200 if (kGL_GrGLStandard == fStandard || glVer >= GR_GL_VER(3,1)) {
201 if (!fFunctions.fGetTexLevelParameteriv) {
202 RETURN_FALSE_INTERFACE;
203 }
204 }
205
206 // GL_EXT_texture_storage is part of desktop 4.2
207 // There is a desktop ARB extension and an ES+desktop EXT extension
208 if (kGL_GrGLStandard == fStandard) {
209 if (glVer >= GR_GL_VER(4,2) ||
210 fExtensions.has("GL_ARB_texture_storage") ||
211 fExtensions.has("GL_EXT_texture_storage")) {
212 if (!fFunctions.fTexStorage2D) {
213 RETURN_FALSE_INTERFACE;
214 }
215 }
216 } else if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_texture_storage")) {
217 if (!fFunctions.fTexStorage2D) {
218 RETURN_FALSE_INTERFACE;
219 }
220 }
221
222 // glTextureBarrier is part of desktop 4.5. There are also ARB and NV extensions.
223 if (kGL_GrGLStandard == fStandard) {
224 if (glVer >= GR_GL_VER(4,5) ||
225 fExtensions.has("GL_ARB_texture_barrier") ||
226 fExtensions.has("GL_NV_texture_barrier")) {
227 if (!fFunctions.fTextureBarrier) {
228 RETURN_FALSE_INTERFACE;
229 }
230 }
231 } else if (fExtensions.has("GL_NV_texture_barrier")) {
232 if (!fFunctions.fTextureBarrier) {
233 RETURN_FALSE_INTERFACE;
234 }
235 }
236
237 if (fExtensions.has("GL_KHR_blend_equation_advanced") ||
238 fExtensions.has("GL_NV_blend_equation_advanced")) {
239 if (!fFunctions.fBlendBarrier) {
240 RETURN_FALSE_INTERFACE;
241 }
242 }
243
244 if (fExtensions.has("GL_EXT_discard_framebuffer")) {
245 if (!fFunctions.fDiscardFramebuffer) {
246 RETURN_FALSE_INTERFACE;
247 }
248 }
249
250 // Required since OpenGL 1.5 and ES 3.0 or with GL_EXT_occlusion_query_boolean
251 if (kGL_GrGLStandard == fStandard || glVer >= GR_GL_VER(3,0) ||
252 fExtensions.has("GL_EXT_occlusion_query_boolean")) {
253 #if 0 // Not yet added to chrome's bindings.
254 if (!fFunctions.fGenQueries ||
255 !fFunctions.fDeleteQueries ||
256 !fFunctions.fBeginQuery ||
257 !fFunctions.fEndQuery ||
258 !fFunctions.fGetQueryiv ||
259 !fFunctions.fGetQueryObjectuiv) {
260 RETURN_FALSE_INTERFACE;
261 }
262 #endif
263 }
264 // glGetQueryObjectiv doesn't exist in ES.
265 if (kGL_GrGLStandard == fStandard && !fFunctions.fGetQueryObjectiv) {
266 RETURN_FALSE_INTERFACE;
267 }
268
269 // FBO MSAA
270 if (kGL_GrGLStandard == fStandard) {
271 // GL 3.0 and the ARB extension have multisample + blit
272 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_ARB_framebuffer_object")) {
273 if (!fFunctions.fRenderbufferStorageMultisample ||
274 !fFunctions.fBlitFramebuffer) {
275 RETURN_FALSE_INTERFACE;
276 }
277 } else {
278 if (fExtensions.has("GL_EXT_framebuffer_blit") &&
279 !fFunctions.fBlitFramebuffer) {
280 RETURN_FALSE_INTERFACE;
281 }
282 if (fExtensions.has("GL_EXT_framebuffer_multisample") &&
283 !fFunctions.fRenderbufferStorageMultisample) {
284 RETURN_FALSE_INTERFACE;
285 }
286 }
287 } else {
288 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_CHROMIUM_framebuffer_multisample")) {
289 if (!fFunctions.fRenderbufferStorageMultisample ||
290 !fFunctions.fBlitFramebuffer) {
291 RETURN_FALSE_INTERFACE;
292 }
293 } else {
294 if (fExtensions.has("GL_ANGLE_framebuffer_multisample") &&
295 !fFunctions.fRenderbufferStorageMultisample) {
296 RETURN_FALSE_INTERFACE;
297 }
298 if (fExtensions.has("GL_ANGLE_framebuffer_blit") &&
299 !fFunctions.fBlitFramebuffer) {
300 RETURN_FALSE_INTERFACE;
301 }
302 }
303 if (fExtensions.has("GL_APPLE_framebuffer_multisample")) {
304 if (!fFunctions.fRenderbufferStorageMultisampleES2APPLE ||
305 !fFunctions.fResolveMultisampleFramebuffer) {
306 RETURN_FALSE_INTERFACE;
307 }
308 }
309 if (fExtensions.has("GL_IMG_multisampled_render_to_texture") ||
310 fExtensions.has("GL_EXT_multisampled_render_to_texture")) {
311 if (!fFunctions.fRenderbufferStorageMultisampleES2EXT ||
312 !fFunctions.fFramebufferTexture2DMultisample) {
313 RETURN_FALSE_INTERFACE;
314 }
315 }
316 }
317
318 // On ES buffer mapping is an extension. On Desktop
319 // buffer mapping was part of original VBO extension
320 // which we require.
321 if (kGL_GrGLStandard == fStandard || fExtensions.has("GL_OES_mapbuffer")) {
322 if (!fFunctions.fMapBuffer ||
323 !fFunctions.fUnmapBuffer) {
324 RETURN_FALSE_INTERFACE;
325 }
326 }
327
328 // Dual source blending
329 if (kGL_GrGLStandard == fStandard) {
330 if (glVer >= GR_GL_VER(3,3) || fExtensions.has("GL_ARB_blend_func_extended")) {
331 if (!fFunctions.fBindFragDataLocationIndexed) {
332 RETURN_FALSE_INTERFACE;
333 }
334 }
335 } else {
336 if (glVer >= GR_GL_VER(3,0) && fExtensions.has("GL_EXT_blend_func_extended")) {
337 if (!fFunctions.fBindFragDataLocation ||
338 !fFunctions.fBindFragDataLocationIndexed) {
339 RETURN_FALSE_INTERFACE;
340 }
341 }
342 }
343
344
345 // glGetStringi was added in version 3.0 of both desktop and ES.
346 if (glVer >= GR_GL_VER(3, 0)) {
347 if (!fFunctions.fGetStringi) {
348 RETURN_FALSE_INTERFACE;
349 }
350 }
351
352 // glVertexAttribIPointer was added in version 3.0 of both desktop and ES.
353 if (glVer >= GR_GL_VER(3, 0)) {
354 if (!fFunctions.fVertexAttribIPointer) {
355 RETURN_FALSE_INTERFACE;
356 }
357 }
358
359 if (kGL_GrGLStandard == fStandard) {
360 if (glVer >= GR_GL_VER(3,1)) {
361 if (!fFunctions.fTexBuffer) {
362 RETURN_FALSE_INTERFACE;
363 }
364 }
365 if (glVer >= GR_GL_VER(4,3)) {
366 if (!fFunctions.fTexBufferRange) {
367 RETURN_FALSE_INTERFACE;
368 }
369 }
370 } else {
371 if (glVer >= GR_GL_VER(3,2) || fExtensions.has("GL_OES_texture_buffer") ||
372 fExtensions.has("GL_EXT_texture_buffer")) {
373 if (!fFunctions.fTexBuffer ||
374 !fFunctions.fTexBufferRange) {
375 RETURN_FALSE_INTERFACE;
376 }
377 }
378 }
379
380 if (kGL_GrGLStandard == fStandard) {
381 if (glVer >= GR_GL_VER(3, 0) || fExtensions.has("GL_ARB_vertex_array_object")) {
382 if (!fFunctions.fBindVertexArray ||
383 !fFunctions.fDeleteVertexArrays ||
384 !fFunctions.fGenVertexArrays) {
385 RETURN_FALSE_INTERFACE;
386 }
387 }
388 } else {
389 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_OES_vertex_array_object")) {
390 if (!fFunctions.fBindVertexArray ||
391 !fFunctions.fDeleteVertexArrays ||
392 !fFunctions.fGenVertexArrays) {
393 RETURN_FALSE_INTERFACE;
394 }
395 }
396 }
397
398 if (fExtensions.has("GL_EXT_debug_marker")) {
399 if (!fFunctions.fInsertEventMarker ||
400 !fFunctions.fPushGroupMarker ||
401 !fFunctions.fPopGroupMarker) {
402 RETURN_FALSE_INTERFACE;
403 }
404 }
405
406 if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,3)) ||
407 fExtensions.has("GL_ARB_invalidate_subdata")) {
408 if (!fFunctions.fInvalidateBufferData ||
409 !fFunctions.fInvalidateBufferSubData ||
410 !fFunctions.fInvalidateFramebuffer ||
411 !fFunctions.fInvalidateSubFramebuffer ||
412 !fFunctions.fInvalidateTexImage ||
413 !fFunctions.fInvalidateTexSubImage) {
414 RETURN_FALSE_INTERFACE;
415 }
416 } else if (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0)) {
417 // ES 3.0 adds the framebuffer functions but not the others.
418 if (!fFunctions.fInvalidateFramebuffer ||
419 !fFunctions.fInvalidateSubFramebuffer) {
420 RETURN_FALSE_INTERFACE;
421 }
422 }
423
424 if (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_CHROMIUM_map_sub")) {
425 if (!fFunctions.fMapBufferSubData ||
426 !fFunctions.fMapTexSubImage2D ||
427 !fFunctions.fUnmapBufferSubData ||
428 !fFunctions.fUnmapTexSubImage2D) {
429 RETURN_FALSE_INTERFACE;
430 }
431 }
432
433 // These functions are added to the 3.0 version of both GLES and GL.
434 if (glVer >= GR_GL_VER(3,0) ||
435 (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_EXT_map_buffer_range")) ||
436 (kGL_GrGLStandard == fStandard && fExtensions.has("GL_ARB_map_buffer_range"))) {
437 if (!fFunctions.fMapBufferRange ||
438 !fFunctions.fFlushMappedBufferRange) {
439 RETURN_FALSE_INTERFACE;
440 }
441 }
442
443 if ((kGL_GrGLStandard == fStandard &&
444 (glVer >= GR_GL_VER(3,2) || fExtensions.has("GL_ARB_texture_multisample"))) ||
445 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) {
446 if (!fFunctions.fGetMultisamplefv) {
447 RETURN_FALSE_INTERFACE;
448 }
449 }
450
451 if ((kGL_GrGLStandard == fStandard &&
452 (glVer >= GR_GL_VER(4,3) || fExtensions.has("GL_ARB_program_interface_query"))) ||
453 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) {
454 if (!fFunctions.fGetProgramResourceLocation) {
455 RETURN_FALSE_INTERFACE;
456 }
457 }
458
459 if (kGLES_GrGLStandard == fStandard || glVer >= GR_GL_VER(4,1) ||
460 fExtensions.has("GL_ARB_ES2_compatibility")) {
461 if (!fFunctions.fGetShaderPrecisionFormat) {
462 RETURN_FALSE_INTERFACE;
463 }
464 }
465
466 if (fExtensions.has("GL_NV_path_rendering") || fExtensions.has("GL_CHROMIUM_path_rendering")) {
467 if (!fFunctions.fMatrixLoadf ||
468 !fFunctions.fMatrixLoadIdentity ||
469 !fFunctions.fPathCommands ||
470 !fFunctions.fPathParameteri ||
471 !fFunctions.fPathParameterf ||
472 !fFunctions.fGenPaths ||
473 !fFunctions.fDeletePaths ||
474 !fFunctions.fIsPath ||
475 !fFunctions.fPathStencilFunc ||
476 !fFunctions.fStencilFillPath ||
477 !fFunctions.fStencilStrokePath ||
478 !fFunctions.fStencilFillPathInstanced ||
479 !fFunctions.fStencilStrokePathInstanced ||
480 !fFunctions.fCoverFillPath ||
481 !fFunctions.fCoverStrokePath ||
482 !fFunctions.fCoverFillPathInstanced ||
483 !fFunctions.fCoverStrokePathInstanced
484 #if 0
485 // List of functions that Skia uses, but which have been added since the initial release
486 // of NV_path_rendering driver. We do not want to fail interface validation due to
487 // missing features, we will just not use the extension.
488 // Update this list -> update GrGLCaps::hasPathRenderingSupport too.
489 || !fFunctions.fStencilThenCoverFillPath ||
490 !fFunctions.fStencilThenCoverStrokePath ||
491 !fFunctions.fStencilThenCoverFillPathInstanced ||
492 !fFunctions.fStencilThenCoverStrokePathInstanced ||
493 !fFunctions.fProgramPathFragmentInputGen
494 #endif
495 ) {
496 RETURN_FALSE_INTERFACE;
497 }
498 if (fExtensions.has("GL_CHROMIUM_path_rendering")) {
499 if (!fFunctions.fBindFragmentInputLocation) {
500 RETURN_FALSE_INTERFACE;
501 }
502 }
503 }
504
505 if (fExtensions.has("GL_EXT_raster_multisample")) {
506 if (!fFunctions.fRasterSamples) {
507 RETURN_FALSE_INTERFACE;
508 }
509 }
510
511 if (fExtensions.has("GL_NV_framebuffer_mixed_samples") ||
512 fExtensions.has("GL_CHROMIUM_framebuffer_mixed_samples")) {
513 if (!fFunctions.fCoverageModulation) {
514 RETURN_FALSE_INTERFACE;
515 }
516 }
517
518 if (kGL_GrGLStandard == fStandard) {
519 if (glVer >= GR_GL_VER(3,1) ||
520 fExtensions.has("GL_EXT_draw_instanced") || fExtensions.has("GL_ARB_draw_instanced")) {
521 if (!fFunctions.fDrawArraysInstanced ||
522 !fFunctions.fDrawElementsInstanced) {
523 RETURN_FALSE_INTERFACE;
524 }
525 }
526 } else if (kGLES_GrGLStandard == fStandard) {
527 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_draw_instanced")) {
528 if (!fFunctions.fDrawArraysInstanced ||
529 !fFunctions.fDrawElementsInstanced) {
530 RETURN_FALSE_INTERFACE;
531 }
532 }
533 }
534
535 if (kGL_GrGLStandard == fStandard) {
536 if (glVer >= GR_GL_VER(3,2) || fExtensions.has("GL_ARB_instanced_arrays")) {
537 if (!fFunctions.fVertexAttribDivisor) {
538 RETURN_FALSE_INTERFACE;
539 }
540 }
541 } else if (kGLES_GrGLStandard == fStandard) {
542 if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_instanced_arrays")) {
543 if (!fFunctions.fVertexAttribDivisor) {
544 RETURN_FALSE_INTERFACE;
545 }
546 }
547 }
548
549 if ((kGL_GrGLStandard == fStandard &&
550 (glVer >= GR_GL_VER(4,0) || fExtensions.has("GL_ARB_draw_indirect"))) ||
551 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) {
552 if (!fFunctions.fDrawArraysIndirect ||
553 !fFunctions.fDrawElementsIndirect) {
554 RETURN_FALSE_INTERFACE;
555 }
556 }
557
558 if ((kGL_GrGLStandard == fStandard &&
559 (glVer >= GR_GL_VER(4,3) || fExtensions.has("GL_ARB_multi_draw_indirect"))) ||
560 (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_EXT_multi_draw_indirect"))) {
561 if (!fFunctions.fMultiDrawArraysIndirect ||
562 !fFunctions.fMultiDrawElementsIndirect) {
563 RETURN_FALSE_INTERFACE;
564 }
565 }
566
567 if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,3)) ||
568 fExtensions.has("GL_KHR_debug")) {
569 if (!fFunctions.fDebugMessageControl ||
570 !fFunctions.fDebugMessageInsert ||
571 !fFunctions.fDebugMessageCallback ||
572 !fFunctions.fGetDebugMessageLog ||
573 !fFunctions.fPushDebugGroup ||
574 !fFunctions.fPopDebugGroup ||
575 !fFunctions.fObjectLabel) {
576 RETURN_FALSE_INTERFACE;
577 }
578 }
579
580 if (fExtensions.has("GL_EXT_window_rectangles")) {
581 if (!fFunctions.fWindowRectangles) {
582 RETURN_FALSE_INTERFACE;
583 }
584 }
585
586 if (kGL_GrGLStandard == fStandard) {
587 if (glVer >= GR_GL_VER(3, 2) || fExtensions.has("GL_ARB_sync")) {
588 if (!fFunctions.fFenceSync ||
589 !fFunctions.fIsSync ||
590 !fFunctions.fClientWaitSync ||
591 !fFunctions.fWaitSync ||
592 !fFunctions.fDeleteSync) {
593 RETURN_FALSE_INTERFACE;
594 }
595 }
596 } else if (kGLES_GrGLStandard == fStandard) {
597 if (glVer >= GR_GL_VER(3, 0) || fExtensions.has("GL_APPLE_sync")) {
598 if (!fFunctions.fFenceSync ||
599 !fFunctions.fIsSync ||
600 !fFunctions.fClientWaitSync ||
601 !fFunctions.fWaitSync ||
602 !fFunctions.fDeleteSync) {
603 RETURN_FALSE_INTERFACE;
604 }
605 }
606 }
607
608 if (fExtensions.has("EGL_KHR_image") || fExtensions.has("EGL_KHR_image_base")) {
609 if (!fFunctions.fEGLCreateImage ||
610 !fFunctions.fEGLDestroyImage) {
611 RETURN_FALSE_INTERFACE;
612 }
613 }
614
615 // glDrawRangeElements was added to ES in 3.0.
616 if (kGL_GrGLStandard == fStandard || glVer >= GR_GL_VER(3,0)) {
617 if (!fFunctions.fDrawRangeElements) {
618 RETURN_FALSE_INTERFACE;
619 }
620 }
621
622 // getInternalformativ was added in GL 4.2, ES 3.0, and with extension ARB_internalformat_query
623 if ((kGL_GrGLStandard == fStandard &&
624 (glVer >= GR_GL_VER(4,2) || fExtensions.has("GL_ARB_internalformat_query"))) ||
625 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0))) {
626 if (!fFunctions.fGetInternalformativ) {
627 RETURN_FALSE_INTERFACE;
628 }
629 }
630
631 if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,1)) ||
632 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0))) {
633 if (!fFunctions.fGetProgramBinary ||
634 !fFunctions.fProgramBinary ||
635 !fFunctions.fProgramParameteri) {
636 RETURN_FALSE_INTERFACE;
637 }
638 }
639
640 if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,1)) ||
641 (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0))) {
642 if (!fFunctions.fBindSampler ||
643 !fFunctions.fDeleteSamplers ||
644 !fFunctions.fGenSamplers ||
645 !fFunctions.fSamplerParameteri ||
646 !fFunctions.fSamplerParameteriv) {
647 RETURN_FALSE_INTERFACE;
648 }
649 }
650
651 return true;
652 }
653
654 #if GR_TEST_UTILS
655
abandon() const656 void GrGLInterface::abandon() const {
657 const_cast<GrGLInterface*>(this)->fFunctions = GrGLInterface::Functions();
658 }
659
660 #endif // GR_TEST_UTILS
661
662