| 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 46620828f85d7d7c261a207988eae4ecfe5f2ea0..c77b2ef547f60a506bb3fdd6ac1c9677198d3d28 100644
|
| --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
|
| @@ -861,6 +861,12 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
|
| // Return 0 if no stencil attachment.
|
| GLenum GetBoundFramebufferStencilFormat(GLenum target);
|
|
|
| + gfx::Vector2d GetBoundFramebufferDrawOffset() const {
|
| + if (GetBoundDrawFramebuffer() || offscreen_target_frame_buffer_.get())
|
| + return gfx::Vector2d();
|
| + return surface_->GetDrawOffset();
|
| + }
|
| +
|
| void MarkDrawBufferAsCleared(GLenum buffer, GLint drawbuffer_i);
|
|
|
| // Wrapper for CompressedTexImage{2|3}D commands.
|
| @@ -1862,6 +1868,9 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
|
| // Wrapper for glViewport
|
| void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
|
|
|
| + // Wrapper for glScissor
|
| + void DoScissor(GLint x, GLint y, GLsizei width, GLsizei height);
|
| +
|
| // Wrapper for glUseProgram
|
| void DoUseProgram(GLuint program);
|
|
|
| @@ -5646,13 +5655,23 @@ void GLES2DecoderImpl::OnUseFramebuffer() const {
|
| return;
|
| state_.fbo_binding_for_scissor_workaround_dirty = false;
|
|
|
| - if (workarounds().restore_scissor_on_fbo_change) {
|
| + if (supports_set_draw_rectangle_) {
|
| + gfx::Vector2d draw_offset = GetBoundFramebufferDrawOffset();
|
| + glViewport(state_.viewport_x + draw_offset.x(),
|
| + state_.viewport_y + draw_offset.y(), state_.viewport_width,
|
| + state_.viewport_height);
|
| + }
|
| +
|
| + if (workarounds().restore_scissor_on_fbo_change ||
|
| + supports_set_draw_rectangle_) {
|
| // The driver forgets the correct scissor when modifying the FBO binding.
|
| - glScissor(state_.scissor_x,
|
| - state_.scissor_y,
|
| - state_.scissor_width,
|
| + gfx::Vector2d scissor_offset = GetBoundFramebufferDrawOffset();
|
| + glScissor(state_.scissor_x + scissor_offset.x(),
|
| + state_.scissor_y + scissor_offset.y(), state_.scissor_width,
|
| state_.scissor_height);
|
| + }
|
|
|
| + if (workarounds().restore_scissor_on_fbo_change) {
|
| // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
|
| // it's unclear how this bug works.
|
| glFlush();
|
| @@ -7655,7 +7674,9 @@ void GLES2DecoderImpl::RestoreClearState() {
|
| glClearDepth(state_.depth_clear);
|
| state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
|
| state_.enable_flags.scissor_test);
|
| - glScissor(state_.scissor_x, state_.scissor_y, state_.scissor_width,
|
| + gfx::Vector2d scissor_offset = GetBoundFramebufferDrawOffset();
|
| + glScissor(state_.scissor_x + scissor_offset.x(),
|
| + state_.scissor_y + scissor_offset.y(), state_.scissor_width,
|
| state_.scissor_height);
|
| }
|
|
|
| @@ -8718,6 +8739,7 @@ void GLES2DecoderImpl::DoSetDrawRectangleCHROMIUM(GLint x,
|
| LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSetDrawRectangleCHROMIUM",
|
| "failed on surface");
|
| }
|
| + OnFboChanged();
|
| }
|
|
|
| void GLES2DecoderImpl::DoReadBuffer(GLenum src) {
|
| @@ -11172,7 +11194,16 @@ void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
|
| state_.viewport_y = y;
|
| state_.viewport_width = std::min(width, viewport_max_width_);
|
| state_.viewport_height = std::min(height, viewport_max_height_);
|
| - glViewport(x, y, width, height);
|
| + gfx::Vector2d viewport_offset = GetBoundFramebufferDrawOffset();
|
| + glViewport(x + viewport_offset.x(), y + viewport_offset.y(), width, height);
|
| +}
|
| +
|
| +void GLES2DecoderImpl::DoScissor(GLint x,
|
| + GLint y,
|
| + GLsizei width,
|
| + GLsizei height) {
|
| + gfx::Vector2d draw_offset = GetBoundFramebufferDrawOffset();
|
| + glScissor(x + draw_offset.x(), y + draw_offset.y(), width, height);
|
| }
|
|
|
| error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
|
| @@ -12461,7 +12492,9 @@ bool GLES2DecoderImpl::ClearLevel(Texture* texture,
|
| glClearDepth(1.0f);
|
| state_.SetDeviceDepthMask(GL_TRUE);
|
| state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
|
| - glScissor(xoffset, yoffset, width, height);
|
| + gfx::Vector2d scissor_offset = GetBoundFramebufferDrawOffset();
|
| + glScissor(xoffset + scissor_offset.x(), yoffset + scissor_offset.y(), width,
|
| + height);
|
| glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
|
|
|
| RestoreClearState();
|
|
|