Chromium Code Reviews| 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 6df7f6a2f816a89bb6e37149101e0a60c27a2da4..4cd857284501e286f8e3163af635b3ffd860e9da 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -5662,6 +5662,18 @@ 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( |
|
qiankun
2016/07/18 04:50:09
4 space indent.
|
| + 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; |
| @@ -5677,6 +5689,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( |
| @@ -5684,14 +5706,19 @@ void GLES2DecoderImpl::InvalidateFramebufferImpl( |
| return; |
| } |
| } |
| + validated_attachments[validated_count++] = attachments[i]; |
| + } |
| + if (invalidate_depth && invalidate_stencil) { |
| + validated_attachments[validated_count++] = GL_DEPTH_STENCIL_ATTACHMENT; |
| } |
| + count = validated_count; |
| // 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]; |
| + GLenum attachment = validated_attachments[i]; |
| if (!framebuffer && GetBackbufferServiceId()) { |
| switch (attachment) { |
| case GL_COLOR_EXT: |
| @@ -5745,10 +5772,21 @@ void GLES2DecoderImpl::InvalidateFramebufferImpl( |
| // Marks each one of them as not cleared. |
| for (GLsizei i = 0; i < count; ++i) { |
| if (framebuffer) { |
| - framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(), |
| - texture_manager(), |
| - attachments[i], |
| - false); |
| + if (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(), |
| + attachments[i], |
| + false); |
| + } |
| } else { |
| switch (attachments[i]) { |
| case GL_COLOR_EXT: |