Bug 1030206 - webgl-1.0.3 Disallow floating point render targets if WEBGL_color_buffer_float is not enabled. r=jgilbert
authorWalter Litwinczyk <wlitwinczyk@mozilla.com>
Mon, 07 Jul 2014 15:15:59 -0700
changeset 215363 e6d756bc2ba72844536a9adf98796e11a0984dc1
parent 215362 de68b320435161095234343a626a0176226cdbbe
child 215364 6471c4d6ffee987c17644ba71e8fcc074289e672
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert
bugs1030206
milestone33.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 1030206 - webgl-1.0.3 Disallow floating point render targets if WEBGL_color_buffer_float is not enabled. r=jgilbert
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/WebGLFramebuffer.cpp
content/canvas/src/WebGLFramebuffer.h
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -2168,17 +2168,17 @@ WebGLContext::ReadPixels(GLint x, GLint 
         return rv.Throw(NS_ERROR_OUT_OF_MEMORY);
     }
 
     bool isSourceTypeFloat = false;
     if (mBoundFramebuffer &&
         mBoundFramebuffer->ColorAttachmentCount() &&
         mBoundFramebuffer->ColorAttachment(0).IsDefined())
     {
-        isSourceTypeFloat = mBoundFramebuffer->ColorAttachment(0).IsReadableFloat();
+        isSourceTypeFloat = mBoundFramebuffer->ColorAttachment(0).IsFloatType();
     }
 
     if (isReadTypeFloat != isSourceTypeFloat)
         return ErrorInvalidOperation("readPixels: Invalid type floatness");
 
     // Check the format and type params to assure they are an acceptable pair (as per spec)
     MakeContextCurrent();
 
--- a/content/canvas/src/WebGLFramebuffer.cpp
+++ b/content/canvas/src/WebGLFramebuffer.cpp
@@ -57,36 +57,42 @@ WebGLFramebuffer::Attachment::HasAlpha()
     if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
         format = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).WebGLFormat();
     else if (Renderbuffer())
         format = Renderbuffer()->InternalFormat();
     return FormatHasAlpha(format);
 }
 
 bool
-WebGLFramebuffer::Attachment::IsReadableFloat() const
+WebGLFramebuffer::Attachment::IsFloatType(FloatType floatType) const
 {
     if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) {
         GLenum type = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).WebGLType();
         switch (type) {
         case LOCAL_GL_FLOAT:
+            return floatType == FloatType::Full ||
+                   floatType == FloatType::Any;
         case LOCAL_GL_HALF_FLOAT_OES:
-            return true;
+            return floatType == FloatType::Half ||
+                   floatType == FloatType::Any;
         }
         return false;
     }
 
     if (Renderbuffer()) {
         GLenum format = Renderbuffer()->InternalFormat();
         switch (format) {
         case LOCAL_GL_RGB16F:
         case LOCAL_GL_RGBA16F:
+            return floatType == FloatType::Half ||
+                   floatType == FloatType::Any;
         case LOCAL_GL_RGB32F:
         case LOCAL_GL_RGBA32F:
-            return true;
+            return floatType == FloatType::Full ||
+                   floatType == FloatType::Any;
         }
         return false;
     }
 
     MOZ_ASSERT(false, "Should not get here.");
     return false;
 }
 
@@ -625,16 +631,36 @@ IsIncomplete(const WebGLFramebuffer::Att
 bool
 WebGLFramebuffer::HasIncompleteAttachments() const
 {
     bool hasIncomplete = false;
 
     size_t count = mColorAttachments.Length();
     for (size_t i = 0; i < count; i++) {
         hasIncomplete |= IsIncomplete(mColorAttachments[i]);
+
+        if (mColorAttachments[i].IsDefined()) {
+            // Excerpt from http://www.khronos.org/registry/webgl/extensions/OES_texture_float/
+            // New implementations should not implicitly support float rendering and
+            // applications should be modified to explicitly enable WEBGL_color_buffer_float.
+            if (mColorAttachments[i].IsFloatType(Attachment::FloatType::Full) &&
+                !Context()->IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float))
+            {
+                hasIncomplete |= true;
+            }
+
+            // Excerpt from http://www.khronos.org/registry/webgl/extensions/OES_texture_half_float/
+            // New implementations should not implicitly support float rendering and
+            // applications should be modified to explicitly enable OES_color_buffer_half_float.
+            if (mColorAttachments[i].IsFloatType(Attachment::FloatType::Half) &&
+                !Context()->IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float))
+            {
+                hasIncomplete |= true;
+            }
+        }
     }
 
     hasIncomplete |= IsIncomplete(mDepthAttachment);
     hasIncomplete |= IsIncomplete(mStencilAttachment);
     hasIncomplete |= IsIncomplete(mDepthStencilAttachment);
 
     return hasIncomplete;
 }
--- a/content/canvas/src/WebGLFramebuffer.h
+++ b/content/canvas/src/WebGLFramebuffer.h
@@ -6,16 +6,17 @@
 #ifndef WEBGLFRAMEBUFFER_H_
 #define WEBGLFRAMEBUFFER_H_
 
 #include "WebGLObjectModel.h"
 
 #include "nsWrapperCache.h"
 
 #include "mozilla/LinkedList.h"
+#include "mozilla/TypedEnum.h"
 
 namespace mozilla {
 
 class WebGLFramebufferAttachable;
 class WebGLTexture;
 class WebGLRenderbuffer;
 namespace gl {
     class GLContext;
@@ -47,17 +48,25 @@ public:
 
         bool IsDefined() const {
             return Texture() || Renderbuffer();
         }
 
         bool IsDeleteRequested() const;
 
         bool HasAlpha() const;
-        bool IsReadableFloat() const;
+
+        // For IsFloatType()
+        MOZ_BEGIN_NESTED_ENUM_CLASS(FloatType)
+            Any = 0,
+            Half,
+            Full
+        MOZ_END_NESTED_ENUM_CLASS(FloatType)
+
+        bool IsFloatType(FloatType floatType = FloatType::Any) const;
 
         void SetTexImage(WebGLTexture* tex, GLenum target, GLint level);
         void SetRenderbuffer(WebGLRenderbuffer* rb);
 
         const WebGLTexture* Texture() const {
             return mTexturePtr;
         }
         WebGLTexture* Texture() {
@@ -191,11 +200,13 @@ private:
     // we only store pointers to attached renderbuffers, not to attached textures, because
     // we will only need to initialize renderbuffers. Textures are already initialized.
     nsTArray<Attachment> mColorAttachments;
     Attachment mDepthAttachment,
                mStencilAttachment,
                mDepthStencilAttachment;
 };
 
+MOZ_FINISH_NESTED_ENUM_CLASS(WebGLFramebuffer::Attachment::FloatType)
+
 } // namespace mozilla
 
 #endif