diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc index 9d0d0e3780442..a9f881925a627 100644 --- a/gpu/command_buffer/service/framebuffer_manager.cc +++ b/gpu/command_buffer/service/framebuffer_manager.cc @@ -456,6 +456,33 @@ bool Framebuffer::HasUnclearedIntRenderbufferAttachments() const { void Framebuffer::ClearUnclearedIntRenderbufferAttachments( RenderbufferManager* renderbuffer_manager) { + // glClearBuffer*iv(GL_COLOR, i, ...) targets DRAW_BUFFERi, not + // COLOR_ATTACHMENTi (ES3 4.2.3): when DRAW_BUFFERi == GL_NONE the clear is a + // silent no-op. Point each draw buffer at its attachment before clearing so + // the clear actually lands, then restore the page-visible state. + base::HeapArray buffers = + base::HeapArray::Uninit(manager_->max_draw_buffers_); + for (uint32_t i = 0; i < manager_->max_draw_buffers_; ++i) { + buffers[i] = GL_NONE; + } + bool need_clear = false; + for (auto const& it : attachments_) { + if (!it.second->IsRenderbufferAttachment() || it.second->cleared() || + !GLES2Util::IsIntegerFormat(it.second->internal_format())) { + continue; + } + if (it.first < GL_COLOR_ATTACHMENT0 || + it.first >= GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_) { + continue; + } + buffers[it.first - GL_COLOR_ATTACHMENT0] = it.first; + need_clear = true; + } + if (!need_clear) { + return; + } + glDrawBuffersARB(manager_->max_draw_buffers_, buffers.data()); + for (AttachmentMap::const_iterator it = attachments_.begin(); it != attachments_.end(); ++it) { if (!it->second->IsRenderbufferAttachment() || it->second->cleared()) @@ -464,8 +491,11 @@ void Framebuffer::ClearUnclearedIntRenderbufferAttachments( if (GLES2Util::IsIntegerFormat(internal_format)) { GLenum attaching_point = it->first; DCHECK_LE(static_cast(GL_COLOR_ATTACHMENT0), attaching_point); - DCHECK_GT(GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_, - attaching_point); + if (attaching_point >= + GL_COLOR_ATTACHMENT0 + manager_->max_draw_buffers_) { + // Can't be addressed via glClearBuffer*iv; leave it marked uncleared. + continue; + } GLint drawbuffer = it->first - GL_COLOR_ATTACHMENT0; if (GLES2Util::IsUnsignedIntegerFormat(internal_format)) { const GLuint kZero[] = { 0u, 0u, 0u, 0u }; @@ -478,6 +508,8 @@ void Framebuffer::ClearUnclearedIntRenderbufferAttachments( it->second->SetCleared(renderbuffer_manager, nullptr, true); } } + + RestoreDrawBuffers(); } bool Framebuffer::HasSRGBAttachments() const {