| // 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. | |
| #ifndef FLOW_TESTING_MOCK_LAYER_H_ | |
| #define FLOW_TESTING_MOCK_LAYER_H_ | |
| #include <functional> | |
| #include <memory> | |
| #include "flutter/flow/diff_context.h" | |
| #include "flutter/flow/layers/cacheable_layer.h" | |
| #include "flutter/flow/layers/container_layer.h" | |
| #include "flutter/flow/layers/layer.h" | |
| #include "flutter/flow/layers/layer_raster_cache_item.h" | |
| #include "flutter/flow/raster_cache.h" | |
| #include "flutter/flow/raster_cache_item.h" | |
| namespace flutter { | |
| namespace testing { | |
| // Mock implementation of the |Layer| interface that does nothing but paint | |
| // the specified |path| into the canvas. It records the |PrerollContext| and | |
| // |PaintContext| data passed in by its parent |Layer|, so the test can later | |
| // verify the data against expected values. | |
| class MockLayer : public Layer { | |
| public: | |
| explicit MockLayer(const SkPath& path, DlPaint paint = DlPaint()); | |
| static std::shared_ptr<MockLayer> Make(SkPath path, | |
| DlPaint paint = DlPaint()) { | |
| return std::make_shared<MockLayer>(path, paint); | |
| } | |
| static std::shared_ptr<MockLayer> MakeOpacityCompatible(SkPath path) { | |
| auto mock_layer = std::make_shared<MockLayer>(path, DlPaint()); | |
| mock_layer->set_fake_opacity_compatible(true); | |
| return mock_layer; | |
| } | |
| void Preroll(PrerollContext* context) override; | |
| void Paint(PaintContext& context) const override; | |
| const MutatorsStack& parent_mutators() { return parent_mutators_; } | |
| const SkMatrix& parent_matrix() { return parent_matrix_; } | |
| const SkRect& parent_cull_rect() { return parent_cull_rect_; } | |
| bool IsReplacing(DiffContext* context, const Layer* layer) const override; | |
| void Diff(DiffContext* context, const Layer* old_layer) override; | |
| const MockLayer* as_mock_layer() const override { return this; } | |
| bool parent_has_platform_view() { | |
| return mock_flags_ & kParentHasPlatformView; | |
| } | |
| bool parent_has_texture_layer() { | |
| return mock_flags_ & kParentHasTextureLayer; | |
| } | |
| bool fake_has_platform_view() { return mock_flags_ & kFakeHasPlatformView; } | |
| bool fake_reads_surface() { return mock_flags_ & kFakeReadsSurface; } | |
| bool fake_opacity_compatible() { | |
| return mock_flags_ & kFakeOpacityCompatible; | |
| } | |
| bool fake_has_texture_layer() { return mock_flags_ & kFakeHasTextureLayer; } | |
| MockLayer& set_parent_has_platform_view(bool flag) { | |
| flag ? (mock_flags_ |= kParentHasPlatformView) | |
| : (mock_flags_ &= ~(kParentHasPlatformView)); | |
| return *this; | |
| } | |
| MockLayer& set_parent_has_texture_layer(bool flag) { | |
| flag ? (mock_flags_ |= kParentHasTextureLayer) | |
| : (mock_flags_ &= ~(kParentHasTextureLayer)); | |
| return *this; | |
| } | |
| MockLayer& set_fake_has_platform_view(bool flag) { | |
| flag ? (mock_flags_ |= kFakeHasPlatformView) | |
| : (mock_flags_ &= ~(kFakeHasPlatformView)); | |
| return *this; | |
| } | |
| MockLayer& set_fake_reads_surface(bool flag) { | |
| flag ? (mock_flags_ |= kFakeReadsSurface) | |
| : (mock_flags_ &= ~(kFakeReadsSurface)); | |
| return *this; | |
| } | |
| MockLayer& set_fake_opacity_compatible(bool flag) { | |
| flag ? (mock_flags_ |= kFakeOpacityCompatible) | |
| : (mock_flags_ &= ~(kFakeOpacityCompatible)); | |
| return *this; | |
| } | |
| MockLayer& set_fake_has_texture_layer(bool flag) { | |
| flag ? (mock_flags_ |= kFakeHasTextureLayer) | |
| : (mock_flags_ &= ~(kFakeHasTextureLayer)); | |
| return *this; | |
| } | |
| void set_expected_paint_matrix(const SkMatrix& matrix) { | |
| expected_paint_matrix_ = matrix; | |
| } | |
| private: | |
| MutatorsStack parent_mutators_; | |
| SkMatrix parent_matrix_; | |
| SkRect parent_cull_rect_ = SkRect::MakeEmpty(); | |
| SkPath fake_paint_path_; | |
| DlPaint fake_paint_; | |
| std::optional<SkMatrix> expected_paint_matrix_; | |
| static constexpr int kParentHasPlatformView = 1 << 0; | |
| static constexpr int kParentHasTextureLayer = 1 << 1; | |
| static constexpr int kFakeHasPlatformView = 1 << 2; | |
| static constexpr int kFakeReadsSurface = 1 << 3; | |
| static constexpr int kFakeOpacityCompatible = 1 << 4; | |
| static constexpr int kFakeHasTextureLayer = 1 << 5; | |
| int mock_flags_ = 0; | |
| FML_DISALLOW_COPY_AND_ASSIGN(MockLayer); | |
| }; | |
| class MockCacheableContainerLayer : public CacheableContainerLayer { | |
| public: | |
| // if render more than 3 frames, try to cache itself. | |
| // if less 3 frames, cache his children | |
| static std::shared_ptr<MockCacheableContainerLayer> CacheLayerOrChildren() { | |
| return std::make_shared<MockCacheableContainerLayer>(true); | |
| } | |
| // if render more than 3 frames, try to cache itself. | |
| // if less 3 frames, cache nothing | |
| static std::shared_ptr<MockCacheableContainerLayer> CacheLayerOnly() { | |
| return std::make_shared<MockCacheableContainerLayer>(); | |
| } | |
| void Preroll(PrerollContext* context) override; | |
| explicit MockCacheableContainerLayer(bool cache_children = false) | |
| : CacheableContainerLayer(3, cache_children) {} | |
| }; | |
| class MockLayerCacheableItem : public LayerRasterCacheItem { | |
| public: | |
| using LayerRasterCacheItem::LayerRasterCacheItem; | |
| }; | |
| class MockCacheableLayer : public MockLayer { | |
| public: | |
| explicit MockCacheableLayer(SkPath path, | |
| DlPaint paint = DlPaint(), | |
| int render_limit = 3) | |
| : MockLayer(path, paint) { | |
| raster_cache_item_ = | |
| std::make_unique<MockLayerCacheableItem>(this, render_limit); | |
| } | |
| const LayerRasterCacheItem* raster_cache_item() const { | |
| return raster_cache_item_.get(); | |
| } | |
| void Preroll(PrerollContext* context) override; | |
| private: | |
| std::unique_ptr<LayerRasterCacheItem> raster_cache_item_; | |
| }; | |
| } // namespace testing | |
| } // namespace flutter | |
| #endif // FLOW_TESTING_MOCK_LAYER_H_ |