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 20c4da8efce5dea9ded6e230dde087e69c9cf0b9..dbfbccf47229b6f4508658c548133146efa14a4c 100644 |
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
| @@ -1202,6 +1202,11 @@ class GLES2DecoderImpl : public GLES2Decoder, |
| // location is not -1. |
| bool CheckCurrentProgramForUniform(GLint location, const char* function_name); |
| + // Checks if the current program samples a texture that is also the color |
| + // image of the current bound framebuffer, i.e., the source and destination |
| + // of the draw operation are the same. |
| + bool CheckDrawingFeedbackLoops(); |
| + |
| // Gets the type of a uniform for a location in the current program. Sets GL |
| // errors if the current program is not valid. Returns true if the current |
| // program is valid and the location exists. Adjusts count so it |
| @@ -5755,6 +5760,38 @@ bool GLES2DecoderImpl::CheckCurrentProgramForUniform( |
| return location != -1; |
| } |
| +bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() { |
|
Ken Russell (switch to Gerrit)
2014/10/16 21:08:30
Have you checked any benchmarks -- e.g. http://web
|
| + Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER); |
| + if (!framebuffer) |
| + return false; |
| + const Framebuffer::Attachment* attachment = |
| + framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0); |
| + if (!attachment) |
| + return false; |
| + |
| + DCHECK(state_.current_program.get()); |
| + const Program::SamplerIndices& sampler_indices = |
| + state_.current_program->sampler_indices(); |
| + for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { |
| + const Program::UniformInfo* uniform_info = |
| + state_.current_program->GetUniformInfo(sampler_indices[ii]); |
| + DCHECK(uniform_info); |
| + if (uniform_info->type != GL_SAMPLER_2D) |
| + continue; |
| + for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { |
| + GLuint texture_unit_index = uniform_info->texture_units[jj]; |
| + if (texture_unit_index >= state_.texture_units.size()) |
| + continue; |
| + TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; |
| + TextureRef* texture_ref = |
| + texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get(); |
| + if (attachment->IsTexture(texture_ref)) |
| + return true; |
| + } |
| + } |
| + return false; |
| +} |
| + |
| bool GLES2DecoderImpl::PrepForSetUniformByLocation( |
| GLint fake_location, |
| const char* function_name, |
| @@ -6251,6 +6288,13 @@ bool GLES2DecoderImpl::IsDrawValid( |
| return false; |
| } |
| + if (CheckDrawingFeedbackLoops()) { |
| + LOCAL_SET_GL_ERROR( |
| + GL_INVALID_OPERATION, function_name, |
| + "Source and destination textures of the draw are the same."); |
| + return false; |
| + } |
| + |
| return state_.vertex_attrib_manager |
| ->ValidateBindings(function_name, |
| this, |