summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorericrk <ericrk@chromium.org>2015-03-21 00:48:11 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-21 07:48:54 +0000
commitdb214180d73e6516d8b2de4f87b8a1ae01bdd45f (patch)
tree28304a8c062a0819a5cbd77de066f0fd559e0582
parentc5056857280ce8822b0eaa0d761bab5d8a7967ff (diff)
downloadchromium_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.cc170
-rw-r--r--cc/output/direct_renderer.h31
-rw-r--r--cc/output/gl_renderer.cc35
-rw-r--r--cc/output/gl_renderer.h10
-rw-r--r--cc/output/gl_renderer_unittest.cc34
-rw-r--r--cc/output/software_renderer.cc29
-rw-r--r--cc/output/software_renderer.h8
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc4
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;