Check for swizzle if we need it. draft
authorJeff Gilbert <jdashg@gmail.com>
Thu, 17 Dec 2015 16:16:56 -0800
changeset 316123 cff595d0ee4d3ae1f38ae628eb9d85bb83a116f3
parent 316122 5db38917bef499bdc02747dff0de5330891ae283
child 316124 da9945f4715cf103134da3e08871fcd5bf1cec80
push id8514
push userjgilbert@mozilla.com
push dateFri, 18 Dec 2015 00:24:33 +0000
milestone45.0a1
Check for swizzle if we need it.
dom/canvas/WebGLContextValidate.cpp
dom/canvas/WebGLFormats.cpp
dom/canvas/WebGLTexture.cpp
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -649,16 +649,18 @@ WebGLContext::InitAndValidateGL()
 {
     if (!gl)
         return false;
 
     // Unconditionally create a new format usage authority. This is
     // important when restoring contexts and extensions need to add
     // formats back into the authority.
     mFormatUsage = CreateFormatUsage(gl);
+    if (!mFormatUsage)
+        return false;
 
     GLenum error = gl->fGetError();
     if (error != LOCAL_GL_NO_ERROR) {
         GenerateWarning("GL error 0x%x occurred during OpenGL context"
                         " initialization, before WebGL initialization!", error);
         return false;
     }
 
--- a/dom/canvas/WebGLFormats.cpp
+++ b/dom/canvas/WebGLFormats.cpp
@@ -455,20 +455,23 @@ AddSimpleUnsized(FormatUsageAuthority* f
                                                                  LOCAL_GL_ZERO,
                                                                  LOCAL_GL_ZERO,
                                                                  LOCAL_GL_RED };
 /*static*/ const GLint FormatUsageInfo::kLumAlphaSwizzleRGBA[4] = { LOCAL_GL_RED,
                                                                     LOCAL_GL_RED,
                                                                     LOCAL_GL_RED,
                                                                     LOCAL_GL_GREEN };
 
-static void
+static bool
 AddLegacyFormats_LA8(FormatUsageAuthority* fua, gl::GLContext* gl)
 {
     if (gl->IsCoreProfile()) {
+        if (!gl->IsSupported(gl::GLFeature::texture_swizzle))
+            return false;
+
         PackingInfo pi;
         DriverUnpackInfo dui;
 
         const auto fnAdd = [fua, &pi, &dui](EffectiveFormat effFormat,
                                             const GLint* swizzle)
         {
             auto usage = fua->EditUsage(effFormat);
             usage->isFilterable = true;
@@ -490,30 +493,32 @@ AddLegacyFormats_LA8(FormatUsageAuthorit
         pi = {LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_UNSIGNED_BYTE};
         dui = {LOCAL_GL_RG8, LOCAL_GL_RG, LOCAL_GL_UNSIGNED_BYTE};
         fnAdd(EffectiveFormat::Luminance8Alpha8, FormatUsageInfo::kLumAlphaSwizzleRGBA);
     } else {
         AddSimpleUnsized(fua, LOCAL_GL_LUMINANCE      , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8      );
         AddSimpleUnsized(fua, LOCAL_GL_ALPHA          , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Alpha8          );
         AddSimpleUnsized(fua, LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8Alpha8);
     }
+
+    return true;
 }
 
-static void
+static bool
 AddUnsizedFormats(FormatUsageAuthority* fua, gl::GLContext* gl)
 {
     // GLES 2.0.25, p63, Table 3.4
     AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE         , EffectiveFormat::RGBA8  );
     AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4, EffectiveFormat::RGBA4  );
     AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1, EffectiveFormat::RGB5_A1);
     AddSimpleUnsized(fua, LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_BYTE         , EffectiveFormat::RGB8   );
     AddSimpleUnsized(fua, LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_SHORT_5_6_5  , EffectiveFormat::RGB565 );
 
     // L, A, LA
-    AddLegacyFormats_LA8(fua, gl);
+    return AddLegacyFormats_LA8(fua, gl);
 }
 
 UniquePtr<FormatUsageAuthority>
 FormatUsageAuthority::CreateForWebGL1(gl::GLContext* gl)
 {
     UniquePtr<FormatUsageAuthority> ret(new FormatUsageAuthority);
     const auto ptr = ret.get();
 
@@ -564,17 +569,18 @@ FormatUsageAuthority::CreateForWebGL1(gl
 
 #undef FOO
 
     ptr->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL,
                        ptr->GetUsage(EffectiveFormat::DEPTH24_STENCIL8));
 
     ////////////////////////////////////////////////////////////////////////////
 
-    AddUnsizedFormats(ptr, gl);
+    if (!AddUnsizedFormats(ptr, gl))
+        return nullptr;
 
     return Move(ret);
 }
 
 UniquePtr<FormatUsageAuthority>
 FormatUsageAuthority::CreateForWebGL2(gl::GLContext* gl)
 {
     UniquePtr<FormatUsageAuthority> ret(new FormatUsageAuthority);
@@ -805,17 +811,18 @@ FormatUsageAuthority::CreateForWebGL2(gl
 
     auto usage = ptr->EditUsage(EffectiveFormat::STENCIL_INDEX8);
     usage->isRenderable = true;
     ptr->AllowRBFormat(LOCAL_GL_STENCIL_INDEX8, usage);
 
     ////////////////
     // Legacy formats
 
-    AddUnsizedFormats(ptr, gl);
+    if (!AddUnsizedFormats(ptr, gl))
+        return nullptr;
 
     if (gfxPrefs::WebGL2CompatMode()) {
         AddSimpleUnsized(ptr, LOCAL_GL_RGBA, LOCAL_GL_FLOAT, EffectiveFormat::RGBA32F);
         AddSimpleUnsized(ptr, LOCAL_GL_RGB , LOCAL_GL_FLOAT, EffectiveFormat::RGB32F );
 
         AddSimpleUnsized(ptr, LOCAL_GL_RGBA, LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::RGBA16F);
         AddSimpleUnsized(ptr, LOCAL_GL_RGB , LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::RGB16F );
     }
--- a/dom/canvas/WebGLTexture.cpp
+++ b/dom/canvas/WebGLTexture.cpp
@@ -513,16 +513,18 @@ WebGLTexture::GetFakeBlackType(const cha
 
 static void
 SetSwizzle(gl::GLContext* gl, TexTarget target, const GLint* swizzle)
 {
     static const GLint kNoSwizzle[4] = { LOCAL_GL_RED, LOCAL_GL_GREEN, LOCAL_GL_BLUE,
                                          LOCAL_GL_ALPHA };
     if (!swizzle) {
         swizzle = kNoSwizzle;
+    } else if (!gl->IsSupported(gl::GLFeature::texture_swizzle)) {
+        MOZ_CRASH("Needs swizzle feature to swizzle!");
     }
 
     gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_SWIZZLE_R, swizzle[0]);
     gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_SWIZZLE_G, swizzle[1]);
     gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_SWIZZLE_B, swizzle[2]);
     gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_SWIZZLE_A, swizzle[3]);
 }