Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/gl/GLContextFeatures.cpp
Line
Count
Source (jump to first uncovered line)
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",
550
        GLVersion::GL3,
551
        GLESVersion::ES3,
552
        GLContext::ARB_framebuffer_sRGB,
553
        {
554
            GLContext::EXT_sRGB,
555
            GLContext::EXT_framebuffer_sRGB,
556
            GLContext::Extensions_End
557
        }
558
    },
559
    {
560
        "sampler_objects",
561
        GLVersion::GL3_3,
562
        GLESVersion::ES3,
563
        GLContext::ARB_sampler_objects,
564
        {
565
            GLContext::Extensions_End
566
        }
567
    },
568
    {
569
        "seamless_cube_map_opt_in",
570
        GLVersion::GL3_2,
571
        GLESVersion::NONE,
572
        GLContext::ARB_seamless_cube_map,
573
        {
574
            GLContext::Extensions_End
575
        }
576
    },
577
    {
578
        "shader_texture_lod",
579
        GLVersion::GL3,
580
        GLESVersion::ES3,
581
        GLContext::Extension_None,
582
        {
583
            GLContext::ARB_shader_texture_lod,
584
            GLContext::EXT_shader_texture_lod,
585
            GLContext::Extensions_End
586
        }
587
    },
588
    {
589
        // Do we have separate DRAW and READ framebuffer bind points?
590
        "split_framebuffer",
591
        GLVersion::GL3,
592
        GLESVersion::ES3,
593
        GLContext::ARB_framebuffer_object,
594
        {
595
            GLContext::ANGLE_framebuffer_blit,
596
            GLContext::APPLE_framebuffer_multisample,
597
            GLContext::EXT_framebuffer_blit,
598
            GLContext::NV_framebuffer_blit,
599
            GLContext::Extensions_End
600
        }
601
    },
602
    {
603
        "standard_derivatives",
604
        GLVersion::GL2,
605
        GLESVersion::ES3,
606
        GLContext::Extension_None,
607
        {
608
            GLContext::OES_standard_derivatives,
609
            GLContext::Extensions_End
610
        }
611
    },
612
    {
613
        "sync",
614
        GLVersion::GL3_2,
615
        GLESVersion::ES3,
616
        GLContext::Extension_None,
617
        {
618
            GLContext::ARB_sync,
619
            GLContext::APPLE_sync,
620
            GLContext::Extensions_End
621
        }
622
    },
623
    {
624
        "texture_3D",
625
        GLVersion::GL1_2,
626
        GLESVersion::ES3,
627
        GLContext::Extension_None,
628
        {
629
            GLContext::EXT_texture3D,
630
            GLContext::OES_texture_3D,
631
            GLContext::Extensions_End
632
        }
633
    },
634
    {
635
        "texture_3D_compressed",
636
        GLVersion::GL1_3,
637
        GLESVersion::ES3,
638
        GLContext::Extension_None,
639
        {
640
            GLContext::ARB_texture_compression,
641
            GLContext::OES_texture_3D,
642
            GLContext::Extensions_End
643
        }
644
    },
645
    {
646
        "texture_3D_copy",
647
        GLVersion::GL1_2,
648
        GLESVersion::ES3,
649
        GLContext::Extension_None,
650
        {
651
            GLContext::EXT_copy_texture,
652
            GLContext::OES_texture_3D,
653
            GLContext::Extensions_End
654
        }
655
    },
656
    {
657
        "texture_float",
658
        GLVersion::GL3,
659
        GLESVersion::ES3,
660
        GLContext::Extension_None,
661
        {
662
            GLContext::ARB_texture_float,
663
            GLContext::OES_texture_float,
664
            GLContext::Extensions_End
665
        }
666
    },
667
    {
668
        "texture_float_linear",
669
        GLVersion::GL3_1,
670
        GLESVersion::ES3,
671
        GLContext::Extension_None,
672
        {
673
            GLContext::ARB_texture_float,
674
            GLContext::OES_texture_float_linear,
675
            GLContext::Extensions_End
676
        }
677
    },
