| Index: gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| index 03ce04134dc62c31df4633c1137cbb290af7591c..8cb4d402878232171f7a51edacfb7ea9f66a377c 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| @@ -5677,6 +5677,16 @@ void GLES2DecoderImpl::InvalidateFramebufferImpl(
|
| const char* function_name, FramebufferOperation op) {
|
| Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
|
|
|
| + // Because of performance issues, no-op if the format of the attachment is
|
| + // DEPTH_STENCIL and only one part is intended to be invalidated.
|
| + bool has_depth_stencil_format = framebuffer &&
|
| + framebuffer->HasDepthStencilFormatAttachment(GL_DEPTH_ATTACHMENT) &&
|
| + framebuffer->HasDepthStencilFormatAttachment(GL_STENCIL_ATTACHMENT);
|
| + bool invalidate_depth = false;
|
| + bool invalidate_stencil = false;
|
| + std::unique_ptr<GLenum[]> validated_attachments(new GLenum[count]);
|
| + GLsizei validated_count = 0;
|
| +
|
| // Validates the attachments. If one of them fails, the whole command fails.
|
| GLenum thresh0 = GL_COLOR_ATTACHMENT0 + group_->max_color_attachments();
|
| GLenum thresh1 = GL_COLOR_ATTACHMENT15;
|
| @@ -5692,6 +5702,16 @@ void GLES2DecoderImpl::InvalidateFramebufferImpl(
|
| function_name, attachments[i], "attachments");
|
| return;
|
| }
|
| + if (has_depth_stencil_format) {
|
| + switch(attachments[i]) {
|
| + case GL_DEPTH_ATTACHMENT:
|
| + invalidate_depth = true;
|
| + continue;
|
| + case GL_STENCIL_ATTACHMENT:
|
| + invalidate_stencil = true;
|
| + continue;
|
| + }
|
| + }
|
| } else {
|
| if (!validators_->backbuffer_attachment.IsValid(attachments[i])) {
|
| LOCAL_SET_GL_ERROR_INVALID_ENUM(
|
| @@ -5699,14 +5719,18 @@ void GLES2DecoderImpl::InvalidateFramebufferImpl(
|
| return;
|
| }
|
| }
|
| + validated_attachments[validated_count++] = attachments[i];
|
| + }
|
| + if (invalidate_depth && invalidate_stencil) {
|
| + validated_attachments[validated_count++] = GL_DEPTH_STENCIL_ATTACHMENT;
|
| }
|
|
|
| // If the default framebuffer is bound but we are still rendering to an
|
| // FBO, translate attachment names that refer to default framebuffer
|
| // channels to corresponding framebuffer attachments.
|
| - std::unique_ptr<GLenum[]> translated_attachments(new GLenum[count]);
|
| - for (GLsizei i = 0; i < count; ++i) {
|
| - GLenum attachment = attachments[i];
|
| + std::unique_ptr<GLenum[]> translated_attachments(new GLenum[validated_count]);
|
| + for (GLsizei i = 0; i < validated_count; ++i) {
|
| + GLenum attachment = validated_attachments[i];
|
| if (!framebuffer && GetBackbufferServiceId()) {
|
| switch (attachment) {
|
| case GL_COLOR_EXT:
|
| @@ -5731,10 +5755,10 @@ void GLES2DecoderImpl::InvalidateFramebufferImpl(
|
| case kFramebufferDiscard:
|
| if (feature_info_->gl_version_info().is_es3) {
|
| glInvalidateFramebuffer(
|
| - target, count, translated_attachments.get());
|
| + target, validated_count, translated_attachments.get());
|
| } else {
|
| glDiscardFramebufferEXT(
|
| - target, count, translated_attachments.get());
|
| + target, validated_count, translated_attachments.get());
|
| }
|
| dirty = true;
|
| break;
|
| @@ -5743,7 +5767,7 @@ void GLES2DecoderImpl::InvalidateFramebufferImpl(
|
| // no-op since the function isn't supported.
|
| } else {
|
| glInvalidateFramebuffer(
|
| - target, count, translated_attachments.get());
|
| + target, validated_count, translated_attachments.get());
|
| dirty = true;
|
| }
|
| break;
|
| @@ -5758,14 +5782,25 @@ void GLES2DecoderImpl::InvalidateFramebufferImpl(
|
| return;
|
|
|
| // Marks each one of them as not cleared.
|
| - for (GLsizei i = 0; i < count; ++i) {
|
| + for (GLsizei i = 0; i < validated_count; ++i) {
|
| if (framebuffer) {
|
| - framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
|
| - texture_manager(),
|
| - attachments[i],
|
| - false);
|
| + if (validated_attachments[i] == GL_DEPTH_STENCIL_ATTACHMENT) {
|
| + framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
|
| + texture_manager(),
|
| + GL_DEPTH_ATTACHMENT,
|
| + false);
|
| + framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
|
| + texture_manager(),
|
| + GL_STENCIL_ATTACHMENT,
|
| + false);
|
| + } else {
|
| + framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
|
| + texture_manager(),
|
| + validated_attachments[i],
|
| + false);
|
| + }
|
| } else {
|
| - switch (attachments[i]) {
|
| + switch (validated_attachments[i]) {
|
| case GL_COLOR_EXT:
|
| backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
|
| break;
|
|
|