diff options
author | ericrk <ericrk@chromium.org> | 2015-03-21 00:48:11 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-21 07:48:54 +0000 |
commit | db214180d73e6516d8b2de4f87b8a1ae01bdd45f (patch) | |
tree | 28304a8c062a0819a5cbd77de066f0fd559e0582 | |
parent | c5056857280ce8822b0eaa0d761bab5d8a7967ff (diff) | |
download | chromium_src-db214180d73e6516d8b2de4f87b8a1ae01bdd45f.zip chromium_src-db214180d73e6516d8b2de4f87b8a1ae01bdd45f.tar.gz chromium_src-db214180d73e6516d8b2de4f87b8a1ae01bdd45f.tar.bz2 |
Refactor discard/clear behavior in DirectRenderer
This CL tries to simplify the logic around per-pass scissor set-up.
- For a given pass, we calculate the intersection of the viewport rect,
the clip rect and any scissor rect.
- We check whether this intersection contains the entire output surface
for the pass - if not, we consider the pass "clipped"
- If the pass is clipped we disable GL discard and restrict clear to
the clipped region. We also clip all quads to the clipped region
(as before).
- If the pass is not clipped, we perform a discard/clear and render
all quads as normal (no clipping).
This flow seems more straightforward, as we don't need to track as
many booleans/values and treat things more uniformly. It does result
in slightly different behavior which required a few unit test changes
(not pixel tests, but tests that expected certain patterns of
scissors/etc...):
- If we are using the scissor optimization, but the scissor rect
contains the entire output surface, we proceed as though we aren't
using the scissor optimization (previously we would apply
full-output-surface clips).
- If both device and scissor clips are applied, we use the intersection
of these to restrict clear (before we would just use the device clip).
- If the viewport does not contain the full output surface, the clear is
restricted to the viewport (before it would clear the entire surface).
BUG=468845
Review URL: https://codereview.chromium.org/1018423002
Cr-Commit-Position: refs/heads/master@{#321697}
-rw-r--r-- | cc/output/direct_renderer.cc | 170 | ||||
-rw-r--r-- | cc/output/direct_renderer.h | 31 | ||||
-rw-r--r-- | cc/output/gl_renderer.cc | 35 | ||||
-rw-r--r-- | cc/output/gl_renderer.h | 10 | ||||
-rw-r--r-- | cc/output/gl_renderer_unittest.cc | 34 | ||||
-rw-r--r-- | cc/output/software_renderer.cc | 29 | ||||
-rw-r--r-- | cc/output/software_renderer.h | 8 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl_unittest.cc | 4 |
8 files changed, 178 insertions, 143 deletions
diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc index 0ae4179..16034ea 100644 --- a/cc/output/direct_renderer.cc +++ b/cc/output/direct_renderer.cc @@ -278,27 +278,32 @@ bool DirectRenderer::NeedDeviceClip(const DrawingFrame* frame) const { return !frame->device_clip_rect.Contains(frame->device_viewport_rect); } -gfx::Rect DirectRenderer::DeviceClipRectInWindowSpace(const DrawingFrame* frame) - const { +gfx::Rect DirectRenderer::DeviceClipRectInDrawSpace( + const DrawingFrame* frame) const { gfx::Rect device_clip_rect = frame->device_clip_rect; - if (FlippedFramebuffer(frame)) - device_clip_rect.set_y(current_surface_size_.height() - - device_clip_rect.bottom()); + device_clip_rect -= current_viewport_rect_.OffsetFromOrigin(); + device_clip_rect += current_draw_rect_.OffsetFromOrigin(); return device_clip_rect; } -void DirectRenderer::SetScissorStateForQuad(const DrawingFrame* frame, - const DrawQuad& quad) { - if (quad.isClipped()) { - SetScissorTestRectInDrawSpace(frame, quad.clipRect()); - return; - } - if (NeedDeviceClip(frame)) { - SetScissorTestRect(DeviceClipRectInWindowSpace(frame)); - return; - } +gfx::Rect DirectRenderer::DeviceViewportRectInDrawSpace( + const DrawingFrame* frame) const { + gfx::Rect device_viewport_rect = frame->device_viewport_rect; + device_viewport_rect -= current_viewport_rect_.OffsetFromOrigin(); + device_viewport_rect += current_draw_rect_.OffsetFromOrigin(); + return device_viewport_rect; +} - EnsureScissorTestDisabled(); +gfx::Rect DirectRenderer::OutputSurfaceRectInDrawSpace( + const DrawingFrame* frame) const { + if (frame->current_render_pass == frame->root_render_pass) { + gfx::Rect output_surface_rect(output_surface_->SurfaceSize()); + output_surface_rect -= current_viewport_rect_.OffsetFromOrigin(); + output_surface_rect += current_draw_rect_.OffsetFromOrigin(); + return output_surface_rect; + } else { + return frame->current_render_pass->output_rect; + } } bool DirectRenderer::ShouldSkipQuad(const DrawQuad& quad, @@ -315,14 +320,23 @@ bool DirectRenderer::ShouldSkipQuad(const DrawQuad& quad, return false; } -void DirectRenderer::SetScissorStateForQuadWithRenderPassScissor( +void DirectRenderer::SetScissorStateForQuad( const DrawingFrame* frame, const DrawQuad& quad, - const gfx::Rect& render_pass_scissor) { - gfx::Rect quad_scissor_rect = render_pass_scissor; - if (quad.isClipped()) - quad_scissor_rect.Intersect(quad.clipRect()); - SetScissorTestRectInDrawSpace(frame, quad_scissor_rect); + const gfx::Rect& render_pass_scissor, + bool use_render_pass_scissor) { + if (use_render_pass_scissor) { + gfx::Rect quad_scissor_rect = render_pass_scissor; + if (quad.isClipped()) + quad_scissor_rect.Intersect(quad.clipRect()); + SetScissorTestRectInDrawSpace(frame, quad_scissor_rect); + return; + } else if (quad.isClipped()) { + SetScissorTestRectInDrawSpace(frame, quad.clipRect()); + return; + } + + EnsureScissorTestDisabled(); } void DirectRenderer::SetScissorTestRectInDrawSpace( @@ -330,8 +344,6 @@ void DirectRenderer::SetScissorTestRectInDrawSpace( const gfx::Rect& draw_space_rect) { gfx::Rect window_space_rect = MoveFromDrawToWindowSpace(frame, draw_space_rect); - if (NeedDeviceClip(frame)) - window_space_rect.Intersect(DeviceClipRectInWindowSpace(frame)); SetScissorTestRect(window_space_rect); } @@ -340,13 +352,9 @@ void DirectRenderer::FinishDrawingQuadList() {} void DirectRenderer::DoDrawPolygon(const DrawPolygon& poly, DrawingFrame* frame, const gfx::Rect& render_pass_scissor, - bool using_scissor_as_optimization) { - if (using_scissor_as_optimization) { - SetScissorStateForQuadWithRenderPassScissor(frame, *poly.original_ref(), - render_pass_scissor); - } else { - SetScissorStateForQuad(frame, *poly.original_ref()); - } + bool use_render_pass_scissor) { + SetScissorStateForQuad(frame, *poly.original_ref(), render_pass_scissor, + use_render_pass_scissor); // If the poly has not been split, then it is just a normal DrawQuad, // and we should save any extra processing that would have to be done. @@ -365,14 +373,14 @@ void DirectRenderer::DoDrawPolygon(const DrawPolygon& poly, void DirectRenderer::FlushPolygons(ScopedPtrDeque<DrawPolygon>* poly_list, DrawingFrame* frame, const gfx::Rect& render_pass_scissor, - bool using_scissor_as_optimization) { + bool use_render_pass_scissor) { if (poly_list->empty()) { return; } BspTree bsp_tree(poly_list); BspWalkActionDrawPolygon action_handler(this, frame, render_pass_scissor, - using_scissor_as_optimization); + use_render_pass_scissor); bsp_tree.TraverseWithActionHandler(&action_handler); DCHECK(poly_list->empty()); } @@ -383,38 +391,53 @@ void DirectRenderer::DrawRenderPass(DrawingFrame* frame, if (!UseRenderPass(frame, render_pass)) return; - bool using_scissor_as_optimization = Capabilities().using_partial_swap; - gfx::Rect render_pass_scissor; - bool draw_rect_covers_full_surface = true; - if (frame->current_render_pass == frame->root_render_pass && - !frame->device_viewport_rect.Contains( - gfx::Rect(output_surface_->SurfaceSize()))) - draw_rect_covers_full_surface = false; - - if (using_scissor_as_optimization) { - render_pass_scissor = ComputeScissorRectForRenderPass(frame); - SetScissorTestRectInDrawSpace(frame, render_pass_scissor); - if (!render_pass_scissor.Contains(frame->current_render_pass->output_rect)) - draw_rect_covers_full_surface = false; + const gfx::Rect surface_rect_in_draw_space = + OutputSurfaceRectInDrawSpace(frame); + gfx::Rect render_pass_scissor_in_draw_space = surface_rect_in_draw_space; + + if (frame->current_render_pass == frame->root_render_pass) { + render_pass_scissor_in_draw_space.Intersect( + DeviceViewportRectInDrawSpace(frame)); } - if (frame->current_render_pass != frame->root_render_pass || - settings_->should_clear_root_render_pass) { - if (NeedDeviceClip(frame)) { - SetScissorTestRect(DeviceClipRectInWindowSpace(frame)); - draw_rect_covers_full_surface = false; - } else if (!using_scissor_as_optimization) { - EnsureScissorTestDisabled(); - } + if (Capabilities().using_partial_swap) { + render_pass_scissor_in_draw_space.Intersect( + ComputeScissorRectForRenderPass(frame)); + } - bool has_external_stencil_test = - output_surface_->HasExternalStencilTest() && - frame->current_render_pass == frame->root_render_pass; + if (NeedDeviceClip(frame)) { + render_pass_scissor_in_draw_space.Intersect( + DeviceClipRectInDrawSpace(frame)); + } - DiscardPixels(has_external_stencil_test, draw_rect_covers_full_surface); - ClearFramebuffer(frame, has_external_stencil_test); + bool render_pass_is_clipped = + !render_pass_scissor_in_draw_space.Contains(surface_rect_in_draw_space); + bool is_root_render_pass = + frame->current_render_pass == frame->root_render_pass; + bool has_external_stencil_test = + is_root_render_pass && output_surface_->HasExternalStencilTest(); + bool should_clear_surface = + !has_external_stencil_test && + (!is_root_render_pass || settings_->should_clear_root_render_pass); + + // If |has_external_stencil_test| we can't discard or clear. Make sure we + // don't need to. + DCHECK_IMPLIES(has_external_stencil_test, + !frame->current_render_pass->has_transparent_background); + + SurfaceInitializationMode mode; + if (should_clear_surface && render_pass_is_clipped) { + mode = SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR; + } else if (should_clear_surface) { + mode = SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR; + } else { + mode = SURFACE_INITIALIZATION_MODE_PRESERVE; } + PrepareSurfaceForPass( + frame, mode, + MoveFromDrawToWindowSpace(frame, render_pass_scissor_in_draw_space)); + const QuadList& quad_list = render_pass->quad_list; ScopedPtrDeque<DrawPolygon> poly_list; @@ -425,15 +448,15 @@ void DirectRenderer::DrawRenderPass(DrawingFrame* frame, const DrawQuad& quad = **it; gfx::QuadF send_quad(quad.visible_rect); - if (using_scissor_as_optimization && - ShouldSkipQuad(quad, render_pass_scissor)) { + if (render_pass_is_clipped && + ShouldSkipQuad(quad, render_pass_scissor_in_draw_space)) { continue; } if (last_sorting_context_id != quad.shared_quad_state->sorting_context_id) { last_sorting_context_id = quad.shared_quad_state->sorting_context_id; - FlushPolygons(&poly_list, frame, render_pass_scissor, - using_scissor_as_optimization); + FlushPolygons(&poly_list, frame, render_pass_scissor_in_draw_space, + render_pass_is_clipped); } // This layer is in a 3D sorting context so we add it to the list of @@ -448,17 +471,13 @@ void DirectRenderer::DrawRenderPass(DrawingFrame* frame, } // We are not in a 3d sorting context, so we should draw the quad normally. - if (using_scissor_as_optimization) { - SetScissorStateForQuadWithRenderPassScissor(frame, quad, - render_pass_scissor); - } else { - SetScissorStateForQuad(frame, quad); - } + SetScissorStateForQuad(frame, quad, render_pass_scissor_in_draw_space, + render_pass_is_clipped); DoDrawQuad(frame, &quad, nullptr); } - FlushPolygons(&poly_list, frame, render_pass_scissor, - using_scissor_as_optimization); + FlushPolygons(&poly_list, frame, render_pass_scissor_in_draw_space, + render_pass_is_clipped); FinishDrawingQuadList(); } @@ -487,7 +506,14 @@ bool DirectRenderer::UseRenderPass(DrawingFrame* frame, size, ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER, RGBA_8888); DCHECK(texture->id()); - return BindFramebufferToTexture(frame, texture, render_pass->output_rect); + if (BindFramebufferToTexture(frame, texture, render_pass->output_rect)) { + InitializeViewport(frame, render_pass->output_rect, + gfx::Rect(render_pass->output_rect.size()), + render_pass->output_rect.size()); + return true; + } + + return false; } bool DirectRenderer::HasAllocatedResourcesForTesting(RenderPassId id) const { diff --git a/cc/output/direct_renderer.h b/cc/output/direct_renderer.h index 3399491..dd3d13b 100644 --- a/cc/output/direct_renderer.h +++ b/cc/output/direct_renderer.h @@ -63,9 +63,15 @@ class CC_EXPORT DirectRenderer : public Renderer { void DoDrawPolygon(const DrawPolygon& poly, DrawingFrame* frame, const gfx::Rect& render_pass_scissor, - bool using_scissor_as_optimization); + bool use_render_pass_scissor); protected: + enum SurfaceInitializationMode { + SURFACE_INITIALIZATION_MODE_PRESERVE, + SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR, + SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR, + }; + DirectRenderer(RendererClient* client, const RendererSettings* settings, OutputSurface* output_surface, @@ -83,15 +89,16 @@ class CC_EXPORT DirectRenderer : public Renderer { const gfx::Rect& draw_rect) const; bool NeedDeviceClip(const DrawingFrame* frame) const; - gfx::Rect DeviceClipRectInWindowSpace(const DrawingFrame* frame) const; + gfx::Rect DeviceClipRectInDrawSpace(const DrawingFrame* frame) const; + gfx::Rect DeviceViewportRectInDrawSpace(const DrawingFrame* frame) const; + gfx::Rect OutputSurfaceRectInDrawSpace(const DrawingFrame* frame) const; static gfx::Rect ComputeScissorRectForRenderPass(const DrawingFrame* frame); - void SetScissorStateForQuad(const DrawingFrame* frame, const DrawQuad& quad); + void SetScissorStateForQuad(const DrawingFrame* frame, + const DrawQuad& quad, + const gfx::Rect& render_pass_scissor, + bool use_render_pass_scissor); bool ShouldSkipQuad(const DrawQuad& quad, const gfx::Rect& render_pass_scissor); - void SetScissorStateForQuadWithRenderPassScissor( - const DrawingFrame* frame, - const DrawQuad& quad, - const gfx::Rect& render_pass_scissor); void SetScissorTestRectInDrawSpace(const DrawingFrame* frame, const gfx::Rect& draw_space_rect); @@ -100,7 +107,7 @@ class CC_EXPORT DirectRenderer : public Renderer { void FlushPolygons(ScopedPtrDeque<DrawPolygon>* poly_list, DrawingFrame* frame, const gfx::Rect& render_pass_scissor, - bool using_scissor_as_optimization); + bool use_render_pass_scissor); void DrawRenderPass(DrawingFrame* frame, const RenderPass* render_pass); bool UseRenderPass(DrawingFrame* frame, const RenderPass* render_pass); @@ -110,10 +117,10 @@ class CC_EXPORT DirectRenderer : public Renderer { const gfx::Rect& target_rect) = 0; virtual void SetDrawViewport(const gfx::Rect& window_space_viewport) = 0; virtual void SetScissorTestRect(const gfx::Rect& scissor_rect) = 0; - virtual void DiscardPixels(bool has_external_stencil_test, - bool draw_rect_covers_full_surface) = 0; - virtual void ClearFramebuffer(DrawingFrame* frame, - bool has_external_stencil_test) = 0; + virtual void PrepareSurfaceForPass( + DrawingFrame* frame, + SurfaceInitializationMode initialization_mode, + const gfx::Rect& render_pass_scissor) = 0; // clip_region is a (possibly null) pointer to a quad in the same // space as the quad. When non-null only the area of the quad that overlaps // with clip_region will be drawn. diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index b49ac8e..e614d8b 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -401,10 +401,8 @@ void GLRenderer::DidChangeVisibility() { void GLRenderer::ReleaseRenderPassTextures() { render_pass_textures_.clear(); } -void GLRenderer::DiscardPixels(bool has_external_stencil_test, - bool draw_rect_covers_full_surface) { - if (has_external_stencil_test || !draw_rect_covers_full_surface || - !capabilities_.using_discard_framebuffer) +void GLRenderer::DiscardPixels() { + if (!capabilities_.using_discard_framebuffer) return; bool using_default_framebuffer = !current_framebuffer_lock_ && @@ -415,15 +413,27 @@ void GLRenderer::DiscardPixels(bool has_external_stencil_test, GL_FRAMEBUFFER, arraysize(attachments), attachments); } -void GLRenderer::ClearFramebuffer(DrawingFrame* frame, - bool has_external_stencil_test) { - // It's unsafe to clear when we have a stencil test because glClear ignores - // stencil. - if (has_external_stencil_test) { - DCHECK(!frame->current_render_pass->has_transparent_background); - return; +void GLRenderer::PrepareSurfaceForPass( + DrawingFrame* frame, + SurfaceInitializationMode initialization_mode, + const gfx::Rect& render_pass_scissor) { + switch (initialization_mode) { + case SURFACE_INITIALIZATION_MODE_PRESERVE: + EnsureScissorTestDisabled(); + return; + case SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR: + EnsureScissorTestDisabled(); + DiscardPixels(); + ClearFramebuffer(frame); + break; + case SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR: + SetScissorTestRect(render_pass_scissor); + ClearFramebuffer(frame); + break; } +} +void GLRenderer::ClearFramebuffer(DrawingFrame* frame) { // On DEBUG builds, opaque render passes are cleared to blue to easily see // regions that were not drawn on the screen. if (frame->current_render_pass->has_transparent_background) @@ -2920,9 +2930,6 @@ bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame, DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE || IsContextLost()); - - InitializeViewport( - frame, target_rect, gfx::Rect(target_rect.size()), target_rect.size()); return true; } diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h index 27f2c42..ddc8791 100644 --- a/cc/output/gl_renderer.h +++ b/cc/output/gl_renderer.h @@ -110,10 +110,9 @@ class CC_EXPORT GLRenderer : public DirectRenderer { const gfx::Rect& target_rect) override; void SetDrawViewport(const gfx::Rect& window_space_viewport) override; void SetScissorTestRect(const gfx::Rect& scissor_rect) override; - void DiscardPixels(bool has_external_stencil_test, - bool draw_rect_covers_full_surface) override; - void ClearFramebuffer(DrawingFrame* frame, - bool has_external_stencil_test) override; + void PrepareSurfaceForPass(DrawingFrame* frame, + SurfaceInitializationMode initialization_mode, + const gfx::Rect& render_pass_scissor) override; void DoDrawQuad(DrawingFrame* frame, const class DrawQuad*, const gfx::QuadF* draw_region) override; @@ -150,6 +149,9 @@ class CC_EXPORT GLRenderer : public DirectRenderer { static void ToGLMatrix(float* gl_matrix, const gfx::Transform& transform); + void DiscardPixels(); + void ClearFramebuffer(DrawingFrame* frame); + void DrawCheckerboardQuad(const DrawingFrame* frame, const CheckerboardDrawQuad* quad, const gfx::QuadF* clip_region); diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc index d1e937a..7e0f8e0 100644 --- a/cc/output/gl_renderer_unittest.cc +++ b/cc/output/gl_renderer_unittest.cc @@ -1412,32 +1412,8 @@ TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) { class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D { public: - FlippedScissorAndViewportContext() - : did_call_viewport_(false), did_call_scissor_(false) {} - ~FlippedScissorAndViewportContext() override { - EXPECT_TRUE(did_call_viewport_); - EXPECT_TRUE(did_call_scissor_); - } - - void viewport(GLint x, GLint y, GLsizei width, GLsizei height) override { - EXPECT_EQ(10, x); - EXPECT_EQ(390, y); - EXPECT_EQ(100, width); - EXPECT_EQ(100, height); - did_call_viewport_ = true; - } - - void scissor(GLint x, GLint y, GLsizei width, GLsizei height) override { - EXPECT_EQ(30, x); - EXPECT_EQ(450, y); - EXPECT_EQ(20, width); - EXPECT_EQ(20, height); - did_call_scissor_ = true; - } - - private: - bool did_call_viewport_; - bool did_call_scissor_; + MOCK_METHOD4(viewport, void(GLint x, GLint y, GLsizei width, GLsizei height)); + MOCK_METHOD4(scissor, void(GLint x, GLint y, GLsizei width, GLsizei height)); }; TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) { @@ -1448,6 +1424,12 @@ TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) { scoped_ptr<FlippedScissorAndViewportContext> context_owned( new FlippedScissorAndViewportContext); + // We expect exactly one call to viewport on this context and exactly two + // to scissor (one to scissor the clear, one to scissor the quad draw). + EXPECT_CALL(*context_owned, viewport(10, 390, 100, 100)); + EXPECT_CALL(*context_owned, scissor(10, 390, 100, 100)); + EXPECT_CALL(*context_owned, scissor(30, 450, 20, 20)); + FakeOutputSurfaceClient output_surface_client; scoped_ptr<OutputSurface> output_surface( new NonReshapableOutputSurface(context_owned.Pass())); diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc index cecd633..bd99d0b1 100644 --- a/cc/output/software_renderer.cc +++ b/cc/output/software_renderer.cc @@ -172,10 +172,6 @@ bool SoftwareRenderer::BindFramebufferToTexture( current_framebuffer_canvas_ = skia::AdoptRef(new SkCanvas(current_framebuffer_lock_->sk_bitmap())); current_canvas_ = current_framebuffer_canvas_.get(); - InitializeViewport(frame, - target_rect, - gfx::Rect(target_rect.size()), - target_rect.size()); return true; } @@ -202,11 +198,7 @@ void SoftwareRenderer::ClearCanvas(SkColor color) { current_canvas_->clear(color); } -void SoftwareRenderer::DiscardPixels(bool has_external_stencil_test, - bool draw_rect_covers_full_surface) {} - -void SoftwareRenderer::ClearFramebuffer(DrawingFrame* frame, - bool has_external_stencil_test) { +void SoftwareRenderer::ClearFramebuffer(DrawingFrame* frame) { if (frame->current_render_pass->has_transparent_background) { ClearCanvas(SkColorSetARGB(0, 0, 0, 0)); } else { @@ -218,6 +210,25 @@ void SoftwareRenderer::ClearFramebuffer(DrawingFrame* frame, } } +void SoftwareRenderer::PrepareSurfaceForPass( + DrawingFrame* frame, + SurfaceInitializationMode initialization_mode, + const gfx::Rect& render_pass_scissor) { + switch (initialization_mode) { + case SURFACE_INITIALIZATION_MODE_PRESERVE: + EnsureScissorTestDisabled(); + return; + case SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR: + EnsureScissorTestDisabled(); + ClearFramebuffer(frame); + break; + case SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR: + SetScissorTestRect(render_pass_scissor); + ClearFramebuffer(frame); + break; + } +} + void SoftwareRenderer::SetDrawViewport( const gfx::Rect& window_space_viewport) {} diff --git a/cc/output/software_renderer.h b/cc/output/software_renderer.h index dc8e2fb..ae8beb4 100644 --- a/cc/output/software_renderer.h +++ b/cc/output/software_renderer.h @@ -48,10 +48,9 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer { const gfx::Rect& target_rect) override; void SetDrawViewport(const gfx::Rect& window_space_viewport) override; void SetScissorTestRect(const gfx::Rect& scissor_rect) override; - void DiscardPixels(bool has_external_stencil_test, - bool draw_rect_covers_full_surface) override; - void ClearFramebuffer(DrawingFrame* frame, - bool has_external_stencil_test) override; + void PrepareSurfaceForPass(DrawingFrame* frame, + SurfaceInitializationMode initialization_mode, + const gfx::Rect& render_pass_scissor) override; void DoDrawQuad(DrawingFrame* frame, const DrawQuad* quad, @@ -74,6 +73,7 @@ class CC_EXPORT SoftwareRenderer : public DirectRenderer { private: void ClearCanvas(SkColor color); + void ClearFramebuffer(DrawingFrame* frame); void SetClipRect(const gfx::Rect& rect); bool IsSoftwareResource(ResourceProvider::ResourceId resource_id) const; diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 7852770..1526f93 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc @@ -5301,8 +5301,8 @@ TEST_F(LayerTreeHostImplTest, PartialSwap) { CreateHostImpl(settings, FakeOutputSurface::Create3d(context_owned.Pass())); SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1)); - // The first frame is not a partially-swapped one. - harness.MustSetScissor(0, 0, 10, 10); + // The first frame is not a partially-swapped one. No scissor should be set. + harness.MustSetNoScissor(); harness.MustDrawSolidQuad(); { LayerTreeHostImpl::FrameData frame; |