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