678
    {
679
        "texture_half_float",
680
        GLVersion::GL3,
681
        GLESVersion::ES3,
682
        GLContext::Extension_None,
683
        {
684
            GLContext::ARB_half_float_pixel,
685
            GLContext::ARB_texture_float,
686
            GLContext::NV_half_float,
687
            GLContext::Extensions_End
688
        }
689
        /**
690
         * We are not including OES_texture_half_float in this feature, because:
691
         *   GL_HALF_FLOAT     = 0x140B
692
         *   GL_HALF_FLOAT_ARB = 0x140B == GL_HALF_FLOAT
693
         *   GL_HALF_FLOAT_NV  = 0x140B == GL_HALF_FLOAT
694
         *   GL_HALF_FLOAT_OES = 0x8D61 != GL_HALF_FLOAT
695
         * WebGL handles this specifically with an OES_texture_half_float check.
696
         */
697
    },
698
    {
699
        "texture_half_float_linear",
700
        GLVersion::GL3_1,
701
        GLESVersion::ES3,
702
        GLContext::Extension_None,
703
        {
704
            GLContext::ARB_half_float_pixel,
705
            GLContext::ARB_texture_float,
706
            GLContext::NV_half_float,
707
            GLContext::OES_texture_half_float_linear,
708
            GLContext::Extensions_End
709
        }
710
    },
711
    {
712
        "texture_non_power_of_two",
713
        GLVersion::GL2,
714
        GLESVersion::ES3,
715
        GLContext::Extension_None,
716
        {
717
            GLContext::ARB_texture_non_power_of_two,
718
            GLContext::OES_texture_npot,
719
            GLContext::Extensions_End
720
        }
721
    },
722
    {
723
        "texture_rg",
724
        GLVersion::GL3,
725
        GLESVersion::ES3,
726
        GLContext::ARB_texture_rg,
727
        {
728
            GLContext::Extensions_End
729
        }
730
    },
731
    {
732
        "texture_storage",
733
        GLVersion::GL4_2,
734
        GLESVersion::ES3,
735
        GLContext::ARB_texture_storage,
736
        {
737
            /*
738
             * Not including GL_EXT_texture_storage here because it
739
             * doesn't guarantee glTexStorage3D, which is required for
740
             * WebGL 2.
741
             */
742
            GLContext::Extensions_End
743
        }
744
    },
745
    {
746
        "texture_swizzle",
747
        GLVersion::GL3_3,
748
        GLESVersion::ES3,
749
        GLContext::ARB_texture_swizzle,
750
        {
751
            GLContext::Extensions_End
752
        }
753
    },
754
    {
755
        "transform_feedback2",
756
        GLVersion::GL4,
757
        GLESVersion::ES3,
758
        GLContext::ARB_transform_feedback2,
759
        {
760
            GLContext::NV_transform_feedback2,
761
            GLContext::Extensions_End
762
        }
763
    },
764
    {
765
        "uniform_buffer_object",
766
        GLVersion::GL3_1,
767
        GLESVersion::ES3,
768
        GLContext::ARB_uniform_buffer_object,
769
        {
770
            GLContext::Extensions_End
771
        }
772
    },
773
    {
774
        "uniform_matrix_nonsquare",
775
        GLVersion::GL2_1,
776
        GLESVersion::ES3,
777
        GLContext::Extension_None,
778
        {
779
            GLContext::Extensions_End
780
        }
781
    },
782
    {
783
        "vertex_array_object",
784
        GLVersion::GL3,
785
        GLESVersion::ES3,
786
        GLContext::ARB_vertex_array_object, // ARB extension
787
        {
788
            GLContext::OES_vertex_array_object,
789
            GLContext::APPLE_vertex_array_object,
790
            GLContext::Extensions_End
791
        }
792
    }
793
};
794
795
static inline const FeatureInfo&
796
GetFeatureInfo(GLFeature feature)
797
0
{
798
0
    static_assert(MOZ_ARRAY_LENGTH(sFeatureInfoArr) == size_t(GLFeature::EnumMax),
799
0
                  "Mismatched lengths for sFeatureInfoInfos and GLFeature enums");
800
0
801
0
    MOZ_ASSERT(feature < GLFeature::EnumMax,
802
0
               "GLContext::GetFeatureInfoInfo : unknown <feature>");
803
0
804
0
    return sFeatureInfoArr[size_t(feature)];
805
0
}
806
807
static inline uint32_t
808
ProfileVersionForFeature(GLFeature feature, ContextProfile profile)
809
0
{
810
0
    MOZ_ASSERT(profile != ContextProfile::Unknown,
811
0
               "GLContext::ProfileVersionForFeature : unknown <profile>");
812
0
813
0
    const FeatureInfo& featureInfo = GetFeatureInfo(feature);
814
0
815
0
    if (profile == ContextProfile::OpenGLES)
816
0
        return (uint32_t)featureInfo.mOpenGLESVersion;
817
0
818
0
    return (uint32_t)featureInfo.mOpenGLVersion;
819
0
}
820
821
bool
822
IsFeaturePartOfProfileVersion(GLFeature feature,
823
                              ContextProfile profile, unsigned int version)
