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