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