/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 */ |