未验证 提交 ecfe5aec 编写于 作者: J Jim Graham 提交者: GitHub

Move layer clip culling to Paint() method to fix child caching (#22336)

上级 8bb47c54
......@@ -18,7 +18,7 @@ void BackdropFilterLayer::Preroll(PrerollContext* context,
void BackdropFilterLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "BackdropFilterLayer::Paint");
FML_DCHECK(needs_painting());
FML_DCHECK(needs_painting(context));
Layer::AutoSaveLayer save = Layer::AutoSaveLayer::Create(
context,
......
......@@ -22,11 +22,11 @@ TEST_F(BackdropFilterLayerTest, PaintingEmptyLayerDies) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(BackdropFilterLayerTest, PaintBeforePrerollDies) {
......@@ -38,7 +38,7 @@ TEST_F(BackdropFilterLayerTest, PaintBeforePrerollDies) {
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -53,7 +53,7 @@ TEST_F(BackdropFilterLayerTest, EmptyFilter) {
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(layer->paint_bounds(), child_bounds);
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
layer->Paint(paint_context());
......@@ -79,7 +79,7 @@ TEST_F(BackdropFilterLayerTest, SimpleFilter) {
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(layer->paint_bounds(), child_bounds);
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
layer->Paint(paint_context());
......@@ -114,9 +114,9 @@ TEST_F(BackdropFilterLayerTest, MultipleChildren) {
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer->paint_bounds(), children_bounds);
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
......@@ -158,10 +158,10 @@ TEST_F(BackdropFilterLayerTest, Nested) {
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer1->paint_bounds(), children_bounds);
EXPECT_EQ(layer2->paint_bounds(), mock_layer2->paint_bounds());
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer1->needs_painting());
EXPECT_TRUE(layer2->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer1->needs_painting(paint_context()));
EXPECT_TRUE(layer2->needs_painting(paint_context()));
EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
......
......@@ -43,8 +43,8 @@ TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerNotCheckBoard) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds);
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(),
......@@ -93,8 +93,8 @@ TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerCheckBoard) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds);
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(),
......@@ -136,8 +136,8 @@ TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerNotCheckBoard) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_path)}));
......@@ -177,8 +177,8 @@ TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerCheckBoard) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_path)}));
......@@ -218,8 +218,8 @@ TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerNotCheckBoard) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)}));
......@@ -259,8 +259,8 @@ TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerCheckBoard) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)}));
......@@ -296,7 +296,7 @@ TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerNotCheckBoard) {
EXPECT_EQ(layer->paint_bounds(),
PhysicalShapeLayer::ComputeShadowBounds(layer_path.getBounds(),
initial_elevation, 1.0f));
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_EQ(layer->elevation(), initial_elevation);
......@@ -340,7 +340,7 @@ TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerCheckBoard) {
EXPECT_EQ(layer->paint_bounds(),
PhysicalShapeLayer::ComputeShadowBounds(layer_path.getBounds(),
initial_elevation, 1.0f));
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_EQ(layer->elevation(), initial_elevation);
......
......@@ -21,21 +21,18 @@ void ClipPathLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
SkRect previous_cull_rect = context->cull_rect;
SkRect clip_path_bounds = clip_path_.getBounds();
children_inside_clip_ = context->cull_rect.intersect(clip_path_bounds);
if (children_inside_clip_) {
TRACE_EVENT_INSTANT0("flutter", "children inside clip rect");
Layer::AutoPrerollSaveLayerState save =
Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer());
context->mutators_stack.PushClipPath(clip_path_);
SkRect child_paint_bounds = SkRect::MakeEmpty();
PrerollChildren(context, matrix, &child_paint_bounds);
if (child_paint_bounds.intersect(clip_path_bounds)) {
set_paint_bounds(child_paint_bounds);
}
context->mutators_stack.Pop();
context->cull_rect.intersect(clip_path_bounds);
Layer::AutoPrerollSaveLayerState save =
Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer());
context->mutators_stack.PushClipPath(clip_path_);
SkRect child_paint_bounds = SkRect::MakeEmpty();
PrerollChildren(context, matrix, &child_paint_bounds);
if (child_paint_bounds.intersect(clip_path_bounds)) {
set_paint_bounds(child_paint_bounds);
}
context->mutators_stack.Pop();
context->cull_rect = previous_cull_rect;
}
......@@ -54,12 +51,7 @@ void ClipPathLayer::UpdateScene(std::shared_ptr<SceneUpdateContext> context) {
void ClipPathLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "ClipPathLayer::Paint");
FML_DCHECK(needs_painting());
if (!children_inside_clip_) {
TRACE_EVENT_INSTANT0("flutter", "children not inside clip rect, skipping");
return;
}
FML_DCHECK(needs_painting(context));
SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
context.internal_nodes_canvas->clipPath(clip_path_,
......
......@@ -28,7 +28,6 @@ class ClipPathLayer : public ContainerLayer {
private:
SkPath clip_path_;
Clip clip_behavior_;
bool children_inside_clip_ = false;
FML_DISALLOW_COPY_AND_ASSIGN(ClipPathLayer);
};
......
......@@ -28,10 +28,10 @@ TEST_F(ClipPathLayerTest, PaintingEmptyLayerDies) {
EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(ClipPathLayerTest, PaintBeforePrerollDies) {
......@@ -39,37 +39,41 @@ TEST_F(ClipPathLayerTest, PaintBeforePrerollDies) {
const SkPath layer_path = SkPath().addRect(layer_bounds);
auto layer = std::make_shared<ClipPathLayer>(layer_path, Clip::hardEdge);
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(ClipPathLayerTest, PaintingCulledLayerDies) {
const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);
const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
const SkRect distant_bounds = SkRect::MakeXYWH(100.0, 100.0, 10.0, 10.0);
const SkPath child_path = SkPath().addRect(child_bounds);
const SkPath layer_path = SkPath().addRect(layer_bounds);
auto mock_layer = std::make_shared<MockLayer>(child_path);
auto layer = std::make_shared<ClipPathLayer>(layer_path, Clip::hardEdge);
layer->Add(mock_layer);
preroll_context()->cull_rect = kEmptyRect; // Cull everything
preroll_context()->cull_rect = distant_bounds; // Cull these children
layer->Preroll(preroll_context(), initial_matrix);
EXPECT_EQ(preroll_context()->cull_rect, kEmptyRect); // Untouched
EXPECT_EQ(preroll_context()->cull_rect, distant_bounds); // Untouched
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect);
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(mock_layer->needs_painting());
EXPECT_FALSE(layer->needs_painting());
EXPECT_EQ(mock_layer->parent_cull_rect(), kEmptyRect);
EXPECT_EQ(mock_layer->parent_matrix(), SkMatrix());
EXPECT_EQ(mock_layer->parent_mutators(), std::vector<Mutator>());
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), child_bounds);
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), distant_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_path)}));
paint_context().internal_nodes_canvas->clipRect(distant_bounds, false);
EXPECT_FALSE(mock_layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -96,8 +100,8 @@ TEST_F(ClipPathLayerTest, ChildOutsideBounds) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds);
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_path)}));
......@@ -131,8 +135,8 @@ TEST_F(ClipPathLayerTest, FullyContainedChild) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_path)}));
......@@ -173,8 +177,8 @@ TEST_F(ClipPathLayerTest, PartiallyContainedChild) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds);
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_path)}));
......
......@@ -16,21 +16,18 @@ void ClipRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
TRACE_EVENT0("flutter", "ClipRectLayer::Preroll");
SkRect previous_cull_rect = context->cull_rect;
children_inside_clip_ = context->cull_rect.intersect(clip_rect_);
if (children_inside_clip_) {
TRACE_EVENT_INSTANT0("flutter", "children inside clip rect");
Layer::AutoPrerollSaveLayerState save =
Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer());
context->mutators_stack.PushClipRect(clip_rect_);
SkRect child_paint_bounds = SkRect::MakeEmpty();
PrerollChildren(context, matrix, &child_paint_bounds);
if (child_paint_bounds.intersect(clip_rect_)) {
set_paint_bounds(child_paint_bounds);
}
context->mutators_stack.Pop();
context->cull_rect.intersect(clip_rect_);
Layer::AutoPrerollSaveLayerState save =
Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer());
context->mutators_stack.PushClipRect(clip_rect_);
SkRect child_paint_bounds = SkRect::MakeEmpty();
PrerollChildren(context, matrix, &child_paint_bounds);
if (child_paint_bounds.intersect(clip_rect_)) {
set_paint_bounds(child_paint_bounds);
}
context->mutators_stack.Pop();
context->cull_rect = previous_cull_rect;
}
......@@ -49,12 +46,7 @@ void ClipRectLayer::UpdateScene(std::shared_ptr<SceneUpdateContext> context) {
void ClipRectLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "ClipRectLayer::Paint");
FML_DCHECK(needs_painting());
if (!children_inside_clip_) {
TRACE_EVENT_INSTANT0("flutter", "children not inside clip rect, skipping");
return;
}
FML_DCHECK(needs_painting(context));
SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
context.internal_nodes_canvas->clipRect(clip_rect_,
......
......@@ -27,7 +27,6 @@ class ClipRectLayer : public ContainerLayer {
private:
SkRect clip_rect_;
Clip clip_behavior_;
bool children_inside_clip_ = false;
FML_DISALLOW_COPY_AND_ASSIGN(ClipRectLayer);
};
......
......@@ -28,46 +28,51 @@ TEST_F(ClipRectLayerTest, PaintingEmptyLayerDies) {
EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(ClipRectLayerTest, PaintBeforePrerollDies) {
const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
auto layer = std::make_shared<ClipRectLayer>(layer_bounds, Clip::hardEdge);
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(ClipRectLayerTest, PaintingCulledLayerDies) {
const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);
const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
const SkRect distant_bounds = SkRect::MakeXYWH(100.0, 100.0, 10.0, 10.0);
const SkPath child_path = SkPath().addRect(child_bounds);
auto mock_layer = std::make_shared<MockLayer>(child_path);
auto layer = std::make_shared<ClipRectLayer>(layer_bounds, Clip::hardEdge);
layer->Add(mock_layer);
preroll_context()->cull_rect = kEmptyRect; // Cull everything
preroll_context()->cull_rect = distant_bounds; // Cull these children
layer->Preroll(preroll_context(), initial_matrix);
EXPECT_EQ(preroll_context()->cull_rect, kEmptyRect); // Untouched
EXPECT_EQ(preroll_context()->cull_rect, distant_bounds); // Untouched
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect);
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(mock_layer->needs_painting());
EXPECT_FALSE(layer->needs_painting());
EXPECT_EQ(mock_layer->parent_cull_rect(), kEmptyRect);
EXPECT_EQ(mock_layer->parent_matrix(), SkMatrix());
EXPECT_EQ(mock_layer->parent_mutators(), std::vector<Mutator>());
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), child_bounds);
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), distant_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(),
std::vector({Mutator(layer_bounds)}));
paint_context().internal_nodes_canvas->clipRect(distant_bounds, false);
EXPECT_FALSE(mock_layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -93,8 +98,8 @@ TEST_F(ClipRectLayerTest, ChildOutsideBounds) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds);
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(),
......@@ -128,8 +133,8 @@ TEST_F(ClipRectLayerTest, FullyContainedChild) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(),
......@@ -170,8 +175,8 @@ TEST_F(ClipRectLayerTest, PartiallyContainedChild) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds);
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(),
......
......@@ -17,21 +17,18 @@ void ClipRRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
SkRect previous_cull_rect = context->cull_rect;
SkRect clip_rrect_bounds = clip_rrect_.getBounds();
children_inside_clip_ = context->cull_rect.intersect(clip_rrect_bounds);
if (children_inside_clip_) {
TRACE_EVENT_INSTANT0("flutter", "children inside clip rect");
Layer::AutoPrerollSaveLayerState save =
Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer());
context->mutators_stack.PushClipRRect(clip_rrect_);
SkRect child_paint_bounds = SkRect::MakeEmpty();
PrerollChildren(context, matrix, &child_paint_bounds);
if (child_paint_bounds.intersect(clip_rrect_bounds)) {
set_paint_bounds(child_paint_bounds);
}
context->mutators_stack.Pop();
context->cull_rect.intersect(clip_rrect_bounds);
Layer::AutoPrerollSaveLayerState save =
Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer());
context->mutators_stack.PushClipRRect(clip_rrect_);
SkRect child_paint_bounds = SkRect::MakeEmpty();
PrerollChildren(context, matrix, &child_paint_bounds);
if (child_paint_bounds.intersect(clip_rrect_bounds)) {
set_paint_bounds(child_paint_bounds);
}
context->mutators_stack.Pop();
context->cull_rect = previous_cull_rect;
}
......@@ -50,12 +47,7 @@ void ClipRRectLayer::UpdateScene(std::shared_ptr<SceneUpdateContext> context) {
void ClipRRectLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "ClipRRectLayer::Paint");
FML_DCHECK(needs_painting());
if (!children_inside_clip_) {
TRACE_EVENT_INSTANT0("flutter", "children not inside clip rect, skipping");
return;
}
FML_DCHECK(needs_painting(context));
SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
context.internal_nodes_canvas->clipRRect(clip_rrect_,
......
......@@ -28,7 +28,6 @@ class ClipRRectLayer : public ContainerLayer {
private:
SkRRect clip_rrect_;
Clip clip_behavior_;
bool children_inside_clip_ = false;
FML_DISALLOW_COPY_AND_ASSIGN(ClipRRectLayer);
};
......
......@@ -30,10 +30,10 @@ TEST_F(ClipRRectLayerTest, PaintingEmptyLayerDies) {
EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(ClipRRectLayerTest, PaintBeforePreollDies) {
......@@ -41,16 +41,17 @@ TEST_F(ClipRRectLayerTest, PaintBeforePreollDies) {
const SkRRect layer_rrect = SkRRect::MakeRect(layer_bounds);
auto layer = std::make_shared<ClipRRectLayer>(layer_rrect, Clip::hardEdge);
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(ClipRRectLayerTest, PaintingCulledLayerDies) {
const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);
const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
const SkRect distant_bounds = SkRect::MakeXYWH(100.0, 100.0, 10.0, 10.0);
const SkPath child_path = SkPath().addRect(child_bounds);
const SkRRect layer_rrect = SkRRect::MakeRect(layer_bounds);
const SkPaint child_paint = SkPaint(SkColors::kYellow);
......@@ -58,21 +59,24 @@ TEST_F(ClipRRectLayerTest, PaintingCulledLayerDies) {
auto layer = std::make_shared<ClipRRectLayer>(layer_rrect, Clip::hardEdge);
layer->Add(mock_layer);
preroll_context()->cull_rect = kEmptyRect; // Cull everything
preroll_context()->cull_rect = distant_bounds; // Cull these children
layer->Preroll(preroll_context(), initial_matrix);
EXPECT_EQ(preroll_context()->cull_rect, kEmptyRect); // Untouched
EXPECT_EQ(preroll_context()->cull_rect, distant_bounds); // Untouched
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect);
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(mock_layer->needs_painting());
EXPECT_FALSE(layer->needs_painting());
EXPECT_EQ(mock_layer->parent_cull_rect(), kEmptyRect);
EXPECT_EQ(mock_layer->parent_matrix(), SkMatrix());
EXPECT_EQ(mock_layer->parent_mutators(), std::vector<Mutator>());
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), child_bounds);
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), distant_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)}));
paint_context().internal_nodes_canvas->clipRect(distant_bounds, false);
EXPECT_FALSE(mock_layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -99,8 +103,8 @@ TEST_F(ClipRRectLayerTest, ChildOutsideBounds) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds);
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)}));
......@@ -134,8 +138,8 @@ TEST_F(ClipRRectLayerTest, FullyContainedChild) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)}));
......@@ -176,8 +180,8 @@ TEST_F(ClipRRectLayerTest, PartiallyContainedChild) {
EXPECT_TRUE(preroll_context()->mutators_stack.is_empty()); // Untouched
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), child_intersect_bounds);
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_cull_rect(), intersect_bounds);
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)}));
......
......@@ -18,7 +18,7 @@ void ColorFilterLayer::Preroll(PrerollContext* context,
void ColorFilterLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "ColorFilterLayer::Paint");
FML_DCHECK(needs_painting());
FML_DCHECK(needs_painting(context));
SkPaint paint;
paint.setColorFilter(filter_);
......
......@@ -22,11 +22,11 @@ TEST_F(ColorFilterLayerTest, PaintingEmptyLayerDies) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(ColorFilterLayerTest, PaintBeforePrerollDies) {
......@@ -38,7 +38,7 @@ TEST_F(ColorFilterLayerTest, PaintBeforePrerollDies) {
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -53,7 +53,7 @@ TEST_F(ColorFilterLayerTest, EmptyFilter) {
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(layer->paint_bounds(), child_bounds);
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
SkPaint filter_paint;
......@@ -82,7 +82,7 @@ TEST_F(ColorFilterLayerTest, SimpleFilter) {
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(layer->paint_bounds(), child_bounds);
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
SkPaint filter_paint;
......@@ -120,9 +120,9 @@ TEST_F(ColorFilterLayerTest, MultipleChildren) {
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer->paint_bounds(), children_bounds);
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
......@@ -168,10 +168,10 @@ TEST_F(ColorFilterLayerTest, Nested) {
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer1->paint_bounds(), children_bounds);
EXPECT_EQ(layer2->paint_bounds(), mock_layer2->paint_bounds());
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer1->needs_painting());
EXPECT_TRUE(layer2->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer1->needs_painting(paint_context()));
EXPECT_TRUE(layer2->needs_painting(paint_context()));
EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
......
......@@ -23,7 +23,7 @@ void ContainerLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
}
void ContainerLayer::Paint(PaintContext& context) const {
FML_DCHECK(needs_painting());
FML_DCHECK(needs_painting(context));
PaintChildren(context);
}
......@@ -72,12 +72,16 @@ void ContainerLayer::PrerollChildren(PrerollContext* context,
}
void ContainerLayer::PaintChildren(PaintContext& context) const {
FML_DCHECK(needs_painting());
// We can no longer call FML_DCHECK here on the needs_painting(context)
// condition as that test is only valid for the PaintContext that
// is initially handed to a layer's Paint() method. By the time the
// layer calls PaintChildren(), though, it may have modified the
// PaintContext so the test doesn't work in this "context".
// Intentionally not tracing here as there should be no self-time
// and the trace event on this common function has a small overhead.
for (auto& layer : layers_) {
if (layer->needs_painting()) {
if (layer->needs_painting(context)) {
layer->Paint(context);
}
}
......
......@@ -28,11 +28,11 @@ TEST_F(ContainerLayerTest, PaintingEmptyLayerDies) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(ContainerLayerTest, PaintBeforePreollDies) {
......@@ -44,7 +44,7 @@ TEST_F(ContainerLayerTest, PaintBeforePreollDies) {
EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -62,8 +62,8 @@ TEST_F(ContainerLayerTest, Simple) {
EXPECT_FALSE(preroll_context()->has_platform_view);
EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds());
EXPECT_EQ(layer->paint_bounds(), child_path.getBounds());
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_FALSE(mock_layer->needs_system_composite());
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
......@@ -98,9 +98,9 @@ TEST_F(ContainerLayerTest, Multiple) {
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_FALSE(mock_layer1->needs_system_composite());
EXPECT_FALSE(mock_layer2->needs_system_composite());
EXPECT_FALSE(layer->needs_system_composite());
......@@ -137,9 +137,9 @@ TEST_F(ContainerLayerTest, MultipleWithEmpty) {
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
EXPECT_EQ(mock_layer2->paint_bounds(), SkPath().getBounds());
EXPECT_EQ(layer->paint_bounds(), child_path1.getBounds());
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_FALSE(mock_layer2->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_FALSE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_FALSE(mock_layer1->needs_system_composite());
EXPECT_FALSE(mock_layer2->needs_system_composite());
EXPECT_FALSE(layer->needs_system_composite());
......@@ -178,9 +178,9 @@ TEST_F(ContainerLayerTest, NeedsSystemComposite) {
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer1->needs_system_composite());
EXPECT_FALSE(mock_layer2->needs_system_composite());
EXPECT_TRUE(layer->needs_system_composite());
......@@ -212,8 +212,8 @@ TEST_F(ContainerLayerTest, MergedOneChild) {
EXPECT_FALSE(preroll_context()->has_platform_view);
EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds());
EXPECT_EQ(layer->paint_bounds(), child_path.getBounds());
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_FALSE(mock_layer->needs_system_composite());
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
......@@ -247,9 +247,9 @@ TEST_F(ContainerLayerTest, MergedMultipleChildren) {
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_FALSE(mock_layer1->needs_system_composite());
EXPECT_FALSE(mock_layer2->needs_system_composite());
EXPECT_FALSE(layer->needs_system_composite());
......
......@@ -63,7 +63,7 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
void ImageFilterLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "ImageFilterLayer::Paint");
FML_DCHECK(needs_painting());
FML_DCHECK(needs_painting(context));
if (context.raster_cache) {
if (context.raster_cache->Draw(this, *context.leaf_nodes_canvas)) {
......
......@@ -21,11 +21,11 @@ TEST_F(ImageFilterLayerTest, PaintingEmptyLayerDies) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(ImageFilterLayerTest, PaintBeforePrerollDies) {
......@@ -37,7 +37,7 @@ TEST_F(ImageFilterLayerTest, PaintBeforePrerollDies) {
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -52,7 +52,7 @@ TEST_F(ImageFilterLayerTest, EmptyFilter) {
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(layer->paint_bounds(), child_bounds);
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
SkPaint filter_paint;
......@@ -85,7 +85,7 @@ TEST_F(ImageFilterLayerTest, SimpleFilter) {
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(layer->paint_bounds(), child_rounded_bounds);
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
SkPaint filter_paint;
......@@ -118,7 +118,7 @@ TEST_F(ImageFilterLayerTest, SimpleFilterBounds) {
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(layer->paint_bounds(), filter_bounds);
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
SkPaint filter_paint;
......@@ -159,9 +159,9 @@ TEST_F(ImageFilterLayerTest, MultipleChildren) {
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer->paint_bounds(), children_rounded_bounds);
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
......@@ -212,10 +212,10 @@ TEST_F(ImageFilterLayerTest, Nested) {
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer1->paint_bounds(), children_rounded_bounds);
EXPECT_EQ(layer2->paint_bounds(), mock_layer2_rounded_bounds);
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer1->needs_painting());
EXPECT_TRUE(layer2->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer1->needs_painting(paint_context()));
EXPECT_TRUE(layer2->needs_painting(paint_context()));
EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
......
......@@ -163,15 +163,40 @@ class Layer {
needs_system_composite_ = value;
}
// Returns the paint bounds in the layer's local coordinate system
// as determined during Preroll(). The bounds should include any
// transform, clip or distortions performed by the layer itself,
// but not any similar modifications inherited from its ancestors.
const SkRect& paint_bounds() const { return paint_bounds_; }
// This must be set by the time Preroll() returns otherwise the layer will
// be assumed to have empty paint bounds (paints no content).
// The paint bounds should be independent of the context outside of this
// layer as the layer may be painted under different conditions than
// the Preroll context. The most common example of this condition is
// that we might Preroll the layer with a cull_rect established by a
// clip layer above it but then we might be asked to paint anyway if
// another layer above us needs to cache its children. During the
// paint operation that arises due to the caching, the clip will
// be the bounds of the layer needing caching, not the cull_rect
// that we saw in the overall Preroll operation.
void set_paint_bounds(const SkRect& paint_bounds) {
paint_bounds_ = paint_bounds;
}
bool needs_painting() const { return !paint_bounds_.isEmpty(); }
// Determines if the layer has any content.
bool is_empty() const { return paint_bounds_.isEmpty(); }
// Determines if the Paint() method is necessary based on the properties
// of the indicated PaintContext object.
bool needs_painting(PaintContext& context) const {
// Workaround for Skia bug (quickReject does not reject empty bounds).
// https://bugs.chromium.org/p/skia/issues/detail?id=10951
if (paint_bounds_.isEmpty()) {
return false;
}
return !context.internal_nodes_canvas->quickReject(paint_bounds_);
}
uint64_t unique_id() const { return unique_id_; }
......
......@@ -79,7 +79,7 @@ void LayerTree::UpdateScene(std::shared_ptr<SceneUpdateContext> context) {
if (root_layer_->needs_system_composite()) {
root_layer_->UpdateScene(context);
}
if (root_layer_->needs_painting()) {
if (!root_layer_->is_empty()) {
frame.AddPaintLayer(root_layer_.get());
}
context->root_node().AddChild(transform.entity_node());
......@@ -117,7 +117,7 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame,
checkerboard_offscreen_layers_,
device_pixel_ratio_};
if (root_layer_->needs_painting()) {
if (root_layer_->needs_painting(context)) {
root_layer_->Paint(context);
}
}
......@@ -176,7 +176,7 @@ sk_sp<SkPicture> LayerTree::Flatten(const SkRect& bounds) {
if (root_layer_) {
root_layer_->Preroll(&preroll_context, root_surface_transformation);
// The needs painting flag may be set after the preroll. So check it after.
if (root_layer_->needs_painting()) {
if (root_layer_->needs_painting(paint_context)) {
root_layer_->Paint(paint_context);
}
}
......
......@@ -46,7 +46,7 @@ TEST_F(LayerTreeTest, PaintingEmptyLayerDies) {
layer_tree().set_root_layer(layer);
layer_tree().Preroll(frame());
EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
EXPECT_FALSE(layer->needs_painting());
EXPECT_TRUE(layer->is_empty());
layer_tree().Paint(frame());
}
......@@ -62,8 +62,8 @@ TEST_F(LayerTreeTest, PaintBeforePreollDies) {
layer_tree().set_root_layer(layer);
EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect);
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(mock_layer->needs_painting());
EXPECT_FALSE(layer->needs_painting());
EXPECT_TRUE(mock_layer->is_empty());
EXPECT_TRUE(layer->is_empty());
layer_tree().Paint(frame());
EXPECT_EQ(mock_canvas().draw_calls(), std::vector<MockCanvas::DrawCall>());
......@@ -81,8 +81,8 @@ TEST_F(LayerTreeTest, Simple) {
layer_tree().Preroll(frame());
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_FALSE(mock_layer->is_empty());
EXPECT_FALSE(layer->is_empty());
EXPECT_EQ(mock_layer->parent_matrix(), root_transform());
layer_tree().Paint(frame());
......@@ -110,9 +110,9 @@ TEST_F(LayerTreeTest, Multiple) {
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_FALSE(mock_layer1->is_empty());
EXPECT_FALSE(mock_layer2->is_empty());
EXPECT_FALSE(layer->is_empty());
EXPECT_FALSE(mock_layer1->needs_system_composite());
EXPECT_FALSE(mock_layer2->needs_system_composite());
EXPECT_FALSE(layer->needs_system_composite());
......@@ -146,9 +146,9 @@ TEST_F(LayerTreeTest, MultipleWithEmpty) {
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
EXPECT_EQ(mock_layer2->paint_bounds(), SkPath().getBounds());
EXPECT_EQ(layer->paint_bounds(), child_path1.getBounds());
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_FALSE(mock_layer2->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_FALSE(mock_layer1->is_empty());
EXPECT_TRUE(mock_layer2->is_empty());
EXPECT_FALSE(layer->is_empty());
EXPECT_FALSE(mock_layer1->needs_system_composite());
EXPECT_FALSE(mock_layer2->needs_system_composite());
EXPECT_FALSE(layer->needs_system_composite());
......@@ -183,9 +183,9 @@ TEST_F(LayerTreeTest, NeedsSystemComposite) {
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_FALSE(mock_layer1->is_empty());
EXPECT_FALSE(mock_layer2->is_empty());
EXPECT_FALSE(layer->is_empty());
EXPECT_TRUE(mock_layer1->needs_system_composite());
EXPECT_FALSE(mock_layer2->needs_system_composite());
EXPECT_TRUE(layer->needs_system_composite());
......
......@@ -46,7 +46,7 @@ void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
void OpacityLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "OpacityLayer::Paint");
FML_DCHECK(needs_painting());
FML_DCHECK(needs_painting(context));
SkPaint paint;
paint.setAlpha(alpha_);
......
......@@ -34,11 +34,11 @@ TEST_F(OpacityLayerTest, PaintingEmptyLayerDies) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(mock_layer->paint_bounds(), SkPath().getBounds());
EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
EXPECT_FALSE(mock_layer->needs_painting());
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(mock_layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(OpacityLayerTest, PaintBeforePreollDies) {
......@@ -50,7 +50,7 @@ TEST_F(OpacityLayerTest, PaintBeforePreollDies) {
layer->Add(mock_layer);
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -156,8 +156,8 @@ TEST_F(OpacityLayerTest, FullyOpaque) {
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds());
EXPECT_EQ(layer->paint_bounds(), expected_layer_bounds);
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(),
SkMatrix::Concat(initial_transform, layer_transform));
EXPECT_EQ(mock_layer->parent_mutators(),
......@@ -206,8 +206,8 @@ TEST_F(OpacityLayerTest, FullyTransparent) {
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds());
EXPECT_EQ(layer->paint_bounds(), expected_layer_bounds);
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(),
SkMatrix::Concat(initial_transform, layer_transform));
EXPECT_EQ(
......@@ -225,8 +225,6 @@ TEST_F(OpacityLayerTest, FullyTransparent) {
MockCanvas::DrawCall{
2, MockCanvas::ClipRectData{kEmptyRect, SkClipOp::kIntersect,
MockCanvas::kHard_ClipEdgeStyle}},
MockCanvas::DrawCall{2,
MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}});
layer->Paint(paint_context());
......@@ -254,8 +252,8 @@ TEST_F(OpacityLayerTest, HalfTransparent) {
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds());
EXPECT_EQ(layer->paint_bounds(), expected_layer_bounds);
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(),
SkMatrix::Concat(initial_transform, layer_transform));
EXPECT_EQ(mock_layer->parent_mutators(),
......@@ -329,11 +327,11 @@ TEST_F(OpacityLayerTest, Nested) {
EXPECT_EQ(mock_layer3->paint_bounds(), child3_path.getBounds());
EXPECT_EQ(layer1->paint_bounds(), expected_layer1_bounds);
EXPECT_EQ(layer2->paint_bounds(), expected_layer2_bounds);
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(mock_layer3->needs_painting());
EXPECT_TRUE(layer1->needs_painting());
EXPECT_TRUE(layer2->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer3->needs_painting(paint_context()));
EXPECT_TRUE(layer1->needs_painting(paint_context()));
EXPECT_TRUE(layer2->needs_painting(paint_context()));
EXPECT_EQ(mock_layer1->parent_matrix(),
SkMatrix::Concat(initial_transform, layer1_transform));
// EXPECT_EQ(mock_layer1->parent_mutators(),
......
......@@ -126,7 +126,7 @@ TEST_F(PerformanceOverlayLayerTest, PaintingEmptyLayerDies) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
// Crashes reading a nullptr.
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()), "");
......@@ -143,7 +143,7 @@ TEST_F(PerformanceOverlayLayerTest, InvalidOptions) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), layer_bounds);
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
// Nothing is drawn if options are invalid (0).
layer->Paint(paint_context());
......@@ -161,7 +161,7 @@ TEST_F(PerformanceOverlayLayerTest, SimpleRasterizerStatistics) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), layer_bounds);
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
layer->Paint(paint_context());
auto overlay_text = PerformanceOverlayLayer::MakeStatisticsText(
......
......@@ -45,7 +45,7 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context,
void PhysicalShapeLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "PhysicalShapeLayer::Paint");
FML_DCHECK(needs_painting());
FML_DCHECK(needs_painting(context));
if (elevation_ != 0) {
DrawShadow(context.leaf_nodes_canvas, path_, shadow_color_, elevation_,
......
......@@ -23,11 +23,11 @@ TEST_F(PhysicalShapeLayerTest, PaintingEmptyLayerDies) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(PhysicalShapeLayerTest, PaintBeforePreollDies) {
......@@ -41,7 +41,7 @@ TEST_F(PhysicalShapeLayerTest, PaintBeforePreollDies) {
layer->Add(mock_layer);
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -54,7 +54,7 @@ TEST_F(PhysicalShapeLayerTest, NonEmptyLayer) {
layer_path, Clip::none);
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), layer_path.getBounds());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
SkPaint layer_paint;
......@@ -93,7 +93,7 @@ TEST_F(PhysicalShapeLayerTest, ChildrenLargerThanPath) {
child_paint_bounds.join(child2->paint_bounds());
EXPECT_EQ(layer->paint_bounds(), layer_path.getBounds());
EXPECT_NE(layer->paint_bounds(), child_paint_bounds);
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
SkPaint layer_paint;
......@@ -129,7 +129,7 @@ TEST_F(PhysicalShapeLayerTest, ElevationSimple) {
EXPECT_EQ(layer->paint_bounds(),
PhysicalShapeLayer::ComputeShadowBounds(layer_path.getBounds(),
initial_elevation, 1.0f));
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_EQ(layer->elevation(), initial_elevation);
......@@ -184,7 +184,7 @@ TEST_F(PhysicalShapeLayerTest, ElevationComplex) {
(PhysicalShapeLayer::ComputeShadowBounds(
layer_path.getBounds(), initial_elevations[i],
1.0f /* pixel_ratio */)));
EXPECT_TRUE(layers[i]->needs_painting());
EXPECT_TRUE(layers[i]->needs_painting(paint_context()));
EXPECT_FALSE(layers[i]->needs_system_composite());
}
......
......@@ -45,7 +45,7 @@ void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
void PictureLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "PictureLayer::Paint");
FML_DCHECK(picture_.get());
FML_DCHECK(needs_painting());
FML_DCHECK(needs_painting(context));
SkAutoCanvasRestore save(context.leaf_nodes_canvas, true);
context.leaf_nodes_canvas->translate(offset_.x(), offset_.y());
......
......@@ -39,7 +39,7 @@ TEST_F(PictureLayerTest, PaintBeforePreollDies) {
EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(PictureLayerTest, PaintingEmptyLayerDies) {
......@@ -51,11 +51,11 @@ TEST_F(PictureLayerTest, PaintingEmptyLayerDies) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -81,7 +81,7 @@ TEST_F(PictureLayerTest, SimplePicture) {
EXPECT_EQ(layer->paint_bounds(),
picture_bounds.makeOffset(layer_offset.fX, layer_offset.fY));
EXPECT_EQ(layer->picture(), mock_picture.get());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
layer->Paint(paint_context());
......
......@@ -26,7 +26,7 @@ TEST_F(PlatformViewLayerTest, NullViewEmbedderDoesntPrerollCompositeOrPaint) {
EXPECT_EQ(layer->paint_bounds(),
SkRect::MakeSize(layer_size)
.makeOffset(layer_offset.fX, layer_offset.fY));
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
#if defined(LEGACY_FUCHSIA_EMBEDDER)
EXPECT_TRUE(layer->needs_system_composite());
#else
......
......@@ -23,7 +23,7 @@ void ShaderMaskLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
void ShaderMaskLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "ShaderMaskLayer::Paint");
FML_DCHECK(needs_painting());
FML_DCHECK(needs_painting(context));
Layer::AutoSaveLayer save =
Layer::AutoSaveLayer::Create(context, paint_bounds(), nullptr);
......
......@@ -23,10 +23,10 @@ TEST_F(ShaderMaskLayerTest, PaintingEmptyLayerDies) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(ShaderMaskLayerTest, PaintBeforePreollDies) {
......@@ -39,7 +39,7 @@ TEST_F(ShaderMaskLayerTest, PaintBeforePreollDies) {
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -57,8 +57,8 @@ TEST_F(ShaderMaskLayerTest, EmptyFilter) {
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
EXPECT_EQ(layer->paint_bounds(), child_bounds);
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
SkPaint filter_paint;
......@@ -98,7 +98,7 @@ TEST_F(ShaderMaskLayerTest, SimpleFilter) {
layer->Preroll(preroll_context(), initial_transform);
EXPECT_EQ(layer->paint_bounds(), child_bounds);
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
SkPaint filter_paint;
......@@ -147,9 +147,9 @@ TEST_F(ShaderMaskLayerTest, MultipleChildren) {
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer->paint_bounds(), children_bounds);
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
......@@ -207,10 +207,10 @@ TEST_F(ShaderMaskLayerTest, Nested) {
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
EXPECT_EQ(layer1->paint_bounds(), children_bounds);
EXPECT_EQ(layer2->paint_bounds(), mock_layer2->paint_bounds());
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer1->needs_painting());
EXPECT_TRUE(layer2->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer1->needs_painting(paint_context()));
EXPECT_TRUE(layer2->needs_painting(paint_context()));
EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
......
......@@ -32,6 +32,7 @@ void TextureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
void TextureLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "TextureLayer::Paint");
FML_DCHECK(needs_painting(context));
std::shared_ptr<Texture> texture =
context.texture_registry.GetTexture(texture_id_);
......
......@@ -25,12 +25,13 @@ TEST_F(TextureLayerTest, InvalidTexture) {
EXPECT_EQ(layer->paint_bounds(),
(SkRect::MakeSize(layer_size)
.makeOffset(layer_offset.fX, layer_offset.fY)));
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
layer->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(), std::vector<MockCanvas::DrawCall>());
}
#ifndef NDEBUG
TEST_F(TextureLayerTest, PaintingEmptyLayerDies) {
const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
const SkSize layer_size = SkSize::Make(0.0f, 0.0f);
......@@ -44,15 +45,27 @@ TEST_F(TextureLayerTest, PaintingEmptyLayerDies) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
layer->Paint(paint_context());
EXPECT_EQ(mock_texture->paint_calls(),
std::vector({MockTexture::PaintCall{
mock_canvas(), layer->paint_bounds(), false, nullptr,
kNone_SkFilterQuality}}));
EXPECT_EQ(mock_canvas().draw_calls(), std::vector<MockCanvas::DrawCall>());
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(context\\)");
}
TEST_F(TextureLayerTest, PaintBeforePreollDies) {
const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
const SkSize layer_size = SkSize::Make(8.0f, 8.0f);
const int64_t texture_id = 0;
auto mock_texture = std::make_shared<MockTexture>(texture_id);
auto layer = std::make_shared<TextureLayer>(
layer_offset, layer_size, texture_id, false, kLow_SkFilterQuality);
// Ensure the texture is located by the Layer.
preroll_context()->texture_registry.RegisterTexture(mock_texture);
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(context\\)");
}
#endif
TEST_F(TextureLayerTest, PaintingWithLowFilterQuality) {
const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
......@@ -69,7 +82,7 @@ TEST_F(TextureLayerTest, PaintingWithLowFilterQuality) {
EXPECT_EQ(layer->paint_bounds(),
(SkRect::MakeSize(layer_size)
.makeOffset(layer_offset.fX, layer_offset.fY)));
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
layer->Paint(paint_context());
EXPECT_EQ(mock_texture->paint_calls(),
......
......@@ -70,7 +70,7 @@ void TransformLayer::UpdateScene(std::shared_ptr<SceneUpdateContext> context) {
void TransformLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "TransformLayer::Paint");
FML_DCHECK(needs_painting());
FML_DCHECK(needs_painting(context));
SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
context.internal_nodes_canvas->concat(transform_);
......
......@@ -20,10 +20,10 @@ TEST_F(TransformLayerTest, PaintingEmptyLayerDies) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
EXPECT_FALSE(layer->needs_painting());
EXPECT_FALSE(layer->needs_painting(paint_context()));
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(TransformLayerTest, PaintBeforePreollDies) {
......@@ -34,7 +34,7 @@ TEST_F(TransformLayerTest, PaintBeforePreollDies) {
layer->Add(mock_layer);
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -50,8 +50,8 @@ TEST_F(TransformLayerTest, Identity) {
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds());
EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(), SkMatrix()); // identity
EXPECT_EQ(mock_layer->parent_cull_rect(), cull_rect);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(SkMatrix())}));
......@@ -80,8 +80,8 @@ TEST_F(TransformLayerTest, Simple) {
EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds());
EXPECT_EQ(layer->paint_bounds(),
layer_transform.mapRect(mock_layer->paint_bounds()));
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(mock_layer->parent_matrix(),
SkMatrix::Concat(initial_transform, layer_transform));
EXPECT_EQ(mock_layer->parent_cull_rect(),
......@@ -124,9 +124,9 @@ TEST_F(TransformLayerTest, Nested) {
layer2_transform.mapRect(mock_layer->paint_bounds()));
EXPECT_EQ(layer1->paint_bounds(),
layer1_transform.mapRect(layer2->paint_bounds()));
EXPECT_TRUE(mock_layer->needs_painting());
EXPECT_TRUE(layer2->needs_painting());
EXPECT_TRUE(layer1->needs_painting());
EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
EXPECT_TRUE(layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer1->needs_painting(paint_context()));
EXPECT_EQ(
mock_layer->parent_matrix(),
SkMatrix::Concat(SkMatrix::Concat(initial_transform, layer1_transform),
......@@ -184,10 +184,10 @@ TEST_F(TransformLayerTest, NestedSeparated) {
layer2_transform.mapRect(mock_layer2->paint_bounds()));
EXPECT_EQ(mock_layer1->paint_bounds(), child_path.getBounds());
EXPECT_EQ(layer1->paint_bounds(), expected_layer1_bounds);
EXPECT_TRUE(mock_layer2->needs_painting());
EXPECT_TRUE(layer2->needs_painting());
EXPECT_TRUE(mock_layer1->needs_painting());
EXPECT_TRUE(layer1->needs_painting());
EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
EXPECT_TRUE(layer2->needs_painting(paint_context()));
EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
EXPECT_TRUE(layer1->needs_painting(paint_context()));
EXPECT_EQ(mock_layer1->parent_matrix(),
SkMatrix::Concat(initial_transform, layer1_transform));
EXPECT_EQ(
......
......@@ -171,7 +171,7 @@ std::unique_ptr<RasterCacheResult> RasterCache::RasterizeLayer(
context->has_platform_view ? nullptr : context->raster_cache,
context->checkerboard_offscreen_layers,
context->frame_device_pixel_ratio};
if (layer->needs_painting()) {
if (layer->needs_painting(paintContext)) {
layer->Paint(paintContext);
}
});
......
......@@ -338,7 +338,7 @@ SceneUpdateContext::Frame::~Frame() {
}
void SceneUpdateContext::Frame::AddPaintLayer(Layer* layer) {
FML_DCHECK(layer->needs_painting());
FML_DCHECK(!layer->is_empty());
paint_layers_.push_back(layer);
paint_bounds_.join(layer->paint_bounds());
}
......
......@@ -33,7 +33,7 @@ void MockLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
}
void MockLayer::Paint(PaintContext& context) const {
FML_DCHECK(needs_painting());
FML_DCHECK(needs_painting(context));
context.leaf_nodes_canvas->drawPath(fake_paint_path_, fake_paint_);
}
......
......@@ -19,7 +19,7 @@ TEST_F(MockLayerTest, PaintBeforePreollDies) {
auto layer = std::make_shared<MockLayer>(path, SkPaint());
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
TEST_F(MockLayerTest, PaintingEmptyLayerDies) {
......@@ -29,7 +29,7 @@ TEST_F(MockLayerTest, PaintingEmptyLayerDies) {
EXPECT_EQ(layer->paint_bounds(), SkPath().getBounds());
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"needs_painting\\(\\)");
"needs_painting\\(context\\)");
}
#endif
......@@ -48,7 +48,7 @@ TEST_F(MockLayerTest, SimpleParams) {
layer->Preroll(preroll_context(), start_matrix);
EXPECT_EQ(preroll_context()->has_platform_view, false);
EXPECT_EQ(layer->paint_bounds(), path.getBounds());
EXPECT_TRUE(layer->needs_painting());
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_EQ(layer->parent_mutators(), std::vector{Mutator(scale_matrix)});
EXPECT_EQ(layer->parent_matrix(), start_matrix);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册