Title: [117506] trunk/Source/WebCore
Revision
117506
Author
commit-qu...@webkit.org
Date
2012-05-17 15:27:48 -0700 (Thu, 17 May 2012)

Log Message

Add more descriptive warnings for framebuffer incomplete conditions
https://bugs.webkit.org/show_bug.cgi?id=86774

Patch by Gregg Tavares <g...@google.com> on 2012-05-17
Reviewed by Kenneth Russell.

No new tests as there is no new functionality

* html/canvas/WebGLFramebuffer.cpp:
(WebCore::WebGLFramebuffer::checkStatus):
(WebCore::WebGLFramebuffer::onAccess):
(WebCore::WebGLFramebuffer::initializeRenderbuffers):
* html/canvas/WebGLFramebuffer.h:
(WebGLFramebuffer):
* html/canvas/WebGLRenderingContext.cpp:
(WebCore):
(WebCore::WebGLRenderingContext::checkFramebufferStatus):
(WebCore::WebGLRenderingContext::clear):
(WebCore::WebGLRenderingContext::copyTexImage2D):
(WebCore::WebGLRenderingContext::copyTexSubImage2D):
(WebCore::WebGLRenderingContext::drawArrays):
(WebCore::WebGLRenderingContext::drawElements):
(WebCore::WebGLRenderingContext::readPixels):
(WebCore::WebGLRenderingContext::printGLWarningToConsole):
* html/canvas/WebGLRenderingContext.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (117505 => 117506)


--- trunk/Source/WebCore/ChangeLog	2012-05-17 22:26:59 UTC (rev 117505)
+++ trunk/Source/WebCore/ChangeLog	2012-05-17 22:27:48 UTC (rev 117506)
@@ -1,3 +1,30 @@
+2012-05-17  Gregg Tavares  <g...@google.com>
+
+        Add more descriptive warnings for framebuffer incomplete conditions
+        https://bugs.webkit.org/show_bug.cgi?id=86774
+
+        Reviewed by Kenneth Russell.
+
+        No new tests as there is no new functionality
+
+        * html/canvas/WebGLFramebuffer.cpp:
+        (WebCore::WebGLFramebuffer::checkStatus):
+        (WebCore::WebGLFramebuffer::onAccess):
+        (WebCore::WebGLFramebuffer::initializeRenderbuffers):
+        * html/canvas/WebGLFramebuffer.h:
+        (WebGLFramebuffer):
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore):
+        (WebCore::WebGLRenderingContext::checkFramebufferStatus):
+        (WebCore::WebGLRenderingContext::clear):
+        (WebCore::WebGLRenderingContext::copyTexImage2D):
+        (WebCore::WebGLRenderingContext::copyTexSubImage2D):
+        (WebCore::WebGLRenderingContext::drawArrays):
+        (WebCore::WebGLRenderingContext::drawElements):
+        (WebCore::WebGLRenderingContext::readPixels):
+        (WebCore::WebGLRenderingContext::printGLWarningToConsole):
+        * html/canvas/WebGLRenderingContext.h:
+
 2012-05-17  Oliver Hunt  <oli...@apple.com>
 
         Endeavour to make the windows test bot actually able to run tests.

Modified: trunk/Source/WebCore/html/canvas/WebGLFramebuffer.cpp (117505 => 117506)


--- trunk/Source/WebCore/html/canvas/WebGLFramebuffer.cpp	2012-05-17 22:26:59 UTC (rev 117505)
+++ trunk/Source/WebCore/html/canvas/WebGLFramebuffer.cpp	2012-05-17 22:27:48 UTC (rev 117506)
@@ -36,30 +36,39 @@
 
 namespace {
 
-    bool isAttachmentComplete(WebGLSharedObject* attachedObject, GC3Denum attachment)
+    bool isAttachmentComplete(WebGLSharedObject* attachedObject, GC3Denum attachment, const char** reason)
     {
         ASSERT(attachedObject && attachedObject->object());
         ASSERT(attachedObject->isRenderbuffer());
+        ASSERT(reason);
         WebGLRenderbuffer* buffer = reinterpret_cast<WebGLRenderbuffer*>(attachedObject);
         switch (attachment) {
         case GraphicsContext3D::DEPTH_ATTACHMENT:
-            if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_COMPONENT16)
+            if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_COMPONENT16) {
+                *reason = "DEPTH_ATTACHMENT is not a depth format";
                 return false;
+            }
             break;
         case GraphicsContext3D::STENCIL_ATTACHMENT:
-            if (buffer->getInternalFormat() != GraphicsContext3D::STENCIL_INDEX8)
+            if (buffer->getInternalFormat() != GraphicsContext3D::STENCIL_INDEX8) {
+                *reason = "STENCIL_ATTACHMENT is not a stencil format";
                 return false;
+            }
             break;
         case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
-            if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_STENCIL)
+            if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_STENCIL) {
+                *reason = "DEPTH_STENCIL_ATTACHMENT is not a depth-stencil format";
                 return false;
+            }
             break;
         default:
             ASSERT_NOT_REACHED();
             return false;
         }
