Generate INVALID_OPERATION if feedback loops exist in CopyTex{Sub}Image2D.
BUG=421695
TEST=gpu_unittests, webgl_conformance_tests
[email protected]
Review URL: https://codereview.chromium.org/656613002
Cr-Commit-Position: refs/heads/master@{#299399}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 96121755..20c4da8e 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1181,6 +1181,10 @@
// attached. Generates GL error if not.
bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
+ // Check that the currently bound read framebuffer's color image
+ // isn't the target texture of the glCopyTex{Sub}Image2D.
+ bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
+
// Check if a framebuffer meets our requirements.
bool CheckFramebufferValid(
Framebuffer* framebuffer,
@@ -3232,6 +3236,20 @@
return true;
}
+bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
+ TextureRef* texture, GLint level) {
+ Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
+ framebuffer_state_.bound_read_framebuffer.get() :
+ framebuffer_state_.bound_draw_framebuffer.get();
+ if (!framebuffer)
+ return false;
+ const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
+ GL_COLOR_ATTACHMENT0);
+ if (!attachment)
+ return false;
+ return attachment->FormsFeedbackLoop(texture, level);
+}
+
gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
Framebuffer* framebuffer =
GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
@@ -8601,6 +8619,13 @@
return;
}
+ if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_OPERATION,
+ "glCopyTexImage2D", "source and destination textures are the same");
+ return;
+ }
+
if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
return;
}
@@ -8719,6 +8744,13 @@
return;
}
+ if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_OPERATION,
+ "glCopyTexSubImage2D", "source and destination textures are the same");
+ return;
+ }
+
if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
return;
}