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;