-        if (!buffer->getWidth() || !buffer->getHeight())
+        if (!buffer->getWidth() || !buffer->getHeight()) {
+            *reason = "attachment has a 0 dimension";
             return false;
+        }
         return true;
     }
 
@@ -319,70 +328,87 @@
     return 0;
 }
 
-GC3Denum WebGLFramebuffer::checkStatus() const
+GC3Denum WebGLFramebuffer::checkStatus(const char** reason) const
 {
     unsigned int count = 0;
     GC3Dsizei width = 0, height = 0;
     if (isDepthAttached()) {
-        if (!isAttachmentComplete(m_depthAttachment.get(), GraphicsContext3D::DEPTH_ATTACHMENT))
+        if (!isAttachmentComplete(m_depthAttachment.get(), GraphicsContext3D::DEPTH_ATTACHMENT, reason))
             return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         width = getImageWidth(m_depthAttachment.get());
         height = getImageHeight(m_depthAttachment.get());
         count++;
     }
     if (isStencilAttached()) {
-        if (!isAttachmentComplete(m_stencilAttachment.get(), GraphicsContext3D::STENCIL_ATTACHMENT))
+        if (!isAttachmentComplete(m_stencilAttachment.get(), GraphicsContext3D::STENCIL_ATTACHMENT, reason))
             return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
         if (!count) {
             width = getImageWidth(m_stencilAttachment.get());
             height = getImageHeight(m_stencilAttachment.get());
         } else {
-            if (width != getImageWidth(m_stencilAttachment.get()) || height != getImageHeight(m_stencilAttachment.get()))
+            if (width != getImageWidth(m_stencilAttachment.get()) || height != getImageHeight(m_stencilAttachment.get())) {
+                *reason = "STENCIL_ATTACHMENT has different dimensions than DEPTH_ATTACHMENT";
                 return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+            }
         }
         count++;
     }
     if (isDepthStencilAttached()) {
-        if (!isAttachmentComplete(m_depthStencilAttachment.get(), GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT))
+        if (!isAttachmentComplete(m_depthStencilAttachment.get(), GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT, reason))
             return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
-        if (!isValidRenderbuffer(m_depthStencilAttachment.get()))
+        if (!isValidRenderbuffer(m_depthStencilAttachment.get())) {
+            *reason = "DEPTH_STENCIL_ATTACHMENT is not valid";
             return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
+        }
         if (!count) {
             width = getImageWidth(m_depthStencilAttachment.get());
             height = getImageHeight(m_depthStencilAttachment.get());
         } else {
-            if (width != getImageWidth(m_depthStencilAttachment.get()) || height != getImageHeight(m_depthStencilAttachment.get()))
+            if (width != getImageWidth(m_depthStencilAttachment.get()) || height != getImageHeight(m_depthStencilAttachment.get())) {
+                *reason = "DEPTH_STENCIL_ATTACHMENT has different dimensions than other attachments";
                 return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+            }
         }
         count++;
     }
     // WebGL specific: no conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments.
-    if (count > 1)
+    if (count > 1) {
+        *reason = "conflicting DEPTH/STENCIL/DEPTH_STENCIL attachments";
         return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
+    }
     if (isColorAttached()) {
         // FIXME: if color buffer is texture, is ALPHA, LUMINANCE or LUMINANCE_ALPHA valid?
-        if (!getColorBufferFormat())
+        if (!getColorBufferFormat()) {
+            *reason = "COLOR_ATTACHMENT0 is an unsupported format";
             return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+        }
         if (!count) {
-            if (!getColorBufferWidth() || !getColorBufferHeight())
+            if (!getColorBufferWidth() || !getColorBufferHeight())  {
+                *reason = "COLOR_ATTACHMENT0 has a 0 dimension";
                 return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+            }
         } else {
-            if (width != getColorBufferWidth() || height != getColorBufferHeight())
+            if (width != getColorBufferWidth() || height != getColorBufferHeight())  {
+                *reason = "COLOR_ATTACHMENT0 has different dimensions than other attachments";
                 return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+            }
         }
+
     } else {
-        if (!count)
+        if (!count) {
+            *reason = "no attachments";
             return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+        }
     }
     return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
 }
 