824
0
{
825
0
    unsigned int profileVersion = ProfileVersionForFeature(feature, profile);
826
0
827
0
    /**
828
0
     * if `profileVersion` is zero, it means that no version of the profile
829
0
     * added support for the feature.
830
0
     */
831
0
    return profileVersion && version >= profileVersion;
832
0
}
833
834
bool
835
GLContext::IsFeatureProvidedByCoreSymbols(GLFeature feature)
836
0
{
837
0
    if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion))
838
0
        return true;
839
0
840
0
    if (IsExtensionSupported(GetFeatureInfo(feature).mARBExtensionWithoutARBSuffix))
841
0
        return true;
842
0
843
0
    return false;
844
0
}
845
846
const char*
847
GLContext::GetFeatureName(GLFeature feature)
848
0
{
849
0
    return GetFeatureInfo(feature).mName;
850
0
}
851
852
void
853
GLContext::InitFeatures()
854
0
{
855
0
    for (size_t featureId = 0; featureId < size_t(GLFeature::EnumMax); featureId++) {
856
0
        GLFeature feature = GLFeature(featureId);
857
0
858
0
        if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion)) {
859
0
            mAvailableFeatures[featureId] = true;
860
0
            continue;
861
0
        }
862
0
863
0
        mAvailableFeatures[featureId] = false;
864
0
865
0
        const FeatureInfo& featureInfo = GetFeatureInfo(feature);
866
0
867
0
        if (IsExtensionSupported(featureInfo.mARBExtensionWithoutARBSuffix)) {
868
0
            mAvailableFeatures[featureId] = true;
869
0
            continue;
870
0
        }
871
0
872
0
        for (size_t j = 0; true; j++) {
873
0
            MOZ_ASSERT(j < kMAX_EXTENSION_GROUP_SIZE,
874
0
                       "kMAX_EXTENSION_GROUP_SIZE too small");
875
0
876
0
            if (featureInfo.mExtensions[j] == GLContext::Extensions_End)
877
0
                break;
878
0
879
0
            if (IsExtensionSupported(featureInfo.mExtensions[j])) {
880
0
                mAvailableFeatures[featureId] = true;
881
0
                break;
882
0
            }
883
0
        }
884
0
    }
885
0
886
0
    if (ShouldDumpExts()) {
887
0
        for (size_t featureId = 0; featureId < size_t(GLFeature::EnumMax); featureId++) {
888
0
            GLFeature feature = GLFeature(featureId);
889
0
            printf_stderr("[%s] Feature::%s\n",
890
0
                          IsSupported(feature) ? "enabled" : "disabled",
891
0
                          GetFeatureName(feature));
892
0
        }
893
0
    }
894
0
}
895
896
void
897
GLContext::MarkUnsupported(GLFeature feature)
898
0
{
899
0
    mAvailableFeatures[size_t(feature)] = false;
900
0
901
0
    const FeatureInfo& featureInfo = GetFeatureInfo(feature);
902
0
903
0
    for (size_t i = 0; true; i++) {
904
0
        MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE, "kMAX_EXTENSION_GROUP_SIZE too small");
905
0
906
0
        if (featureInfo.mExtensions[i] == GLContext::Extensions_End)
907
0
            break;
908
0
909
0
        MarkExtensionUnsupported(featureInfo.mExtensions[i]);
910
0
    }
911
0
912
0
    MOZ_ASSERT(!IsSupported(feature), "GLContext::MarkUnsupported has failed!");
913
0
914
0
    NS_WARNING(nsPrintfCString("%s marked as unsupported",
915
0
                               GetFeatureName(feature)).get());
916
0
}
917
918
} /* namespace gl */
919
} /* namespace mozilla */