summaryrefslogtreecommitdiffstats
path: root/dom/canvas/WebGLContextExtensions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/canvas/WebGLContextExtensions.cpp')
-rw-r--r--dom/canvas/WebGLContextExtensions.cpp565
1 files changed, 565 insertions, 0 deletions
diff --git a/dom/canvas/WebGLContextExtensions.cpp b/dom/canvas/WebGLContextExtensions.cpp
new file mode 100644
index 0000000000..70548e62dc
--- /dev/null
+++ b/dom/canvas/WebGLContextExtensions.cpp
@@ -0,0 +1,565 @@
+/* -*- Mode: C++; tab-width: 4; 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 "WebGLContext.h"
+#include "ClientWebGLExtensions.h"
+#include "GLContext.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/ToJSValue.h"
+#include "mozilla/EnumeratedRange.h"
+#include "mozilla/StaticPrefs_webgl.h"
+#include "nsString.h"
+#include "WebGLContextUtils.h"
+#include "WebGLExtensions.h"
+
+namespace mozilla {
+
+const char* GetExtensionName(const WebGLExtensionID ext) {
+ static EnumeratedArray<WebGLExtensionID, WebGLExtensionID::Max, const char*>
+ sExtensionNamesEnumeratedArray;
+ static bool initialized = false;
+
+ if (!initialized) {
+ initialized = true;
+
+#define WEBGL_EXTENSION_IDENTIFIER(x) \
+ sExtensionNamesEnumeratedArray[WebGLExtensionID::x] = #x;
+
+ WEBGL_EXTENSION_IDENTIFIER(ANGLE_instanced_arrays)
+ WEBGL_EXTENSION_IDENTIFIER(EXT_blend_minmax)
+ WEBGL_EXTENSION_IDENTIFIER(EXT_color_buffer_float)
+ WEBGL_EXTENSION_IDENTIFIER(EXT_color_buffer_half_float)
+ WEBGL_EXTENSION_IDENTIFIER(EXT_disjoint_timer_query)
+ WEBGL_EXTENSION_IDENTIFIER(EXT_float_blend)
+ WEBGL_EXTENSION_IDENTIFIER(EXT_frag_depth)
+ WEBGL_EXTENSION_IDENTIFIER(EXT_shader_texture_lod)
+ WEBGL_EXTENSION_IDENTIFIER(EXT_sRGB)
+ WEBGL_EXTENSION_IDENTIFIER(EXT_texture_compression_bptc)
+ WEBGL_EXTENSION_IDENTIFIER(EXT_texture_compression_rgtc)
+ WEBGL_EXTENSION_IDENTIFIER(EXT_texture_filter_anisotropic)
+ WEBGL_EXTENSION_IDENTIFIER(EXT_texture_norm16)
+ WEBGL_EXTENSION_IDENTIFIER(MOZ_debug)
+ WEBGL_EXTENSION_IDENTIFIER(OES_draw_buffers_indexed)
+ WEBGL_EXTENSION_IDENTIFIER(OES_element_index_uint)
+ WEBGL_EXTENSION_IDENTIFIER(OES_fbo_render_mipmap)
+ WEBGL_EXTENSION_IDENTIFIER(OES_standard_derivatives)
+ WEBGL_EXTENSION_IDENTIFIER(OES_texture_float)
+ WEBGL_EXTENSION_IDENTIFIER(OES_texture_float_linear)
+ WEBGL_EXTENSION_IDENTIFIER(OES_texture_half_float)
+ WEBGL_EXTENSION_IDENTIFIER(OES_texture_half_float_linear)
+ WEBGL_EXTENSION_IDENTIFIER(OES_vertex_array_object)
+ WEBGL_EXTENSION_IDENTIFIER(OVR_multiview2)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_color_buffer_float)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_astc)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_etc)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_etc1)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_pvrtc)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_s3tc)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_compressed_texture_s3tc_srgb)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_debug_renderer_info)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_debug_shaders)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_depth_texture)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_draw_buffers)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_explicit_present)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_lose_context)
+ WEBGL_EXTENSION_IDENTIFIER(WEBGL_provoking_vertex)
+
+#undef WEBGL_EXTENSION_IDENTIFIER
+ }
+
+ return sExtensionNamesEnumeratedArray[ext];
+}
+
+// ----------------------------
+// ClientWebGLContext
+
+void ClientWebGLContext::GetExtension(JSContext* cx, const nsAString& wideName,
+ JS::MutableHandle<JSObject*> retval,
+ dom::CallerType callerType,
+ ErrorResult& rv) {
+ retval.set(nullptr);
+ const FuncScope funcScope(*this, "getExtension");
+ if (IsContextLost()) return;
+
+ const auto name = NS_ConvertUTF16toUTF8(wideName);
+
+ auto ext = WebGLExtensionID::Max;
+
+ // step 1: figure what extension is wanted
+ for (const auto extension : MakeEnumeratedRange(WebGLExtensionID::Max)) {
+ const auto& curName = GetExtensionName(extension);
+ if (name.Equals(curName, nsCaseInsensitiveCStringComparator)) {
+ ext = extension;
+ break;
+ }
+ }
+
+ if (ext == WebGLExtensionID::Max) return;
+
+ RefPtr<ClientWebGLExtensionBase> extObj;
+ if (ext == WebGLExtensionID::WEBGL_lose_context) {
+ extObj = mExtLoseContext;
+ } else {
+ extObj = GetExtension(ext, callerType);
+ }
+ if (!extObj) return;
+
+ // Ugh, this would be easier returning `any` than `object`.
+ JS::Rooted<JS::Value> v(cx);
+ MOZ_ALWAYS_TRUE(dom::ToJSValue(cx, extObj, &v));
+ if (v.isObject()) {
+ retval.set(&v.toObject());
+ }
+}
+
+RefPtr<ClientWebGLExtensionBase> ClientWebGLContext::GetExtension(
+ const WebGLExtensionID ext, const dom::CallerType callerType) {
+ if (ext == WebGLExtensionID::WEBGL_lose_context) {
+ // Always the same.
+ return mExtLoseContext;
+ }
+
+ if (!mNotLost) return nullptr;
+
+ if (!IsSupported(ext, callerType)) return nullptr;
+
+ auto& extSlot = mNotLost->extensions[UnderlyingValue(ext)];
+ if (MOZ_UNLIKELY(!extSlot)) {
+ extSlot = [&]() -> RefPtr<ClientWebGLExtensionBase> {
+ switch (ext) {
+ // ANGLE_
+ case WebGLExtensionID::ANGLE_instanced_arrays:
+ return new ClientWebGLExtensionInstancedArrays(*this);
+
+ // EXT_
+ case WebGLExtensionID::EXT_blend_minmax:
+ return new ClientWebGLExtensionBlendMinMax(*this);
+ case WebGLExtensionID::EXT_color_buffer_float:
+ return new ClientWebGLExtensionEXTColorBufferFloat(*this);
+ case WebGLExtensionID::EXT_color_buffer_half_float:
+ return new ClientWebGLExtensionColorBufferHalfFloat(*this);
+ case WebGLExtensionID::EXT_disjoint_timer_query:
+ return new ClientWebGLExtensionDisjointTimerQuery(*this);
+ case WebGLExtensionID::EXT_float_blend:
+ return new ClientWebGLExtensionFloatBlend(*this);
+ case WebGLExtensionID::EXT_frag_depth:
+ return new ClientWebGLExtensionFragDepth(*this);
+ case WebGLExtensionID::EXT_shader_texture_lod:
+ return new ClientWebGLExtensionShaderTextureLod(*this);
+ case WebGLExtensionID::EXT_sRGB:
+ return new ClientWebGLExtensionSRGB(*this);
+ case WebGLExtensionID::EXT_texture_compression_bptc:
+ return new ClientWebGLExtensionCompressedTextureBPTC(*this);
+ case WebGLExtensionID::EXT_texture_compression_rgtc:
+ return new ClientWebGLExtensionCompressedTextureRGTC(*this);
+ case WebGLExtensionID::EXT_texture_filter_anisotropic:
+ return new ClientWebGLExtensionTextureFilterAnisotropic(*this);
+ case WebGLExtensionID::EXT_texture_norm16:
+ return new ClientWebGLExtensionTextureNorm16(*this);
+
+ // MOZ_
+ case WebGLExtensionID::MOZ_debug:
+ return new ClientWebGLExtensionMOZDebug(*this);
+
+ // OES_
+ case WebGLExtensionID::OES_draw_buffers_indexed:
+ return new ClientWebGLExtensionDrawBuffersIndexed(*this);
+ case WebGLExtensionID::OES_element_index_uint:
+ return new ClientWebGLExtensionElementIndexUint(*this);
+ case WebGLExtensionID::OES_fbo_render_mipmap:
+ return new ClientWebGLExtensionFBORenderMipmap(*this);
+ case WebGLExtensionID::OES_standard_derivatives:
+ return new ClientWebGLExtensionStandardDerivatives(*this);
+ case WebGLExtensionID::OES_texture_float:
+ return new ClientWebGLExtensionTextureFloat(*this);
+ case WebGLExtensionID::OES_texture_float_linear:
+ return new ClientWebGLExtensionTextureFloatLinear(*this);
+ case WebGLExtensionID::OES_texture_half_float:
+ return new ClientWebGLExtensionTextureHalfFloat(*this);
+ case WebGLExtensionID::OES_texture_half_float_linear:
+ return new ClientWebGLExtensionTextureHalfFloatLinear(*this);
+ case WebGLExtensionID::OES_vertex_array_object:
+ return new ClientWebGLExtensionVertexArray(*this);
+
+ // OVR_
+ case WebGLExtensionID::OVR_multiview2:
+ return new ClientWebGLExtensionMultiview(*this);
+
+ // WEBGL_
+ case WebGLExtensionID::WEBGL_color_buffer_float:
+ return new ClientWebGLExtensionColorBufferFloat(*this);
+ case WebGLExtensionID::WEBGL_compressed_texture_astc:
+ return new ClientWebGLExtensionCompressedTextureASTC(*this);
+ case WebGLExtensionID::WEBGL_compressed_texture_etc:
+ return new ClientWebGLExtensionCompressedTextureES3(*this);
+ case WebGLExtensionID::WEBGL_compressed_texture_etc1:
+ return new ClientWebGLExtensionCompressedTextureETC1(*this);
+ case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
+ return new ClientWebGLExtensionCompressedTexturePVRTC(*this);
+ case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
+ return new ClientWebGLExtensionCompressedTextureS3TC(*this);
+ case WebGLExtensionID::WEBGL_compressed_texture_s3tc_srgb:
+ return new ClientWebGLExtensionCompressedTextureS3TC_SRGB(*this);
+ case WebGLExtensionID::WEBGL_debug_renderer_info: {
+ if (callerType != dom::CallerType::System) {
+ JsWarning(
+ "WEBGL_debug_renderer_info is deprecated in Firefox and will "
+ "be removed. Please use RENDERER.");
+ }
+ return new ClientWebGLExtensionDebugRendererInfo(*this);
+ }
+ case WebGLExtensionID::WEBGL_debug_shaders:
+ return new ClientWebGLExtensionDebugShaders(*this);
+ case WebGLExtensionID::WEBGL_depth_texture:
+ return new ClientWebGLExtensionDepthTexture(*this);
+ case WebGLExtensionID::WEBGL_draw_buffers:
+ return new ClientWebGLExtensionDrawBuffers(*this);
+ case WebGLExtensionID::WEBGL_explicit_present:
+ return new ClientWebGLExtensionExplicitPresent(*this);
+ case WebGLExtensionID::WEBGL_provoking_vertex:
+ return new ClientWebGLExtensionProvokingVertex(*this);
+
+ case WebGLExtensionID::WEBGL_lose_context:
+ case WebGLExtensionID::Max:
+ break;
+ }
+ MOZ_CRASH("illegal extension enum");
+ }();
+ MOZ_ASSERT(extSlot);
+ RequestExtension(ext);
+ }
+
+ return extSlot;
+}
+
+// ----------------------------
+// WebGLContext
+
+bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const {
+ switch (ext) {
+ case WebGLExtensionID::MOZ_debug:
+ case WebGLExtensionID::WEBGL_debug_renderer_info:
+ case WebGLExtensionID::WEBGL_debug_shaders:
+ case WebGLExtensionID::WEBGL_lose_context:
+ // Always supported.
+ return true;
+
+ // In alphabetical order
+ // ANGLE_
+ case WebGLExtensionID::ANGLE_instanced_arrays:
+ return WebGLExtensionInstancedArrays::IsSupported(this);
+
+ // EXT_
+ case WebGLExtensionID::EXT_blend_minmax:
+ return WebGLExtensionBlendMinMax::IsSupported(this);
+
+ case WebGLExtensionID::EXT_color_buffer_float:
+ return WebGLExtensionEXTColorBufferFloat::IsSupported(this);
+
+ case WebGLExtensionID::EXT_color_buffer_half_float:
+ return WebGLExtensionColorBufferHalfFloat::IsSupported(this);
+
+ case WebGLExtensionID::EXT_disjoint_timer_query:
+ return WebGLExtensionDisjointTimerQuery::IsSupported(this);
+
+ case WebGLExtensionID::EXT_float_blend:
+ return WebGLExtensionFloatBlend::IsSupported(this);
+
+ case WebGLExtensionID::EXT_frag_depth:
+ return WebGLExtensionFragDepth::IsSupported(this);
+
+ case WebGLExtensionID::EXT_shader_texture_lod:
+ return WebGLExtensionShaderTextureLod::IsSupported(this);
+
+ case WebGLExtensionID::EXT_sRGB:
+ return WebGLExtensionSRGB::IsSupported(this);
+
+ case WebGLExtensionID::EXT_texture_compression_bptc:
+ return WebGLExtensionCompressedTextureBPTC::IsSupported(this);
+
+ case WebGLExtensionID::EXT_texture_compression_rgtc:
+ return WebGLExtensionCompressedTextureRGTC::IsSupported(this);
+
+ case WebGLExtensionID::EXT_texture_filter_anisotropic:
+ return gl->IsExtensionSupported(
+ gl::GLContext::EXT_texture_filter_anisotropic);
+
+ case WebGLExtensionID::EXT_texture_norm16:
+ return WebGLExtensionTextureNorm16::IsSupported(this);
+
+ // OES_
+ case WebGLExtensionID::OES_draw_buffers_indexed:
+ if (!IsWebGL2()) return false;
+ return gl->IsSupported(gl::GLFeature::draw_buffers_indexed) &&
+ gl->IsSupported(gl::GLFeature::get_integer_indexed);
+
+ case WebGLExtensionID::OES_element_index_uint:
+ if (IsWebGL2()) return false;
+ return gl->IsSupported(gl::GLFeature::element_index_uint);
+
+ case WebGLExtensionID::OES_fbo_render_mipmap:
+ return WebGLExtensionFBORenderMipmap::IsSupported(this);
+
+ case WebGLExtensionID::OES_standard_derivatives:
+ if (IsWebGL2()) return false;
+ return gl->IsSupported(gl::GLFeature::standard_derivatives);
+
+ case WebGLExtensionID::OES_texture_float:
+ return WebGLExtensionTextureFloat::IsSupported(this);
+
+ case WebGLExtensionID::OES_texture_float_linear:
+ return gl->IsSupported(gl::GLFeature::texture_float_linear);
+
+ case WebGLExtensionID::OES_texture_half_float:
+ return WebGLExtensionTextureHalfFloat::IsSupported(this);
+
+ case WebGLExtensionID::OES_texture_half_float_linear:
+ if (IsWebGL2()) return false;
+ return gl->IsSupported(gl::GLFeature::texture_half_float_linear);
+
+ case WebGLExtensionID::OES_vertex_array_object:
+ return !IsWebGL2(); // Always supported in webgl1.
+
+ // OVR_
+ case WebGLExtensionID::OVR_multiview2:
+ return WebGLExtensionMultiview::IsSupported(this);
+
+ // WEBGL_
+ case WebGLExtensionID::WEBGL_color_buffer_float:
+ return WebGLExtensionColorBufferFloat::IsSupported(this);
+
+ case WebGLExtensionID::WEBGL_compressed_texture_astc:
+ return WebGLExtensionCompressedTextureASTC::IsSupported(this);
+
+ case WebGLExtensionID::WEBGL_compressed_texture_etc:
+ return gl->IsSupported(gl::GLFeature::ES3_compatibility) &&
+ !gl->IsANGLE();
+
+ case WebGLExtensionID::WEBGL_compressed_texture_etc1:
+ return gl->IsExtensionSupported(
+ gl::GLContext::OES_compressed_ETC1_RGB8_texture) &&
+ !gl->IsANGLE();
+
+ case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
+ return gl->IsExtensionSupported(
+ gl::GLContext::IMG_texture_compression_pvrtc);
+
+ case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
+ return WebGLExtensionCompressedTextureS3TC::IsSupported(this);
+
+ case WebGLExtensionID::WEBGL_compressed_texture_s3tc_srgb:
+ return WebGLExtensionCompressedTextureS3TC_SRGB::IsSupported(this);
+
+ case WebGLExtensionID::WEBGL_depth_texture:
+ return WebGLExtensionDepthTexture::IsSupported(this);
+
+ case WebGLExtensionID::WEBGL_draw_buffers:
+ return WebGLExtensionDrawBuffers::IsSupported(this);
+
+ case WebGLExtensionID::WEBGL_explicit_present:
+ return WebGLExtensionExplicitPresent::IsSupported(this);
+
+ case WebGLExtensionID::WEBGL_provoking_vertex:
+ if (!gl->IsSupported(gl::GLFeature::provoking_vertex)) return false;
+
+ // > Implementations SHOULD only expose this extension when
+ // > FIRST_VERTEX_CONVENTION is more efficient than the default behavior
+ // > of LAST_VERTEX_CONVENTION.
+ if (gl->IsANGLE()) return true; // Better on D3D.
+ if (kIsMacOS) {
+ // Better on Metal, so probably Mac in general.
+ return true;
+ }
+ return false; // Probably not better for Win+GL, Linux, or Android.
+
+ case WebGLExtensionID::Max:
+ break;
+ }
+
+ MOZ_CRASH();
+}
+
+bool WebGLContext::IsExtensionExplicit(const WebGLExtensionID ext) const {
+ return mExtensions[ext] && mExtensions[ext]->IsExplicit();
+}
+
+void WebGLContext::WarnIfImplicit(const WebGLExtensionID ext) const {
+ const auto& extension = mExtensions[ext];
+ if (!extension || extension->IsExplicit()) return;
+
+ GenerateWarning(
+ "Using format enabled by implicitly enabled extension: %s. "
+ "For maximal portability enable it explicitly.",
+ GetExtensionName(ext));
+}
+
+void WebGLContext::RequestExtension(const WebGLExtensionID ext,
+ const bool explicitly) {
+ const auto& limits = Limits();
+ if (!limits.supportedExtensions[ext]) return;
+
+ auto& slot = mExtensions[ext];
+ switch (ext) {
+ // ANGLE_
+ case WebGLExtensionID::ANGLE_instanced_arrays:
+ slot.reset(new WebGLExtensionInstancedArrays(this));
+ break;
+
+ // EXT_
+ case WebGLExtensionID::EXT_blend_minmax:
+ slot.reset(new WebGLExtensionBlendMinMax(this));
+ break;
+ case WebGLExtensionID::EXT_color_buffer_float:
+ slot.reset(new WebGLExtensionEXTColorBufferFloat(this));
+ break;
+ case WebGLExtensionID::EXT_color_buffer_half_float:
+ slot.reset(new WebGLExtensionColorBufferHalfFloat(this));
+ break;
+ case WebGLExtensionID::EXT_disjoint_timer_query:
+ slot.reset(new WebGLExtensionDisjointTimerQuery(this));
+ break;
+ case WebGLExtensionID::EXT_float_blend:
+ slot.reset(new WebGLExtensionFloatBlend(this));
+ break;
+ case WebGLExtensionID::EXT_frag_depth:
+ slot.reset(new WebGLExtensionFragDepth(this));
+ break;
+ case WebGLExtensionID::EXT_shader_texture_lod:
+ slot.reset(new WebGLExtensionShaderTextureLod(this));
+ break;
+ case WebGLExtensionID::EXT_sRGB:
+ slot.reset(new WebGLExtensionSRGB(this));
+ break;
+ case WebGLExtensionID::EXT_texture_compression_bptc:
+ slot.reset(new WebGLExtensionCompressedTextureBPTC(this));
+ break;
+ case WebGLExtensionID::EXT_texture_compression_rgtc:
+ slot.reset(new WebGLExtensionCompressedTextureRGTC(this));
+ break;
+ case WebGLExtensionID::EXT_texture_filter_anisotropic:
+ slot.reset(new WebGLExtensionTextureFilterAnisotropic(this));
+ break;
+ case WebGLExtensionID::EXT_texture_norm16:
+ slot.reset(new WebGLExtensionTextureNorm16(this));
+ break;
+
+ // MOZ_
+ case WebGLExtensionID::MOZ_debug:
+ slot.reset(new WebGLExtensionMOZDebug(this));
+ break;
+
+ // OES_
+ case WebGLExtensionID::OES_draw_buffers_indexed:
+ slot.reset(new WebGLExtensionDrawBuffersIndexed(this));
+ break;
+ case WebGLExtensionID::OES_element_index_uint:
+ slot.reset(new WebGLExtensionElementIndexUint(this));
+ break;
+ case WebGLExtensionID::OES_fbo_render_mipmap:
+ slot.reset(new WebGLExtensionFBORenderMipmap(this));
+ break;
+ case WebGLExtensionID::OES_standard_derivatives:
+ slot.reset(new WebGLExtensionStandardDerivatives(this));
+ break;
+ case WebGLExtensionID::OES_texture_float:
+ slot.reset(new WebGLExtensionTextureFloat(this));
+ break;
+ case WebGLExtensionID::OES_texture_float_linear:
+ slot.reset(new WebGLExtensionTextureFloatLinear(this));
+ break;
+ case WebGLExtensionID::OES_texture_half_float:
+ slot.reset(new WebGLExtensionTextureHalfFloat(this));
+ break;
+ case WebGLExtensionID::OES_texture_half_float_linear:
+ slot.reset(new WebGLExtensionTextureHalfFloatLinear(this));
+ break;
+ case WebGLExtensionID::OES_vertex_array_object:
+ slot.reset(new WebGLExtensionVertexArray(this));
+ break;
+
+ // WEBGL_
+ case WebGLExtensionID::OVR_multiview2:
+ slot.reset(new WebGLExtensionMultiview(this));
+ break;
+
+ // WEBGL_
+ case WebGLExtensionID::WEBGL_color_buffer_float:
+ slot.reset(new WebGLExtensionColorBufferFloat(this));
+ break;
+ case WebGLExtensionID::WEBGL_compressed_texture_astc:
+ slot.reset(new WebGLExtensionCompressedTextureASTC(this));
+ break;
+ case WebGLExtensionID::WEBGL_compressed_texture_etc:
+ slot.reset(new WebGLExtensionCompressedTextureES3(this));
+ break;
+ case WebGLExtensionID::WEBGL_compressed_texture_etc1:
+ slot.reset(new WebGLExtensionCompressedTextureETC1(this));
+ break;
+ case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
+ slot.reset(new WebGLExtensionCompressedTexturePVRTC(this));
+ break;
+ case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
+ slot.reset(new WebGLExtensionCompressedTextureS3TC(this));
+ break;
+ case WebGLExtensionID::WEBGL_compressed_texture_s3tc_srgb:
+ slot.reset(new WebGLExtensionCompressedTextureS3TC_SRGB(this));
+ break;
+ case WebGLExtensionID::WEBGL_debug_renderer_info:
+ slot.reset(new WebGLExtensionDebugRendererInfo(this));
+ break;
+ case WebGLExtensionID::WEBGL_debug_shaders:
+ slot.reset(new WebGLExtensionDebugShaders(this));
+ break;
+ case WebGLExtensionID::WEBGL_depth_texture:
+ slot.reset(new WebGLExtensionDepthTexture(this));
+ break;
+ case WebGLExtensionID::WEBGL_draw_buffers:
+ slot.reset(new WebGLExtensionDrawBuffers(this));
+ break;
+ case WebGLExtensionID::WEBGL_explicit_present:
+ slot.reset(new WebGLExtensionExplicitPresent(this));
+ break;
+ case WebGLExtensionID::WEBGL_lose_context:
+ slot.reset(new WebGLExtensionLoseContext(this));
+ break;
+ case WebGLExtensionID::WEBGL_provoking_vertex:
+ slot.reset(new WebGLExtensionProvokingVertex(this));
+ break;
+
+ case WebGLExtensionID::Max:
+ MOZ_CRASH();
+ }
+ MOZ_ASSERT(slot);
+ const auto& obj = slot;
+
+ if (explicitly && !obj->IsExplicit()) {
+ obj->SetExplicit();
+ }
+
+ // Also enable implied extensions.
+ switch (ext) {
+ case WebGLExtensionID::EXT_color_buffer_float:
+ RequestExtension(WebGLExtensionID::EXT_float_blend, false);
+ break;
+
+ case WebGLExtensionID::OES_texture_float:
+ RequestExtension(WebGLExtensionID::EXT_float_blend, false);
+ RequestExtension(WebGLExtensionID::WEBGL_color_buffer_float, false);
+ break;
+
+ case WebGLExtensionID::OES_texture_half_float:
+ RequestExtension(WebGLExtensionID::EXT_color_buffer_half_float, false);
+ break;
+
+ case WebGLExtensionID::WEBGL_color_buffer_float:
+ RequestExtension(WebGLExtensionID::EXT_float_blend, false);
+ break;
+
+ default:
+ break;
+ }
+}
+
+} // namespace mozilla