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