1 | // Copyright 2013 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | #ifndef FLOW_TESTING_MOCK_LAYER_H_ |
6 | #define FLOW_TESTING_MOCK_LAYER_H_ |
7 | |
8 | #include <functional> |
9 | #include <memory> |
10 | #include "flutter/flow/diff_context.h" |
11 | #include "flutter/flow/layers/cacheable_layer.h" |
12 | #include "flutter/flow/layers/container_layer.h" |
13 | #include "flutter/flow/layers/layer.h" |
14 | #include "flutter/flow/layers/layer_raster_cache_item.h" |
15 | #include "flutter/flow/raster_cache.h" |
16 | #include "flutter/flow/raster_cache_item.h" |
17 | |
18 | namespace flutter { |
19 | namespace testing { |
20 | |
21 | // Mock implementation of the |Layer| interface that does nothing but paint |
22 | // the specified |path| into the canvas. It records the |PrerollContext| and |
23 | // |PaintContext| data passed in by its parent |Layer|, so the test can later |
24 | // verify the data against expected values. |
25 | class MockLayer : public Layer { |
26 | public: |
27 | explicit MockLayer(const SkPath& path, DlPaint paint = DlPaint()); |
28 | |
29 | static std::shared_ptr<MockLayer> Make(SkPath path, |
30 | DlPaint paint = DlPaint()) { |
31 | return std::make_shared<MockLayer>(args&: path, args&: paint); |
32 | } |
33 | |
34 | static std::shared_ptr<MockLayer> MakeOpacityCompatible(SkPath path) { |
35 | auto mock_layer = std::make_shared<MockLayer>(args&: path, args: DlPaint()); |
36 | mock_layer->set_fake_opacity_compatible(true); |
37 | return mock_layer; |
38 | } |
39 | |
40 | void Preroll(PrerollContext* context) override; |
41 | void Paint(PaintContext& context) const override; |
42 | |
43 | const MutatorsStack& parent_mutators() { return parent_mutators_; } |
44 | const SkMatrix& parent_matrix() { return parent_matrix_; } |
45 | const SkRect& parent_cull_rect() { return parent_cull_rect_; } |
46 | |
47 | bool IsReplacing(DiffContext* context, const Layer* layer) const override; |
48 | void Diff(DiffContext* context, const Layer* old_layer) override; |
49 | const MockLayer* as_mock_layer() const override { return this; } |
50 | |
51 | bool parent_has_platform_view() { |
52 | return mock_flags_ & kParentHasPlatformView; |
53 | } |
54 | |
55 | bool parent_has_texture_layer() { |
56 | return mock_flags_ & kParentHasTextureLayer; |
57 | } |
58 | |
59 | bool fake_has_platform_view() { return mock_flags_ & kFakeHasPlatformView; } |
60 | |
61 | bool fake_reads_surface() { return mock_flags_ & kFakeReadsSurface; } |
62 | |
63 | bool fake_opacity_compatible() { |
64 | return mock_flags_ & kFakeOpacityCompatible; |
65 | } |
66 | |
67 | bool fake_has_texture_layer() { return mock_flags_ & kFakeHasTextureLayer; } |
68 | |
69 | MockLayer& set_parent_has_platform_view(bool flag) { |
70 | flag ? (mock_flags_ |= kParentHasPlatformView) |
71 | : (mock_flags_ &= ~(kParentHasPlatformView)); |
72 | return *this; |
73 | } |
74 | |
75 | MockLayer& set_parent_has_texture_layer(bool flag) { |
76 | flag ? (mock_flags_ |= kParentHasTextureLayer) |
77 | : (mock_flags_ &= ~(kParentHasTextureLayer)); |
78 | return *this; |
79 | } |
80 | |
81 | MockLayer& set_fake_has_platform_view(bool flag) { |
82 | flag ? (mock_flags_ |= kFakeHasPlatformView) |
83 | : (mock_flags_ &= ~(kFakeHasPlatformView)); |
84 | return *this; |
85 | } |
86 | |
87 | MockLayer& set_fake_reads_surface(bool flag) { |
88 | flag ? (mock_flags_ |= kFakeReadsSurface) |
89 | : (mock_flags_ &= ~(kFakeReadsSurface)); |
90 | return *this; |
91 | } |
92 | |
93 | MockLayer& set_fake_opacity_compatible(bool flag) { |
94 | flag ? (mock_flags_ |= kFakeOpacityCompatible) |
95 | : (mock_flags_ &= ~(kFakeOpacityCompatible)); |
96 | return *this; |
97 | } |
98 | |
99 | MockLayer& set_fake_has_texture_layer(bool flag) { |
100 | flag ? (mock_flags_ |= kFakeHasTextureLayer) |
101 | : (mock_flags_ &= ~(kFakeHasTextureLayer)); |
102 | return *this; |
103 | } |
104 | |
105 | void set_expected_paint_matrix(const SkMatrix& matrix) { |
106 | expected_paint_matrix_ = matrix; |
107 | } |
108 | |
109 | private: |
110 | MutatorsStack parent_mutators_; |
111 | SkMatrix parent_matrix_; |
112 | SkRect parent_cull_rect_ = SkRect::MakeEmpty(); |
113 | SkPath fake_paint_path_; |
114 | DlPaint fake_paint_; |
115 | std::optional<SkMatrix> expected_paint_matrix_; |
116 | |
117 | static constexpr int kParentHasPlatformView = 1 << 0; |
118 | static constexpr int kParentHasTextureLayer = 1 << 1; |
119 | static constexpr int kFakeHasPlatformView = 1 << 2; |
120 | static constexpr int kFakeReadsSurface = 1 << 3; |
121 | static constexpr int kFakeOpacityCompatible = 1 << 4; |
122 | static constexpr int kFakeHasTextureLayer = 1 << 5; |
123 | |
124 | int mock_flags_ = 0; |
125 | |
126 | FML_DISALLOW_COPY_AND_ASSIGN(MockLayer); |
127 | }; |
128 | |
129 | class MockCacheableContainerLayer : public CacheableContainerLayer { |
130 | public: |
131 | // if render more than 3 frames, try to cache itself. |
132 | // if less 3 frames, cache his children |
133 | static std::shared_ptr<MockCacheableContainerLayer> CacheLayerOrChildren() { |
134 | return std::make_shared<MockCacheableContainerLayer>(args: true); |
135 | } |
136 | |
137 | // if render more than 3 frames, try to cache itself. |
138 | // if less 3 frames, cache nothing |
139 | static std::shared_ptr<MockCacheableContainerLayer> CacheLayerOnly() { |
140 | return std::make_shared<MockCacheableContainerLayer>(); |
141 | } |
142 | |
143 | void Preroll(PrerollContext* context) override; |
144 | |
145 | explicit MockCacheableContainerLayer(bool cache_children = false) |
146 | : CacheableContainerLayer(3, cache_children) {} |
147 | }; |
148 | |
149 | class MockLayerCacheableItem : public LayerRasterCacheItem { |
150 | public: |
151 | using LayerRasterCacheItem::LayerRasterCacheItem; |
152 | }; |
153 | class MockCacheableLayer : public MockLayer { |
154 | public: |
155 | explicit MockCacheableLayer(SkPath path, |
156 | DlPaint paint = DlPaint(), |
157 | int render_limit = 3) |
158 | : MockLayer(path, paint) { |
159 | raster_cache_item_ = |
160 | std::make_unique<MockLayerCacheableItem>(args: this, args&: render_limit); |
161 | } |
162 | |
163 | const LayerRasterCacheItem* raster_cache_item() const { |
164 | return raster_cache_item_.get(); |
165 | } |
166 | |
167 | void Preroll(PrerollContext* context) override; |
168 | |
169 | private: |
170 | std::unique_ptr<LayerRasterCacheItem> raster_cache_item_; |
171 | }; |
172 | |
173 | } // namespace testing |
174 | } // namespace flutter |
175 | |
176 | #endif // FLOW_TESTING_MOCK_LAYER_H_ |
177 | |