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_LAYER_TEST_H_
6#define FLOW_TESTING_LAYER_TEST_H_
7
8#include "flutter/flow/layers/layer.h"
9
10#include <optional>
11#include <utility>
12
13#include "flutter/flow/testing/mock_raster_cache.h"
14#include "flutter/fml/macros.h"
15#include "flutter/testing/canvas_test.h"
16#include "flutter/testing/mock_canvas.h"
17#include "third_party/skia/include/core/SkCanvas.h"
18#include "third_party/skia/include/core/SkImageInfo.h"
19#include "third_party/skia/include/utils/SkNWayCanvas.h"
20
21namespace flutter {
22namespace testing {
23
24// This fixture allows generating tests which can |Paint()| and |Preroll()|
25// |Layer|'s.
26// |LayerTest| is a default implementation based on |::testing::Test|.
27//
28// By default the preroll and paint contexts will not use a raster cache.
29// If a test needs to verify the proper operation of a layer in the presence
30// of a raster cache then a number of options can be enabled by using the
31// methods |LayerTestBase::use_null_raster_cache()|,
32// |LayerTestBase::use_mock_raster_cache()| or
33// |LayerTestBase::use_skia_raster_cache()|
34//
35// |BaseT| should be the base test type, such as |::testing::Test| below.
36template <typename BaseT>
37class LayerTestBase : public CanvasTestBase<BaseT> {
38 using TestT = CanvasTestBase<BaseT>;
39
40 public:
41 LayerTestBase()
42 : preroll_context_({
43 nullptr, /* raster_cache */
44 nullptr, /* gr_context */
45 nullptr, /* external_view_embedder */
46 mutators_stack_, TestT::mock_canvas().imageInfo().colorSpace(),
47 kGiantRect, /* cull_rect */
48 false, /* layer reads from surface */
49 raster_time_, ui_time_, texture_registry_,
50 false, /* checkerboard_offscreen_layers */
51 1.0f, /* frame_device_pixel_ratio */
52 false, /* has_platform_view */
53 }),
54 paint_context_({
55 TestT::mock_canvas().internal_canvas(), /* internal_nodes_canvas */
56 &TestT::mock_canvas(), /* leaf_nodes_canvas */
57 nullptr, /* gr_context */
58 nullptr, /* external_view_embedder */
59 raster_time_, ui_time_, texture_registry_,
60 nullptr, /* raster_cache */
61 false, /* checkerboard_offscreen_layers */
62 1.0f, /* frame_device_pixel_ratio */
63 }) {
64 use_null_raster_cache();
65 }
66
67 /**
68 * @brief Use no raster cache in the preroll_context() and
69 * paint_context() structures.
70 *
71 * This method must be called before using the preroll_context() and
72 * paint_context() structures in calls to the Layer::Preroll() and
73 * Layer::Paint() methods. This is the default mode of operation.
74 *
75 * @see use_mock_raster_cache()
76 * @see use_skia_raster_cache()
77 */
78 void use_null_raster_cache() { set_raster_cache_(nullptr); }
79
80 /**
81 * @brief Use a mock raster cache in the preroll_context() and
82 * paint_context() structures.
83 *
84 * This method must be called before using the preroll_context() and
85 * paint_context() structures in calls to the Layer::Preroll() and
86 * Layer::Paint() methods. The mock raster cache behaves like a normal
87 * raster cache with respect to decisions about when layers and pictures
88 * should be cached, but it does not incur the overhead of rendering the
89 * layers or caching the resulting pixels.
90 *
91 * @see use_null_raster_cache()
92 * @see use_skia_raster_cache()
93 */
94 void use_mock_raster_cache() {
95 set_raster_cache_(std::make_unique<MockRasterCache>());
96 }
97
98 /**
99 * @brief Use a normal raster cache in the preroll_context() and
100 * paint_context() structures.
101 *
102 * This method must be called before using the preroll_context() and
103 * paint_context() structures in calls to the Layer::Preroll() and
104 * Layer::Paint() methods. The Skia raster cache will behave identically
105 * to the raster cache typically used when handling a frame on a device
106 * including rendering the contents of pictures and layers to an
107 * SkImage, but using a software rather than a hardware renderer.
108 *
109 * @see use_null_raster_cache()
110 * @see use_mock_raster_cache()
111 */
112 void use_skia_raster_cache() {
113 set_raster_cache_(std::make_unique<RasterCache>());
114 }
115
116 TextureRegistry& texture_regitry() { return texture_registry_; }
117 RasterCache* raster_cache() { return raster_cache_.get(); }
118 PrerollContext* preroll_context() { return &preroll_context_; }
119 Layer::PaintContext& paint_context() { return paint_context_; }
120
121 private:
122 void set_raster_cache_(std::unique_ptr<RasterCache> raster_cache) {
123 raster_cache_ = std::move(raster_cache);
124 preroll_context_.raster_cache = raster_cache_.get();
125 paint_context_.raster_cache = raster_cache_.get();
126 }
127
128 Stopwatch raster_time_;
129 Stopwatch ui_time_;
130 MutatorsStack mutators_stack_;
131 TextureRegistry texture_registry_;
132
133 std::unique_ptr<RasterCache> raster_cache_;
134 PrerollContext preroll_context_;
135 Layer::PaintContext paint_context_;
136
137 FML_DISALLOW_COPY_AND_ASSIGN(LayerTestBase);
138};
139using LayerTest = LayerTestBase<::testing::Test>;
140
141} // namespace testing
142} // namespace flutter
143
144#endif // FLOW_TESTING_LAYER_TEST_H_
145