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