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 4d54739da5538081fa7d797233eeac0e9431ae54..dec594bace509fa92307fb3482b5b04ca16f56cd 100644 |
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
@@ -41,6 +41,7 @@ |
#include "gpu/command_buffer/service/feature_info.h" |
#include "gpu/command_buffer/service/framebuffer_manager.h" |
#include "gpu/command_buffer/service/gl_utils.h" |
+#include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h" |
#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" |
#include "gpu/command_buffer/service/gles2_cmd_validation.h" |
#include "gpu/command_buffer/service/gpu_state_tracer.h" |
@@ -1840,6 +1841,7 @@ class GLES2DecoderImpl : public GLES2Decoder, |
#endif |
scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_; |
+ scoped_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_; |
// Cached values of the currently assigned viewport dimensions. |
GLsizei viewport_max_width_; |
@@ -2764,6 +2766,14 @@ bool GLES2DecoderImpl::Initialize( |
AsyncPixelTransferManager::Create(context.get())); |
async_pixel_transfer_manager_->Initialize(texture_manager()); |
+ if (workarounds().gl_clear_broken) { |
+ DCHECK(!clear_framebuffer_blit_.get()); |
+ LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit"); |
+ clear_framebuffer_blit_.reset(new ClearFramebufferResourceManager(this)); |
+ if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR) |
+ return false; |
+ } |
+ |
framebuffer_manager()->AddObserver(this); |
return true; |
@@ -3549,6 +3559,8 @@ void GLES2DecoderImpl::Destroy(bool have_context) { |
copy_texture_CHROMIUM_.reset(); |
} |
+ clear_framebuffer_blit_.reset(); |
+ |
if (state_.current_program.get()) { |
program_manager()->UnuseProgram(shader_manager(), |
state_.current_program.get()); |
@@ -3614,6 +3626,7 @@ void GLES2DecoderImpl::Destroy(bool have_context) { |
state_.current_program = NULL; |
copy_texture_CHROMIUM_.reset(); |
+ clear_framebuffer_blit_.reset(); |
if (query_manager_.get()) { |
query_manager_->Destroy(have_context); |
@@ -5106,6 +5119,19 @@ error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) { |
if (CheckBoundFramebuffersValid("glClear")) { |
ApplyDirtyState(); |
ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get()); |
+ if (workarounds().gl_clear_broken) { |
+ ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround", |
+ GetErrorState()); |
+ if (!BoundFramebufferHasDepthAttachment()) |
+ mask &= ~GL_DEPTH_BUFFER_BIT; |
+ if (!BoundFramebufferHasStencilAttachment()) |
+ mask &= ~GL_STENCIL_BUFFER_BIT; |
+ clear_framebuffer_blit_->ClearFramebuffer( |
+ this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red, |
+ state_.color_clear_green, state_.color_clear_blue, |
+ state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear); |
+ return error::kNoError; |
+ } |
glClear(mask); |
} |
return error::kNoError; |
@@ -7578,6 +7604,11 @@ void GLES2DecoderImpl::FinishReadPixels( |
} else { |
data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); |
} |
+ if (!data) { |
+ LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer", |
+ "Unable to map memory for readback."); |
+ return; |
+ } |
memcpy(pixels, data, pixels_size); |
// GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't |
// have to restore the state. |
@@ -7779,7 +7810,10 @@ error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size, |
GLuint buffer = 0; |
glGenBuffersARB(1, &buffer); |
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer); |
- glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ); |
+ // For ANGLE client version 2, GL_STREAM_READ is not available. |
+ const GLenum usage_hint = |
+ features().is_angle ? GL_STATIC_DRAW : GL_STREAM_READ; |
+ glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint); |
GLenum error = glGetError(); |
if (error == GL_NO_ERROR) { |
glReadPixels(x, y, width, height, format, type, 0); |