tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

WebGLContextExtensions.cpp (22016B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      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 "ClientWebGLExtensions.h"
      7 #include "GLContext.h"
      8 #include "WebGLContext.h"
      9 #include "WebGLContextUtils.h"
     10 #include "WebGLExtensions.h"
     11 #include "mozilla/EnumeratedRange.h"
     12 #include "mozilla/StaticPrefs_webgl.h"
     13 #include "mozilla/dom/BindingDeclarations.h"
     14 #include "mozilla/dom/ToJSValue.h"
     15 #include "nsString.h"
     16 
     17 namespace mozilla {
     18 
     19 const char* GetExtensionName(const WebGLExtensionID ext) {
     20  switch (ext) {
     21 #define WEBGL_EXTENSION_IDENTIFIER(x) \
     22  case WebGLExtensionID::x:           \
     23    return #x;
     24 
     25    WEBGL_EXTENSION_IDENTIFIER(ANGLE_instanced_arrays)
     26    WEBGL_EXTENSION_IDENTIFIER(EXT_blend_minmax)
     27    WEBGL_EXTENSION_IDENTIFIER(EXT_color_buffer_float)
     28    WEBGL_EXTENSION_IDENTIFIER(EXT_color_buffer_half_float)
     29    WEBGL_EXTENSION_IDENTIFIER(EXT_depth_clamp)
     30    WEBGL_EXTENSION_IDENTIFIER(EXT_disjoint_timer_query)
     31    WEBGL_EXTENSION_IDENTIFIER(EXT_float_blend)
     32    WEBGL_EXTENSION_IDENTIFIER(EXT_frag_depth)
     33    WEBGL_EXTENSION_IDENTIFIER(EXT_shader_texture_lod)
     34    WEBGL_EXTENSION_IDENTIFIER(EXT_sRGB)
     35    WEBGL_EXTENSION_IDENTIFIER(EXT_texture_compression_bptc)
     36    WEBGL_EXTENSION_IDENTIFIER(EXT_texture_compression_rgtc)
     37    WEBGL_EXTENSION_IDENTIFIER(EXT_texture_filter_anisotropic)
     38    WEBGL_EXTENSION_IDENTIFIER(EXT_texture_norm16)
     39    WEBGL_EXTENSION_IDENTIFIER(MOZ_debug)
     40    WEBGL_EXTENSION_IDENTIFIER(OES_draw_buffers_indexed)
     41    WEBGL_EXTENSION_IDENTIFIER(OES_element_index_uint)
     42    WEBGL_EXTENSION_IDENTIFIER(OES_fbo_render_mipmap)
     43    WEBGL_EXTENSION_IDENTIFIER(OES_standard_derivatives)
     44    WEBGL_EXTENSION_IDENTIFIER(OES_texture_float)
     45    WEBGL_EXTENSION_IDENTIFIER(OES_texture_float_linear)
     46    WEBGL_EXTENSION_IDENTIFIER(OES_texture_half_float)
     47    WEBGL_EXTENSION_IDENTIFIER(OES_texture_half_float_linear)
     48    WEBGL_EXTENSION_IDENTIFIER(OES_vertex_array_object)
     49    WEBGL_EXTENSION_IDENTIFIER(OVR_multiview2)
     50    WEBGL_EXTENSION_IDENTIFIER(WEBGL_color_buffer_float)
     51    WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_astc)
     52    WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_etc)
     53    WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_etc1)
     54    WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_pvrtc)
     55    WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_s3tc)
     56    WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_s3tc_srgb)
     57    WEBGL_EXTENSION_IDENTIFIER(WEBGL_debug_renderer_info)
     58    WEBGL_EXTENSION_IDENTIFIER(WEBGL_debug_shaders)
     59    WEBGL_EXTENSION_IDENTIFIER(WEBGL_depth_texture)
     60    WEBGL_EXTENSION_IDENTIFIER(WEBGL_draw_buffers)
     61    WEBGL_EXTENSION_IDENTIFIER(WEBGL_explicit_present)
     62    WEBGL_EXTENSION_IDENTIFIER(WEBGL_lose_context)
     63    WEBGL_EXTENSION_IDENTIFIER(WEBGL_provoking_vertex)
     64 
     65 #undef WEBGL_EXTENSION_IDENTIFIER
     66 
     67    case WebGLExtensionID::Max:
     68      break;
     69  }
     70  MOZ_CRASH("bad WebGLExtensionID");
     71 }
     72 
     73 // ----------------------------
     74 // ClientWebGLContext
     75 
     76 void ClientWebGLContext::GetExtension(JSContext* cx, const nsAString& wideName,
     77                                      JS::MutableHandle<JSObject*> retval,
     78                                      dom::CallerType callerType,
     79                                      ErrorResult& rv) {
     80  retval.set(nullptr);
     81  const FuncScope funcScope(*this, "getExtension");
     82  if (IsContextLost()) return;
     83 
     84  const auto name = NS_ConvertUTF16toUTF8(wideName);
     85 
     86  auto ext = WebGLExtensionID::Max;
     87 
     88  // step 1: figure what extension is wanted
     89  for (const auto extension : MakeEnumeratedRange(WebGLExtensionID::Max)) {
     90    const auto& curName = GetExtensionName(extension);
     91    if (name.Equals(curName, nsCaseInsensitiveCStringComparator)) {
     92      ext = extension;
     93      break;
     94    }
     95  }
     96 
     97  if (ext == WebGLExtensionID::Max) return;
     98 
     99  RefPtr<ClientWebGLExtensionBase> extObj;
    100  if (ext == WebGLExtensionID::WEBGL_lose_context) {
    101    extObj = mExtLoseContext;
    102  } else {
    103    extObj = GetExtension(ext, callerType);
    104  }
    105  if (!extObj) return;
    106 
    107  // Ugh, this would be easier returning `any` than `object`.
    108  JS::Rooted<JS::Value> v(cx);
    109  MOZ_ALWAYS_TRUE(dom::ToJSValue(cx, extObj, &v));
    110  if (v.isObject()) {
    111    retval.set(&v.toObject());
    112  }
    113 }
    114 
    115 RefPtr<ClientWebGLExtensionBase> ClientWebGLContext::GetExtension(
    116    const WebGLExtensionID ext, const dom::CallerType callerType) {
    117  if (ext == WebGLExtensionID::WEBGL_lose_context) {
    118    // Always the same.
    119    return mExtLoseContext;
    120  }
    121 
    122  if (!mNotLost) return nullptr;
    123 
    124  if (!IsSupported(ext, callerType)) return nullptr;
    125 
    126  auto& extSlot = mNotLost->extensions[UnderlyingValue(ext)];
    127  if (MOZ_UNLIKELY(!extSlot)) {
    128    extSlot = [&]() -> RefPtr<ClientWebGLExtensionBase> {
    129      switch (ext) {
    130        // ANGLE_
    131        case WebGLExtensionID::ANGLE_instanced_arrays:
    132          return new ClientWebGLExtensionInstancedArrays(*this);
    133 
    134        // EXT_
    135        case WebGLExtensionID::EXT_blend_minmax:
    136          return new ClientWebGLExtensionBlendMinMax(*this);
    137        case WebGLExtensionID::EXT_color_buffer_float:
    138          return new ClientWebGLExtensionEXTColorBufferFloat(*this);
    139        case WebGLExtensionID::EXT_color_buffer_half_float:
    140          return new ClientWebGLExtensionColorBufferHalfFloat(*this);
    141        case WebGLExtensionID::EXT_depth_clamp:
    142          return new ClientWebGLExtensionDepthClamp(*this);
    143        case WebGLExtensionID::EXT_disjoint_timer_query:
    144          return new ClientWebGLExtensionDisjointTimerQuery(*this);
    145        case WebGLExtensionID::EXT_float_blend:
    146          return new ClientWebGLExtensionFloatBlend(*this);
    147        case WebGLExtensionID::EXT_frag_depth:
    148          return new ClientWebGLExtensionFragDepth(*this);
    149        case WebGLExtensionID::EXT_shader_texture_lod:
    150          return new ClientWebGLExtensionShaderTextureLod(*this);
    151        case WebGLExtensionID::EXT_sRGB:
    152          return new ClientWebGLExtensionSRGB(*this);
    153        case WebGLExtensionID::EXT_texture_compression_bptc:
    154          return new ClientWebGLExtensionCompressedTextureBPTC(*this);
    155        case WebGLExtensionID::EXT_texture_compression_rgtc:
    156          return new ClientWebGLExtensionCompressedTextureRGTC(*this);
    157        case WebGLExtensionID::EXT_texture_filter_anisotropic:
    158          return new ClientWebGLExtensionTextureFilterAnisotropic(*this);
    159        case WebGLExtensionID::EXT_texture_norm16:
    160          return new ClientWebGLExtensionTextureNorm16(*this);
    161 
    162        // MOZ_
    163        case WebGLExtensionID::MOZ_debug:
    164          return new ClientWebGLExtensionMOZDebug(*this);
    165 
    166        // OES_
    167        case WebGLExtensionID::OES_draw_buffers_indexed:
    168          return new ClientWebGLExtensionDrawBuffersIndexed(*this);
    169        case WebGLExtensionID::OES_element_index_uint:
    170          return new ClientWebGLExtensionElementIndexUint(*this);
    171        case WebGLExtensionID::OES_fbo_render_mipmap:
    172          return new ClientWebGLExtensionFBORenderMipmap(*this);
    173        case WebGLExtensionID::OES_standard_derivatives:
    174          return new ClientWebGLExtensionStandardDerivatives(*this);
    175        case WebGLExtensionID::OES_texture_float:
    176          return new ClientWebGLExtensionTextureFloat(*this);
    177        case WebGLExtensionID::OES_texture_float_linear:
    178          return new ClientWebGLExtensionTextureFloatLinear(*this);
    179        case WebGLExtensionID::OES_texture_half_float:
    180          return new ClientWebGLExtensionTextureHalfFloat(*this);
    181        case WebGLExtensionID::OES_texture_half_float_linear:
    182          return new ClientWebGLExtensionTextureHalfFloatLinear(*this);
    183        case WebGLExtensionID::OES_vertex_array_object:
    184          return new ClientWebGLExtensionVertexArray(*this);
    185 
    186        // OVR_
    187        case WebGLExtensionID::OVR_multiview2:
    188          return new ClientWebGLExtensionMultiview(*this);
    189 
    190        // WEBGL_
    191        case WebGLExtensionID::WEBGL_color_buffer_float:
    192          return new ClientWebGLExtensionColorBufferFloat(*this);
    193        case WebGLExtensionID::WEBGL_compressed_texture_astc:
    194          return new ClientWebGLExtensionCompressedTextureASTC(*this);
    195        case WebGLExtensionID::WEBGL_compressed_texture_etc:
    196          return new ClientWebGLExtensionCompressedTextureES3(*this);
    197        case WebGLExtensionID::WEBGL_compressed_texture_etc1:
    198          return new ClientWebGLExtensionCompressedTextureETC1(*this);
    199        case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
    200          return new ClientWebGLExtensionCompressedTexturePVRTC(*this);
    201        case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
    202          return new ClientWebGLExtensionCompressedTextureS3TC(*this);
    203        case WebGLExtensionID::WEBGL_compressed_texture_s3tc_srgb:
    204          return new ClientWebGLExtensionCompressedTextureS3TC_SRGB(*this);
    205        case WebGLExtensionID::WEBGL_debug_renderer_info: {
    206          if (callerType != dom::CallerType::System) {
    207            JsWarning(
    208                "WEBGL_debug_renderer_info is deprecated in Firefox and will "
    209                "be removed. Please use RENDERER.");
    210          }
    211          return new ClientWebGLExtensionDebugRendererInfo(*this);
    212        }
    213        case WebGLExtensionID::WEBGL_debug_shaders:
    214          return new ClientWebGLExtensionDebugShaders(*this);
    215        case WebGLExtensionID::WEBGL_depth_texture:
    216          return new ClientWebGLExtensionDepthTexture(*this);
    217        case WebGLExtensionID::WEBGL_draw_buffers:
    218          return new ClientWebGLExtensionDrawBuffers(*this);
    219        case WebGLExtensionID::WEBGL_explicit_present:
    220          return new ClientWebGLExtensionExplicitPresent(*this);
    221        case WebGLExtensionID::WEBGL_provoking_vertex:
    222          return new ClientWebGLExtensionProvokingVertex(*this);
    223 
    224        case WebGLExtensionID::WEBGL_lose_context:
    225        case WebGLExtensionID::Max:
    226          break;
    227      }
    228      MOZ_CRASH("illegal extension enum");
    229    }();
    230    MOZ_ASSERT(extSlot);
    231    RequestExtension(ext);
    232  }
    233 
    234  return extSlot;
    235 }
    236 
    237 // ----------------------------
    238 // WebGLContext
    239 
    240 bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const {
    241  switch (ext) {
    242    case WebGLExtensionID::MOZ_debug:
    243    case WebGLExtensionID::WEBGL_debug_renderer_info:
    244    case WebGLExtensionID::WEBGL_debug_shaders:
    245    case WebGLExtensionID::WEBGL_lose_context:
    246      // Always supported.
    247      return true;
    248 
    249    // In alphabetical order
    250    // ANGLE_
    251    case WebGLExtensionID::ANGLE_instanced_arrays:
    252      return WebGLExtensionInstancedArrays::IsSupported(this);
    253 
    254    // EXT_
    255    case WebGLExtensionID::EXT_blend_minmax:
    256      return WebGLExtensionBlendMinMax::IsSupported(this);
    257 
    258    case WebGLExtensionID::EXT_color_buffer_float:
    259      return WebGLExtensionEXTColorBufferFloat::IsSupported(this);
    260 
    261    case WebGLExtensionID::EXT_color_buffer_half_float:
    262      return WebGLExtensionColorBufferHalfFloat::IsSupported(this);
    263 
    264    case WebGLExtensionID::EXT_depth_clamp:
    265      return gl->IsSupported(gl::GLFeature::depth_clamp);
    266 
    267    case WebGLExtensionID::EXT_disjoint_timer_query:
    268      return WebGLExtensionDisjointTimerQuery::IsSupported(this);
    269 
    270    case WebGLExtensionID::EXT_float_blend:
    271      return WebGLExtensionFloatBlend::IsSupported(this);
    272 
    273    case WebGLExtensionID::EXT_frag_depth:
    274      return WebGLExtensionFragDepth::IsSupported(this);
    275 
    276    case WebGLExtensionID::EXT_shader_texture_lod:
    277      return WebGLExtensionShaderTextureLod::IsSupported(this);
    278 
    279    case WebGLExtensionID::EXT_sRGB:
    280      return WebGLExtensionSRGB::IsSupported(this);
    281 
    282    case WebGLExtensionID::EXT_texture_compression_bptc:
    283      return WebGLExtensionCompressedTextureBPTC::IsSupported(this);
    284 
    285    case WebGLExtensionID::EXT_texture_compression_rgtc:
    286      return WebGLExtensionCompressedTextureRGTC::IsSupported(this);
    287 
    288    case WebGLExtensionID::EXT_texture_filter_anisotropic:
    289      return gl->IsExtensionSupported(
    290          gl::GLContext::EXT_texture_filter_anisotropic);
    291 
    292    case WebGLExtensionID::EXT_texture_norm16:
    293      return WebGLExtensionTextureNorm16::IsSupported(this);
    294 
    295    // OES_
    296    case WebGLExtensionID::OES_draw_buffers_indexed:
    297      if (!IsWebGL2()) return false;
    298      return gl->IsSupported(gl::GLFeature::draw_buffers_indexed) &&
    299             gl->IsSupported(gl::GLFeature::get_integer_indexed);
    300 
    301    case WebGLExtensionID::OES_element_index_uint:
    302      if (IsWebGL2()) return false;
    303      return gl->IsSupported(gl::GLFeature::element_index_uint);
    304 
    305    case WebGLExtensionID::OES_fbo_render_mipmap:
    306      return WebGLExtensionFBORenderMipmap::IsSupported(this);
    307 
    308    case WebGLExtensionID::OES_standard_derivatives:
    309      if (IsWebGL2()) return false;
    310      return gl->IsSupported(gl::GLFeature::standard_derivatives);
    311 
    312    case WebGLExtensionID::OES_texture_float:
    313      return WebGLExtensionTextureFloat::IsSupported(this);
    314 
    315    case WebGLExtensionID::OES_texture_float_linear:
    316      return gl->IsSupported(gl::GLFeature::texture_float_linear);
    317 
    318    case WebGLExtensionID::OES_texture_half_float:
    319      return WebGLExtensionTextureHalfFloat::IsSupported(this);
    320 
    321    case WebGLExtensionID::OES_texture_half_float_linear:
    322      if (IsWebGL2()) return false;
    323      return gl->IsSupported(gl::GLFeature::texture_half_float_linear);
    324 
    325    case WebGLExtensionID::OES_vertex_array_object:
    326      return !IsWebGL2();  // Always supported in webgl1.
    327 
    328    // OVR_
    329    case WebGLExtensionID::OVR_multiview2:
    330      return WebGLExtensionMultiview::IsSupported(this);
    331 
    332    // WEBGL_
    333    case WebGLExtensionID::WEBGL_color_buffer_float:
    334      return WebGLExtensionColorBufferFloat::IsSupported(this);
    335 
    336    case WebGLExtensionID::WEBGL_compressed_texture_astc:
    337      return WebGLExtensionCompressedTextureASTC::IsSupported(this);
    338 
    339    case WebGLExtensionID::WEBGL_compressed_texture_etc:
    340      return gl->IsSupported(gl::GLFeature::ES3_compatibility) &&
    341             !gl->IsANGLE();
    342 
    343    case WebGLExtensionID::WEBGL_compressed_texture_etc1:
    344      return gl->IsExtensionSupported(
    345                 gl::GLContext::OES_compressed_ETC1_RGB8_texture) &&
    346             !gl->IsANGLE();
    347 
    348    case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
    349      return gl->IsExtensionSupported(
    350          gl::GLContext::IMG_texture_compression_pvrtc);
    351 
    352    case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
    353      return WebGLExtensionCompressedTextureS3TC::IsSupported(this);
    354 
    355    case WebGLExtensionID::WEBGL_compressed_texture_s3tc_srgb:
    356      return WebGLExtensionCompressedTextureS3TC_SRGB::IsSupported(this);
    357 
    358    case WebGLExtensionID::WEBGL_depth_texture:
    359      return WebGLExtensionDepthTexture::IsSupported(this);
    360 
    361    case WebGLExtensionID::WEBGL_draw_buffers:
    362      return WebGLExtensionDrawBuffers::IsSupported(this);
    363 
    364    case WebGLExtensionID::WEBGL_explicit_present:
    365      return WebGLExtensionExplicitPresent::IsSupported(this);
    366 
    367    case WebGLExtensionID::WEBGL_provoking_vertex:
    368      if (!gl->IsSupported(gl::GLFeature::provoking_vertex)) return false;
    369 
    370      // > Implementations SHOULD only expose this extension when
    371      // > FIRST_VERTEX_CONVENTION is more efficient than the default behavior
    372      // > of LAST_VERTEX_CONVENTION.
    373      if (gl->IsANGLE()) return true;  // Better on D3D.
    374      if (kIsMacOS) {
    375        // Better on Metal, so probably Mac in general.
    376        return true;
    377      }
    378      return false;  // Probably not better for Win+GL, Linux, or Android.
    379 
    380    case WebGLExtensionID::Max:
    381      break;
    382  }
    383 
    384  MOZ_CRASH();
    385 }
    386 
    387 bool WebGLContext::IsExtensionExplicit(const WebGLExtensionID ext) const {
    388  return mExtensions[ext] && mExtensions[ext]->IsExplicit();
    389 }
    390 
    391 void WebGLContext::WarnIfImplicit(const WebGLExtensionID ext) const {
    392  const auto& extension = mExtensions[ext];
    393  if (!extension || extension->IsExplicit()) return;
    394 
    395  GenerateWarning(
    396      "Using format enabled by implicitly enabled extension: %s. "
    397      "For maximal portability enable it explicitly.",
    398      GetExtensionName(ext));
    399 }
    400 
    401 void WebGLContext::RequestExtension(const WebGLExtensionID ext,
    402                                    const bool explicitly) {
    403  const auto& limits = Limits();
    404  if (!limits.supportedExtensions[ext]) return;
    405 
    406  auto& slot = mExtensions[ext];
    407  switch (ext) {
    408    // ANGLE_
    409    case WebGLExtensionID::ANGLE_instanced_arrays:
    410      slot.reset(new WebGLExtensionInstancedArrays(this));
    411      break;
    412 
    413    // EXT_
    414    case WebGLExtensionID::EXT_blend_minmax:
    415      slot.reset(new WebGLExtensionBlendMinMax(this));
    416      break;
    417    case WebGLExtensionID::EXT_color_buffer_float:
    418      slot.reset(new WebGLExtensionEXTColorBufferFloat(this));
    419      break;
    420    case WebGLExtensionID::EXT_color_buffer_half_float:
    421      slot.reset(new WebGLExtensionColorBufferHalfFloat(this));
    422      break;
    423    case WebGLExtensionID::EXT_depth_clamp:
    424      slot.reset(new WebGLExtensionDepthClamp(this));
    425      break;
    426    case WebGLExtensionID::EXT_disjoint_timer_query:
    427      slot.reset(new WebGLExtensionDisjointTimerQuery(this));
    428      break;
    429    case WebGLExtensionID::EXT_float_blend:
    430      slot.reset(new WebGLExtensionFloatBlend(this));
    431      break;
    432    case WebGLExtensionID::EXT_frag_depth:
    433      slot.reset(new WebGLExtensionFragDepth(this));
    434      break;
    435    case WebGLExtensionID::EXT_shader_texture_lod:
    436      slot.reset(new WebGLExtensionShaderTextureLod(this));
    437      break;
    438    case WebGLExtensionID::EXT_sRGB:
    439      slot.reset(new WebGLExtensionSRGB(this));
    440      break;
    441    case WebGLExtensionID::EXT_texture_compression_bptc:
    442      slot.reset(new WebGLExtensionCompressedTextureBPTC(this));
    443      break;
    444    case WebGLExtensionID::EXT_texture_compression_rgtc:
    445      slot.reset(new WebGLExtensionCompressedTextureRGTC(this));
    446      break;
    447    case WebGLExtensionID::EXT_texture_filter_anisotropic:
    448      slot.reset(new WebGLExtensionTextureFilterAnisotropic(this));
    449      break;
    450    case WebGLExtensionID::EXT_texture_norm16:
    451      slot.reset(new WebGLExtensionTextureNorm16(this));
    452      break;
    453 
    454    // MOZ_
    455    case WebGLExtensionID::MOZ_debug:
    456      slot.reset(new WebGLExtensionMOZDebug(this));
    457      break;
    458 
    459    // OES_
    460    case WebGLExtensionID::OES_draw_buffers_indexed:
    461      slot.reset(new WebGLExtensionDrawBuffersIndexed(this));
    462      break;
    463    case WebGLExtensionID::OES_element_index_uint:
    464      slot.reset(new WebGLExtensionElementIndexUint(this));
    465      break;
    466    case WebGLExtensionID::OES_fbo_render_mipmap:
    467      slot.reset(new WebGLExtensionFBORenderMipmap(this));
    468      break;
    469    case WebGLExtensionID::OES_standard_derivatives:
    470      slot.reset(new WebGLExtensionStandardDerivatives(this));
    471      break;
    472    case WebGLExtensionID::OES_texture_float:
    473      slot.reset(new WebGLExtensionTextureFloat(this));
    474      break;
    475    case WebGLExtensionID::OES_texture_float_linear:
    476      slot.reset(new WebGLExtensionTextureFloatLinear(this));
    477      break;
    478    case WebGLExtensionID::OES_texture_half_float:
    479      slot.reset(new WebGLExtensionTextureHalfFloat(this));
    480      break;
    481    case WebGLExtensionID::OES_texture_half_float_linear:
    482      slot.reset(new WebGLExtensionTextureHalfFloatLinear(this));
    483      break;
    484    case WebGLExtensionID::OES_vertex_array_object:
    485      slot.reset(new WebGLExtensionVertexArray(this));
    486      break;
    487 
    488    // WEBGL_
    489    case WebGLExtensionID::OVR_multiview2:
    490      slot.reset(new WebGLExtensionMultiview(this));
    491      break;
    492 
    493    // WEBGL_
    494    case WebGLExtensionID::WEBGL_color_buffer_float:
    495      slot.reset(new WebGLExtensionColorBufferFloat(this));
    496      break;
    497    case WebGLExtensionID::WEBGL_compressed_texture_astc:
    498      slot.reset(new WebGLExtensionCompressedTextureASTC(this));
    499      break;
    500    case WebGLExtensionID::WEBGL_compressed_texture_etc:
    501      slot.reset(new WebGLExtensionCompressedTextureES3(this));
    502      break;
    503    case WebGLExtensionID::WEBGL_compressed_texture_etc1:
    504      slot.reset(new WebGLExtensionCompressedTextureETC1(this));
    505      break;
    506    case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
    507      slot.reset(new WebGLExtensionCompressedTexturePVRTC(this));
    508      break;
    509    case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
    510      slot.reset(new WebGLExtensionCompressedTextureS3TC(this));
    511      break;
    512    case WebGLExtensionID::WEBGL_compressed_texture_s3tc_srgb:
    513      slot.reset(new WebGLExtensionCompressedTextureS3TC_SRGB(this));
    514      break;
    515    case WebGLExtensionID::WEBGL_debug_renderer_info:
    516      slot.reset(new WebGLExtensionDebugRendererInfo(this));
    517      break;
    518    case WebGLExtensionID::WEBGL_debug_shaders:
    519      slot.reset(new WebGLExtensionDebugShaders(this));
    520      break;
    521    case WebGLExtensionID::WEBGL_depth_texture:
    522      slot.reset(new WebGLExtensionDepthTexture(this));
    523      break;
    524    case WebGLExtensionID::WEBGL_draw_buffers:
    525      slot.reset(new WebGLExtensionDrawBuffers(this));
    526      break;
    527    case WebGLExtensionID::WEBGL_explicit_present:
    528      slot.reset(new WebGLExtensionExplicitPresent(this));
    529      break;
    530    case WebGLExtensionID::WEBGL_lose_context:
    531      slot.reset(new WebGLExtensionLoseContext(this));
    532      break;
    533    case WebGLExtensionID::WEBGL_provoking_vertex:
    534      slot.reset(new WebGLExtensionProvokingVertex(this));
    535      break;
    536 
    537    case WebGLExtensionID::Max:
    538      MOZ_CRASH();
    539  }
    540  MOZ_ASSERT(slot);
    541  const auto& obj = slot;
    542 
    543  if (explicitly && !obj->IsExplicit()) {
    544    obj->SetExplicit();
    545  }
    546 
    547  // Also enable implied extensions.
    548  switch (ext) {
    549    case WebGLExtensionID::EXT_color_buffer_float:
    550      RequestExtension(WebGLExtensionID::EXT_float_blend, false);
    551      break;
    552 
    553    case WebGLExtensionID::OES_texture_float:
    554      RequestExtension(WebGLExtensionID::EXT_float_blend, false);
    555      RequestExtension(WebGLExtensionID::WEBGL_color_buffer_float, false);
    556      break;
    557 
    558    case WebGLExtensionID::OES_texture_half_float:
    559      RequestExtension(WebGLExtensionID::EXT_color_buffer_half_float, false);
    560      break;
    561 
    562    case WebGLExtensionID::WEBGL_color_buffer_float:
    563      RequestExtension(WebGLExtensionID::EXT_float_blend, false);
    564      break;
    565 
    566    default:
    567      break;
    568  }
    569 }
    570 
    571 }  // namespace mozilla