未验证 提交 572c3435 编写于 作者: F fredlee12345678 提交者: GitHub

add checker board for clip_path,clip_rect,clip_rrect,physical_shap_layer (#20997)

上级 83b9df9d
...@@ -41,6 +41,7 @@ FILE: ../../../flutter/flow/instrumentation.h ...@@ -41,6 +41,7 @@ FILE: ../../../flutter/flow/instrumentation.h
FILE: ../../../flutter/flow/layers/backdrop_filter_layer.cc FILE: ../../../flutter/flow/layers/backdrop_filter_layer.cc
FILE: ../../../flutter/flow/layers/backdrop_filter_layer.h FILE: ../../../flutter/flow/layers/backdrop_filter_layer.h
FILE: ../../../flutter/flow/layers/backdrop_filter_layer_unittests.cc FILE: ../../../flutter/flow/layers/backdrop_filter_layer_unittests.cc
FILE: ../../../flutter/flow/layers/checkerboard_layertree_unittests.cc
FILE: ../../../flutter/flow/layers/child_scene_layer.cc FILE: ../../../flutter/flow/layers/child_scene_layer.cc
FILE: ../../../flutter/flow/layers/child_scene_layer.h FILE: ../../../flutter/flow/layers/child_scene_layer.h
FILE: ../../../flutter/flow/layers/clip_path_layer.cc FILE: ../../../flutter/flow/layers/clip_path_layer.cc
......
...@@ -137,6 +137,7 @@ if (enable_unittests) { ...@@ -137,6 +137,7 @@ if (enable_unittests) {
"flow_test_utils.h", "flow_test_utils.h",
"gl_context_switch_unittests.cc", "gl_context_switch_unittests.cc",
"layers/backdrop_filter_layer_unittests.cc", "layers/backdrop_filter_layer_unittests.cc",
"layers/checkerboard_layertree_unittests.cc",
"layers/clip_path_layer_unittests.cc", "layers/clip_path_layer_unittests.cc",
"layers/clip_rect_layer_unittests.cc", "layers/clip_rect_layer_unittests.cc",
"layers/clip_rrect_layer_unittests.cc", "layers/clip_rrect_layer_unittests.cc",
......
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/flow/layers/clip_path_layer.h"
#include "flutter/flow/layers/clip_rect_layer.h"
#include "flutter/flow/layers/clip_rrect_layer.h"
#include "flutter/flow/layers/physical_shape_layer.h"
#include "flutter/flow/testing/layer_test.h"
#include "flutter/flow/testing/mock_layer.h"
#include "flutter/fml/macros.h"
#include "flutter/testing/mock_canvas.h"
namespace flutter {
namespace testing {
using CheckerBoardLayerTest = LayerTest;
#ifndef NDEBUG
TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerNotCheckBoard) {
const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f);
const SkRect cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 2.0, 4.0);
const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0);
const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
const SkPath child_path = SkPath().addRect(child_bounds);
const SkPaint child_paint = SkPaint(SkColors::kYellow);
const SkPaint clip_paint;
auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
auto layer = std::make_shared<ClipRectLayer>(layer_bounds,
Clip::antiAliasWithSaveLayer);
layer->Add(mock_layer);
SkRect intersect_bounds = layer_bounds;
SkRect child_intersect_bounds = layer_bounds;
intersect_bounds.intersect(cull_bounds);
child_intersect_bounds.intersect(child_bounds);
preroll_context()->cull_rect = cull_bounds; // Cull child
layer->Preroll(preroll_context(), initial_matrix);
EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched
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_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_bounds)}));
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{
1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect,
MockCanvas::kSoft_ClipEdgeStyle}},
MockCanvas::DrawCall{
1,
MockCanvas::SaveLayerData{layer_bounds, clip_paint, nullptr, 2}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerCheckBoard) {
const SkMatrix initial_matrix = SkMatrix::MakeTrans(0.5f, 1.0f);
const SkRect cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 2.0, 4.0);
const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0);
const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
const SkPath child_path = SkPath().addRect(child_bounds);
const SkPaint child_paint = SkPaint(SkColors::kYellow);
const SkPaint clip_paint;
auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
auto layer = std::make_shared<ClipRectLayer>(layer_bounds,
Clip::antiAliasWithSaveLayer);
layer->Add(mock_layer);
SkRect intersect_bounds = layer_bounds;
SkRect child_intersect_bounds = layer_bounds;
intersect_bounds.intersect(cull_bounds);
child_intersect_bounds.intersect(child_bounds);
preroll_context()->cull_rect = cull_bounds; // Cull child
layer->Preroll(preroll_context(), initial_matrix);
EXPECT_EQ(preroll_context()->cull_rect, cull_bounds); // Untouched
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_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_bounds)}));
layer->Paint(check_board_context());
EXPECT_NE(
mock_canvas().draw_calls(),
std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{
1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect,
MockCanvas::kSoft_ClipEdgeStyle}},
MockCanvas::DrawCall{
1,
MockCanvas::SaveLayerData{layer_bounds, clip_paint, nullptr, 2}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerNotCheckBoard) {
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 SkPath child_path = SkPath().addRect(child_bounds);
const SkPath layer_path = SkPath().addRect(layer_bounds);
const SkPaint child_paint = SkPaint(SkColors::kYellow);
const SkPaint clip_paint;
auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
auto layer =
std::make_shared<ClipPathLayer>(layer_path, Clip::antiAliasWithSaveLayer);
layer->Add(mock_layer);
layer->Preroll(preroll_context(), initial_matrix);
EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched
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_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)}));
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{
1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect,
MockCanvas::kSoft_ClipEdgeStyle}},
MockCanvas::DrawCall{
1,
MockCanvas::SaveLayerData{child_bounds, clip_paint, nullptr, 2}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerCheckBoard) {
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 SkPath child_path = SkPath().addRect(child_bounds);
const SkPath layer_path = SkPath().addRect(layer_bounds);
const SkPaint child_paint = SkPaint(SkColors::kYellow);
const SkPaint clip_paint;
auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
auto layer =
std::make_shared<ClipPathLayer>(layer_path, Clip::antiAliasWithSaveLayer);
layer->Add(mock_layer);
layer->Preroll(preroll_context(), initial_matrix);
EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched
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_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)}));
layer->Paint(check_board_context());
EXPECT_NE(
mock_canvas().draw_calls(),
std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{
1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect,
MockCanvas::kSoft_ClipEdgeStyle}},
MockCanvas::DrawCall{
1,
MockCanvas::SaveLayerData{child_bounds, clip_paint, nullptr, 2}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerNotCheckBoard) {
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 SkPath child_path = SkPath().addRect(child_bounds);
const SkRRect layer_rrect = SkRRect::MakeRect(layer_bounds);
const SkPaint child_paint = SkPaint(SkColors::kYellow);
const SkPaint clip_paint;
auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
auto layer = std::make_shared<ClipRRectLayer>(layer_rrect,
Clip::antiAliasWithSaveLayer);
layer->Add(mock_layer);
layer->Preroll(preroll_context(), initial_matrix);
EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched
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_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)}));
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{
1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect,
MockCanvas::kSoft_ClipEdgeStyle}},
MockCanvas::DrawCall{
1,
MockCanvas::SaveLayerData{child_bounds, clip_paint, nullptr, 2}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerCheckBoard) {
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 SkPath child_path = SkPath().addRect(child_bounds);
const SkRRect layer_rrect = SkRRect::MakeRect(layer_bounds);
const SkPaint child_paint = SkPaint(SkColors::kYellow);
const SkPaint clip_paint;
auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
auto layer = std::make_shared<ClipRRectLayer>(layer_rrect,
Clip::antiAliasWithSaveLayer);
layer->Add(mock_layer);
layer->Preroll(preroll_context(), initial_matrix);
EXPECT_EQ(preroll_context()->cull_rect, kGiantRect); // Untouched
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_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)}));
layer->Paint(check_board_context());
EXPECT_NE(
mock_canvas().draw_calls(),
std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{
1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect,
MockCanvas::kSoft_ClipEdgeStyle}},
MockCanvas::DrawCall{
1,
MockCanvas::SaveLayerData{child_bounds, clip_paint, nullptr, 2}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerNotCheckBoard) {
constexpr float initial_elevation = 20.0f;
SkPath layer_path;
const SkRect paint_bounds = SkRect::MakeXYWH(0, 0, 8, 8);
const SkPaint clip_paint;
layer_path.addRect(0, 0, 8, 8).close();
auto layer = std::make_shared<PhysicalShapeLayer>(
SK_ColorGREEN, SK_ColorBLACK, initial_elevation, layer_path,
Clip::antiAliasWithSaveLayer);
layer->Preroll(preroll_context(), SkMatrix());
// The Fuchsia system compositor handles all elevated PhysicalShapeLayers and
// their shadows , so we do not do any painting there.
EXPECT_EQ(layer->paint_bounds(),
PhysicalShapeLayer::ComputeShadowBounds(layer_path.getBounds(),
initial_elevation, 1.0f));
EXPECT_TRUE(layer->needs_painting());
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_EQ(layer->elevation(), initial_elevation);
// The Fuchsia system compositor handles all elevated PhysicalShapeLayers and
// their shadows , so we do not use the direct |Paint()| path there.
#if !defined(LEGACY_FUCHSIA_EMBEDDER)
SkPaint layer_paint;
layer_paint.setColor(SK_ColorGREEN);
layer_paint.setAntiAlias(true);
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector(
{MockCanvas::DrawCall{0, MockCanvas::DrawShadowData{layer_path}},
MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{
1, MockCanvas::ClipRectData{paint_bounds, SkClipOp::kIntersect,
MockCanvas::kSoft_ClipEdgeStyle}},
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{layer->paint_bounds(), clip_paint,
nullptr, 2}},
MockCanvas::DrawCall{2, MockCanvas::DrawPaint{layer_paint}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
#endif
}
TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerCheckBoard) {
constexpr float initial_elevation = 20.0f;
SkPath layer_path;
const SkRect paint_bounds = SkRect::MakeXYWH(0, 0, 8, 8);
const SkPaint clip_paint;
layer_path.addRect(0, 0, 8, 8).close();
auto layer = std::make_shared<PhysicalShapeLayer>(
SK_ColorGREEN, SK_ColorBLACK, initial_elevation, layer_path,
Clip::antiAliasWithSaveLayer);
layer->Preroll(preroll_context(), SkMatrix());
// The Fuchsia system compositor handles all elevated PhysicalShapeLayers and
// their shadows , so we do not do any painting there.
EXPECT_EQ(layer->paint_bounds(),
PhysicalShapeLayer::ComputeShadowBounds(layer_path.getBounds(),
initial_elevation, 1.0f));
EXPECT_TRUE(layer->needs_painting());
EXPECT_FALSE(layer->needs_system_composite());
EXPECT_EQ(layer->elevation(), initial_elevation);
// The Fuchsia system compositor handles all elevated PhysicalShapeLayers and
// their shadows , so we do not use the direct |Paint()| path there.
#if !defined(LEGACY_FUCHSIA_EMBEDDER)
SkPaint layer_paint;
layer_paint.setColor(SK_ColorGREEN);
layer_paint.setAntiAlias(true);
layer->Paint(check_board_context());
EXPECT_NE(
mock_canvas().draw_calls(),
std::vector(
{MockCanvas::DrawCall{0, MockCanvas::DrawShadowData{layer_path}},
MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{
1, MockCanvas::ClipRectData{paint_bounds, SkClipOp::kIntersect,
MockCanvas::kSoft_ClipEdgeStyle}},
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{layer->paint_bounds(), clip_paint,
nullptr, 2}},
MockCanvas::DrawCall{2, MockCanvas::DrawPaint{layer_paint}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
#endif
}
#endif
} // namespace testing
} // namespace flutter
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "flutter/flow/layers/clip_path_layer.h" #include "flutter/flow/layers/clip_path_layer.h"
#include "flutter/flow/paint_utils.h"
#if defined(LEGACY_FUCHSIA_EMBEDDER) #if defined(LEGACY_FUCHSIA_EMBEDDER)
#include "lib/ui/scenic/cpp/commands.h" #include "lib/ui/scenic/cpp/commands.h"
...@@ -70,6 +71,9 @@ void ClipPathLayer::Paint(PaintContext& context) const { ...@@ -70,6 +71,9 @@ void ClipPathLayer::Paint(PaintContext& context) const {
PaintChildren(context); PaintChildren(context);
if (UsesSaveLayer()) { if (UsesSaveLayer()) {
context.internal_nodes_canvas->restore(); context.internal_nodes_canvas->restore();
if (context.checkerboard_offscreen_layers) {
DrawCheckerboard(context.internal_nodes_canvas, paint_bounds());
}
} }
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "flutter/flow/layers/clip_rect_layer.h" #include "flutter/flow/layers/clip_rect_layer.h"
#include "flutter/flow/paint_utils.h"
namespace flutter { namespace flutter {
...@@ -65,6 +66,9 @@ void ClipRectLayer::Paint(PaintContext& context) const { ...@@ -65,6 +66,9 @@ void ClipRectLayer::Paint(PaintContext& context) const {
PaintChildren(context); PaintChildren(context);
if (UsesSaveLayer()) { if (UsesSaveLayer()) {
context.internal_nodes_canvas->restore(); context.internal_nodes_canvas->restore();
if (context.checkerboard_offscreen_layers) {
DrawCheckerboard(context.internal_nodes_canvas, clip_rect_);
}
} }
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "flutter/flow/layers/clip_rrect_layer.h" #include "flutter/flow/layers/clip_rrect_layer.h"
#include "flutter/flow/paint_utils.h"
namespace flutter { namespace flutter {
...@@ -66,6 +67,9 @@ void ClipRRectLayer::Paint(PaintContext& context) const { ...@@ -66,6 +67,9 @@ void ClipRRectLayer::Paint(PaintContext& context) const {
PaintChildren(context); PaintChildren(context);
if (UsesSaveLayer()) { if (UsesSaveLayer()) {
context.internal_nodes_canvas->restore(); context.internal_nodes_canvas->restore();
if (context.checkerboard_offscreen_layers) {
DrawCheckerboard(context.internal_nodes_canvas, paint_bounds());
}
} }
} }
......
...@@ -87,6 +87,12 @@ void PhysicalShapeLayer::Paint(PaintContext& context) const { ...@@ -87,6 +87,12 @@ void PhysicalShapeLayer::Paint(PaintContext& context) const {
PaintChildren(context); PaintChildren(context);
context.internal_nodes_canvas->restoreToCount(saveCount); context.internal_nodes_canvas->restoreToCount(saveCount);
if (UsesSaveLayer()) {
if (context.checkerboard_offscreen_layers) {
DrawCheckerboard(context.internal_nodes_canvas, paint_bounds());
}
}
} }
SkRect PhysicalShapeLayer::ComputeShadowBounds(const SkRect& bounds, SkRect PhysicalShapeLayer::ComputeShadowBounds(const SkRect& bounds,
......
...@@ -60,6 +60,16 @@ class LayerTestBase : public CanvasTestBase<BaseT> { ...@@ -60,6 +60,16 @@ class LayerTestBase : public CanvasTestBase<BaseT> {
nullptr, /* raster_cache */ nullptr, /* raster_cache */
false, /* checkerboard_offscreen_layers */ false, /* checkerboard_offscreen_layers */
1.0f, /* frame_device_pixel_ratio */ 1.0f, /* frame_device_pixel_ratio */
}),
check_board_context_({
TestT::mock_canvas().internal_canvas(), /* internal_nodes_canvas */
&TestT::mock_canvas(), /* leaf_nodes_canvas */
nullptr, /* gr_context */
nullptr, /* external_view_embedder */
raster_time_, ui_time_, texture_registry_,
nullptr, /* raster_cache */
true, /* checkerboard_offscreen_layers */
1.0f, /* frame_device_pixel_ratio */
}) { }) {
use_null_raster_cache(); use_null_raster_cache();
} }
...@@ -117,6 +127,7 @@ class LayerTestBase : public CanvasTestBase<BaseT> { ...@@ -117,6 +127,7 @@ class LayerTestBase : public CanvasTestBase<BaseT> {
RasterCache* raster_cache() { return raster_cache_.get(); } RasterCache* raster_cache() { return raster_cache_.get(); }
PrerollContext* preroll_context() { return &preroll_context_; } PrerollContext* preroll_context() { return &preroll_context_; }
Layer::PaintContext& paint_context() { return paint_context_; } Layer::PaintContext& paint_context() { return paint_context_; }
Layer::PaintContext& check_board_context() { return check_board_context_; }
private: private:
void set_raster_cache_(std::unique_ptr<RasterCache> raster_cache) { void set_raster_cache_(std::unique_ptr<RasterCache> raster_cache) {
...@@ -133,6 +144,7 @@ class LayerTestBase : public CanvasTestBase<BaseT> { ...@@ -133,6 +144,7 @@ class LayerTestBase : public CanvasTestBase<BaseT> {
std::unique_ptr<RasterCache> raster_cache_; std::unique_ptr<RasterCache> raster_cache_;
PrerollContext preroll_context_; PrerollContext preroll_context_;
Layer::PaintContext paint_context_; Layer::PaintContext paint_context_;
Layer::PaintContext check_board_context_;
FML_DISALLOW_COPY_AND_ASSIGN(LayerTestBase); FML_DISALLOW_COPY_AND_ASSIGN(LayerTestBase);
}; };
......
...@@ -190,8 +190,8 @@ void MockCanvas::onDrawPatch(const SkPoint[12], ...@@ -190,8 +190,8 @@ void MockCanvas::onDrawPatch(const SkPoint[12],
FML_DCHECK(false); FML_DCHECK(false);
} }
void MockCanvas::onDrawPaint(const SkPaint&) { void MockCanvas::onDrawPaint(const SkPaint& skPaint) {
FML_DCHECK(false); draw_calls_.emplace_back(DrawCall{current_layer_, DrawPaint{skPaint}});
} }
void MockCanvas::onDrawBehind(const SkPaint&) { void MockCanvas::onDrawBehind(const SkPaint&) {
...@@ -450,5 +450,14 @@ std::ostream& operator<<(std::ostream& os, const MockCanvas::DrawCall& draw) { ...@@ -450,5 +450,14 @@ std::ostream& operator<<(std::ostream& os, const MockCanvas::DrawCall& draw) {
return os << "[Layer: " << draw.layer << ", Data: " << draw.data << "]"; return os << "[Layer: " << draw.layer << ", Data: " << draw.data << "]";
} }
bool operator==(const MockCanvas::DrawPaint& a,
const MockCanvas::DrawPaint& b) {
return a.paint == b.paint;
}
std::ostream& operator<<(std::ostream& os, const MockCanvas::DrawPaint& data) {
return os << data.paint;
}
} // namespace testing } // namespace testing
} // namespace flutter } // namespace flutter
...@@ -108,6 +108,10 @@ class MockCanvas : public SkCanvasVirtualEnforcer<SkCanvas> { ...@@ -108,6 +108,10 @@ class MockCanvas : public SkCanvasVirtualEnforcer<SkCanvas> {
ClipEdgeStyle style; ClipEdgeStyle style;
}; };
struct DrawPaint {
SkPaint paint;
};
// Discriminated union of all the different |DrawCall| types. It is roughly // Discriminated union of all the different |DrawCall| types. It is roughly
// equivalent to the different methods in |SkCanvas|' public API. // equivalent to the different methods in |SkCanvas|' public API.
using DrawCallData = std::variant<SaveData, using DrawCallData = std::variant<SaveData,
...@@ -123,7 +127,8 @@ class MockCanvas : public SkCanvasVirtualEnforcer<SkCanvas> { ...@@ -123,7 +127,8 @@ class MockCanvas : public SkCanvasVirtualEnforcer<SkCanvas> {
DrawShadowData, DrawShadowData,
ClipRectData, ClipRectData,
ClipRRectData, ClipRRectData,
ClipPathData>; ClipPathData,
DrawPaint>;
// A single call made against this canvas. // A single call made against this canvas.
struct DrawCall { struct DrawCall {
...@@ -305,7 +310,10 @@ extern bool operator==(const MockCanvas::DrawCall& a, ...@@ -305,7 +310,10 @@ extern bool operator==(const MockCanvas::DrawCall& a,
const MockCanvas::DrawCall& b); const MockCanvas::DrawCall& b);
extern std::ostream& operator<<(std::ostream& os, extern std::ostream& operator<<(std::ostream& os,
const MockCanvas::DrawCall& draw); const MockCanvas::DrawCall& draw);
extern bool operator==(const MockCanvas::DrawPaint& a,
const MockCanvas::DrawPaint& b);
extern std::ostream& operator<<(std::ostream& os,
const MockCanvas::DrawPaint& data);
} // namespace testing } // namespace testing
} // namespace flutter } // namespace flutter
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册