Bug 1494809 - Support WebGL exts for BPTC and RGTC. - r=kvark,qdot
authorJeff Gilbert <jgilbert@mozilla.com>
Thu, 27 Sep 2018 16:37:40 -0700
changeset 499106 ae8e6587acbcc40cbb42e882f15294f4425e301d
parent 499105 651195783637aaecb7c8ec048ce6225ee9ed0c0a
child 499107 798ec47e6c16bdf317c71c92eb986c674afe5127
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskvark, qdot
bugs1494809
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1494809 - Support WebGL exts for BPTC and RGTC. - r=kvark,qdot
dom/bindings/Bindings.conf
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextExtensions.cpp
dom/canvas/WebGLExtensionCompressedTextureBPTC.cpp
dom/canvas/WebGLExtensionCompressedTextureRGTC.cpp
dom/canvas/WebGLExtensions.h
dom/canvas/WebGLFormats.cpp
dom/canvas/WebGLFormats.h
dom/canvas/WebGLTextureUpload.cpp
dom/canvas/WebGLTypes.h
dom/canvas/moz.build
dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_texture_compression_bptc.html
dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_texture_compression_rgtc.html
dom/canvas/test/webgl-mochitest/ensure-exts/test_common.html
dom/canvas/test/webgl-mochitest/mochitest.ini
dom/webidl/WebGLRenderingContext.webidl
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextFeatures.cpp
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1109,16 +1109,26 @@ DOMInterfaces = {
     'headerFile': 'WebGLActiveInfo.h'
 },
 
 'WebGLBuffer': {
     'nativeType': 'mozilla::WebGLBuffer',
     'headerFile': 'WebGLBuffer.h'
 },
 
+'EXT_texture_compression_bptc': {
+    'nativeType': 'mozilla::WebGLExtensionCompressedTextureBPTC',
+    'headerFile': 'WebGLExtensions.h'
+},
+
+'EXT_texture_compression_rgtc': {
+    'nativeType': 'mozilla::WebGLExtensionCompressedTextureRGTC',
+    'headerFile': 'WebGLExtensions.h'
+},
+
 'WEBGL_compressed_texture_astc': {
     'nativeType': 'mozilla::WebGLExtensionCompressedTextureASTC',
     'headerFile': 'WebGLExtensions.h'
 },
 
 'WEBGL_compressed_texture_atc': {
     'nativeType': 'mozilla::WebGLExtensionCompressedTextureATC',
     'headerFile': 'WebGLExtensions.h'
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -284,19 +284,21 @@ class WebGLContext
     friend class ScopedDrawCallWrapper;
     friend class ScopedDrawWithTransformFeedback;
     friend class ScopedFakeVertexAttrib0;
     friend class ScopedFBRebinder;
     friend class WebGL2Context;
     friend class WebGLContextUserData;
     friend class WebGLExtensionCompressedTextureASTC;
     friend class WebGLExtensionCompressedTextureATC;
+    friend class WebGLExtensionCompressedTextureBPTC;
     friend class WebGLExtensionCompressedTextureES3;
     friend class WebGLExtensionCompressedTextureETC1;
     friend class WebGLExtensionCompressedTexturePVRTC;
+    friend class WebGLExtensionCompressedTextureRGTC;
     friend class WebGLExtensionCompressedTextureS3TC;
     friend class WebGLExtensionCompressedTextureS3TC_SRGB;
     friend class WebGLExtensionDepthTexture;
     friend class WebGLExtensionDisjointTimerQuery;
     friend class WebGLExtensionDrawBuffers;
     friend class WebGLExtensionLoseContext;
     friend class WebGLExtensionMOZDebug;
     friend class WebGLExtensionVertexArray;
--- a/dom/canvas/WebGLContextExtensions.cpp
+++ b/dom/canvas/WebGLContextExtensions.cpp
@@ -34,16 +34,18 @@ WebGLContext::GetExtensionString(WebGLEx
 
         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_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_disjoint_timer_query)
         WEBGL_EXTENSION_IDENTIFIER(MOZ_debug)
         WEBGL_EXTENSION_IDENTIFIER(OES_element_index_uint)
         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)
