Fix tex-(half-)float exts for WebGL1 on !GLES. draft
authorJeff Gilbert <jdashg@gmail.com>
Thu, 17 Dec 2015 16:16:54 -0800
changeset 316102 701fd5fd3d0d53e1262d08e397d500d46bc5c529
parent 316101 033d8756c84bc8d0b07e6f9348210c2c6f3d8e99
child 316103 debcc0911099800ed5efb8febe593e971a43695b
push id8514
push userjgilbert@mozilla.com
push dateFri, 18 Dec 2015 00:24:33 +0000
milestone45.0a1
Fix tex-(half-)float exts for WebGL1 on !GLES.
dom/canvas/WebGLContextExtensions.cpp
dom/canvas/WebGLExtensionTextureFloat.cpp
dom/canvas/WebGLExtensionTextureHalfFloat.cpp
dom/canvas/WebGLExtensions.h
--- a/dom/canvas/WebGLContextExtensions.cpp
+++ b/dom/canvas/WebGLContextExtensions.cpp
@@ -168,23 +168,19 @@ WebGLContext::IsExtensionSupported(WebGL
             return WebGLExtensionSRGB::IsSupported(this);
 
         // OES_
         case WebGLExtensionID::OES_element_index_uint:
             return gl->IsSupported(gl::GLFeature::element_index_uint);
         case WebGLExtensionID::OES_standard_derivatives:
             return gl->IsSupported(gl::GLFeature::standard_derivatives);
         case WebGLExtensionID::OES_texture_float:
-            return gl->IsSupported(gl::GLFeature::texture_float);
+            return WebGLExtensionTextureFloat::IsSupported(this);
         case WebGLExtensionID::OES_texture_half_float:
-            // If we have Feature::texture_half_float, we must not be on ES2
-            // and need to translate HALF_FLOAT_OES -> HALF_FLOAT.  We do that
-            // right before making the relevant calls.
-            return gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float) ||
-                   gl->IsSupported(gl::GLFeature::texture_half_float);
+            return WebGLExtensionTextureHalfFloat::IsSupported(this);
 
         case WebGLExtensionID::OES_vertex_array_object:
             return true;
 
         // WEBGL_
         case WebGLExtensionID::WEBGL_depth_texture:
             // WEBGL_depth_texture supports DEPTH_STENCIL textures
             if (!gl->IsSupported(gl::GLFeature::packed_depth_stencil))
