Index: Source/core/html/canvas/WebGLFramebuffer.cpp |
diff --git a/Source/core/html/canvas/WebGLFramebuffer.cpp b/Source/core/html/canvas/WebGLFramebuffer.cpp |
index 106af406ac1a1603bac6d3ceb599113b0eccbacb..f81eece28f78f0a8d93f760106e39af42da2b5df 100644 |
--- a/Source/core/html/canvas/WebGLFramebuffer.cpp |
+++ b/Source/core/html/canvas/WebGLFramebuffer.cpp |
@@ -54,8 +54,8 @@ namespace { |
virtual bool isSharedObject(WebGLSharedObject*) const override; |
virtual bool valid() const override; |
virtual void onDetached(WebGraphicsContext3D*) override; |
- virtual void attach(WebGraphicsContext3D*, GLenum attachment) override; |
- virtual void unattach(WebGraphicsContext3D*, GLenum attachment) override; |
+ virtual void attach(WebGraphicsContext3D*, GLenum target, GLenum attachment) override; |
+ virtual void unattach(WebGraphicsContext3D*, GLenum target, GLenum attachment) override; |
RefPtrWillBeMember<WebGLRenderbuffer> m_renderbuffer; |
}; |
@@ -117,24 +117,24 @@ namespace { |
m_renderbuffer->onDetached(context); |
} |
- void WebGLRenderbufferAttachment::attach(WebGraphicsContext3D* context, GLenum attachment) |
+ void WebGLRenderbufferAttachment::attach(WebGraphicsContext3D* context, GLenum target, GLenum attachment) |
{ |
Platform3DObject object = objectOrZero(m_renderbuffer.get()); |
if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL && m_renderbuffer->emulatedStencilBuffer()) { |
- context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, object); |
- context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, objectOrZero(m_renderbuffer->emulatedStencilBuffer())); |
+ context->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, object); |
+ context->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, objectOrZero(m_renderbuffer->emulatedStencilBuffer())); |
} else { |
- context->framebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, object); |
+ context->framebufferRenderbuffer(target, attachment, GL_RENDERBUFFER, object); |
} |
} |
- void WebGLRenderbufferAttachment::unattach(WebGraphicsContext3D* context, GLenum attachment) |
+ void WebGLRenderbufferAttachment::unattach(WebGraphicsContext3D* context, GLenum target, GLenum attachment) |
{ |
if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL) { |
- context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); |
- context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); |
+ context->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); |
+ context->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); |
} else { |
- context->framebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, 0); |
+ context->framebufferRenderbuffer(target, attachment, GL_RENDERBUFFER, 0); |
} |
} |
@@ -162,8 +162,8 @@ namespace { |
virtual bool isSharedObject(WebGLSharedObject*) const override; |
virtual bool valid() const override; |
virtual void onDetached(WebGraphicsContext3D*) override; |
- virtual void attach(WebGraphicsContext3D*, GLenum attachment) override; |
- virtual void unattach(WebGraphicsContext3D*, GLenum attachment) override; |
+ virtual void attach(WebGraphicsContext3D*, GLenum target, GLenum attachment) override; |
+ virtual void unattach(WebGraphicsContext3D*, GLenum target, GLenum attachment) override; |
RefPtrWillBeMember<WebGLTexture> m_texture; |
GLenum m_target; |
@@ -223,19 +223,19 @@ namespace { |
m_texture->onDetached(context); |
} |
- void WebGLTextureAttachment::attach(WebGraphicsContext3D* context, GLenum attachment) |
+ void WebGLTextureAttachment::attach(WebGraphicsContext3D* context, GLenum target, GLenum attachment) |
{ |
Platform3DObject object = objectOrZero(m_texture.get()); |
- context->framebufferTexture2D(GL_FRAMEBUFFER, attachment, m_target, object, m_level); |
+ context->framebufferTexture2D(target, attachment, m_target, object, m_level); |
} |
- void WebGLTextureAttachment::unattach(WebGraphicsContext3D* context, GLenum attachment) |
+ void WebGLTextureAttachment::unattach(WebGraphicsContext3D* context, GLenum target, GLenum attachment) |
{ |
if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL) { |
- context->framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_target, 0, m_level); |
- context->framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, m_target, 0, m_level); |
+ context->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, m_target, 0, m_level); |
+ context->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, m_target, 0, m_level); |
} else { |
- context->framebufferTexture2D(GL_FRAMEBUFFER, attachment, m_target, 0, m_level); |
+ context->framebufferTexture2D(target, attachment, m_target, 0, m_level); |
} |
} |
@@ -292,45 +292,51 @@ WebGLFramebuffer::~WebGLFramebuffer() |
detachAndDeleteObject(); |
} |
-void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GLenum attachment, GLenum texTarget, WebGLTexture* texture, GLint level) |
+void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GLenum target, GLenum attachment, GLenum texTarget, WebGLTexture* texture, GLint level) |
{ |
ASSERT(isBound()); |
- removeAttachmentFromBoundFramebuffer(attachment); |
+ removeAttachmentFromBoundFramebuffer(attachment, target); |
if (!m_object) |
return; |
if (texture && texture->object()) { |
- m_attachments.add(attachment, WebGLTextureAttachment::create(texture, texTarget, level)); |
+ if (target == GL_READ_FRAMEBUFFER) |
+ m_attachmentsForReadFramebuffer.add(attachment, WebGLTextureAttachment::create(texture, texTarget, level)); |
+ else |
+ m_attachments.add(attachment, WebGLTextureAttachment::create(texture, texTarget, level)); |
drawBuffersIfNecessary(false); |
texture->onAttached(); |
} |
} |
-void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GLenum attachment, WebGLRenderbuffer* renderbuffer) |
+void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GLenum target, GLenum attachment, WebGLRenderbuffer* renderbuffer) |
{ |
ASSERT(isBound()); |
- removeAttachmentFromBoundFramebuffer(attachment); |
+ removeAttachmentFromBoundFramebuffer(attachment, target); |
if (!m_object) |
return; |
if (renderbuffer && renderbuffer->object()) { |
- m_attachments.add(attachment, WebGLRenderbufferAttachment::create(renderbuffer)); |
+ if (target == GL_READ_FRAMEBUFFER) |
+ m_attachmentsForReadFramebuffer.add(attachment, WebGLRenderbufferAttachment::create(renderbuffer)); |
+ else |
+ m_attachments.add(attachment, WebGLRenderbufferAttachment::create(renderbuffer)); |
drawBuffersIfNecessary(false); |
renderbuffer->onAttached(); |
} |
} |
-void WebGLFramebuffer::attach(GLenum attachment, GLenum attachmentPoint) |
+void WebGLFramebuffer::attach(GLenum target, GLenum attachment, GLenum attachmentPoint) |
{ |
ASSERT(isBound()); |
- WebGLAttachment* attachmentObject = getAttachment(attachment); |
+ WebGLAttachment* attachmentObject = getAttachment(target, attachment); |
if (attachmentObject) |
- attachmentObject->attach(context()->webContext(), attachmentPoint); |
+ attachmentObject->attach(context()->webContext(), target, attachmentPoint); |
} |
WebGLSharedObject* WebGLFramebuffer::getAttachmentObject(GLenum attachment) const |
{ |
if (!m_object) |
return nullptr; |
- WebGLAttachment* attachmentObject = getAttachment(attachment); |
+ WebGLAttachment* attachmentObject = getAttachment(GL_FRAMEBUFFER, attachment); |
return attachmentObject ? attachmentObject->object() : nullptr; |
} |
@@ -421,39 +427,46 @@ bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GLe |
return true; |
} |
-WebGLFramebuffer::WebGLAttachment* WebGLFramebuffer::getAttachment(GLenum attachment) const |
+WebGLFramebuffer::WebGLAttachment* WebGLFramebuffer::getAttachment(GLenum target, GLenum attachment) const |
{ |
+ if (target == GL_READ_FRAMEBUFFER) { |
+ const AttachmentMap::const_iterator it = m_attachmentsForReadFramebuffer.find(attachment); |
+ return (it != m_attachmentsForReadFramebuffer.end()) ? it->value.get() : 0; |
+ } |
const AttachmentMap::const_iterator it = m_attachments.find(attachment); |
return (it != m_attachments.end()) ? it->value.get() : 0; |
} |
-void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GLenum attachment) |
+void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GLenum attachment, GLenum target) |
{ |
ASSERT(isBound()); |
if (!m_object) |
return; |
- WebGLAttachment* attachmentObject = getAttachment(attachment); |
+ WebGLAttachment* attachmentObject = getAttachment(target, attachment); |
if (attachmentObject) { |
attachmentObject->onDetached(context()->webContext()); |
- m_attachments.remove(attachment); |
+ if (target == GL_READ_FRAMEBUFFER) |
+ m_attachmentsForReadFramebuffer.remove(attachment); |
+ else |
+ m_attachments.remove(attachment); |
drawBuffersIfNecessary(false); |
switch (attachment) { |
case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL: |
- attach(GL_DEPTH_ATTACHMENT, GL_DEPTH_ATTACHMENT); |
- attach(GL_STENCIL_ATTACHMENT, GL_STENCIL_ATTACHMENT); |
+ attach(target, GL_DEPTH_ATTACHMENT, GL_DEPTH_ATTACHMENT); |
+ attach(target, GL_STENCIL_ATTACHMENT, GL_STENCIL_ATTACHMENT); |
break; |
case GL_DEPTH_ATTACHMENT: |
- attach(GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL, GL_DEPTH_ATTACHMENT); |
+ attach(target, GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL, GL_DEPTH_ATTACHMENT); |
break; |
case GL_STENCIL_ATTACHMENT: |
- attach(GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL, GL_STENCIL_ATTACHMENT); |
+ attach(target, GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL, GL_STENCIL_ATTACHMENT); |
break; |
} |
} |
} |
-void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* attachment) |
+void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* attachment, GLenum target) |
{ |
ASSERT(isBound()); |
if (!m_object) |
@@ -464,12 +477,12 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* a |
bool checkMore = true; |
while (checkMore) { |
checkMore = false; |
- for (const auto& it : m_attachments) { |
+ for (const auto& it : (target == GL_READ_FRAMEBUFFER ? m_attachmentsForReadFramebuffer : m_attachments)) { |
WebGLAttachment* attachmentObject = it.value.get(); |
if (attachmentObject->isSharedObject(attachment)) { |
GLenum attachmentType = it.key; |
- attachmentObject->unattach(context()->webContext(), attachmentType); |
- removeAttachmentFromBoundFramebuffer(attachmentType); |
+ attachmentObject->unattach(context()->webContext(), target, attachmentType); |
+ removeAttachmentFromBoundFramebuffer(attachmentType, target); |
checkMore = true; |
break; |
} |
@@ -481,20 +494,20 @@ GLenum WebGLFramebuffer::colorBufferFormat() const |
{ |
if (!m_object) |
return 0; |
- WebGLAttachment* attachment = getAttachment(GL_COLOR_ATTACHMENT0); |
+ WebGLAttachment* attachment = getAttachment(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0); |
if (!attachment) |
return 0; |
return attachment->format(); |
} |
-GLenum WebGLFramebuffer::checkStatus(const char** reason) const |
+GLenum WebGLFramebuffer::checkStatus(const char** reason, GLenum target) const |
{ |
unsigned count = 0; |
GLsizei width = 0, height = 0; |
bool haveDepth = false; |
bool haveStencil = false; |
bool haveDepthStencil = false; |
- for (const auto& it : m_attachments) { |
+ for (const auto& it : (target == GL_READ_FRAMEBUFFER ? m_attachmentsForReadFramebuffer : m_attachments)) { |
WebGLAttachment* attachment = it.value.get(); |
if (!isAttachmentComplete(attachment, it.key, reason)) |
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; |
@@ -544,18 +557,18 @@ GLenum WebGLFramebuffer::checkStatus(const char** reason) const |
return GL_FRAMEBUFFER_COMPLETE; |
} |
-bool WebGLFramebuffer::onAccess(WebGraphicsContext3D* context3d, const char** reason) |
+bool WebGLFramebuffer::onAccess(WebGraphicsContext3D* context3d, GLenum target, const char** reason) |
{ |
- if (checkStatus(reason) != GL_FRAMEBUFFER_COMPLETE) |
+ if (checkStatus(reason, target) != GL_FRAMEBUFFER_COMPLETE) |
return false; |
return true; |
} |
bool WebGLFramebuffer::hasStencilBuffer() const |
{ |
- WebGLAttachment* attachment = getAttachment(GL_STENCIL_ATTACHMENT); |
+ WebGLAttachment* attachment = getAttachment(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT); |
if (!attachment) |
- attachment = getAttachment(GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL); |
+ attachment = getAttachment(GL_FRAMEBUFFER, GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL); |
return attachment && attachment->valid(); |
} |
@@ -571,6 +584,8 @@ void WebGLFramebuffer::deleteObjectImpl(WebGraphicsContext3D* context3d) |
// not needed. |
for (const auto& attachment : m_attachments) |
attachment.value->onDetached(context3d); |
+ for (const auto& attachment : m_attachmentsForReadFramebuffer) |
+ attachment.value->onDetached(context3d); |
#endif |
context3d->deleteFramebuffer(m_object); |
@@ -598,7 +613,7 @@ void WebGLFramebuffer::drawBuffersIfNecessary(bool force) |
bool reset = force; |
// This filtering works around graphics driver bugs on Mac OS X. |
for (size_t i = 0; i < m_drawBuffers.size(); ++i) { |
- if (m_drawBuffers[i] != GL_NONE && getAttachment(m_drawBuffers[i])) { |
+ if (m_drawBuffers[i] != GL_NONE && getAttachment(GL_FRAMEBUFFER, m_drawBuffers[i])) { |
if (m_filteredDrawBuffers[i] != m_drawBuffers[i]) { |
m_filteredDrawBuffers[i] = m_drawBuffers[i]; |
reset = true; |
@@ -631,6 +646,7 @@ DEFINE_TRACE(WebGLFramebuffer) |
{ |
#if ENABLE(OILPAN) |
visitor->trace(m_attachments); |
+ visitor->trace(m_attachmentsForReadFramebuffer); |
#endif |
WebGLContextObject::trace(visitor); |
} |