mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
7a17e909ef
Differential Revision: https://phabricator.services.mozilla.com/D174197
643 lines
22 KiB
C++
643 lines
22 KiB
C++
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "GLContext.h"
|
|
#include "nsPrintfCString.h"
|
|
|
|
namespace mozilla {
|
|
namespace gl {
|
|
|
|
const size_t kMAX_EXTENSION_GROUP_SIZE = 5;
|
|
|
|
enum class GLVersion : uint32_t {
|
|
NONE = 0, // Feature is not supported natively by GL
|
|
GL1_2 = 120,
|
|
GL1_3 = 130,
|
|
GL2 = 200,
|
|
GL2_1 = 210,
|
|
GL3 = 300,
|
|
GL3_1 = 310,
|
|
GL3_2 = 320,
|
|
GL3_3 = 330,
|
|
GL4 = 400,
|
|
GL4_1 = 410,
|
|
GL4_2 = 420,
|
|
GL4_3 = 430,
|
|
};
|
|
|
|
enum class GLESVersion : uint32_t {
|
|
NONE = 0, // Feature is not support natively by GL ES
|
|
ES2 = 200,
|
|
ES3 = 300,
|
|
ES3_1 = 310,
|
|
ES3_2 = 320,
|
|
};
|
|
|
|
// ARB_ES2_compatibility is natively supported in OpenGL 4.1.
|
|
static const GLVersion kGLCoreVersionForES2Compat = GLVersion::GL4_1;
|
|
|
|
// ARB_ES3_compatibility is natively supported in OpenGL 4.3.
|
|
static const GLVersion kGLCoreVersionForES3Compat = GLVersion::GL4_3;
|
|
|
|
struct FeatureInfo {
|
|
const char* mName;
|
|
|
|
/* The (desktop) OpenGL version that provides this feature */
|
|
GLVersion mOpenGLVersion;
|
|
|
|
/* The OpenGL ES version that provides this feature */
|
|
GLESVersion mOpenGLESVersion;
|
|
|
|
/* If there is an ARB extension, and its function symbols are
|
|
* not decorated with an ARB suffix, then its extension ID should go
|
|
* here, and NOT in mExtensions. For example, ARB_vertex_array_object
|
|
* functions do not have an ARB suffix, because it is an extension that
|
|
* was created to match core GL functionality and will never differ.
|
|
* Some ARB extensions do have a suffix, if they were created before
|
|
* a core version of the functionality existed.
|
|
*
|
|
* If there is no such ARB extension, pass 0 (GLContext::Extension_None)
|
|
*/
|
|
GLContext::GLExtensions mARBExtensionWithoutARBSuffix;
|
|
|
|
/* Extensions that also provide this feature */
|
|
GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE];
|
|
};
|
|
|
|
static const FeatureInfo sFeatureInfoArr[] = {
|
|
{"bind_buffer_offset",
|
|
GLVersion::NONE,
|
|
GLESVersion::NONE,
|
|
GLContext::Extension_None,
|
|
{
|
|
|
|
GLContext::EXT_transform_feedback, GLContext::NV_transform_feedback2,
|
|
GLContext::Extensions_End}},
|
|
{"blend_minmax",
|
|
GLVersion::GL2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::EXT_blend_minmax, GLContext::Extensions_End}},
|
|
{"clear_buffers",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::Extensions_End}},
|
|
{"copy_buffer",
|
|
GLVersion::GL3_1,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_copy_buffer,
|
|
{GLContext::Extensions_End}},
|
|
{"depth_texture",
|
|
GLVersion::GL2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_depth_texture, GLContext::OES_depth_texture,
|
|
// Intentionally avoid putting ANGLE_depth_texture here,
|
|
// it does not offer quite the same functionality.
|
|
GLContext::Extensions_End}},
|
|
{"draw_buffers",
|
|
GLVersion::GL2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_draw_buffers, GLContext::EXT_draw_buffers,
|
|
GLContext::Extensions_End}},
|
|
{"draw_buffers_indexed",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3_2,
|
|
GLContext::Extension_None,
|
|
{GLContext::OES_draw_buffers_indexed, GLContext::Extensions_End}},
|
|
{"draw_instanced",
|
|
GLVersion::GL3_1,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_draw_instanced, GLContext::EXT_draw_instanced,
|
|
GLContext::NV_draw_instanced, GLContext::ANGLE_instanced_arrays,
|
|
GLContext::Extensions_End}},
|
|
{"element_index_uint",
|
|
GLVersion::GL2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::OES_element_index_uint, GLContext::Extensions_End}},
|
|
{"ES2_compatibility",
|
|
kGLCoreVersionForES2Compat,
|
|
GLESVersion::ES2, // OpenGL ES version
|
|
GLContext::ARB_ES2_compatibility, // no suffix on ARB extension
|
|
{GLContext::Extensions_End}},
|
|
{"ES3_compatibility",
|
|
kGLCoreVersionForES3Compat,
|
|
GLESVersion::ES3, // OpenGL ES version
|
|
GLContext::ARB_ES3_compatibility, // no suffix on ARB extension
|
|
{GLContext::Extensions_End}},
|
|
{"EXT_color_buffer_float",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3_2,
|
|
GLContext::Extension_None,
|
|
{GLContext::EXT_color_buffer_float, GLContext::Extensions_End}},
|
|
{// Removes clamping for float color outputs from frag shaders.
|
|
"frag_color_float",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_color_buffer_float, GLContext::EXT_color_buffer_float,
|
|
GLContext::EXT_color_buffer_half_float,
|
|
GLContext::CHROMIUM_color_buffer_float_rgba, GLContext::Extensions_End}},
|
|
{"frag_depth",
|
|
GLVersion::GL2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::EXT_frag_depth, GLContext::Extensions_End}},
|
|
{// Check for just the blit framebuffer blit part of
|
|
// ARB_framebuffer_object
|
|
"framebuffer_blit",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_framebuffer_object,
|
|
{GLContext::ANGLE_framebuffer_blit, GLContext::EXT_framebuffer_blit,
|
|
GLContext::NV_framebuffer_blit, GLContext::Extensions_End}},
|
|
{// Check for just the multisample renderbuffer part of
|
|
// ARB_framebuffer_object
|
|
"framebuffer_multisample",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_framebuffer_object,
|
|
{GLContext::ANGLE_framebuffer_multisample,
|
|
GLContext::APPLE_framebuffer_multisample,
|
|
GLContext::EXT_framebuffer_multisample,
|
|
GLContext::EXT_multisampled_render_to_texture,
|
|
GLContext::Extensions_End}},
|
|
{// ARB_framebuffer_object support
|
|
"framebuffer_object",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_framebuffer_object,
|
|
{GLContext::Extensions_End}},
|
|
{// EXT_framebuffer_object/OES_framebuffer_object support
|
|
"framebuffer_object_EXT_OES",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES2,
|
|
GLContext::Extension_None,
|
|
{GLContext::EXT_framebuffer_object, GLContext::OES_framebuffer_object,
|
|
GLContext::Extensions_End}},
|
|
{"get_integer_indexed",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::EXT_draw_buffers2, GLContext::Extensions_End}},
|
|
{"get_integer64_indexed",
|
|
GLVersion::GL3_2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::Extensions_End}},
|
|
{"get_query_object_i64v",
|
|
GLVersion::GL3_3,
|
|
GLESVersion::NONE,
|
|
GLContext::ARB_timer_query,
|
|
{GLContext::ANGLE_timer_query, GLContext::EXT_disjoint_timer_query,
|
|
GLContext::EXT_timer_query, GLContext::Extensions_End}},
|
|
{
|
|
"get_query_object_iv",
|
|
GLVersion::GL2,
|
|
GLESVersion::NONE,
|
|
GLContext::Extension_None,
|
|
{GLContext::Extensions_End}
|
|
/*
|
|
* XXX_get_query_object_iv only provide GetQueryObjectiv provided by
|
|
* ARB_occlusion_query (added by OpenGL 2.0).
|
|
*/
|
|
},
|
|
{"gpu_shader4",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::EXT_gpu_shader4, GLContext::Extensions_End}},
|
|
{"instanced_arrays",
|
|
GLVersion::GL3_3,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_instanced_arrays, GLContext::NV_instanced_arrays,
|
|
GLContext::ANGLE_instanced_arrays, GLContext::Extensions_End}},
|
|
{
|
|
"instanced_non_arrays",
|
|
GLVersion::GL3_3,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_instanced_arrays, GLContext::Extensions_End}
|
|
/* This is an expanded version of `instanced_arrays` that allows for all
|
|
* enabled active attrib arrays to have non-zero divisors.
|
|
* ANGLE_instanced_arrays and NV_instanced_arrays forbid this, but GLES3
|
|
* has no such restriction.
|
|
*/
|
|
},
|
|
{"internalformat_query",
|
|
GLVersion::GL4_2,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_internalformat_query,
|
|
{GLContext::Extensions_End}},
|
|
{"invalidate_framebuffer",
|
|
GLVersion::GL4_3,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_invalidate_subdata,
|
|
{GLContext::Extensions_End}},
|
|
{"map_buffer_range",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_map_buffer_range,
|
|
{GLContext::EXT_map_buffer_range, GLContext::Extensions_End}},
|
|
{"multiview",
|
|
GLVersion::NONE,
|
|
GLESVersion::NONE,
|
|
GLContext::Extension_None,
|
|
{GLContext::ANGLE_multiview, GLContext::OVR_multiview2,
|
|
GLContext::Extensions_End}},
|
|
{
|
|
"occlusion_query",
|
|
GLVersion::GL2,
|
|
GLESVersion::NONE,
|
|
GLContext::Extension_None,
|
|
{GLContext::Extensions_End}
|
|
// XXX_occlusion_query depend on ARB_occlusion_query (added in
|
|
// OpenGL 2.0)
|
|
},
|
|
{
|
|
"occlusion_query_boolean",
|
|
kGLCoreVersionForES3Compat,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_ES3_compatibility,
|
|
{GLContext::EXT_occlusion_query_boolean, GLContext::Extensions_End}
|
|
/*
|
|
* XXX_occlusion_query_boolean provide ANY_SAMPLES_PASSED_CONSERVATIVE,
|
|
* but EXT_occlusion_query_boolean is only a OpenGL ES extension. But
|
|
* it is supported on desktop if ARB_ES3_compatibility because
|
|
* EXT_occlusion_query_boolean (added in OpenGL ES 3.0).
|
|
*/
|
|
},
|
|
{
|
|
"occlusion_query2",
|
|
GLVersion::GL3_3,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_occlusion_query2, GLContext::ARB_ES3_compatibility,
|
|
GLContext::EXT_occlusion_query_boolean, GLContext::Extensions_End}
|
|
/*
|
|
* XXX_occlusion_query2 (add in OpenGL 3.3) provide ANY_SAMPLES_PASSED,
|
|
* which is provided by ARB_occlusion_query2,
|
|
* EXT_occlusion_query_boolean (added in OpenGL ES 3.0) and
|
|
* ARB_ES3_compatibility
|
|
*/
|
|
},
|
|
{"packed_depth_stencil",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::EXT_packed_depth_stencil, GLContext::OES_packed_depth_stencil,
|
|
GLContext::Extensions_End}},
|
|
{"prim_restart",
|
|
GLVersion::GL3_1,
|
|
GLESVersion::NONE,
|
|
GLContext::Extension_None,
|
|
{// GLContext::NV_primitive_restart, // Has different enum values.
|
|
GLContext::Extensions_End}},
|
|
{"prim_restart_fixed",
|
|
kGLCoreVersionForES3Compat,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_ES3_compatibility,
|
|
{GLContext::Extensions_End}},
|
|
{"provoking_vertex",
|
|
GLVersion::GL3_2,
|
|
GLESVersion::NONE,
|
|
GLContext::ARB_provoking_vertex,
|
|
{GLContext::ANGLE_provoking_vertex, GLContext::EXT_provoking_vertex,
|
|
GLContext::Extensions_End}},
|
|
{"query_counter",
|
|
GLVersion::GL3_3,
|
|
GLESVersion::NONE,
|
|
GLContext::ARB_timer_query,
|
|
{GLContext::ANGLE_timer_query, GLContext::EXT_disjoint_timer_query,
|
|
// EXT_timer_query does NOT support GL_TIMESTAMP retrieval with
|
|
// QueryCounter.
|
|
GLContext::Extensions_End}},
|
|
{
|
|
"query_objects",
|
|
GLVersion::GL2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ANGLE_timer_query, GLContext::EXT_disjoint_timer_query,
|
|
GLContext::EXT_occlusion_query_boolean, GLContext::Extensions_End}
|
|
/*
|
|
* XXX_query_objects only provide entry points commonly supported by
|
|
* ARB_occlusion_query (added in OpenGL 2.0),
|
|
* EXT_occlusion_query_boolean (added in OpenGL ES 3.0), and
|
|
* ARB_timer_query (added in OpenGL 3.3)
|
|
*/
|
|
},
|
|
{"query_time_elapsed",
|
|
GLVersion::GL3_3,
|
|
GLESVersion::NONE,
|
|
GLContext::ARB_timer_query,
|
|
{GLContext::ANGLE_timer_query, GLContext::EXT_disjoint_timer_query,
|
|
GLContext::EXT_timer_query, GLContext::Extensions_End}},
|
|
{"read_buffer",
|
|
GLVersion::GL2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::Extensions_End}},
|
|
{"renderbuffer_color_float",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3_2,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_texture_float, GLContext::EXT_color_buffer_float,
|
|
GLContext::CHROMIUM_color_buffer_float_rgba, GLContext::Extensions_End}},
|
|
{"renderbuffer_color_half_float",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3_2,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_texture_float, GLContext::EXT_color_buffer_float,
|
|
GLContext::EXT_color_buffer_half_float, GLContext::Extensions_End}},
|
|
{"robust_buffer_access_behavior",
|
|
GLVersion::NONE,
|
|
GLESVersion::NONE,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_robust_buffer_access_behavior,
|
|
GLContext::KHR_robust_buffer_access_behavior, GLContext::Extensions_End}},
|
|
{"robustness",
|
|
GLVersion::NONE,
|
|
GLESVersion::NONE,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_robustness, GLContext::EXT_robustness,
|
|
GLContext::KHR_robustness, GLContext::Extensions_End}},
|
|
{"sRGB",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_framebuffer_sRGB,
|
|
{GLContext::EXT_sRGB, GLContext::EXT_framebuffer_sRGB,
|
|
GLContext::Extensions_End}},
|
|
{"sampler_objects",
|
|
GLVersion::GL3_3,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_sampler_objects,
|
|
{GLContext::Extensions_End}},
|
|
{"seamless_cube_map_opt_in",
|
|
GLVersion::GL3_2,
|
|
GLESVersion::NONE,
|
|
GLContext::ARB_seamless_cube_map,
|
|
{GLContext::Extensions_End}},
|
|
{"shader_texture_lod",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_shader_texture_lod, GLContext::EXT_shader_texture_lod,
|
|
GLContext::Extensions_End}},
|
|
{// Do we have separate DRAW and READ framebuffer bind points?
|
|
"split_framebuffer",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_framebuffer_object,
|
|
{GLContext::ANGLE_framebuffer_blit,
|
|
GLContext::APPLE_framebuffer_multisample, GLContext::EXT_framebuffer_blit,
|
|
GLContext::NV_framebuffer_blit, GLContext::Extensions_End}},
|
|
{"standard_derivatives",
|
|
GLVersion::GL2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::OES_standard_derivatives, GLContext::Extensions_End}},
|
|
{"sync",
|
|
GLVersion::GL3_2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_sync, GLContext::APPLE_sync, GLContext::Extensions_End}},
|
|
{"texture_3D",
|
|
GLVersion::GL1_2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::OES_texture_3D, GLContext::Extensions_End}},
|
|
{"texture_3D_compressed",
|
|
GLVersion::GL1_3,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_texture_compression, GLContext::OES_texture_3D,
|
|
GLContext::Extensions_End}},
|
|
{"texture_3D_copy",
|
|
GLVersion::GL1_2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::EXT_copy_texture, GLContext::OES_texture_3D,
|
|
GLContext::Extensions_End}},
|
|
{"texture_compression_bptc",
|
|
GLVersion::GL4_2,
|
|
GLESVersion::NONE,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_texture_compression_bptc,
|
|
GLContext::EXT_texture_compression_bptc, GLContext::Extensions_End}},
|
|
{"texture_compression_rgtc",
|
|
GLVersion::GL3,
|
|
GLESVersion::NONE,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_texture_compression_rgtc,
|
|
GLContext::EXT_texture_compression_rgtc, GLContext::Extensions_End}},
|
|
{"texture_float",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_texture_float, GLContext::OES_texture_float,
|
|
GLContext::Extensions_End}},
|
|
{"texture_float_linear",
|
|
GLVersion::GL3_1,
|
|
GLESVersion::NONE,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_texture_float, GLContext::OES_texture_float_linear,
|
|
GLContext::Extensions_End}},
|
|
{
|
|
"texture_half_float",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_half_float_pixel, GLContext::ARB_texture_float,
|
|
GLContext::NV_half_float, GLContext::Extensions_End}
|
|
/**
|
|
* We are not including OES_texture_half_float in this feature, because:
|
|
* GL_HALF_FLOAT = 0x140B
|
|
* GL_HALF_FLOAT_ARB = 0x140B == GL_HALF_FLOAT
|
|
* GL_HALF_FLOAT_NV = 0x140B == GL_HALF_FLOAT
|
|
* GL_HALF_FLOAT_OES = 0x8D61 != GL_HALF_FLOAT
|
|
* WebGL handles this specifically with an OES_texture_half_float check.
|
|
*/
|
|
},
|
|
{"texture_half_float_linear",
|
|
GLVersion::GL3_1,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_half_float_pixel, GLContext::ARB_texture_float,
|
|
GLContext::NV_half_float, GLContext::OES_texture_half_float_linear,
|
|
GLContext::Extensions_End}},
|
|
{"texture_non_power_of_two",
|
|
GLVersion::GL2,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::ARB_texture_non_power_of_two, GLContext::OES_texture_npot,
|
|
GLContext::Extensions_End}},
|
|
{"texture_norm16",
|
|
GLVersion::GL3_1,
|
|
GLESVersion::ES3_1,
|
|
GLContext::EXT_texture_norm16,
|
|
{GLContext::Extensions_End}},
|
|
{"texture_rg",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_texture_rg,
|
|
{GLContext::Extensions_End}},
|
|
{"texture_storage",
|
|
GLVersion::GL4_2,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_texture_storage,
|
|
{/*
|
|
* Not including GL_EXT_texture_storage here because it
|
|
* doesn't guarantee glTexStorage3D, which is required for
|
|
* WebGL 2.
|
|
*/
|
|
GLContext::Extensions_End}},
|
|
{"texture_swizzle",
|
|
GLVersion::GL3_3,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_texture_swizzle,
|
|
{GLContext::Extensions_End}},
|
|
{"transform_feedback2",
|
|
GLVersion::GL4,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_transform_feedback2,
|
|
{GLContext::NV_transform_feedback2, GLContext::Extensions_End}},
|
|
{"uniform_buffer_object",
|
|
GLVersion::GL3_1,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_uniform_buffer_object,
|
|
{GLContext::Extensions_End}},
|
|
{"uniform_matrix_nonsquare",
|
|
GLVersion::GL2_1,
|
|
GLESVersion::ES3,
|
|
GLContext::Extension_None,
|
|
{GLContext::Extensions_End}},
|
|
{"vertex_array_object",
|
|
GLVersion::GL3,
|
|
GLESVersion::ES3,
|
|
GLContext::ARB_vertex_array_object, // ARB extension
|
|
{GLContext::OES_vertex_array_object, GLContext::APPLE_vertex_array_object,
|
|
GLContext::Extensions_End}}};
|
|
|
|
static inline const FeatureInfo& GetFeatureInfo(GLFeature feature) {
|
|
static_assert(MOZ_ARRAY_LENGTH(sFeatureInfoArr) == size_t(GLFeature::EnumMax),
|
|
"Mismatched lengths for sFeatureInfoInfos and GLFeature enums");
|
|
|
|
MOZ_ASSERT(feature < GLFeature::EnumMax,
|
|
"GLContext::GetFeatureInfoInfo : unknown <feature>");
|
|
|
|
return sFeatureInfoArr[size_t(feature)];
|
|
}
|
|
|
|
static inline uint32_t ProfileVersionForFeature(GLFeature feature,
|
|
ContextProfile profile) {
|
|
MOZ_ASSERT(profile != ContextProfile::Unknown,
|
|
"GLContext::ProfileVersionForFeature : unknown <profile>");
|
|
|
|
const FeatureInfo& featureInfo = GetFeatureInfo(feature);
|
|
|
|
if (profile == ContextProfile::OpenGLES)
|
|
return (uint32_t)featureInfo.mOpenGLESVersion;
|
|
|
|
return (uint32_t)featureInfo.mOpenGLVersion;
|
|
}
|
|
|
|
static bool IsFeaturePartOfProfileVersion(GLFeature feature,
|
|
ContextProfile profile,
|
|
unsigned int version) {
|
|
unsigned int profileVersion = ProfileVersionForFeature(feature, profile);
|
|
|
|
/**
|
|
* if `profileVersion` is zero, it means that no version of the profile
|
|
* added support for the feature.
|
|
*/
|
|
return profileVersion && version >= profileVersion;
|
|
}
|
|
|
|
bool GLContext::IsFeatureProvidedByCoreSymbols(GLFeature feature) {
|
|
if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion)) return true;
|
|
|
|
if (IsExtensionSupported(
|
|
GetFeatureInfo(feature).mARBExtensionWithoutARBSuffix))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
const char* GLContext::GetFeatureName(GLFeature feature) {
|
|
return GetFeatureInfo(feature).mName;
|
|
}
|
|
|
|
void GLContext::InitFeatures() {
|
|
for (size_t featureId = 0; featureId < size_t(GLFeature::EnumMax);
|
|
featureId++) {
|
|
GLFeature feature = GLFeature(featureId);
|
|
|
|
if (IsFeaturePartOfProfileVersion(feature, mProfile, mVersion)) {
|
|
mAvailableFeatures[featureId] = true;
|
|
continue;
|
|
}
|
|
|
|
mAvailableFeatures[featureId] = false;
|
|
|
|
const FeatureInfo& featureInfo = GetFeatureInfo(feature);
|
|
|
|
if (IsExtensionSupported(featureInfo.mARBExtensionWithoutARBSuffix)) {
|
|
mAvailableFeatures[featureId] = true;
|
|
continue;
|
|
}
|
|
|
|
for (size_t j = 0; true; j++) {
|
|
MOZ_ASSERT(j < kMAX_EXTENSION_GROUP_SIZE,
|
|
"kMAX_EXTENSION_GROUP_SIZE too small");
|
|
|
|
if (featureInfo.mExtensions[j] == GLContext::Extensions_End) break;
|
|
|
|
if (IsExtensionSupported(featureInfo.mExtensions[j])) {
|
|
mAvailableFeatures[featureId] = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ShouldDumpExts()) {
|
|
for (size_t featureId = 0; featureId < size_t(GLFeature::EnumMax);
|
|
featureId++) {
|
|
GLFeature feature = GLFeature(featureId);
|
|
printf_stderr("[%s] Feature::%s\n",
|
|
IsSupported(feature) ? "enabled" : "disabled",
|
|
GetFeatureName(feature));
|
|
}
|
|
}
|
|
}
|
|
|
|
void GLContext::MarkUnsupported(GLFeature feature) {
|
|
mAvailableFeatures[size_t(feature)] = false;
|
|
|
|
const FeatureInfo& featureInfo = GetFeatureInfo(feature);
|
|
|
|
for (size_t i = 0; true; i++) {
|
|
MOZ_ASSERT(i < kMAX_EXTENSION_GROUP_SIZE,
|
|
"kMAX_EXTENSION_GROUP_SIZE too small");
|
|
|
|
if (featureInfo.mExtensions[i] == GLContext::Extensions_End) break;
|
|
|
|
MarkExtensionUnsupported(featureInfo.mExtensions[i]);
|
|
}
|
|
|
|
MOZ_ASSERT(!IsSupported(feature), "GLContext::MarkUnsupported has failed!");
|
|
|
|
NS_WARNING(
|
|
nsPrintfCString("%s marked as unsupported", GetFeatureName(feature))
|
|
.get());
|
|
}
|
|
|
|
} /* namespace gl */
|
|
} /* namespace mozilla */
|