Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "GLContext.h"
7 : #include "nsPrintfCString.h"
8 :
9 : namespace mozilla {
10 : namespace gl {
11 :
12 : const size_t kMAX_EXTENSION_GROUP_SIZE = 5;
13 :
14 : enum class GLVersion : uint32_t {
15 : NONE = 0, // Feature is not supported natively by GL
16 : GL1_2 = 120,
17 : GL1_3 = 130,
18 : GL2 = 200,
19 : GL2_1 = 210,
20 : GL3 = 300,
21 : GL3_1 = 310,
22 : GL3_2 = 320,
23 : GL3_3 = 330,
24 : GL4 = 400,
25 : GL4_1 = 410,
26 : GL4_2 = 420,
27 : GL4_3 = 430,
28 : };
29 :
30 : enum class GLESVersion : uint32_t {
31 : NONE = 0, // Feature is not support natively by GL ES
32 : ES2 = 200,
33 : ES3 = 300,
34 : ES3_1 = 310,
35 : ES3_2 = 320,
36 : };
37 :
38 : // ARB_ES2_compatibility is natively supported in OpenGL 4.1.
39 : static const GLVersion kGLCoreVersionForES2Compat = GLVersion::GL4_1;
40 :
41 : // ARB_ES3_compatibility is natively supported in OpenGL 4.3.
42 : static const GLVersion kGLCoreVersionForES3Compat = GLVersion::GL4_3;
43 :
44 : struct FeatureInfo
45 : {
46 : const char* mName;
47 :
48 : /* The (desktop) OpenGL version that provides this feature */
49 : GLVersion mOpenGLVersion;
50 :
51 : /* The OpenGL ES version that provides this feature */
52 : GLESVersion mOpenGLESVersion;
53 :
54 : /* If there is an ARB extension, and its function symbols are
55 : * not decorated with an ARB suffix, then its extension ID should go
56 : * here, and NOT in mExtensions. For example, ARB_vertex_array_object
57 : * functions do not have an ARB suffix, because it is an extension that
58 : * was created to match core GL functionality and will never differ.
59 : * Some ARB extensions do have a suffix, if they were created before
60 : * a core version of the functionality existed.
61 : *
62 : * If there is no such ARB extension, pass 0 (GLContext::Extension_None)
63 : */
64 : GLContext::GLExtensions mARBExtensionWithoutARBSuffix;
65 :
66 : /* Extensions that also provide this feature */
67 : GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE];
68 : };
69 :
70 : static const FeatureInfo sFeatureInfoArr[] = {
71 : {
72 : "bind_buffer_offset",
73 : GLVersion::NONE,
74 : GLESVersion::NONE,
75 : GLContext::Extension_None,
76 : {
77 :
78 : GLContext::EXT_transform_feedback,
79 : GLContext::NV_transform_feedback2,
80 : GLContext::Extensions_End
81 : }
82 : },
83 : {
84 : "blend_minmax",
85 : GLVersion::GL2,
86 : GLESVersion::ES3,
87 : GLContext::Extension_None,
88 : {
89 : GLContext::EXT_blend_minmax,
90 : GLContext::Extensions_End
91 : }
92 : },
93 : {
94 : "clear_buffers",
95 : GLVersion::GL3,
96 : GLESVersion::ES3,
97 : GLContext::Extension_None,
98 : {
99 : GLContext::Extensions_End
100 : }
101 : },
102 : {
103 : "copy_buffer",
104 : GLVersion::GL3_1,
105 : GLESVersion::ES3,
106 : GLContext::ARB_copy_buffer,
107 : {
108 : GLContext::Extensions_End
109 : }
110 : },
111 : {
112 : "depth_texture",
113 : GLVersion::GL2,
114 : GLESVersion::ES3,
115 : GLContext::Extension_None,
116 : {
117 : GLContext::ARB_depth_texture,
118 : GLContext::OES_depth_texture,
119 : // Intentionally avoid putting ANGLE_depth_texture here,
120 : // it does not offer quite the same functionality.
121 : GLContext::Extensions_End
122 : }
123 : },
124 : {
125 : "draw_buffers",
126 : GLVersion::GL2,
127 : GLESVersion::ES3,
128 : GLContext::Extension_None,
129 : {
130 : GLContext::ARB_draw_buffers,
131 : GLContext::EXT_draw_buffers,
132 : GLContext::Extensions_End
133 : }
134 : },
135 : {
136 : "draw_instanced",
137 : GLVersion::GL3_1,
138 : GLESVersion::ES3,
139 : GLContext::Extension_None,
140 : {
141 : GLContext::ARB_draw_instanced,
142 : GLContext::EXT_draw_instanced,
143 : GLContext::NV_draw_instanced,
144 : GLContext::ANGLE_instanced_arrays,
145 : GLContext::Extensions_End
146 : }
147 : },
148 : {
149 : "draw_range_elements",
150 : GLVersion::GL1_2,
151 : GLESVersion::ES3,
152 : GLContext::Extension_None,
153 : {
154 : GLContext::EXT_draw_range_elements,
155 : GLContext::Extensions_End
156 : }
157 : },
158 : {
159 : "element_index_uint",
160 : GLVersion::GL2,
161 : GLESVersion::ES3,
162 : GLContext::Extension_None,
163 : {
164 : GLContext::OES_element_index_uint,
165 : GLContext::Extensions_End
166 : }
167 : },
168 : {
169 : "ES2_compatibility",
170 : kGLCoreVersionForES2Compat,
171 : GLESVersion::ES2, // OpenGL ES version
172 : GLContext::ARB_ES2_compatibility, // no suffix on ARB extension
173 : {
174 : GLContext::Extensions_End
175 : }
176 : },
177 : {
178 : "ES3_compatibility",
179 : kGLCoreVersionForES3Compat,
180 : GLESVersion::ES3, // OpenGL ES version
181 : GLContext::ARB_ES3_compatibility, // no suffix on ARB extension
182 : {
183 : GLContext::Extensions_End
184 : }
185 : },
186 : {
187 : "EXT_color_buffer_float",
188 : GLVersion::GL3,
189 : GLESVersion::ES3_2,
190 : GLContext::Extension_None,
191 : {
192 : GLContext::EXT_color_buffer_float,
193 : GLContext::Extensions_End
194 : }
195 : },
196 : {
197 : // Removes clamping for float color outputs from frag shaders.
198 : "frag_color_float",
199 : GLVersion::GL3,
200 : GLESVersion::ES3,
201 : GLContext::Extension_None,
202 : {
203 : GLContext::ARB_color_buffer_float,
204 : GLContext::EXT_color_buffer_float,
205 : GLContext::EXT_color_buffer_half_float,
206 : GLContext::Extensions_End
207 : }
208 : },
209 : {
210 : "frag_depth",
211 : GLVersion::GL2,
212 : GLESVersion::ES3,
213 : GLContext::Extension_None,
214 : {
215 : GLContext::EXT_frag_depth,
216 : GLContext::Extensions_End
217 : }
218 : },
219 : {
220 : // Check for just the blit framebuffer blit part of
221 : // ARB_framebuffer_object
222 : "framebuffer_blit",
223 : GLVersion::GL3,
224 : GLESVersion::ES3,
225 : GLContext::ARB_framebuffer_object,
226 : {
227 : GLContext::ANGLE_framebuffer_blit,
228 : GLContext::EXT_framebuffer_blit,
229 : GLContext::NV_framebuffer_blit,
230 : GLContext::Extensions_End
231 : }
232 : },
233 : {
234 : // Check for just the multisample renderbuffer part of
235 : // ARB_framebuffer_object
236 : "framebuffer_multisample",
237 : GLVersion::GL3,
238 : GLESVersion::ES3,
239 : GLContext::ARB_framebuffer_object,
240 : {
241 : GLContext::ANGLE_framebuffer_multisample,
242 : GLContext::APPLE_framebuffer_multisample,
243 : GLContext::EXT_framebuffer_multisample,
244 : GLContext::EXT_multisampled_render_to_texture,
245 : GLContext::Extensions_End
246 : }
247 : },
248 : {
249 : // ARB_framebuffer_object support
250 : "framebuffer_object",
251 : GLVersion::GL3,
252 : GLESVersion::ES3,
253 : GLContext::ARB_framebuffer_object,
254 : {
255 : GLContext::Extensions_End
256 : }
257 : },
258 : {
259 : // EXT_framebuffer_object/OES_framebuffer_object support
260 : "framebuffer_object_EXT_OES",
261 : GLVersion::GL3,
262 : GLESVersion::ES2,
263 : GLContext::Extension_None,
264 : {
265 : GLContext::EXT_framebuffer_object,
266 : GLContext::OES_framebuffer_object,
267 : GLContext::Extensions_End
268 : }
269 : },
270 : {
271 : "get_integer_indexed",
272 : GLVersion::GL3,
273 : GLESVersion::ES3,
274 : GLContext::Extension_None,
275 : {
276 : GLContext::EXT_draw_buffers2,
277 : GLContext::Extensions_End
278 : }
279 : },
280 : {
281 : "get_integer64_indexed",
282 : GLVersion::GL3_2,
283 : GLESVersion::ES3,
284 : GLContext::Extension_None,
285 : {
286 : GLContext::Extensions_End
287 : }
288 : },
289 : {
290 : "get_query_object_i64v",
291 : GLVersion::GL3_3,
292 : GLESVersion::NONE,
293 : GLContext::ARB_timer_query,
294 : {
295 : GLContext::ANGLE_timer_query,
296 : GLContext::EXT_disjoint_timer_query,
297 : GLContext::EXT_timer_query,
298 : GLContext::Extensions_End
299 : }
300 : },
301 : {
302 : "get_query_object_iv",
303 : GLVersion::GL2,
304 : GLESVersion::NONE,
305 : GLContext::Extension_None,
306 : {
307 : GLContext::Extensions_End
308 : }
309 : /*
310 : * XXX_get_query_object_iv only provide GetQueryObjectiv provided by
311 : * ARB_occlusion_query (added by OpenGL 2.0).
312 : */
313 : },
314 : {
315 : "gpu_shader4",
316 : GLVersion::GL3,
317 : GLESVersion::ES3,
318 : GLContext::Extension_None,
319 : {
320 : GLContext::EXT_gpu_shader4,
321 : GLContext::Extensions_End
322 : }
323 : },
324 : {
325 : "instanced_arrays",
326 : GLVersion::GL3_3,
327 : GLESVersion::ES3,
328 : GLContext::Extension_None,
329 : {
330 : GLContext::ARB_instanced_arrays,
331 : GLContext::NV_instanced_arrays,
332 : GLContext::ANGLE_instanced_arrays,
333 : GLContext::Extensions_End
334 : }
335 : },
336 : {
337 : "instanced_non_arrays",
338 : GLVersion::GL3_3,
339 : GLESVersion::ES3,
340 : GLContext::Extension_None,
341 : {
342 : GLContext::ARB_instanced_arrays,
343 : GLContext::Extensions_End
344 : }
345 : /* This is an expanded version of `instanced_arrays` that allows for all
346 : * enabled active attrib arrays to have non-zero divisors.
347 : * ANGLE_instanced_arrays and NV_instanced_arrays forbid this, but GLES3
348 : * has no such restriction.
349 : */
350 : },
351 : {
352 : "internalformat_query",
353 : GLVersion::GL4_2,
354 : GLESVersion::ES3,
355 : GLContext::ARB_internalformat_query,
356 : {
357 : GLContext::Extensions_End
358 : }
359 : },
360 : {
361 : "invalidate_framebuffer",
362 : GLVersion::GL4_3,
363 : GLESVersion::ES3,
364 : GLContext::ARB_invalidate_subdata,
365 : {
366 : GLContext::Extensions_End
367 : }
368 : },
369 : {
370 : "map_buffer_range",
371 : GLVersion::GL3,
372 : GLESVersion::ES3,
373 : GLContext::ARB_map_buffer_range,
374 : {
375 : GLContext::Extensions_End
376 : }
377 : },
378 : {
379 : "occlusion_query",
380 : GLVersion::GL2,
381 : GLESVersion::NONE,
382 : GLContext::Extension_None,
383 : {
384 : GLContext::Extensions_End
385 : }
386 : // XXX_occlusion_query depend on ARB_occlusion_query (added in OpenGL 2.0)
387 : },
388 : {
389 : "occlusion_query_boolean",
390 : kGLCoreVersionForES3Compat,
391 : GLESVersion::ES3,
392 : GLContext::ARB_ES3_compatibility,
393 : {
394 : GLContext::EXT_occlusion_query_boolean,
395 : GLContext::Extensions_End
396 : }
397 : /*
398 : * XXX_occlusion_query_boolean provide ANY_SAMPLES_PASSED_CONSERVATIVE,
399 : * but EXT_occlusion_query_boolean is only a OpenGL ES extension. But
400 : * it is supported on desktop if ARB_ES3_compatibility because
401 : * EXT_occlusion_query_boolean (added in OpenGL ES 3.0).
402 : */
403 : },
404 : {
405 : "occlusion_query2",
406 : GLVersion::GL3_3,
407 : GLESVersion::ES3,
408 : GLContext::Extension_None,
409 : {
410 : GLContext::ARB_occlusion_query2,
411 : GLContext::ARB_ES3_compatibility,
412 : GLContext::EXT_occlusion_query_boolean,
413 : GLContext::Extensions_End
414 : }
415 : /*
416 : * XXX_occlusion_query2 (add in OpenGL 3.3) provide ANY_SAMPLES_PASSED,
417 : * which is provided by ARB_occlusion_query2, EXT_occlusion_query_boolean
418 : * (added in OpenGL ES 3.0) and ARB_ES3_compatibility
419 : */
420 : },
421 : {
422 : "packed_depth_stencil",
423 : GLVersion::GL3,
424 : GLESVersion::ES3,
425 : GLContext::Extension_None,
426 : {
427 : GLContext::EXT_packed_depth_stencil,
428 : GLContext::OES_packed_depth_stencil,
429 : GLContext::Extensions_End
430 : }
431 : },
432 : {
433 : "prim_restart",
434 : GLVersion::GL3_1,
435 : GLESVersion::NONE,
436 : GLContext::Extension_None,
437 : {
438 : //GLContext::NV_primitive_restart, // Has different enum values.
439 : GLContext::Extensions_End
440 : }
441 : },
442 : {
443 : "prim_restart_fixed",
444 : kGLCoreVersionForES3Compat,
445 : GLESVersion::ES3,
446 : GLContext::ARB_ES3_compatibility,
447 : {
448 : GLContext::Extensions_End
449 : }
450 : },
451 : {
452 : "query_counter",
453 : GLVersion::GL3_3,
454 : GLESVersion::NONE,
455 : GLContext::ARB_timer_query,
456 : {
457 : GLContext::ANGLE_timer_query,
458 : GLContext::EXT_disjoint_timer_query,
459 : // EXT_timer_query does NOT support GL_TIMESTAMP retrieval with
460 : // QueryCounter.
461 : GLContext::Extensions_End
462 : }
463 : },
464 : {
465 : "query_objects",
466 : GLVersion::GL2,
467 : GLESVersion::ES3,
468 : GLContext::Extension_None,
469 : {
470 : GLContext::ANGLE_timer_query,
471 : GLContext::EXT_disjoint_timer_query,
472 : GLContext::EXT_occlusion_query_boolean,
473 : GLContext::Extensions_End
474 : }
475 : /*
476 : * XXX_query_objects only provide entry points commonly supported by
477 : * ARB_occlusion_query (added in OpenGL 2.0), EXT_occlusion_query_boolean
478 : * (added in OpenGL ES 3.0), and ARB_timer_query (added in OpenGL 3.3)
479 : */
480 : },
481 : {
482 : "query_time_elapsed",
483 : GLVersion::GL3_3,
484 : GLESVersion::NONE,
485 : GLContext::ARB_timer_query,
486 : {
487 : GLContext::ANGLE_timer_query,
488 : GLContext::EXT_disjoint_timer_query,
489 : GLContext::EXT_timer_query,
490 : GLContext::Extensions_End
491 : }
492 : },
493 : {
494 : "read_buffer",
495 : GLVersion::GL2,
496 : GLESVersion::ES3,
497 : GLContext::Extension_None,
498 : {
499 : GLContext::Extensions_End
500 : }
501 : },
502 : {
503 : "renderbuffer_color_float",
504 : GLVersion::GL3,
505 : GLESVersion::ES3_2,
506 : GLContext::Extension_None,
507 : {
508 : GLContext::ARB_texture_float,
509 : GLContext::EXT_color_buffer_float,
510 : GLContext::Extensions_End
511 : }
512 : },
513 : {
514 : "renderbuffer_color_half_float",
515 : GLVersion::GL3,
516 : GLESVersion::ES3_2,
517 : GLContext::Extension_None,
518 : {
519 : GLContext::ARB_texture_float,
520 : GLContext::EXT_color_buffer_float,
521 : GLContext::EXT_color_buffer_half_float,
522 : GLContext::Extensions_End
523 : }
524 : },
525 : {
526 : "robust_buffer_access_behavior",
527 : GLVersion::NONE,
528 : GLESVersion::NONE,
529 : GLContext::Extension_None,
530 : {
531 : GLContext::ARB_robust_buffer_access_behavior,
532 : GLContext::KHR_robust_buffer_access_behavior,
533 : GLContext::Extensions_End
534 : }
535 : },
536 : {
537 : "robustness",
538 : GLVersion::NONE,
539 : GLESVersion::NONE,
540 : GLContext::Extension_None,
541 : {
542 : GLContext::ARB_robustness,
543 : GLContext::EXT_robustness,
544 : GLContext::KHR_robustness,
545 : GLContext::Extensions_End
546 : }
547 : },
548 : {
549 : "sRGB_framebuffer",
550 : GLVersion::GL3,
551 : GLESVersion::ES3,
552 : GLContext::ARB_framebuffer_sRGB,
553 : {
554 : GLContext::EXT_framebuffer_sRGB,
555 : GLContext::EXT_sRGB_write_control,
556 : GLContext::Extensions_End
557 : }
558 : },
559 : {
560 : "sRGB_texture",
561 : GLVersion::GL2_1,
562 : GLESVersion::ES3,
563 : GLContext::Extension_None,
564 : {
565 : GLContext::EXT_sRGB,
566 : GLContext::EXT_texture_sRGB,
567 : GLContext::Extensions_End
568 : }
569 : },
570 : {
571 : "sampler_objects",
572 : GLVersion::GL3_3,
573 : GLESVersion::ES3,
574 : GLContext::ARB_sampler_objects,
575 : {
576 : GLContext::Extensions_End
577 : }
578 : },
579 : {
580 : "seamless_cube_map_opt_in",
581 : GLVersion::GL3_2,
582 : GLESVersion::NONE,
583 : GLContext::ARB_seamless_cube_map,
584 : {
585 : GLContext::Extensions_End
586 : }
587 : },
588 : {
589 : "shader_texture_lod",
590 : GLVersion::NONE,
591 : GLESVersion::NONE,
592 : GLContext::Extension_None,
593 : {
594 : GLContext::ARB_shader_texture_lod,
595 : GLContext::EXT_shader_texture_lod,
596 : GLContext::Extensions_End
597 : }
598 : },
599 : {
600 : // Do we have separate DRAW and READ framebuffer bind points?
601 : "split_framebuffer",
602 : GLVersion::GL3,
603 : GLESVersion::ES3,
604 : GLContext::ARB_framebuffer_object,
605 : {
606 : GLContext::ANGLE_framebuffer_blit,
607 : GLContext::APPLE_framebuffer_multisample,
608 : GLContext::EXT_framebuffer_blit,
609 : GLContext::NV_framebuffer_blit,
610 : GLContext::Extensions_End
611 : }
612 : },
613 : {
614 : "standard_derivatives",
615 : GLVersion::GL2,
616 : GLESVersion::ES3,
617 : GLContext::Extension_None,
618 : {
619 : GLContext::OES_standard_derivatives,
620 : GLContext::Extensions_End
621 : }
622 : },
623 : {
624 : "sync",
625 : GLVersion::GL3_2,
626 : GLESVersion::ES3,
627 : GLContext::Extension_None,
628 : {
629 : GLContext::ARB_sync,
630 : GLContext::APPLE_sync,
631 : GLContext::Extensions_End
632 : }
633 : },
634 : {
635 : "texture_3D",
636 : GLVersion::GL1_2,
637 : GLESVersion::ES3,
638 : GLContext::Extension_None,
639 : {
640 : GLContext::EXT_texture3D,
641 : GLContext::OES_texture_3D,
642 : GLContext::Extensions_End
643 : }
644 : },
645 : {
646 : "texture_3D_compressed",
647 : GLVersion::GL1_3,
648 : GLESVersion::ES3,
649 : GLContext::Extension_None,
650 : {
651 : GLContext::ARB_texture_compression,
652 : GLContext::OES_texture_3D,
653 : GLContext::Extensions_End
654 : }
655 : },
656 : {
657 : "texture_3D_copy",
658 : GLVersion::GL1_2,
659 : GLESVersion::ES3,
660 : GLContext::Extension_None,
661 : {
662 : GLContext::EXT_copy_texture,
663 : GLContext::OES_texture_3D,
664 : GLContext::Extensions_End
665 : }
666 : },
667 : {
668 : "texture_float",
669 : GLVersion::GL3,
670 : GLESVersion::ES3,
671 : GLContext::Extension_None,
672 : {
673 : GLContext::ARB_texture_float,
674 : GLContext::OES_texture_float,
675 : GLContext::Extensions_End
676 : }
677 : },
678 : {
679 : "texture_float_linear",
680 : GLVersion::GL3_1,
681 : GLESVersion::ES3,
682 : GLContext::Extension_None,
683 : {
684 : GLContext::ARB_texture_float,
685 : GLContext::OES_texture_float_linear,
686 : GLContext::Extensions_End
687 : }
688 : },
689 : {
690 : "texture_half_float",
691 : GLVersion::GL3,
692 : GLESVersion::ES3,
693 : GLContext::Extension_None,
694 : {
695 : GLContext::ARB_half_float_pixel,
696 : GLContext::ARB_texture_float,
697 : GLContext::NV_half_float,
698 : GLContext::Extensions_End
699 : }
700 : /**
701 : * We are not including OES_texture_half_float in this feature, because:
702 : * GL_HALF_FLOAT = 0x140B
703 : * GL_HALF_FLOAT_ARB = 0x140B == GL_HALF_FLOAT
704 : * GL_HALF_FLOAT_NV = 0x140B == GL_HALF_FLOAT
705 : * GL_HALF_FLOAT_OES = 0x8D61 != GL_HALF_FLOAT
706 : * WebGL handles this specifically with an OES_texture_half_float check.
707 : */
708 : },
709 : {
710 : "texture_half_float_linear",
711 : GLVersion::GL3_1,
712 : GLESVersion::ES3,
713 : GLContext::Extension_None,
714 : {
715 : GLContext::ARB_half_float_pixel,
716 : GLContext::ARB_texture_float,
717 : GLContext::NV_half_float,
718 : GLContext::OES_texture_half_float_linear,
719 : GLContext::Extensions_End
720 : }
721 : },
722 : {
723 : "texture_non_power_of_two",
724 : GLVersion::GL2,
725 : GLESVersion::ES3,
726 : GLContext::Extension_None,
727 : {
728 : GLContext::ARB_texture_non_power_of_two,
729 : GLContext::OES_texture_npot,
730 : GLContext::Extensions_End
731 : }
732 : },
733 : {
734 : "texture_rg",
735 : GLVersion::GL3,
736 : GLESVersion::ES3,
737 : GLContext::ARB_texture_rg,
738 : {
739 : GLContext::Extensions_End
740 : }
741 : },
742 : {
743 : "texture_storage",
744 : GLVersion::GL4_2,
745 : GLESVersion::ES3,
746 : GLContext::ARB_texture_storage,
747 : {
748 : /*
749 : * Not including GL_EXT_texture_storage here because it
750 : * doesn't guarantee glTexStorage3D, which is required for
751 : * WebGL 2.
752 : */
753 : GLContext::Extensions_End
754 : }
755 : },
756 : {
757 : "texture_swizzle",
758 : GLVersion::GL3_3,
759 : GLESVersion::ES3,
760 : GLContext::ARB_texture_swizzle,
761 : {
762 : GLContext::Extensions_End
763 : }
764 : },
765 : {
766 : "transform_feedback2",
767 : GLVersion::GL4,
768 : GLESVersion::ES3,
769 : GLContext::ARB_transform_feedback2,
770 : {
771 : GLContext::NV_transform_feedback2,
772 : GLContext::Extensions_End
773 : }
774 : },
775 : {
776 : "uniform_buffer_object",
777 : GLVersion::GL3_1,
778 : GLESVersion::ES3,
779 : GLContext::ARB_uniform_buffer_object,
780 : {
781 : GLContext::Extensions_End
782 : }
783 : },
784 : {
785 : "uniform_matrix_nonsquare",
786 : GLVersion::GL2_1,
787 : GLESVersion::ES3,
788 : GLContext::Extension_None,
789 : {
790 : GLContext::Extensions_End
791 : }
792 : },
793 : {
794 : "vertex_array_object",
795 : GLVersion::GL3,
796 : GLESVersion::ES3,
797 : GLContext::ARB_vertex_array_object, // ARB extension
798 : {
799 : GLContext::OES_vertex_array_object,
800 : GLContext::APPLE_vertex_array_object,
801 : GLContext::Extensions_End
802 : }
803 : }
804 : };
805 :
806 : static inline const FeatureInfo&
807 0 : GetFeatureInfo(GLFeature feature)
808 : {
809 : static_assert(MOZ_ARRAY_LENGTH(sFeatureInfoArr) == size_t(GLFeature::EnumMax),
810 : "Mismatched lengths for sFeatureInfoInfos and GLFeature enums");
811 :
812 0 : MOZ_ASSERT(feature < GLFeature::EnumMax,
813 : "GLContext::GetFeatureInfoInfo : unknown <feature>");
814 :
815 0 : return sFeatureInfoArr[size_t(feature)];
816 : }
817 :
818 : static inline uint32_t
819 0 : ProfileVersionForFeature(GLFeature feature, ContextProfile profile)
820 : {
821 0 : MOZ_ASSERT(profile != ContextProfile::Unknown,
822 : "GLContext::ProfileVersionForFeature : unknown <profile>");
823 :
824 0 : const FeatureInfo& featureInfo = GetFeatureInfo(feature);
825 :
826 0 : if (profile == ContextProfile::OpenGLES)
827 0 : return (uint32_t)featureInfo.mOpenGLESVersion;
828 :
829 0 : return (uint32_t)featureInfo.mOpenGLVersion;
830 : }
831 :
832 : bool
833 0 : IsFeaturePartOfProfileVersion(GLFeature feature,
834 : ContextProfile profile, unsigned int version)
835 : {
836 0 : unsigned int profileVersion = ProfileVersionForFeature(feature, profile);
837 :
838 : /**
839 : * if `profileVersion` is zero, it means that no version of the profile
840 : * added support for the feature.
841 : */
842 0 : return profileVersion && version >= profileVersion;
843 : }
844 :
845 : bool
846 0 : GLContext::IsFeatureProvidedByCoreSymbols(GLFeature feature)
847 : {
848 0 : if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion))
849 0 : return true;
850 :
851 0 : if (IsExtensionSupported(GetFeatureInfo(feature).mARBExtensionWithoutARBSuffix))
852 0 : return true;
853 :
854 0 : return false;
855 : }
856 :
857 : const char*
858 0 : GLContext::GetFeatureName(GLFeature feature)
859 : {
860 0 : return GetFeatureInfo(feature).mName;
861 : }
862 :
863 : void
864 0 : GLContext::InitFeatures()
865 : {
866 0 : for (size_t featureId = 0; featureId < size_t(GLFeature::EnumMax); featureId++) {
867 0 : GLFeature feature = GLFeature(featureId);
868 :
869 0 : if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion)) {
870 0 : mAvailableFeatures[featureId] = true;
871 0 : continue;
872 : }
873 :
874 0 : mAvailableFeatures[featureId] = false;
875 :
876 0 : const FeatureInfo& featureInfo = GetFeatureInfo(feature);
877 :
878 0 : if (IsExtensionSupported(featureInfo.mARBExtensionWithoutARBSuffix)) {
879 0 : mAvailableFeatures[featureId] = true;
880 0 : continue;
881 : }
882 :
883 0 : for (size_t j = 0; true; j++) {
884 0 : MOZ_ASSERT(j < kMAX_EXTENSION_GROUP_SIZE,
885 : "kMAX_EXTENSION_GROUP_SIZE too small");
886 :
887 0 : if (featureInfo.mExtensions[j] == GLContext::Extensions_End)
888 0 : break;
889 :
890 0 : if (IsExtensionSupported(featureInfo.mExtensions[j])) {
891 0 : mAvailableFeatures[featureId] = true;
892 0 : break;
893 : }
894 : }
895 : }
896 :
897 0 : if (ShouldDumpExts()) {
898 0 : for (size_t featureId = 0; featureId < size_t(GLFeature::EnumMax); featureId++) {
899 0 : GLFeature feature = GLFeature(featureId);
900 0 : printf_stderr("[%s] Feature::%s\n",
901 0 : IsSupported(feature) ? "enabled" : "disabled",
902 0 : GetFeatureName(feature));
903 : }
904 : }
905 0 : }
906 :
907 : void
908 0 : GLContext::MarkUnsupported(GLFeature feature)
909 : {
910 0 : mAvailableFeatures[size_t(feature)] = false;
911 :
912 0 : const FeatureInfo& featureInfo = GetFeatureInfo(feature);
913 :
914 0 : for (size_t i = 0; true; i++) {
915 0 : MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
916 :
917 0 : if (featureInfo.mExtensions[i] == GLContext::Extensions_End)
918 0 : break;
919 :
920 0 : MarkExtensionUnsupported(featureInfo.mExtensions[i]);
921 : }
922 :
923 0 : MOZ_ASSERT(!IsSupported(feature), "GLContext::MarkUnsupported has failed!");
924 :
925 0 : NS_WARNING(nsPrintfCString("%s marked as unsupported",
926 0 : GetFeatureName(feature)).get());
927 0 : }
928 :
929 : } /* namespace gl */
930 : } /* namespace mozilla */
|