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 
GrGLInterfaceAddTestDebugMarker(const GrGLInterface * interface,GrGLInsertEventMarkerProc insertEventMarkerFn,GrGLPushGroupMarkerProc pushGroupMarkerFn,GrGLPopGroupMarkerProc popGroupMarkerFn)15 const GrGLInterface* GrGLInterfaceAddTestDebugMarker(const GrGLInterface* interface,
16                                                      GrGLInsertEventMarkerProc insertEventMarkerFn,
17                                                      GrGLPushGroupMarkerProc pushGroupMarkerFn,
18                                                      GrGLPopGroupMarkerProc popGroupMarkerFn) {
19     GrGLInterface* newInterface = GrGLInterface::NewClone(interface);
20 
21     if (!newInterface->fExtensions.has("GL_EXT_debug_marker")) {
22         newInterface->fExtensions.add("GL_EXT_debug_marker");
23     }
24 
25     newInterface->fFunctions.fInsertEventMarker = insertEventMarkerFn;
26     newInterface->fFunctions.fPushGroupMarker = pushGroupMarkerFn;
27     newInterface->fFunctions.fPopGroupMarker = popGroupMarkerFn;
28 
29     return newInterface;
30 }
31 
GrGLInterface()32 GrGLInterface::GrGLInterface() {
33     fStandard = kNone_GrGLStandard;
34 }
35 
NewClone(const GrGLInterface * interface)36 GrGLInterface* GrGLInterface::NewClone(const GrGLInterface* interface) {
37     SkASSERT(interface);
38 
39     GrGLInterface* clone = new GrGLInterface;
40     clone->fStandard = interface->fStandard;
41     clone->fExtensions = interface->fExtensions;
42     clone->fFunctions = interface->fFunctions;
43     return clone;
44 }
45 
46 #ifdef SK_DEBUG
47     static int kIsDebug = 1;
48 #else
49     static int kIsDebug = 0;
50 #endif
51 
52 #define RETURN_FALSE_INTERFACE                                                                   \
53     if (kIsDebug) { SkDebugf("%s:%d GrGLInterface::validate() failed.\n", __FILE__, __LINE__); } \
54     return false;
55 
validate() const56 bool GrGLInterface::validate() const {
57 
58     if (kNone_GrGLStandard == fStandard) {
59         RETURN_FALSE_INTERFACE
60     }
61 
62     if (!fExtensions.isInitialized()) {
63         RETURN_FALSE_INTERFACE
64     }
65 
66     // functions that are always required
67     if (nullptr == fFunctions.fActiveTexture ||
68         nullptr == fFunctions.fAttachShader ||
69         nullptr == fFunctions.fBindAttribLocation ||
70         nullptr == fFunctions.fBindBuffer ||
71         nullptr == fFunctions.fBindTexture ||
72         nullptr == fFunctions.fBlendColor ||      // -> GL >= 1.4 or extension, ES >= 2.0
73         nullptr == fFunctions.fBlendEquation ||   // -> GL >= 1.4 or extension, ES >= 2.0
74         nullptr == fFunctions.fBlendFunc ||
75         nullptr == fFunctions.fBufferData ||
76         nullptr == fFunctions.fBufferSubData ||
77         nullptr == fFunctions.fClear ||
78         nullptr == fFunctions.fClearColor ||
79         nullptr == fFunctions.fClearStencil ||
80         nullptr == fFunctions.fColorMask ||
81         nullptr == fFunctions.fCompileShader ||
82         nullptr == fFunctions.fCopyTexSubImage2D ||
83         nullptr == fFunctions.fCreateProgram ||
84         nullptr == fFunctions.fCreateShader ||
85         nullptr == fFunctions.fCullFace ||
86         nullptr == fFunctions.fDeleteBuffers ||
87         nullptr == fFunctions.fDeleteProgram ||
88         nullptr == fFunctions.fDeleteShader ||
89         nullptr == fFunctions.fDeleteTextures ||
90         nullptr == fFunctions.fDepthMask ||
91         nullptr == fFunctions.fDisable ||
92         nullptr == fFunctions.fDisableVertexAttribArray ||
93         nullptr == fFunctions.fDrawArrays ||
94         nullptr == fFunctions.fDrawElements ||
95         nullptr == fFunctions.fEnable ||
96         nullptr == fFunctions.fEnableVertexAttribArray ||
97         nullptr == fFunctions.fFrontFace ||
98         nullptr == fFunctions.fGenBuffers ||
99         nullptr == fFunctions.fGenTextures ||
100         nullptr == fFunctions.fGetBufferParameteriv ||
101         nullptr == fFunctions.fGenerateMipmap ||
102         nullptr == fFunctions.fGetError ||
103         nullptr == fFunctions.fGetIntegerv ||
104         nullptr == fFunctions.fGetProgramInfoLog ||
105         nullptr == fFunctions.fGetProgramiv ||
106         nullptr == fFunctions.fGetShaderInfoLog ||
107         nullptr == fFunctions.fGetShaderiv ||
108         nullptr == fFunctions.fGetString ||
109         nullptr == fFunctions.fGetUniformLocation ||
110 #if 0 //  Not included in Chrome yet
111         nullptr == fFunctions.fIsTexture ||
112 #endif
113         nullptr == fFunctions.fLinkProgram ||
114         nullptr == fFunctions.fLineWidth ||
115         nullptr == fFunctions.fPixelStorei ||
116         nullptr == fFunctions.fReadPixels ||
117         nullptr == fFunctions.fScissor ||
118         nullptr == fFunctions.fShaderSource ||
119         nullptr == fFunctions.fStencilFunc ||
120         nullptr == fFunctions.fStencilMask ||
121         nullptr == fFunctions.fStencilOp ||
122         nullptr == fFunctions.fTexImage2D ||
123         nullptr == fFunctions.fTexParameteri ||
124         nullptr == fFunctions.fTexParameteriv ||
125         nullptr == fFunctions.fTexSubImage2D ||
126         nullptr == fFunctions.fUniform1f ||
127         nullptr == fFunctions.fUniform1i ||
128         nullptr == fFunctions.fUniform1fv ||
129         nullptr == fFunctions.fUniform1iv ||
130         nullptr == fFunctions.fUniform2f ||
131         nullptr == fFunctions.fUniform2i ||
132         nullptr == fFunctions.fUniform2fv ||
133         nullptr == fFunctions.fUniform2iv ||
134         nullptr == fFunctions.fUniform3f ||
135         nullptr == fFunctions.fUniform3i ||
136         nullptr == fFunctions.fUniform3fv ||
137         nullptr == fFunctions.fUniform3iv ||
138         nullptr == fFunctions.fUniform4f ||
139         nullptr == fFunctions.fUniform4i ||
140         nullptr == fFunctions.fUniform4fv ||
141         nullptr == fFunctions.fUniform4iv ||
142         nullptr == fFunctions.fUniformMatrix2fv ||
143         nullptr == fFunctions.fUniformMatrix3fv ||
144         nullptr == fFunctions.fUniformMatrix4fv ||
145         nullptr == fFunctions.fUseProgram ||
146         nullptr == fFunctions.fVertexAttrib1f ||
147         nullptr == fFunctions.fVertexAttrib2fv ||
148         nullptr == fFunctions.fVertexAttrib3fv ||
149         nullptr == fFunctions.fVertexAttrib4fv ||
150         nullptr == fFunctions.fVertexAttribPointer ||
151         nullptr == fFunctions.fViewport ||
152         nullptr == fFunctions.fBindFramebuffer ||
153         nullptr == fFunctions.fBindRenderbuffer ||
154         nullptr == fFunctions.fCheckFramebufferStatus ||
155         nullptr == fFunctions.fDeleteFramebuffers ||
156         nullptr == fFunctions.fDeleteRenderbuffers ||
157         nullptr == fFunctions.fFinish ||
158         nullptr == fFunctions.fFlush ||
159         nullptr == fFunctions.fFramebufferRenderbuffer ||
160         nullptr == fFunctions.fFramebufferTexture2D ||
161         nullptr == fFunctions.fGetFramebufferAttachmentParameteriv ||
162         nullptr == fFunctions.fGetRenderbufferParameteriv ||
163         nullptr == fFunctions.fGenFramebuffers ||
164         nullptr == fFunctions.fGenRenderbuffers ||
165         nullptr == fFunctions.fRenderbufferStorage) {
166         RETURN_FALSE_INTERFACE
167     }
168 
169     GrGLVersion glVer = GrGLGetVersion(this);
170     if (GR_GL_INVALID_VER == glVer) {
171         RETURN_FALSE_INTERFACE
172     }
173 
174     // Now check that baseline ES/Desktop fns not covered above are present
175     // and that we have fn pointers for any advertised fExtensions that we will
176     // try to use.
177 
178     // these functions are part of ES2, we assume they are available
179     // On the desktop we assume they are available if the extension
180     // is present or GL version is high enough.
181     if (kGLES_GrGLStandard == fStandard) {
182         if (nullptr == fFunctions.fStencilFuncSeparate ||
183             nullptr == fFunctions.fStencilMaskSeparate ||
184             nullptr == fFunctions.fStencilOpSeparate) {
185             RETURN_FALSE_INTERFACE
186         }
187     } else if (kGL_GrGLStandard == fStandard) {
188 
189         if (glVer >= GR_GL_VER(2,0)) {
190             if (nullptr == fFunctions.fStencilFuncSeparate ||
191                 nullptr == fFunctions.fStencilMaskSeparate ||
192                 nullptr == fFunctions.fStencilOpSeparate) {
193                 RETURN_FALSE_INTERFACE
194             }
195         }
196         if (glVer >= GR_GL_VER(3,0) && nullptr == fFunctions.fBindFragDataLocation) {
197             RETURN_FALSE_INTERFACE
198         }
199         if (glVer >= GR_GL_VER(2,0) || fExtensions.has("GL_ARB_draw_buffers")) {
200             if (nullptr == fFunctions.fDrawBuffers) {
201                 RETURN_FALSE_INTERFACE
202             }
203         }
204 
205         if (glVer >= GR_GL_VER(1,5) || fExtensions.has("GL_ARB_occlusion_query")) {
206             if (nullptr == fFunctions.fGenQueries ||
207                 nullptr == fFunctions.fDeleteQueries ||
208                 nullptr == fFunctions.fBeginQuery ||
209                 nullptr == fFunctions.fEndQuery ||
210                 nullptr == fFunctions.fGetQueryiv ||
211                 nullptr == fFunctions.fGetQueryObjectiv ||
212                 nullptr == fFunctions.fGetQueryObjectuiv) {
213                 RETURN_FALSE_INTERFACE
214             }
215         }
216         if (glVer >= GR_GL_VER(3,3) ||
217             fExtensions.has("GL_ARB_timer_query") ||
218             fExtensions.has("GL_EXT_timer_query")) {
219             if (nullptr == fFunctions.fGetQueryObjecti64v ||
220                 nullptr == fFunctions.fGetQueryObjectui64v) {
221                 RETURN_FALSE_INTERFACE
222             }
223         }
224         if (glVer >= GR_GL_VER(3,3) || fExtensions.has("GL_ARB_timer_query")) {
225             if (nullptr == fFunctions.fQueryCounter) {
226                 RETURN_FALSE_INTERFACE
227             }
228         }
229     }
230 
231     // optional function on desktop before 1.3
232     if (kGL_GrGLStandard != fStandard ||
233         (glVer >= GR_GL_VER(1,3)) ||
234         fExtensions.has("GL_ARB_texture_compression")) {
235         if (nullptr == fFunctions.fCompressedTexImage2D
236 #if 0
237             || nullptr == fFunctions.fCompressedTexSubImage2D
238 #endif
239             ) {
240             RETURN_FALSE_INTERFACE
241         }
242     }
243 
244     // part of desktop GL, but not ES
245     if (kGL_GrGLStandard == fStandard &&
246         (nullptr == fFunctions.fGetTexLevelParameteriv ||
247          nullptr == fFunctions.fDrawBuffer ||
248          nullptr == fFunctions.fReadBuffer)) {
249         RETURN_FALSE_INTERFACE
250     }
251 
252     // GL_EXT_texture_storage is part of desktop 4.2
253     // There is a desktop ARB extension and an ES+desktop EXT extension
254     if (kGL_GrGLStandard == fStandard) {
255         if (glVer >= GR_GL_VER(4,2) ||
256             fExtensions.has("GL_ARB_texture_storage") ||
257             fExtensions.has("GL_EXT_texture_storage")) {
258             if (nullptr == fFunctions.fTexStorage2D) {
259                 RETURN_FALSE_INTERFACE
260             }
261         }
262     } else if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_texture_storage")) {
263         if (nullptr == fFunctions.fTexStorage2D) {
264             RETURN_FALSE_INTERFACE
265         }
266     }
267 
268     // glTextureBarrier is part of desktop 4.5. There are also ARB and NV extensions.
269     if (kGL_GrGLStandard == fStandard) {
270         if (glVer >= GR_GL_VER(4,5) ||
271             fExtensions.has("GL_ARB_texture_barrier") ||
272             fExtensions.has("GL_NV_texture_barrier")) {
273             if (nullptr == fFunctions.fTextureBarrier) {
274                 RETURN_FALSE_INTERFACE
275             }
276         }
277     } else if (fExtensions.has("GL_NV_texture_barrier")) {
278         if (nullptr == fFunctions.fTextureBarrier) {
279             RETURN_FALSE_INTERFACE
280         }
281     }
282 
283     if (fExtensions.has("GL_KHR_blend_equation_advanced") ||
284         fExtensions.has("GL_NV_blend_equation_advanced")) {
285         if (nullptr == fFunctions.fBlendBarrier) {
286             RETURN_FALSE_INTERFACE
287         }
288     }
289 
290     if (fExtensions.has("GL_EXT_discard_framebuffer")) {
291         if (nullptr == fFunctions.fDiscardFramebuffer) {
292             RETURN_FALSE_INTERFACE
293         }
294     }
295 
296     // FBO MSAA
297     if (kGL_GrGLStandard == fStandard) {
298         // GL 3.0 and the ARB extension have multisample + blit
299         if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_ARB_framebuffer_object")) {
300             if (nullptr == fFunctions.fRenderbufferStorageMultisample ||
301                 nullptr == fFunctions.fBlitFramebuffer) {
302                 RETURN_FALSE_INTERFACE
303             }
304         } else {
305             if (fExtensions.has("GL_EXT_framebuffer_blit") &&
306                 nullptr == fFunctions.fBlitFramebuffer) {
307                 RETURN_FALSE_INTERFACE
308             }
309             if (fExtensions.has("GL_EXT_framebuffer_multisample") &&
310                 nullptr == fFunctions.fRenderbufferStorageMultisample) {
311                 RETURN_FALSE_INTERFACE
312             }
313         }
314     } else {
315         if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_CHROMIUM_framebuffer_multisample")) {
316             if (nullptr == fFunctions.fRenderbufferStorageMultisample ||
317                 nullptr == fFunctions.fBlitFramebuffer) {
318                 RETURN_FALSE_INTERFACE
319             }
320         } else {
321             if (fExtensions.has("GL_ANGLE_framebuffer_multisample") &&
322                 nullptr == fFunctions.fRenderbufferStorageMultisample) {
323                 RETURN_FALSE_INTERFACE
324             }
325             if (fExtensions.has("GL_ANGLE_framebuffer_blit") &&
326                 nullptr == fFunctions.fBlitFramebuffer) {
327                 RETURN_FALSE_INTERFACE
328             }
329         }
330         if (fExtensions.has("GL_APPLE_framebuffer_multisample")) {
331             if (nullptr == fFunctions.fRenderbufferStorageMultisampleES2APPLE ||
332                 nullptr == fFunctions.fResolveMultisampleFramebuffer) {
333                 RETURN_FALSE_INTERFACE
334             }
335         }
336         if (fExtensions.has("GL_IMG_multisampled_render_to_texture") ||
337             fExtensions.has("GL_EXT_multisampled_render_to_texture")) {
338             if (nullptr == fFunctions.fRenderbufferStorageMultisampleES2EXT ||
339                 nullptr == fFunctions.fFramebufferTexture2DMultisample) {
340                 RETURN_FALSE_INTERFACE
341             }
342         }
343     }
344 
345     // On ES buffer mapping is an extension. On Desktop
346     // buffer mapping was part of original VBO extension
347     // which we require.
348     if (kGL_GrGLStandard == fStandard || fExtensions.has("GL_OES_mapbuffer")) {
349         if (nullptr == fFunctions.fMapBuffer ||
350             nullptr == fFunctions.fUnmapBuffer) {
351             RETURN_FALSE_INTERFACE
352         }
353     }
354 
355     // Dual source blending
356     if (kGL_GrGLStandard == fStandard) {
357         if (glVer >= GR_GL_VER(3,3) || fExtensions.has("GL_ARB_blend_func_extended")) {
358             if (nullptr == fFunctions.fBindFragDataLocationIndexed) {
359                 RETURN_FALSE_INTERFACE
360             }
361         }
362     } else {
363         if (glVer >= GR_GL_VER(3,0) && fExtensions.has("GL_EXT_blend_func_extended")) {
364             if (nullptr == fFunctions.fBindFragDataLocation ||
365                 nullptr == fFunctions.fBindFragDataLocationIndexed) {
366                 RETURN_FALSE_INTERFACE
367             }
368         }
369     }
370 
371 
372     // glGetStringi was added in version 3.0 of both desktop and ES.
373     if (glVer >= GR_GL_VER(3, 0)) {
374         if (nullptr == fFunctions.fGetStringi) {
375             RETURN_FALSE_INTERFACE
376         }
377     }
378 
379     // glVertexAttribIPointer was added in version 3.0 of both desktop and ES.
380     if (glVer >= GR_GL_VER(3, 0)) {
381         if (NULL == fFunctions.fVertexAttribIPointer) {
382             RETURN_FALSE_INTERFACE
383         }
384     }
385 
386     if (kGL_GrGLStandard == fStandard) {
387         if (glVer >= GR_GL_VER(3,1)) {
388             if (nullptr == fFunctions.fTexBuffer) {
389                 RETURN_FALSE_INTERFACE;
390             }
391         }
392         if (glVer >= GR_GL_VER(4,3)) {
393             if (nullptr == fFunctions.fTexBufferRange) {
394                 RETURN_FALSE_INTERFACE;
395             }
396         }
397     } else {
398         if (glVer >= GR_GL_VER(3,2) || fExtensions.has("GL_OES_texture_buffer") ||
399             fExtensions.has("GL_EXT_texture_buffer")) {
400             if (nullptr == fFunctions.fTexBuffer ||
401                 nullptr == fFunctions.fTexBufferRange) {
402                 RETURN_FALSE_INTERFACE;
403             }
404         }
405     }
406 
407     if (kGL_GrGLStandard == fStandard) {
408         if (glVer >= GR_GL_VER(3, 0) || fExtensions.has("GL_ARB_vertex_array_object")) {
409             if (nullptr == fFunctions.fBindVertexArray ||
410                 nullptr == fFunctions.fDeleteVertexArrays ||
411                 nullptr == fFunctions.fGenVertexArrays) {
412                 RETURN_FALSE_INTERFACE
413             }
414         }
415     } else {
416         if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_OES_vertex_array_object")) {
417             if (nullptr == fFunctions.fBindVertexArray ||
418                 nullptr == fFunctions.fDeleteVertexArrays ||
419                 nullptr == fFunctions.fGenVertexArrays) {
420                 RETURN_FALSE_INTERFACE
421             }
422         }
423     }
424 
425     if (fExtensions.has("GL_EXT_debug_marker")) {
426         if (nullptr == fFunctions.fInsertEventMarker ||
427             nullptr == fFunctions.fPushGroupMarker ||
428             nullptr == fFunctions.fPopGroupMarker) {
429             RETURN_FALSE_INTERFACE
430         }
431     }
432 
433     if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,3)) ||
434         fExtensions.has("GL_ARB_invalidate_subdata")) {
435         if (nullptr == fFunctions.fInvalidateBufferData ||
436             nullptr == fFunctions.fInvalidateBufferSubData ||
437             nullptr == fFunctions.fInvalidateFramebuffer ||
438             nullptr == fFunctions.fInvalidateSubFramebuffer ||
439             nullptr == fFunctions.fInvalidateTexImage ||
440             nullptr == fFunctions.fInvalidateTexSubImage) {
441             RETURN_FALSE_INTERFACE;
442         }
443     } else if (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0)) {
444         // ES 3.0 adds the framebuffer functions but not the others.
445         if (nullptr == fFunctions.fInvalidateFramebuffer ||
446             nullptr == fFunctions.fInvalidateSubFramebuffer) {
447             RETURN_FALSE_INTERFACE;
448         }
449     }
450 
451     if (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_CHROMIUM_map_sub")) {
452         if (nullptr == fFunctions.fMapBufferSubData ||
453             nullptr == fFunctions.fMapTexSubImage2D ||
454             nullptr == fFunctions.fUnmapBufferSubData ||
455             nullptr == fFunctions.fUnmapTexSubImage2D) {
456             RETURN_FALSE_INTERFACE;
457         }
458     }
459 
460     // These functions are added to the 3.0 version of both GLES and GL.
461     if (glVer >= GR_GL_VER(3,0) ||
462         (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_EXT_map_buffer_range")) ||
463         (kGL_GrGLStandard == fStandard && fExtensions.has("GL_ARB_map_buffer_range"))) {
464         if (nullptr == fFunctions.fMapBufferRange ||
465             nullptr == fFunctions.fFlushMappedBufferRange) {
466             RETURN_FALSE_INTERFACE;
467         }
468     }
469 
470     if ((kGL_GrGLStandard == fStandard &&
471          (glVer >= GR_GL_VER(3,2) || fExtensions.has("GL_ARB_texture_multisample"))) ||
472         (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) {
473         if (NULL == fFunctions.fGetMultisamplefv) {
474             RETURN_FALSE_INTERFACE
475         }
476     }
477 
478     if ((kGL_GrGLStandard == fStandard &&
479          (glVer >= GR_GL_VER(4,3) || fExtensions.has("GL_ARB_program_interface_query"))) ||
480         (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) {
481         if (nullptr == fFunctions.fGetProgramResourceLocation) {
482             RETURN_FALSE_INTERFACE
483         }
484     }
485 
486     if (kGLES_GrGLStandard == fStandard || glVer >= GR_GL_VER(4,1) ||
487         fExtensions.has("GL_ARB_ES2_compatibility")) {
488         if (nullptr == fFunctions.fGetShaderPrecisionFormat) {
489             RETURN_FALSE_INTERFACE
490         }
491     }
492 
493     if (fExtensions.has("GL_NV_path_rendering") || fExtensions.has("GL_CHROMIUM_path_rendering")) {
494         if (nullptr == fFunctions.fMatrixLoadf ||
495             nullptr == fFunctions.fMatrixLoadIdentity ||
496             nullptr == fFunctions.fPathCommands ||
497             nullptr == fFunctions.fPathParameteri ||
498             nullptr == fFunctions.fPathParameterf ||
499             nullptr == fFunctions.fGenPaths ||
500             nullptr == fFunctions.fDeletePaths ||
501             nullptr == fFunctions.fIsPath ||
502             nullptr == fFunctions.fPathStencilFunc ||
503             nullptr == fFunctions.fStencilFillPath ||
504             nullptr == fFunctions.fStencilStrokePath ||
505             nullptr == fFunctions.fStencilFillPathInstanced ||
506             nullptr == fFunctions.fStencilStrokePathInstanced ||
507             nullptr == fFunctions.fCoverFillPath ||
508             nullptr == fFunctions.fCoverStrokePath ||
509             nullptr == fFunctions.fCoverFillPathInstanced ||
510             nullptr == fFunctions.fCoverStrokePathInstanced
511 #if 0
512             // List of functions that Skia uses, but which have been added since the initial release
513             // of NV_path_rendering driver. We do not want to fail interface validation due to
514             // missing features, we will just not use the extension.
515             // Update this list -> update GrGLCaps::hasPathRenderingSupport too.
516             || nullptr == fFunctions.fStencilThenCoverFillPath ||
517             nullptr == fFunctions.fStencilThenCoverStrokePath ||
518             nullptr == fFunctions.fStencilThenCoverFillPathInstanced ||
519             nullptr == fFunctions.fStencilThenCoverStrokePathInstanced ||
520             nullptr == fFunctions.fProgramPathFragmentInputGen
521 #endif
522             ) {
523             RETURN_FALSE_INTERFACE
524         }
525         if (fExtensions.has("GL_CHROMIUM_path_rendering")) {
526             if (nullptr == fFunctions.fBindFragmentInputLocation) {
527                 RETURN_FALSE_INTERFACE
528             }
529         }
530     }
531 
532     if (fExtensions.has("GL_EXT_raster_multisample")) {
533         if (nullptr == fFunctions.fRasterSamples) {
534             RETURN_FALSE_INTERFACE
535         }
536     }
537 
538     if (fExtensions.has("GL_NV_framebuffer_mixed_samples") ||
539         fExtensions.has("GL_CHROMIUM_framebuffer_mixed_samples")) {
540         if (nullptr == fFunctions.fCoverageModulation) {
541             RETURN_FALSE_INTERFACE
542         }
543     }
544 
545     if (kGL_GrGLStandard == fStandard) {
546         if (glVer >= GR_GL_VER(3,1) ||
547             fExtensions.has("GL_EXT_draw_instanced") || fExtensions.has("GL_ARB_draw_instanced")) {
548             if (nullptr == fFunctions.fDrawArraysInstanced ||
549                 nullptr == fFunctions.fDrawElementsInstanced) {
550                 RETURN_FALSE_INTERFACE
551             }
552         }
553     } else if (kGLES_GrGLStandard == fStandard) {
554         if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_draw_instanced")) {
555             if (nullptr == fFunctions.fDrawArraysInstanced ||
556                 nullptr == fFunctions.fDrawElementsInstanced) {
557                 RETURN_FALSE_INTERFACE
558             }
559         }
560     }
561 
562     if (kGL_GrGLStandard == fStandard) {
563         if (glVer >= GR_GL_VER(3,2) || fExtensions.has("GL_ARB_instanced_arrays")) {
564             if (nullptr == fFunctions.fVertexAttribDivisor) {
565                 RETURN_FALSE_INTERFACE
566             }
567         }
568     } else if (kGLES_GrGLStandard == fStandard) {
569         if (glVer >= GR_GL_VER(3,0) || fExtensions.has("GL_EXT_instanced_arrays")) {
570             if (nullptr == fFunctions.fVertexAttribDivisor) {
571                 RETURN_FALSE_INTERFACE
572             }
573         }
574     }
575 
576     if ((kGL_GrGLStandard == fStandard &&
577          (glVer >= GR_GL_VER(4,0) || fExtensions.has("GL_ARB_draw_indirect"))) ||
578         (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1))) {
579         if (NULL == fFunctions.fDrawArraysIndirect ||
580             NULL == fFunctions.fDrawElementsIndirect) {
581             RETURN_FALSE_INTERFACE
582         }
583     }
584 
585     if ((kGL_GrGLStandard == fStandard &&
586          (glVer >= GR_GL_VER(4,3) || fExtensions.has("GL_ARB_multi_draw_indirect"))) ||
587         (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_EXT_multi_draw_indirect"))) {
588         if (NULL == fFunctions.fMultiDrawArraysIndirect ||
589             NULL == fFunctions.fMultiDrawElementsIndirect) {
590             RETURN_FALSE_INTERFACE
591         }
592     }
593 
594     if (fExtensions.has("GL_NV_bindless_texture")) {
595         if (nullptr == fFunctions.fGetTextureHandle ||
596             nullptr == fFunctions.fGetTextureSamplerHandle ||
597             nullptr == fFunctions.fMakeTextureHandleResident ||
598             nullptr == fFunctions.fMakeTextureHandleNonResident ||
599             nullptr == fFunctions.fGetImageHandle ||
600             nullptr == fFunctions.fMakeImageHandleResident ||
601             nullptr == fFunctions.fMakeImageHandleNonResident ||
602             nullptr == fFunctions.fIsTextureHandleResident ||
603             nullptr == fFunctions.fIsImageHandleResident ||
604             nullptr == fFunctions.fUniformHandleui64 ||
605             nullptr == fFunctions.fUniformHandleui64v ||
606             nullptr == fFunctions.fProgramUniformHandleui64 ||
607             nullptr == fFunctions.fProgramUniformHandleui64v) {
608             RETURN_FALSE_INTERFACE
609         }
610     }
611 
612     if (kGL_GrGLStandard == fStandard && fExtensions.has("GL_EXT_direct_state_access")) {
613         if (nullptr == fFunctions.fTextureParameteri ||
614             nullptr == fFunctions.fTextureParameteriv ||
615             nullptr == fFunctions.fTextureParameterf ||
616             nullptr == fFunctions.fTextureParameterfv ||
617             nullptr == fFunctions.fTextureImage1D ||
618             nullptr == fFunctions.fTextureImage2D ||
619             nullptr == fFunctions.fTextureSubImage1D ||
620             nullptr == fFunctions.fTextureSubImage2D ||
621             nullptr == fFunctions.fCopyTextureImage1D ||
622             nullptr == fFunctions.fCopyTextureImage2D ||
623             nullptr == fFunctions.fCopyTextureSubImage1D ||
624             nullptr == fFunctions.fCopyTextureSubImage2D ||
625             nullptr == fFunctions.fGetTextureImage ||
626             nullptr == fFunctions.fGetTextureParameterfv ||
627             nullptr == fFunctions.fGetTextureParameteriv ||
628             nullptr == fFunctions.fGetTextureLevelParameterfv ||
629             nullptr == fFunctions.fGetTextureLevelParameteriv) {
630             RETURN_FALSE_INTERFACE
631         }
632         if (glVer >= GR_GL_VER(1,2)) {
633             if (nullptr == fFunctions.fTextureImage3D ||
634                 nullptr == fFunctions.fTextureSubImage3D ||
635                 nullptr == fFunctions.fCopyTextureSubImage3D ||
636                 nullptr == fFunctions.fCompressedTextureImage3D ||
637                 nullptr == fFunctions.fCompressedTextureImage2D ||
638                 nullptr == fFunctions.fCompressedTextureImage1D ||
639                 nullptr == fFunctions.fCompressedTextureSubImage3D ||
640                 nullptr == fFunctions.fCompressedTextureSubImage2D ||
641                 nullptr == fFunctions.fCompressedTextureSubImage1D ||
642                 nullptr == fFunctions.fGetCompressedTextureImage) {
643                 RETURN_FALSE_INTERFACE
644             }
645         }
646         if (glVer >= GR_GL_VER(1,5)) {
647             if (nullptr == fFunctions.fNamedBufferData ||
648                 nullptr == fFunctions.fNamedBufferSubData ||
649                 nullptr == fFunctions.fMapNamedBuffer ||
650                 nullptr == fFunctions.fUnmapNamedBuffer ||
651                 nullptr == fFunctions.fGetNamedBufferParameteriv ||
652                 nullptr == fFunctions.fGetNamedBufferPointerv ||
653                 nullptr == fFunctions.fGetNamedBufferSubData) {
654                 RETURN_FALSE_INTERFACE
655             }
656         }
657         if (glVer >= GR_GL_VER(2,0)) {
658             if (nullptr == fFunctions.fProgramUniform1f ||
659                 nullptr == fFunctions.fProgramUniform2f ||
660                 nullptr == fFunctions.fProgramUniform3f ||
661                 nullptr == fFunctions.fProgramUniform4f ||
662                 nullptr == fFunctions.fProgramUniform1i ||
663                 nullptr == fFunctions.fProgramUniform2i ||
664                 nullptr == fFunctions.fProgramUniform3i ||
665                 nullptr == fFunctions.fProgramUniform4i ||
666                 nullptr == fFunctions.fProgramUniform1fv ||
667                 nullptr == fFunctions.fProgramUniform2fv ||
668                 nullptr == fFunctions.fProgramUniform3fv ||
669                 nullptr == fFunctions.fProgramUniform4fv ||
670                 nullptr == fFunctions.fProgramUniform1iv ||
671                 nullptr == fFunctions.fProgramUniform2iv ||
672                 nullptr == fFunctions.fProgramUniform3iv ||
673                 nullptr == fFunctions.fProgramUniform4iv ||
674                 nullptr == fFunctions.fProgramUniformMatrix2fv ||
675                 nullptr == fFunctions.fProgramUniformMatrix3fv ||
676                 nullptr == fFunctions.fProgramUniformMatrix4fv) {
677                 RETURN_FALSE_INTERFACE
678             }
679         }
680         if (glVer >= GR_GL_VER(2,1)) {
681             if (nullptr == fFunctions.fProgramUniformMatrix2x3fv ||
682                 nullptr == fFunctions.fProgramUniformMatrix3x2fv ||
683                 nullptr == fFunctions.fProgramUniformMatrix2x4fv ||
684                 nullptr == fFunctions.fProgramUniformMatrix4x2fv ||
685                 nullptr == fFunctions.fProgramUniformMatrix3x4fv ||
686                 nullptr == fFunctions.fProgramUniformMatrix4x3fv) {
687                 RETURN_FALSE_INTERFACE
688             }
689         }
690         if (glVer >= GR_GL_VER(3,0)) {
691             if (nullptr == fFunctions.fNamedRenderbufferStorage ||
692                 nullptr == fFunctions.fGetNamedRenderbufferParameteriv ||
693                 nullptr == fFunctions.fNamedRenderbufferStorageMultisample ||
694                 nullptr == fFunctions.fCheckNamedFramebufferStatus ||
695                 nullptr == fFunctions.fNamedFramebufferTexture1D ||
696                 nullptr == fFunctions.fNamedFramebufferTexture2D ||
697                 nullptr == fFunctions.fNamedFramebufferTexture3D ||
698                 nullptr == fFunctions.fNamedFramebufferRenderbuffer ||
699                 nullptr == fFunctions.fGetNamedFramebufferAttachmentParameteriv ||
700                 nullptr == fFunctions.fGenerateTextureMipmap ||
701                 nullptr == fFunctions.fFramebufferDrawBuffer ||
702                 nullptr == fFunctions.fFramebufferDrawBuffers ||
703                 nullptr == fFunctions.fFramebufferReadBuffer ||
704                 nullptr == fFunctions.fGetFramebufferParameteriv ||
705                 nullptr == fFunctions.fNamedCopyBufferSubData ||
706                 nullptr == fFunctions.fVertexArrayVertexOffset ||
707                 nullptr == fFunctions.fVertexArrayColorOffset ||
708                 nullptr == fFunctions.fVertexArrayEdgeFlagOffset ||
709                 nullptr == fFunctions.fVertexArrayIndexOffset ||
710                 nullptr == fFunctions.fVertexArrayNormalOffset ||
711                 nullptr == fFunctions.fVertexArrayTexCoordOffset ||
712                 nullptr == fFunctions.fVertexArrayMultiTexCoordOffset ||
713                 nullptr == fFunctions.fVertexArrayFogCoordOffset ||
714                 nullptr == fFunctions.fVertexArraySecondaryColorOffset ||
715                 nullptr == fFunctions.fVertexArrayVertexAttribOffset ||
716                 nullptr == fFunctions.fVertexArrayVertexAttribIOffset ||
717                 nullptr == fFunctions.fEnableVertexArray ||
718                 nullptr == fFunctions.fDisableVertexArray ||
719                 nullptr == fFunctions.fEnableVertexArrayAttrib ||
720                 nullptr == fFunctions.fDisableVertexArrayAttrib ||
721                 nullptr == fFunctions.fGetVertexArrayIntegerv ||
722                 nullptr == fFunctions.fGetVertexArrayPointerv ||
723                 nullptr == fFunctions.fGetVertexArrayIntegeri_v ||
724                 nullptr == fFunctions.fGetVertexArrayPointeri_v ||
725                 nullptr == fFunctions.fMapNamedBufferRange ||
726                 nullptr == fFunctions.fFlushMappedNamedBufferRange) {
727                 RETURN_FALSE_INTERFACE
728             }
729         }
730         if (glVer >= GR_GL_VER(3,1)) {
731             if (nullptr == fFunctions.fTextureBuffer) {
732                 RETURN_FALSE_INTERFACE;
733             }
734         }
735     }
736 
737     if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,3)) ||
738         fExtensions.has("GL_KHR_debug")) {
739         if (nullptr == fFunctions.fDebugMessageControl ||
740             nullptr == fFunctions.fDebugMessageInsert ||
741             nullptr == fFunctions.fDebugMessageCallback ||
742             nullptr == fFunctions.fGetDebugMessageLog ||
743             nullptr == fFunctions.fPushDebugGroup ||
744             nullptr == fFunctions.fPopDebugGroup ||
745             nullptr == fFunctions.fObjectLabel) {
746             RETURN_FALSE_INTERFACE
747         }
748     }
749 
750     if (fExtensions.has("GL_EXT_window_rectangles")) {
751         if (nullptr == fFunctions.fWindowRectangles) {
752             RETURN_FALSE_INTERFACE
753         }
754     }
755 
756     if ((kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(4,0)) ||
757         fExtensions.has("GL_ARB_sample_shading")) {
758         if (nullptr == fFunctions.fMinSampleShading) {
759             RETURN_FALSE_INTERFACE
760         }
761     } else if (kGLES_GrGLStandard == fStandard && fExtensions.has("GL_OES_sample_shading")) {
762         if (nullptr == fFunctions.fMinSampleShading) {
763             RETURN_FALSE_INTERFACE
764         }
765     }
766 
767     if (kGL_GrGLStandard == fStandard) {
768         if (glVer >= GR_GL_VER(3, 2) || fExtensions.has("GL_ARB_sync")) {
769             if (nullptr == fFunctions.fFenceSync ||
770                 nullptr == fFunctions.fClientWaitSync ||
771                 nullptr == fFunctions.fWaitSync ||
772                 nullptr == fFunctions.fDeleteSync) {
773                 RETURN_FALSE_INTERFACE
774             }
775         }
776     } else if (kGLES_GrGLStandard == fStandard) {
777         if (glVer >= GR_GL_VER(3, 0)) {
778             if (nullptr == fFunctions.fFenceSync ||
779                 nullptr == fFunctions.fClientWaitSync ||
780                 nullptr == fFunctions.fWaitSync ||
781                 nullptr == fFunctions.fDeleteSync) {
782                 RETURN_FALSE_INTERFACE
783             }
784         }
785     }
786 
787     if (fExtensions.has("EGL_KHR_image") || fExtensions.has("EGL_KHR_image_base")) {
788         if (nullptr == fFunctions.fEGLCreateImage ||
789             nullptr == fFunctions.fEGLDestroyImage) {
790             RETURN_FALSE_INTERFACE
791         }
792     }
793 
794     if (kGL_GrGLStandard == fStandard && glVer >= GR_GL_VER(2,0)) {
795         if (nullptr == fFunctions.fDrawRangeElements) {
796             RETURN_FALSE_INTERFACE;
797         }
798     } else if (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,0)) {
799         if (nullptr == fFunctions.fDrawRangeElements) {
800             RETURN_FALSE_INTERFACE;
801         }
802     }
803 
804     if (kGL_GrGLStandard == fStandard) {
805         if (glVer >= GR_GL_VER(4,2) || fExtensions.has("GL_ARB_shader_image_load_store")) {
806             if (nullptr == fFunctions.fBindImageTexture ||
807                 nullptr == fFunctions.fMemoryBarrier) {
808                 RETURN_FALSE_INTERFACE;
809             }
810         }
811         if (glVer >= GR_GL_VER(4,5) || fExtensions.has("GL_ARB_ES3_1_compatibility")) {
812             if (nullptr == fFunctions.fMemoryBarrierByRegion) {
813                 RETURN_FALSE_INTERFACE;
814             }
815         }
816     } else if (kGLES_GrGLStandard == fStandard && glVer >= GR_GL_VER(3,1)) {
817         if (nullptr == fFunctions.fBindImageTexture ||
818             nullptr == fFunctions.fMemoryBarrier ||
819             nullptr == fFunctions.fMemoryBarrierByRegion) {
820             RETURN_FALSE_INTERFACE;
821         }
822     }
823 
824     return true;
825 }
826