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: |