--- a/dom/canvas/WebGLExtensionTextureFloat.cpp
+++ b/dom/canvas/WebGLExtensionTextureFloat.cpp
@@ -9,76 +9,107 @@
 #include "WebGLContext.h"
 #include "WebGLFormats.h"
 
 namespace mozilla {
 
 WebGLExtensionTextureFloat::WebGLExtensionTextureFloat(WebGLContext* webgl)
     : WebGLExtensionBase(webgl)
 {
+    MOZ_ASSERT(IsSupported(webgl));
+
     auto& fua = webgl->mFormatUsage;
     gl::GLContext* gl = webgl->GL();
 
     webgl::PackingInfo pi;
     webgl::DriverUnpackInfo dui;
     const GLint* swizzle = nullptr;
 
-    const auto fnAdd = [&fua, &pi, &dui, &swizzle](webgl::EffectiveFormat effFormat) {
-        MOZ_ASSERT(!pi.type && !dui.unpackType);
-        pi.type = LOCAL_GL_FLOAT;
-        dui.unpackType = LOCAL_GL_FLOAT;
-
+    const auto fnAdd = [&fua, &pi, &dui, &swizzle](webgl::EffectiveFormat effFormat)
+    {
         auto usage = fua->EditUsage(effFormat);
         fua->AddUnsizedTexFormat(pi, usage);
         usage->AddUnpack(pi, dui);
 
         usage->textureSwizzleRGBA = swizzle;
     };
 
-    const bool isCore = gl->IsCoreProfile();
+    const bool needSizedInternal = !gl->IsGLES();
+    MOZ_ASSERT_IF(needSizedInternal, gl->IsSupported(gl::GLFeature::texture_swizzle));
+
+    ////////////////
 
-    pi = {LOCAL_GL_RGBA, 0};
+    pi = {LOCAL_GL_RGBA, LOCAL_GL_FLOAT};
     dui = {pi.format, pi.format, pi.type};
+    swizzle = nullptr;
+    if (needSizedInternal) {
+        dui.internalFormat = LOCAL_GL_RGBA32F;
+    }
     fnAdd(webgl::EffectiveFormat::RGBA32F);
 
-    pi = {LOCAL_GL_RGB, 0};
+    //////
+
+    pi = {LOCAL_GL_RGB, LOCAL_GL_FLOAT};
     dui = {pi.format, pi.format, pi.type};
+    swizzle = nullptr;
+    if (needSizedInternal) {
+        dui.internalFormat = LOCAL_GL_RGB32F;
+    }
     fnAdd(webgl::EffectiveFormat::RGB32F);
 
-    pi = {LOCAL_GL_LUMINANCE, 0};
-    if (isCore) {
-        dui = {LOCAL_GL_R32F, LOCAL_GL_RED, 0};
+    //////
+
+    pi = {LOCAL_GL_LUMINANCE, LOCAL_GL_FLOAT};
+    dui = {pi.format, pi.format, pi.type};
+    swizzle = nullptr;
+    if (needSizedInternal) {
+        dui = {LOCAL_GL_R32F, LOCAL_GL_RED, LOCAL_GL_FLOAT};
         swizzle = webgl::FormatUsageInfo::kLuminanceSwizzleRGBA;
-    } else {
-        dui = {pi.format, pi.format, pi.type};
-        swizzle = nullptr;
     }
     fnAdd(webgl::EffectiveFormat::Luminance32F);
 
-    pi = {LOCAL_GL_ALPHA, 0};
-    if (isCore) {
-        dui = {LOCAL_GL_R32F, LOCAL_GL_RED, 0};
+    //////
+
+    pi = {LOCAL_GL_ALPHA, LOCAL_GL_FLOAT};
+    dui = {pi.format, pi.format, pi.type};
+    swizzle = nullptr;
+    if (needSizedInternal) {
+        dui = {LOCAL_GL_R32F, LOCAL_GL_RED, LOCAL_GL_FLOAT};
         swizzle = webgl::FormatUsageInfo::kAlphaSwizzleRGBA;
-    } else {
-        dui = {pi.format, pi.format, pi.type};
-        swizzle = nullptr;
     }
     fnAdd(webgl::EffectiveFormat::Alpha32F);
 
-    pi = {LOCAL_GL_LUMINANCE_ALPHA, 0};
+    //////
+
+    pi = {LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_FLOAT};
     dui = {pi.format, pi.format, pi.type};
-    if (isCore) {
-        dui = {LOCAL_GL_RG32F, LOCAL_GL_RG, 0};
+    swizzle = nullptr;
+    if (needSizedInternal) {
+        dui = {LOCAL_GL_RG32F, LOCAL_GL_RG, LOCAL_GL_FLOAT};
         swizzle = webgl::FormatUsageInfo::kLumAlphaSwizzleRGBA;
-    } else {
-        dui = {pi.format, pi.format, pi.type};
-        swizzle = nullptr;
     }
     fnAdd(webgl::EffectiveFormat::Luminance32FAlpha32F);
 }
 
 WebGLExtensionTextureFloat::~WebGLExtensionTextureFloat()
 {
 }
 
+bool
+WebGLExtensionTextureFloat::IsSupported(const WebGLContext* webgl)
+{
+    gl::GLContext* gl = webgl->GL();
+
+    if (!gl->IsSupported(gl::GLFeature::texture_float))
+        return false;
+
+    const bool needSizedInternal = !gl->IsGLES();
+    const bool hasSwizzle = gl->IsSupported(gl::GLFeature::texture_swizzle);
+
+    if (needSizedInternal && !hasSwizzle)
+        return false;
+
+    return true;
+}
+
 IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureFloat, OES_texture_float)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLExtensionTextureHalfFloat.cpp
+++ b/dom/canvas/WebGLExtensionTextureHalfFloat.cpp
@@ -16,77 +16,107 @@ WebGLExtensionTextureHalfFloat::WebGLExt
 {
     auto& fua = webgl->mFormatUsage;
     gl::GLContext* gl = webgl->GL();
 
     webgl::PackingInfo pi;
     webgl::DriverUnpackInfo dui;
     const GLint* swizzle = nullptr;
 
-    GLenum driverUnpackType = LOCAL_GL_HALF_FLOAT;
-    if (!gl->IsSupported(gl::GLFeature::texture_half_float)) {
-        MOZ_ASSERT(gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float));
-        driverUnpackType = LOCAL_GL_HALF_FLOAT_OES;
-    }
-
-    const auto fnAdd = [&fua, &pi, &dui, &swizzle,
-                        driverUnpackType](webgl::EffectiveFormat effFormat)
+    const auto fnAdd = [&fua, &pi, &dui, &swizzle](webgl::EffectiveFormat effFormat)
     {
-        MOZ_ASSERT(!pi.type && !dui.unpackType);
-        pi.type = LOCAL_GL_HALF_FLOAT_OES;
-        dui.unpackType = driverUnpackType;
-
         auto usage = fua->EditUsage(effFormat);
         fua->AddUnsizedTexFormat(pi, usage);
         usage->AddUnpack(pi, dui);
 
         usage->textureSwizzleRGBA = swizzle;
     };
 
-    const bool isCore = gl->IsCoreProfile();
+    const bool needSizedInternal = !gl->IsGLES();
+    MOZ_ASSERT_IF(needSizedInternal, gl->IsSupported(gl::GLFeature::texture_swizzle));
+
+    GLenum driverUnpackType = LOCAL_GL_HALF_FLOAT;
+    if (!gl->IsSupported(gl::GLFeature::texture_half_float)) {
+        MOZ_ASSERT(gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float));
+        driverUnpackType = LOCAL_GL_HALF_FLOAT_OES;
+    }
 
-    pi = {LOCAL_GL_RGBA, 0};
+    ////////////////
+
+    pi = {LOCAL_GL_RGBA, LOCAL_GL_HALF_FLOAT_OES};
     dui = {pi.format, pi.format, pi.type};
+    swizzle = nullptr;
+    if (needSizedInternal) {
+        dui.internalFormat = LOCAL_GL_RGBA16F;
+    }
     fnAdd(webgl::EffectiveFormat::RGBA16F);
 
-    pi = {LOCAL_GL_RGB, 0};
+    //////
+
+    pi = {LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT_OES};
     dui = {pi.format, pi.format, pi.type};
+    swizzle = nullptr;
+    if (needSizedInternal) {
+        dui.internalFormat = LOCAL_GL_RGB16F;
+    }
     fnAdd(webgl::EffectiveFormat::RGB16F);
 
-    pi = {LOCAL_GL_LUMINANCE, 0};
-    if (isCore) {
-        dui = {LOCAL_GL_R16F, LOCAL_GL_RED, 0};
+    //////
+
+    pi = {LOCAL_GL_LUMINANCE, LOCAL_GL_HALF_FLOAT_OES};
+    dui = {pi.format, pi.format, driverUnpackType};
+    swizzle = nullptr;
+    if (needSizedInternal) {
+        dui = {LOCAL_GL_R16F, LOCAL_GL_RED, driverUnpackType};
         swizzle = webgl::FormatUsageInfo::kLuminanceSwizzleRGBA;
-    } else {
-        dui = {pi.format, pi.format, pi.type};
-        swizzle = nullptr;
     }
     fnAdd(webgl::EffectiveFormat::Luminance16F);
 
-    pi = {LOCAL_GL_ALPHA, 0};
-    if (isCore) {
-        dui = {LOCAL_GL_R16F, LOCAL_GL_RED, 0};
+    //////
+
+    pi = {LOCAL_GL_ALPHA, LOCAL_GL_HALF_FLOAT_OES};
+    dui = {pi.format, pi.format, driverUnpackType};
+    swizzle = nullptr;
+    if (needSizedInternal) {
+        dui = {LOCAL_GL_R16F, LOCAL_GL_RED, driverUnpackType};
         swizzle = webgl::FormatUsageInfo::kAlphaSwizzleRGBA;
-    } else {
-        dui = {pi.format, pi.format, pi.type};
-        swizzle = nullptr;
     }
     fnAdd(webgl::EffectiveFormat::Alpha16F);
 
-    pi = {LOCAL_GL_LUMINANCE_ALPHA, 0};
-    dui = {pi.format, pi.format, pi.type};
-    if (isCore) {
-        dui = {LOCAL_GL_RG16F, LOCAL_GL_RG, 0};
+    //////
+
+    pi = {LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_HALF_FLOAT_OES};
+    dui = {pi.format, pi.format, driverUnpackType};
+    swizzle = nullptr;
+    if (needSizedInternal) {
+        dui = {LOCAL_GL_RG16F, LOCAL_GL_RG, driverUnpackType};
         swizzle = webgl::FormatUsageInfo::kLumAlphaSwizzleRGBA;
-    } else {
-        dui = {pi.format, pi.format, pi.type};
-        swizzle = nullptr;
     }
     fnAdd(webgl::EffectiveFormat::Luminance16FAlpha16F);
 }
 
 WebGLExtensionTextureHalfFloat::~WebGLExtensionTextureHalfFloat()
 {
 }
 
+bool
+WebGLExtensionTextureHalfFloat::IsSupported(const WebGLContext* webgl)
+{
+    gl::GLContext* gl = webgl->GL();
+
+    if (!gl->IsSupported(gl::GLFeature::texture_half_float) &&
+        !gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float))
+    {
+        return false;
+    }
+
+    const bool needSizedInternal = !gl->IsGLES();
+    const bool hasSwizzle = gl->IsSupported(gl::GLFeature::texture_swizzle);
+
+    if (needSizedInternal && !hasSwizzle)
+        return false;
+
+    return true;
+}
+
 IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionTextureHalfFloat, OES_texture_half_float)
 
 } // namespace mozilla
--- a/dom/canvas/WebGLExtensions.h
+++ b/dom/canvas/WebGLExtensions.h
@@ -214,16 +214,18 @@ class WebGLExtensionTextureFloat
     : public WebGLExtensionBase
 {
 public:
     static void InitWebGLFormats(webgl::FormatUsageAuthority* authority);
 
     explicit WebGLExtensionTextureFloat(WebGLContext*);
     virtual ~WebGLExtensionTextureFloat();
 
+    static bool IsSupported(const WebGLContext*);
+
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionTextureFloatLinear
     : public WebGLExtensionBase
 {
 public:
     explicit WebGLExtensionTextureFloatLinear(WebGLContext*);
@@ -236,16 +238,18 @@ class WebGLExtensionTextureHalfFloat
     : public WebGLExtensionBase
 {
 public:
     static void InitWebGLFormats(webgl::FormatUsageAuthority* authority);
 
     explicit WebGLExtensionTextureHalfFloat(WebGLContext*);
     virtual ~WebGLExtensionTextureHalfFloat();
 
+    static bool IsSupported(const WebGLContext*);
+
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionTextureHalfFloatLinear
     : public WebGLExtensionBase
 {
 public:
     explicit WebGLExtensionTextureHalfFloatLinear(WebGLContext*);