Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(978)

Unified Diff: gpu/command_buffer/service/gles2_cmd_decoder.cc

Issue 2496813002: [Command buffer] workaround the framebuffer completeness bug for Intel Mac (Closed)
Patch Set: Reset (not restore) read buffer and/or draw buffers for all read/draw related APIs Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 6f0d2e8db079242a81d3e81a1c5dcb2d04f1e9c2..8ea561fe86e2061e93f6e19274d8383bb12f219b 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1431,6 +1431,14 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
void DoBufferSubData(
GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
+ // A workaround to adjust read buffer and draw buffers to GL_NONE
+ // if the specified read buffer or draw buffers have no image attached.
Zhenyao Mo 2016/11/14 19:42:24 have missing images.
yunchao 2016/11/15 16:21:59 Done.
+ // Return false if read buffer has no image or all of the draw buffers
+ // have no image. Then we can generate INVALID_OPERATION or return directly
+ // in the callers accordingly.
+ bool AdjustColorBufferAttachmentsIfNecessary(
+ bool read, bool draw);
+
// Wrapper for glCheckFramebufferStatus
GLenum DoCheckFramebufferStatus(GLenum target);
@@ -7213,6 +7221,13 @@ error::Error GLES2DecoderImpl::HandleDeleteProgram(
error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
const char* func_name = "glClear";
DCHECK(!ShouldDeferDraws());
+ if (mask & GL_COLOR_BUFFER_BIT &&
Zhenyao Mo 2016/11/14 19:42:24 (mask & GL_COLOR_BUFFER_BIT) != 0
yunchao 2016/11/15 16:21:59 Done.
+ workarounds().adjust_framebuffer_complete_status &&
+ SupportsDrawBuffers() &&
+ framebuffer_state_.clear_state_dirty) {
+ if (!AdjustColorBufferAttachmentsIfNecessary(false, true))
+ return error::kNoError;
+ }
if (CheckBoundDrawFramebufferValid(func_name)) {
ApplyDirtyState();
if (workarounds().gl_clear_broken) {
@@ -7532,6 +7547,39 @@ void GLES2DecoderImpl::RestoreClearState() {
state_.scissor_height);
}
+bool GLES2DecoderImpl::AdjustColorBufferAttachmentsIfNecessary(
+ bool read, bool draw) {
+ DCHECK(workarounds().adjust_framebuffer_complete_status &&
+ SupportsDrawBuffers() &&
+ framebuffer_state_.clear_state_dirty);
+ if (read) {
+ const Framebuffer* framebuffer =
+ GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER);
+ if (framebuffer &&
+ framebuffer->ReadBufferHasNoImage() &&
+ framebuffer->ColorBuffersHaveImage()) {
+ glReadBuffer(GL_NONE);
+ return false;
+ }
+ } else {
+ GLsizei num = 0;
+ GLenum buf[8];
+ for (int i = 0; i < 8; ++i)
+ buf[i] = GL_NONE;
+ const Framebuffer* framebuffer =
+ GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER);
+ if (framebuffer &&
+ framebuffer->DrawBuffersHaveNoImage(num, buf) &&
+ framebuffer->ColorBuffersHaveImage()) {
+ glDrawBuffersARB(8, buf);
+ }
+ if (num == 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
Framebuffer* framebuffer =
GetFramebufferInfoForTarget(target);
@@ -7542,6 +7590,21 @@ GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
if (completeness != GL_FRAMEBUFFER_COMPLETE) {
return completeness;
}
+
+ bool has_image = true;
+ if (workarounds().adjust_framebuffer_complete_status &&
+ SupportsDrawBuffers() &&
+ framebuffer_state_.clear_state_dirty) {
+ if (target == GL_READ_FRAMEBUFFER) {
+ has_image = AdjustColorBufferAttachmentsIfNecessary(true, false);
+ } else {
+ has_image = AdjustColorBufferAttachmentsIfNecessary(false, true);
+ }
+ if (!has_image) {
+ return GL_FRAMEBUFFER_COMPLETE;
+ }
+ }
+
return framebuffer->GetStatus(texture_manager(), target);
}
@@ -7832,6 +7895,19 @@ void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
const char* func_name = "glBlitFramebufferCHROMIUM";
DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
+ if (workarounds().adjust_framebuffer_complete_status &&
+ (mask & GL_COLOR_BUFFER_BIT) != 0 &&
+ SupportsDrawBuffers() &&
+ framebuffer_state_.clear_state_dirty) {
+ if (!AdjustColorBufferAttachmentsIfNecessary(false, true)) {
+ return;
+ }
+ if (!AdjustColorBufferAttachmentsIfNecessary(true, false)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
+ "no valid color image");
+ return;
+ }
+ }
if (!CheckBoundFramebufferValid(func_name)) {
return;
}
@@ -9806,6 +9882,13 @@ error::Error GLES2DecoderImpl::DoDrawArrays(
LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
return error::kNoError;
}
+ if (workarounds().adjust_framebuffer_complete_status &&
+ SupportsDrawBuffers() &&
+ framebuffer_state_.clear_state_dirty) {
+ if (!AdjustColorBufferAttachmentsIfNecessary(false, true)) {
+ return error::kNoError;
+ }
+ }
if (!CheckBoundDrawFramebufferValid(function_name)) {
Zhenyao Mo 2016/11/14 19:42:24 All this same code is right above CheckBoundDrawFr
yunchao 2016/11/15 16:21:59 Done. It is a little different in Clear and Clea
return error::kNoError;
}
@@ -9970,6 +10053,13 @@ error::Error GLES2DecoderImpl::DoDrawElements(const char* function_name,
return error::kNoError;
}
+ if (workarounds().adjust_framebuffer_complete_status &&
+ SupportsDrawBuffers() &&
+ framebuffer_state_.clear_state_dirty) {
+ if (!AdjustColorBufferAttachmentsIfNecessary(false, true)) {
+ return error::kNoError;
+ }
+ }
if (!CheckBoundDrawFramebufferValid(function_name)) {
return error::kNoError;
}
@@ -11195,6 +11285,16 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32_t immediate_data_size,
return error::kNoError;
}
+ if (workarounds().adjust_framebuffer_complete_status &&
+ SupportsDrawBuffers() &&
+ framebuffer_state_.clear_state_dirty) {
+ if (!AdjustColorBufferAttachmentsIfNecessary(true, false)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
+ "no valid color image");
+ return error::kNoError;
+ }
+ }
+
if (!CheckBoundReadFramebufferValid(
func_name, GL_INVALID_FRAMEBUFFER_OPERATION)) {
return error::kNoError;
@@ -13828,6 +13928,16 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
return;
}
+ if (workarounds().adjust_framebuffer_complete_status &&
+ SupportsDrawBuffers() &&
+ framebuffer_state_.clear_state_dirty) {
+ if (!AdjustColorBufferAttachmentsIfNecessary(true, false)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
+ "no valid color image");
+ return;
+ }
+ }
+
if (!CheckBoundReadFramebufferValid(func_name,
GL_INVALID_FRAMEBUFFER_OPERATION)) {
return;
@@ -14075,6 +14185,15 @@ void GLES2DecoderImpl::DoCopyTexSubImage2D(
return;
}
+ if (workarounds().adjust_framebuffer_complete_status &&
+ SupportsDrawBuffers() &&
+ framebuffer_state_.clear_state_dirty) {
+ if (!AdjustColorBufferAttachmentsIfNecessary(true, false)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
+ "no valid color image");
+ return;
+ }
+ }
if (!CheckBoundReadFramebufferValid(func_name,
GL_INVALID_FRAMEBUFFER_OPERATION)) {
return;
@@ -14191,6 +14310,15 @@ void GLES2DecoderImpl::DoCopyTexSubImage3D(
return;
}
+ if (workarounds().adjust_framebuffer_complete_status &&
+ SupportsDrawBuffers() &&
+ framebuffer_state_.clear_state_dirty) {
+ if (!AdjustColorBufferAttachmentsIfNecessary(true, false)) {
+ LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, func_name,
+ "no valid color image");
+ return;
+ }
+ }
if (!CheckBoundReadFramebufferValid(func_name,
GL_INVALID_FRAMEBUFFER_OPERATION)) {
return;

Powered by Google App Engine
This is Rietveld 408576698