-bool WebGLFramebuffer::onAccess(GraphicsContext3D* context3d, bool needToInitializeRenderbuffers)
+bool WebGLFramebuffer::onAccess(GraphicsContext3D* context3d, bool needToInitializeRenderbuffers, const char** reason)
 {
-    if (checkStatus() != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
+    if (checkStatus(reason) != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
         return false;
     if (needToInitializeRenderbuffers)
-        return initializeRenderbuffers(context3d);
+        return initializeRenderbuffers(context3d, reason);
     return true;
 }
 
@@ -404,7 +430,7 @@
     context3d->deleteFramebuffer(object);
 }
 
-bool WebGLFramebuffer::initializeRenderbuffers(GraphicsContext3D* g3d)
+bool WebGLFramebuffer::initializeRenderbuffers(GraphicsContext3D* g3d, const char** reason)
 {
     ASSERT(object());
     bool initColor = false, initDepth = false, initStencil = false;
@@ -431,8 +457,10 @@
 
     // We only clear un-initialized renderbuffers when they are ready to be
     // read, i.e., when the framebuffer is complete.
-    if (g3d->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
+    if (g3d->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
+        *reason = "framebuffer not complete";
         return false;
+    }
 
     GC3Dfloat colorClearValue[] = {0, 0, 0, 0}, depthClearValue = 0;
     GC3Dint stencilClearValue = 0;

Modified: trunk/Source/WebCore/html/canvas/WebGLFramebuffer.h (117505 => 117506)


--- trunk/Source/WebCore/html/canvas/WebGLFramebuffer.h	2012-05-17 22:26:59 UTC (rev 117505)
+++ trunk/Source/WebCore/html/canvas/WebGLFramebuffer.h	2012-05-17 22:27:48 UTC (rev 117506)
@@ -61,13 +61,13 @@
     // Return false if the framebuffer is incomplete; otherwise initialize
     // the buffers if they haven't been initialized and
     // needToInitializeRenderbuffers is true.
-    bool onAccess(GraphicsContext3D*, bool needToInitializeRenderbuffers);
+    bool onAccess(GraphicsContext3D*, bool needToInitializeRenderbuffers, const char** reason);
 
     // Software version of glCheckFramebufferStatus(), except that when
     // FRAMEBUFFER_COMPLETE is returned, it is still possible for
     // glCheckFramebufferStatus() to return FRAMEBUFFER_UNSUPPORTED,
     // depending on hardware implementation.
-    GC3Denum checkStatus() const;
+    GC3Denum checkStatus(const char** reason) const;
 
     bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
 
@@ -84,7 +84,7 @@
     virtual bool isFramebuffer() const { return true; }
 
     // Return false if framebuffer is incomplete.
-    bool initializeRenderbuffers(GraphicsContext3D*);
+    bool initializeRenderbuffers(GraphicsContext3D*, const char** reason);
 
     // Check if the framebuffer is currently bound.
     bool isBound() const;

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (117505 => 117506)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp	2012-05-17 22:26:59 UTC (rev 117505)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp	2012-05-17 22:27:48 UTC (rev 117506)
@@ -1165,9 +1165,12 @@
     }
     if (!m_framebufferBinding || !m_framebufferBinding->object())
         return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
-    GC3Denum result = m_framebufferBinding->checkStatus();
-    if (result != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
+    const char* reason = "framebuffer incomplete";
+    GC3Denum result = m_framebufferBinding->checkStatus(&reason);
+    if (result != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
+        printGLWarningToConsole("checkFramebufferStatus", reason);
         return result;
+    }
     result = m_context->checkFramebufferStatus(target);
     cleanupAfterGraphicsCall(false);
     return result;
@@ -1181,8 +1184,9 @@
         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clear", "invalid mask");
         return;
     }
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) {
-        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear", "can not render to framebuffer");
+    const char* reason = "framebuffer incomplete";
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
         return;
     }
     if (!clearIfComposited(mask))
@@ -1333,8 +1337,9 @@
         synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
         return;
     }
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) {
-        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", "framebuffer not readable");
+    const char* reason = "framebuffer incomplete";
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
         return;
     }
     clearIfComposited();
@@ -1379,8 +1384,9 @@
         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format");
         return;
     }
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) {
-        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", "framebuffer not readable");
+    const char* reason = "framebuffer incomplete";
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
         return;
     }
     clearIfComposited();
@@ -1878,8 +1884,9 @@
         }
     }
 
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) {
-        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "drawArrays", "framebuffer can not be rendered to");
+    const char* reason = "framebuffer incomplete";
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "drawArrays", reason);
         return;
     }
 
@@ -1952,8 +1959,9 @@
         }
     }
 
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) {
-        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "drawElements", "framebuffer can not be rendered to");
+    const char* reason = "framebuffer incomplete";
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "drawElements", reason);
         return;
     }
     clearIfComposited();
@@ -3255,8 +3263,9 @@
         synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "ArrayBufferView not Uint8Array");
         return;
     }
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) {
-        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "readPixels", "framebuffer not readable");
+    const char* reason = "framebuffer incomplete";
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {
+        synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
         return;
     }
     // Calculate array size, taking into consideration of PACK_ALIGNMENT.
@@ -5532,6 +5541,14 @@
 }
 
 
+void WebGLRenderingContext::printGLWarningToConsole(const char* functionName, const char* description)
+{
+    if (m_synthesizedErrorsToConsole) {
+        String str = String("WebGL: ") + String(functionName) + ": " + String(description);
+        printGLErrorToConsole(str);
+    }
+}
+
 void WebGLRenderingContext::applyStencilTest()
 {
     bool haveStencilBuffer = false;

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h (117505 => 117506)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h	2012-05-17 22:26:59 UTC (rev 117505)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h	2012-05-17 22:27:48 UTC (rev 117506)
@@ -634,6 +634,7 @@
 
     // Helper function to print GL errors to console.
     void printGLErrorToConsole(const String&);
+    void printGLWarningToConsole(const char* function, const char* reason);
 
     // Helper function to print warnings to console. Currently
     // used only to warn about use of obsolete functions.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to