@@ -115,16 +117,26 @@ WebGLContext::IsExtensionSupported(WebGL
 {
     if (mDisableExtensions)
         return false;
 
     // Extensions for both WebGL 1 and 2.
     switch (ext) {
     // In alphabetical order
     // EXT_
+    case WebGLExtensionID::EXT_texture_compression_bptc:
+        if (!gfxPrefs::WebGLDraftExtensionsEnabled())
+            return false;
+        return WebGLExtensionCompressedTextureBPTC::IsSupported(this);
+
+    case WebGLExtensionID::EXT_texture_compression_rgtc:
+        if (!gfxPrefs::WebGLDraftExtensionsEnabled())
+            return false;
+        return WebGLExtensionCompressedTextureRGTC::IsSupported(this);
+
     case WebGLExtensionID::EXT_texture_filter_anisotropic:
         return gl->IsExtensionSupported(gl::GLContext::EXT_texture_filter_anisotropic);
 
     // OES_
     case WebGLExtensionID::OES_texture_float_linear:
         return gl->IsSupported(gl::GLFeature::texture_float_linear);
 
     // WEBGL_
@@ -340,16 +352,22 @@ WebGLContext::EnableExtension(WebGLExten
         obj = new WebGLExtensionFragDepth(this);
         break;
     case WebGLExtensionID::EXT_shader_texture_lod:
         obj = new WebGLExtensionShaderTextureLod(this);
         break;
     case WebGLExtensionID::EXT_sRGB:
         obj = new WebGLExtensionSRGB(this);
         break;
+    case WebGLExtensionID::EXT_texture_compression_bptc:
+        obj = new WebGLExtensionCompressedTextureBPTC(this);
+        break;
+    case WebGLExtensionID::EXT_texture_compression_rgtc:
+        obj = new WebGLExtensionCompressedTextureRGTC(this);
+        break;
     case WebGLExtensionID::EXT_texture_filter_anisotropic:
         obj = new WebGLExtensionTextureFilterAnisotropic(this);
         break;
 
     // MOZ_
     case WebGLExtensionID::MOZ_debug:
         obj = new WebGLExtensionMOZDebug(this);
         break;
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGLExtensionCompressedTextureBPTC.cpp
@@ -0,0 +1,49 @@
+/* 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 "WebGLExtensions.h"
+
+#include "GLContext.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
+#include "WebGLContext.h"
+#include "WebGLFormats.h"
+
+namespace mozilla {
+
+WebGLExtensionCompressedTextureBPTC::WebGLExtensionCompressedTextureBPTC(WebGLContext* const webgl)
+    : WebGLExtensionBase(webgl)
+{
+    MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
+
+    auto& fua = webgl->mFormatUsage;
+
+    const auto fnAdd = [&](const GLenum sizedFormat,
+                           const webgl::EffectiveFormat effFormat)
+    {
+        auto usage = fua->EditUsage(effFormat);
+        usage->isFilterable = true;
+        fua->AllowSizedTexFormat(sizedFormat, usage);
+
+        webgl->mCompressedTextureFormats.AppendElement(sizedFormat);
+    };
+
+#define _(X) LOCAL_GL_ ## X, webgl::EffectiveFormat::X
+
+    fnAdd(_(COMPRESSED_RGBA_BPTC_UNORM));
+    fnAdd(_(COMPRESSED_SRGB_ALPHA_BPTC_UNORM));
+    fnAdd(_(COMPRESSED_RGB_BPTC_SIGNED_FLOAT));
+    fnAdd(_(COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT));
+
+#undef _
+}
+
+bool
+WebGLExtensionCompressedTextureBPTC::IsSupported(const WebGLContext* const webgl)
+{
+    return webgl->gl->IsSupported(gl::GLFeature::texture_compression_bptc);
+}
+
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureBPTC, EXT_texture_compression_bptc)
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/canvas/WebGLExtensionCompressedTextureRGTC.cpp
@@ -0,0 +1,49 @@
+/* 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 "WebGLExtensions.h"
+
+#include "GLContext.h"
+#include "mozilla/dom/WebGLRenderingContextBinding.h"
+#include "WebGLContext.h"
+#include "WebGLFormats.h"
+
+namespace mozilla {
+
+WebGLExtensionCompressedTextureRGTC::WebGLExtensionCompressedTextureRGTC(WebGLContext* const webgl)
+    : WebGLExtensionBase(webgl)
+{
+    MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported.");
+
+    auto& fua = webgl->mFormatUsage;
+
+    const auto fnAdd = [&](const GLenum sizedFormat,
+                           const webgl::EffectiveFormat effFormat)
+    {
+        auto usage = fua->EditUsage(effFormat);
+        usage->isFilterable = true;
+        fua->AllowSizedTexFormat(sizedFormat, usage);
+
+        webgl->mCompressedTextureFormats.AppendElement(sizedFormat);
+    };
+
+#define _(X) LOCAL_GL_ ## X, webgl::EffectiveFormat::X
+
+    fnAdd(_(COMPRESSED_RED_RGTC1));
+    fnAdd(_(COMPRESSED_SIGNED_RED_RGTC1));
+    fnAdd(_(COMPRESSED_RG_RGTC2));
+    fnAdd(_(COMPRESSED_SIGNED_RG_RGTC2));
+
+#undef _
+}
+
+bool
+WebGLExtensionCompressedTextureRGTC::IsSupported(const WebGLContext* const webgl)
+{
+    return webgl->gl->IsSupported(gl::GLFeature::texture_compression_rgtc);
+}
+
+IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionCompressedTextureRGTC, EXT_texture_compression_rgtc)
+
+} // namespace mozilla
--- a/dom/canvas/WebGLExtensions.h
+++ b/dom/canvas/WebGLExtensions.h
@@ -84,16 +84,27 @@ class WebGLExtensionCompressedTextureATC
 {
 public:
     explicit WebGLExtensionCompressedTextureATC(WebGLContext*);
     virtual ~WebGLExtensionCompressedTextureATC();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
+class WebGLExtensionCompressedTextureBPTC final
+    : public WebGLExtensionBase
+{
+public:
+    explicit WebGLExtensionCompressedTextureBPTC(WebGLContext* webgl);
+
+    static bool IsSupported(const WebGLContext* webgl);
+
+    DECL_WEBGL_EXTENSION_GOOP
+};
+
 class WebGLExtensionCompressedTextureES3
     : public WebGLExtensionBase
 {
 public:
     explicit WebGLExtensionCompressedTextureES3(WebGLContext*);
     virtual ~WebGLExtensionCompressedTextureES3();
 
     DECL_WEBGL_EXTENSION_GOOP
@@ -114,16 +125,27 @@ class WebGLExtensionCompressedTexturePVR
 {
 public:
     explicit WebGLExtensionCompressedTexturePVRTC(WebGLContext*);
     virtual ~WebGLExtensionCompressedTexturePVRTC();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
+class WebGLExtensionCompressedTextureRGTC final
+    : public WebGLExtensionBase
+{
+public:
+    explicit WebGLExtensionCompressedTextureRGTC(WebGLContext* webgl);
+
+    static bool IsSupported(const WebGLContext* webgl);
+
+    DECL_WEBGL_EXTENSION_GOOP
+};
+
 class WebGLExtensionCompressedTextureS3TC
     : public WebGLExtensionBase
 {
 public:
     explicit WebGLExtensionCompressedTextureS3TC(WebGLContext*);
     virtual ~WebGLExtensionCompressedTextureS3TC();
 
     static bool IsSupported(const WebGLContext*);
--- a/dom/canvas/WebGLFormats.cpp
+++ b/dom/canvas/WebGLFormats.cpp
@@ -102,16 +102,28 @@ InitCompressedFormatInfo()
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 ,  64, 4, 4, CompressionFamily::ES3);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,  64, 4, 4, CompressionFamily::ES3);
 
     // AMD_compressed_ATC_texture
     AddCompressedFormatInfo(EffectiveFormat::ATC_RGB_AMD                    ,  64, 4, 4, CompressionFamily::ATC);
     AddCompressedFormatInfo(EffectiveFormat::ATC_RGBA_EXPLICIT_ALPHA_AMD    , 128, 4, 4, CompressionFamily::ATC);
     AddCompressedFormatInfo(EffectiveFormat::ATC_RGBA_INTERPOLATED_ALPHA_AMD, 128, 4, 4, CompressionFamily::ATC);
 
+    // EXT_texture_compression_bptc
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_BPTC_UNORM        , 16*8, 4, 4, CompressionFamily::BPTC);
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_BPTC_UNORM  , 16*8, 4, 4, CompressionFamily::BPTC);
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_BPTC_SIGNED_FLOAT  , 16*8, 4, 4, CompressionFamily::BPTC);
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, 16*8, 4, 4, CompressionFamily::BPTC);
+
+    // EXT_texture_compression_rgtc
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RED_RGTC1       ,  8*8, 4, 4, CompressionFamily::RGTC);
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RED_RGTC1,  8*8, 4, 4, CompressionFamily::RGTC);
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RG_RGTC2        , 16*8, 4, 4, CompressionFamily::RGTC);
+    AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RG_RGTC2 , 16*8, 4, 4, CompressionFamily::RGTC);
+
     // EXT_texture_compression_s3tc
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_S3TC_DXT1_EXT ,  64, 4, 4, CompressionFamily::S3TC);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT1_EXT,  64, 4, 4, CompressionFamily::S3TC);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT3_EXT, 128, 4, 4, CompressionFamily::S3TC);
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT5_EXT, 128, 4, 4, CompressionFamily::S3TC);
 
     // EXT_texture_compression_s3tc_srgb
     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_S3TC_DXT1_EXT ,       64, 4, 4, CompressionFamily::S3TC);
@@ -318,16 +330,28 @@ InitFormatInfo()
     AddFormatInfo(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     AddFormatInfo(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
 
     // AMD_compressed_ATC_texture
     AddFormatInfo(FOO(ATC_RGB_AMD                    ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
     AddFormatInfo(FOO(ATC_RGBA_EXPLICIT_ALPHA_AMD    ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     AddFormatInfo(FOO(ATC_RGBA_INTERPOLATED_ALPHA_AMD), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
 
+    // EXT_texture_compression_bptc
+    AddFormatInfo(FOO(COMPRESSED_RGBA_BPTC_UNORM        ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
+    AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_BPTC_UNORM  ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
+    AddFormatInfo(FOO(COMPRESSED_RGB_BPTC_SIGNED_FLOAT  ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float   );
+    AddFormatInfo(FOO(COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float   );
+
+    // EXT_texture_compression_rgtc
+    AddFormatInfo(FOO(COMPRESSED_RED_RGTC1       ), 0, 1,0,0,0, 0,0, UnsizedFormat::R , false, ComponentType::NormUInt);
+    AddFormatInfo(FOO(COMPRESSED_SIGNED_RED_RGTC1), 0, 1,0,0,0, 0,0, UnsizedFormat::R , false, ComponentType::NormInt );
+    AddFormatInfo(FOO(COMPRESSED_RG_RGTC2        ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG, false, ComponentType::NormUInt);
+    AddFormatInfo(FOO(COMPRESSED_SIGNED_RG_RGTC2 ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG, false, ComponentType::NormInt );
+
     // EXT_texture_compression_s3tc
     AddFormatInfo(FOO(COMPRESSED_RGB_S3TC_DXT1_EXT ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
     AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT1_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT3_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT5_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
 
     // EXT_texture_compression_s3tc_srgb
     AddFormatInfo(FOO(COMPRESSED_SRGB_S3TC_DXT1_EXT ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , true, ComponentType::NormUInt);
--- a/dom/canvas/WebGLFormats.h
+++ b/dom/canvas/WebGLFormats.h
@@ -108,16 +108,28 @@ enum class EffectiveFormat : EffectiveFo
     COMPRESSED_RGBA8_ETC2_EAC,
     COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
 
     // AMD_compressed_ATC_texture
     ATC_RGB_AMD,
     ATC_RGBA_EXPLICIT_ALPHA_AMD,
     ATC_RGBA_INTERPOLATED_ALPHA_AMD,
 
+    // EXT_texture_compression_bptc
+    COMPRESSED_RGBA_BPTC_UNORM,
+    COMPRESSED_SRGB_ALPHA_BPTC_UNORM,
+    COMPRESSED_RGB_BPTC_SIGNED_FLOAT,
+    COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,
+
+    // EXT_texture_compression_rgtc
+    COMPRESSED_RED_RGTC1,
+    COMPRESSED_SIGNED_RED_RGTC1,
+    COMPRESSED_RG_RGTC2,
+    COMPRESSED_SIGNED_RG_RGTC2,
+
     // EXT_texture_compression_s3tc
     COMPRESSED_RGB_S3TC_DXT1_EXT,
     COMPRESSED_RGBA_S3TC_DXT1_EXT,
     COMPRESSED_RGBA_S3TC_DXT3_EXT,
     COMPRESSED_RGBA_S3TC_DXT5_EXT,
 
     // EXT_texture_sRGB
     COMPRESSED_SRGB_S3TC_DXT1_EXT,
@@ -207,19 +219,21 @@ enum class ComponentType : uint8_t {
     NormUInt,     // RGBA8, DEPTH_COMPONENT16
     Float,        // RGBA32F
     Special,      // DEPTH24_STENCIL8
 };
 
 enum class CompressionFamily : uint8_t {
     ASTC,
     ATC,
+    BPTC,
     ES3, // ETC2 or EAC
     ETC1,
     PVRTC,
+    RGTC,
     S3TC,
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
 struct CompressedFormatInfo
 {
     const EffectiveFormat effectiveFormat;
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -1013,72 +1013,48 @@ static bool
 ValidateTargetForFormat(WebGLContext* webgl, TexImageTarget target,
                         const webgl::FormatInfo* format)
 {
     // GLES 3.0.4 p127:
     // "Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are
     //  supported by texture image specification commands only if `target` is TEXTURE_2D,
     //  TEXTURE_2D_ARRAY, or TEXTURE_CUBE_MAP. Using these formats in conjunction with any
     //  other `target` will result in an INVALID_OPERATION error."
+    const bool ok = [&]() {
+        if (bool(format->d) & (target == LOCAL_GL_TEXTURE_3D))
+            return false;
 
-    switch (format->effectiveFormat) {
-    // TEXTURE_2D_ARRAY but not TEXTURE_3D:
-    // D and DS formats
-    case webgl::EffectiveFormat::DEPTH_COMPONENT16:
-    case webgl::EffectiveFormat::DEPTH_COMPONENT24:
-    case webgl::EffectiveFormat::DEPTH_COMPONENT32F:
-    case webgl::EffectiveFormat::DEPTH24_STENCIL8:
-    case webgl::EffectiveFormat::DEPTH32F_STENCIL8:
-    // CompressionFamily::ES3
-    case webgl::EffectiveFormat::COMPRESSED_R11_EAC:
-    case webgl::EffectiveFormat::COMPRESSED_SIGNED_R11_EAC:
-    case webgl::EffectiveFormat::COMPRESSED_RG11_EAC:
-    case webgl::EffectiveFormat::COMPRESSED_SIGNED_RG11_EAC:
-    case webgl::EffectiveFormat::COMPRESSED_RGB8_ETC2:
-    case webgl::EffectiveFormat::COMPRESSED_SRGB8_ETC2:
-    case webgl::EffectiveFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-    case webgl::EffectiveFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-    case webgl::EffectiveFormat::COMPRESSED_RGBA8_ETC2_EAC:
-    case webgl::EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
-    // CompressionFamily::S3TC
-    case webgl::EffectiveFormat::COMPRESSED_RGB_S3TC_DXT1_EXT:
-    case webgl::EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT1_EXT:
-    case webgl::EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT3_EXT:
-    case webgl::EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT5_EXT:
-        if (target == LOCAL_GL_TEXTURE_3D) {
-            webgl->ErrorInvalidOperation("Format %s cannot be used with TEXTURE_3D.",
-                                         format->name);
-            return false;
+        if (format->compression) {
+            switch (format->compression->family) {
+            case webgl::CompressionFamily::ES3:
+            case webgl::CompressionFamily::S3TC:
+                if (target == LOCAL_GL_TEXTURE_3D)
+                    return false;
+                break;
+
+            case webgl::CompressionFamily::ATC:
+            case webgl::CompressionFamily::ETC1:
+            case webgl::CompressionFamily::PVRTC:
+            case webgl::CompressionFamily::RGTC:
+                if (target == LOCAL_GL_TEXTURE_3D ||
+                    target == LOCAL_GL_TEXTURE_2D_ARRAY)
+                {
+                    return false;
+                }
+                break;
+            default:
+                break;
+            }
         }
-        break;
-
-    // No 3D targets:
-    // CompressionFamily::ATC
-    case webgl::EffectiveFormat::ATC_RGB_AMD:
-    case webgl::EffectiveFormat::ATC_RGBA_EXPLICIT_ALPHA_AMD:
-    case webgl::EffectiveFormat::ATC_RGBA_INTERPOLATED_ALPHA_AMD:
-    // CompressionFamily::PVRTC
-    case webgl::EffectiveFormat::COMPRESSED_RGB_PVRTC_4BPPV1:
-    case webgl::EffectiveFormat::COMPRESSED_RGBA_PVRTC_4BPPV1:
-    case webgl::EffectiveFormat::COMPRESSED_RGB_PVRTC_2BPPV1:
-    case webgl::EffectiveFormat::COMPRESSED_RGBA_PVRTC_2BPPV1:
-    // CompressionFamily::ETC1
-    case webgl::EffectiveFormat::ETC1_RGB8_OES:
-        if (target == LOCAL_GL_TEXTURE_3D ||
-            target == LOCAL_GL_TEXTURE_2D_ARRAY)
-        {
-            webgl->ErrorInvalidOperation("Format %s cannot be used with TEXTURE_3D or"
-                                         " TEXTURE_2D_ARRAY.",
-                                         format->name);
-            return false;
-        }
-        break;
-
-    default:
-        break;
+        return true;
+    }();
+    if (!ok) {
+        webgl->ErrorInvalidOperation("Format %s cannot be used with target %s.",
+                                     format->name, GetEnumName(target.get()));
+        return false;
     }
 
     return true;
 }
 
 void
 WebGLTexture::TexStorage(TexTarget target, GLsizei levels,
                          GLenum sizedFormat, GLsizei width, GLsizei height, GLsizei depth)
@@ -1593,16 +1569,18 @@ WebGLTexture::CompressedTexSubImage(TexI
     case webgl::CompressionFamily::ATC:
         mContext->ErrorInvalidOperation("Format does not allow sub-image"
                                         " updates.");
         return;
 
     // Block-aligned:
     case webgl::CompressionFamily::ES3:  // Yes, the ES3 formats don't match the ES3
     case webgl::CompressionFamily::S3TC: // default behavior.
+    case webgl::CompressionFamily::BPTC:
+    case webgl::CompressionFamily::RGTC:
         if (!IsSubImageBlockAligned(dstFormat->compression, imageInfo, xOffset, yOffset,
                                     blob->mWidth, blob->mHeight))
         {
             mContext->ErrorInvalidOperation("Format requires block-aligned sub-image"
                                             " updates.");
             return;
         }
         break;
--- a/dom/canvas/WebGLTypes.h
+++ b/dom/canvas/WebGLTypes.h
@@ -139,16 +139,18 @@ enum class WebGLTexDimensions : uint8_t 
 };
 
 // Please keep extensions in alphabetic order.
 enum class WebGLExtensionID : uint8_t {
     ANGLE_instanced_arrays,
     EXT_blend_minmax,
     EXT_color_buffer_float,
     EXT_color_buffer_half_float,
+    EXT_texture_compression_bptc,
+    EXT_texture_compression_rgtc,
     EXT_frag_depth,
     EXT_sRGB,
     EXT_shader_texture_lod,
     EXT_texture_filter_anisotropic,
     EXT_disjoint_timer_query,
     MOZ_debug,
     OES_element_index_uint,
     OES_standard_derivatives,
--- a/dom/canvas/moz.build
+++ b/dom/canvas/moz.build
@@ -121,19 +121,21 @@ UNIFIED_SOURCES += [
     'WebGLContextVertexArray.cpp',
     'WebGLContextVertices.cpp',
     'WebGLExtensionBase.cpp',
     'WebGLExtensionBlendMinMax.cpp',
     'WebGLExtensionColorBufferFloat.cpp',
     'WebGLExtensionColorBufferHalfFloat.cpp',
     'WebGLExtensionCompressedTextureASTC.cpp',
     'WebGLExtensionCompressedTextureATC.cpp',
+    'WebGLExtensionCompressedTextureBPTC.cpp',
     'WebGLExtensionCompressedTextureES3.cpp',
     'WebGLExtensionCompressedTextureETC1.cpp',
     'WebGLExtensionCompressedTexturePVRTC.cpp',
+    'WebGLExtensionCompressedTextureRGTC.cpp',
     'WebGLExtensionCompressedTextureS3TC.cpp',
     'WebGLExtensionCompressedTextureS3TC_SRGB.cpp',
     'WebGLExtensionDebugRendererInfo.cpp',
     'WebGLExtensionDebugShaders.cpp',
     'WebGLExtensionDepthTexture.cpp',
     'WebGLExtensionDisjointTimerQuery.cpp',
     'WebGLExtensionDrawBuffers.cpp',
     'WebGLExtensionElementIndexUint.cpp',
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_texture_compression_bptc.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta charset='utf-8'/>
+    <script src='/tests/SimpleTest/SimpleTest.js'></script>
+    <link rel='stylesheet' href='/tests/SimpleTest/test.css'>
+    <script src='ensure-ext.js'></script>
+  </head>
+  <body>
+    <script>
+
+'use strict';
+EnsureExt('EXT_texture_compression_bptc', false);
+
+Lastly_WithDraftExtsEnabled(() => {
+  EnsureExt('EXT_texture_compression_bptc', true);
+});
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_texture_compression_rgtc.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+  <head>
+    <meta charset='utf-8'/>
+    <script src='/tests/SimpleTest/SimpleTest.js'></script>
+    <link rel='stylesheet' href='/tests/SimpleTest/test.css'>
+    <script src='ensure-ext.js'></script>
+  </head>
+  <body>
+    <script>
+
+'use strict';
+EnsureExt('EXT_texture_compression_rgtc', false);
+
+Lastly_WithDraftExtsEnabled(() => {
+  EnsureExt('EXT_texture_compression_rgtc', true);
+});
+
+    </script>
+  </body>
+</html>
--- a/dom/canvas/test/webgl-mochitest/ensure-exts/test_common.html
+++ b/dom/canvas/test/webgl-mochitest/ensure-exts/test_common.html
@@ -14,17 +14,16 @@
 var ENSURE = 'ENSURE'; // Works on all test machines.
 var FORBID = 'FORBID'; // Should not work on any test machine.
 var MACHINE_SPECIFIC = 'MACHINE_SPECIFIC';
 
 var defaultExts = [
     // Ratified
     ['ANGLE_instanced_arrays'        , [MACHINE_SPECIFIC, FORBID          ]],
     ['EXT_blend_minmax'              , [MACHINE_SPECIFIC, FORBID          ]],
-    ['EXT_disjoint_timer_query'      , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
     ['EXT_frag_depth'                , [MACHINE_SPECIFIC, FORBID          ]],
     ['EXT_shader_texture_lod'        , [MACHINE_SPECIFIC, FORBID          ]],
     ['EXT_texture_filter_anisotropic', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
     ['OES_element_index_uint'        , [ENSURE          , FORBID          ]],
     ['OES_standard_derivatives'      , [MACHINE_SPECIFIC, FORBID          ]],
     ['OES_texture_float'             , [ENSURE          , FORBID          ]],
     ['OES_texture_float_linear'      , [ENSURE          , ENSURE          ]],
     ['OES_texture_half_float'        , [ENSURE          , FORBID          ]],
@@ -33,32 +32,36 @@ var defaultExts = [
     ['WEBGL_compressed_texture_s3tc' , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
     ['WEBGL_debug_renderer_info'     , [ENSURE          , ENSURE          ]],
     ['WEBGL_debug_shaders'           , [ENSURE          , ENSURE          ]],
     ['WEBGL_depth_texture'           , [MACHINE_SPECIFIC, FORBID          ]],
     ['WEBGL_draw_buffers'            , [MACHINE_SPECIFIC, FORBID          ]],
     ['WEBGL_lose_context'            , [ENSURE          , ENSURE          ]],
 
     // Community Approved
-    ['EXT_color_buffer_float'        , [FORBID          , ENSURE          ]],
-    ['EXT_color_buffer_half_float'   , [MACHINE_SPECIFIC, FORBID          ]],
-    ['EXT_sRGB'                      , [MACHINE_SPECIFIC, FORBID          ]],
-    ['WEBGL_color_buffer_float'      , [MACHINE_SPECIFIC, FORBID          ]],
-    ['WEBGL_compressed_texture_atc'  , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
-    ['WEBGL_compressed_texture_etc1' , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
-    ['WEBGL_compressed_texture_pvrtc', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['EXT_color_buffer_float'            , [FORBID          , ENSURE          ]],
+    ['EXT_color_buffer_half_float'       , [MACHINE_SPECIFIC, FORBID          ]],
+    ['EXT_disjoint_timer_query'          , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['EXT_sRGB'                          , [MACHINE_SPECIFIC, FORBID          ]],
+    ['WEBGL_color_buffer_float'          , [MACHINE_SPECIFIC, FORBID          ]],
+    ['WEBGL_compressed_texture_astc'     , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['WEBGL_compressed_texture_atc'      , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['WEBGL_compressed_texture_etc'      , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['WEBGL_compressed_texture_etc1'     , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['WEBGL_compressed_texture_pvrtc'    , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['WEBGL_compressed_texture_s3tc_srgb', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
 ];
 
 var draftExts = [
-    ['WEBGL_compressed_texture_es3', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['EXT_texture_compression_bptc', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
+    ['EXT_texture_compression_rgtc', [MACHINE_SPECIFIC, MACHINE_SPECIFIC]],
 ];
 
 var nonImplementedExts = [
     'OES_fbo_render_mipmap',
-    'WEBGL_compressed_texture_astc',
     'WEBGL_security_sensitive_resources',
     'WEBGL_shared_resources',
 ];
 
 ////////////////////
 
 function TestExtFor(contextType, extName, status) {
     switch (status) {
--- a/dom/canvas/test/webgl-mochitest/mochitest.ini
+++ b/dom/canvas/test/webgl-mochitest/mochitest.ini
@@ -21,16 +21,20 @@ fail-if = (os == 'android')
 [ensure-exts/test_EXT_disjoint_timer_query.html]
 fail-if = 1
 [ensure-exts/test_EXT_frag_depth.html]
 fail-if = (os == 'android')
 [ensure-exts/test_EXT_sRGB.html]
 fail-if = (os == 'android')
 [ensure-exts/test_EXT_shader_texture_lod.html]
 fail-if = (os == 'android')
+[ensure-exts/test_EXT_texture_compression_bptc.html]
+fail-if = (os == 'android') || (os == 'linux') || (os == 'mac') || (os == 'win')
+[ensure-exts/test_EXT_texture_compression_rgtc.html]
+fail-if = (os == 'android') || (os == 'linux') || (os == 'mac') || (os == 'win')
 [ensure-exts/test_EXT_texture_filter_anisotropic.html]
 fail-if = (os == 'android') || (os == 'linux')
 [ensure-exts/test_OES_standard_derivatives.html]
 fail-if = (os == 'android')
 [ensure-exts/test_WEBGL_color_buffer_float.html]
 fail-if = (os == 'android')
 [ensure-exts/test_WEBGL_compressed_texture_atc.html]
 fail-if = (os == 'android') || (os == 'linux') || (os == 'mac') || (os == 'win')
--- a/dom/webidl/WebGLRenderingContext.webidl
+++ b/dom/webidl/WebGLRenderingContext.webidl
@@ -811,16 +811,32 @@ partial interface WebGLRenderingContext 
     [Func="mozilla::dom::DOMPrefs::gfx_offscreencanvas_enabled"]
     void commit();
 };
 
 ////////////////////////////////////////
 // specific extension interfaces
 
 [NoInterfaceObject]
+interface EXT_texture_compression_bptc {
+    const GLenum COMPRESSED_RGBA_BPTC_UNORM_EXT = 0x8E8C;
+    const GLenum COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT = 0x8E8D;
+    const GLenum COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT = 0x8E8E;
+    const GLenum COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT = 0x8E8F;
+};
+
+[NoInterfaceObject]
+interface EXT_texture_compression_rgtc {
+    const GLenum COMPRESSED_RED_RGTC1_EXT = 0x8DBB;
+    const GLenum COMPRESSED_SIGNED_RED_RGTC1_EXT = 0x8DBC;
+    const GLenum COMPRESSED_RED_GREEN_RGTC2_EXT = 0x8DBD;
+    const GLenum COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT = 0x8DBE;
+};
+
+[NoInterfaceObject]
 interface WEBGL_compressed_texture_s3tc
 {
     const GLenum COMPRESSED_RGB_S3TC_DXT1_EXT  = 0x83F0;
     const GLenum COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
     const GLenum COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
     const GLenum COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
 };
 
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -106,16 +106,18 @@ static const char* const sExtensionNames
     "GL_ARB_pixel_buffer_object",
     "GL_ARB_robust_buffer_access_behavior",
     "GL_ARB_robustness",
     "GL_ARB_sampler_objects",
     "GL_ARB_seamless_cube_map",
     "GL_ARB_shader_texture_lod",
     "GL_ARB_sync",
     "GL_ARB_texture_compression",
+    "GL_ARB_texture_compression_bptc",
+    "GL_ARB_texture_compression_rgtc",
     "GL_ARB_texture_float",
     "GL_ARB_texture_non_power_of_two",
     "GL_ARB_texture_rectangle",
     "GL_ARB_texture_rg",
     "GL_ARB_texture_storage",
     "GL_ARB_texture_swizzle",
     "GL_ARB_timer_query",
     "GL_ARB_transform_feedback2",
@@ -141,17 +143,19 @@ static const char* const sExtensionNames
     "GL_EXT_occlusion_query_boolean",
     "GL_EXT_packed_depth_stencil",
     "GL_EXT_read_format_bgra",
     "GL_EXT_robustness",
     "GL_EXT_sRGB",
     "GL_EXT_sRGB_write_control",
     "GL_EXT_shader_texture_lod",
     "GL_EXT_texture3D",
+    "GL_EXT_texture_compression_bptc",
     "GL_EXT_texture_compression_dxt1",
+    "GL_EXT_texture_compression_rgtc",
     "GL_EXT_texture_compression_s3tc",
     "GL_EXT_texture_compression_s3tc_srgb",
     "GL_EXT_texture_filter_anisotropic",
     "GL_EXT_texture_format_BGRA8888",
     "GL_EXT_texture_sRGB",
     "GL_EXT_texture_storage",
     "GL_EXT_timer_query",
     "GL_EXT_transform_feedback",
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -127,16 +127,18 @@ enum class GLFeature {
     seamless_cube_map_opt_in,
     shader_texture_lod,
     split_framebuffer,
     standard_derivatives,
     sync,
     texture_3D,
     texture_3D_compressed,
     texture_3D_copy,
+    texture_compression_bptc,
+    texture_compression_rgtc,
     texture_float,
     texture_float_linear,
     texture_half_float,
     texture_half_float_linear,
     texture_non_power_of_two,
     texture_rg,
     texture_storage,
     texture_swizzle,
@@ -405,16 +407,18 @@ public:
         ARB_pixel_buffer_object,
         ARB_robust_buffer_access_behavior,
         ARB_robustness,
         ARB_sampler_objects,
         ARB_seamless_cube_map,
         ARB_shader_texture_lod,
         ARB_sync,
         ARB_texture_compression,
+        ARB_texture_compression_bptc,
+        ARB_texture_compression_rgtc,
         ARB_texture_float,
         ARB_texture_non_power_of_two,
         ARB_texture_rectangle,
         ARB_texture_rg,
         ARB_texture_storage,
         ARB_texture_swizzle,
         ARB_timer_query,
         ARB_transform_feedback2,
@@ -440,17 +444,19 @@ public:
         EXT_occlusion_query_boolean,
         EXT_packed_depth_stencil,
         EXT_read_format_bgra,
         EXT_robustness,
         EXT_sRGB,
         EXT_sRGB_write_control,
         EXT_shader_texture_lod,
         EXT_texture3D,
+        EXT_texture_compression_bptc,
         EXT_texture_compression_dxt1,
+        EXT_texture_compression_rgtc,
         EXT_texture_compression_s3tc,
         EXT_texture_compression_s3tc_srgb,
         EXT_texture_filter_anisotropic,
         EXT_texture_format_BGRA8888,
         EXT_texture_sRGB,
         EXT_texture_storage,
         EXT_timer_query,
         EXT_transform_feedback,
--- a/gfx/gl/GLContextFeatures.cpp
+++ b/gfx/gl/GLContextFeatures.cpp
@@ -649,16 +649,38 @@ static const FeatureInfo sFeatureInfoArr
         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