Flutter Engine
The Flutter Engine
path_unittests.cc
Go to the documentation of this file.
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#include "flutter/lib/ui/painting/path.h"
6
7#include <memory>
8
9#include "flutter/common/task_runners.h"
10#include "flutter/fml/synchronization/waitable_event.h"
11#include "flutter/runtime/dart_vm.h"
12#include "flutter/shell/common/shell_test.h"
13#include "flutter/shell/common/thread_host.h"
14#include "flutter/testing/testing.h"
15
16namespace flutter {
17namespace testing {
18
19TEST_F(ShellTest, PathVolatilityOldPathsBecomeNonVolatile) {
20 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
21
22 auto native_validate_path = [message_latch](Dart_NativeArguments args) {
23 auto handle = Dart_GetNativeArgument(args, 0);
24 intptr_t peer = 0;
27 EXPECT_FALSE(Dart_IsError(result));
28 CanvasPath* path = reinterpret_cast<CanvasPath*>(peer);
30 EXPECT_TRUE(path->path().isVolatile());
31 std::shared_ptr<VolatilePathTracker> tracker =
33 EXPECT_TRUE(tracker);
34
35 for (int i = 0; i < VolatilePathTracker::kFramesOfVolatility; i++) {
36 EXPECT_TRUE(path->path().isVolatile());
37 tracker->OnFrame();
38 }
39 EXPECT_FALSE(path->path().isVolatile());
40 message_latch->Signal();
41 };
42
43 Settings settings = CreateSettingsForFixture();
44 TaskRunners task_runners("test", // label
45 GetCurrentTaskRunner(), // platform
46 CreateNewThread(), // raster
47 CreateNewThread(), // ui
48 CreateNewThread() // io
49 );
50
51 AddNativeCallback("ValidatePath", CREATE_NATIVE_ENTRY(native_validate_path));
52
53 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
54
55 ASSERT_TRUE(shell->IsSetup());
57 configuration.SetEntrypoint("createPath");
58
59 shell->RunEngine(std::move(configuration), [](auto result) {
61 });
62
63 message_latch->Wait();
64
65 DestroyShell(std::move(shell), task_runners);
66}
67
68TEST_F(ShellTest, PathVolatilityGCRemovesPathFromTracker) {
70 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
71
72 auto native_validate_path = [message_latch](Dart_NativeArguments args) {
73 auto handle = Dart_GetNativeArgument(args, 0);
74 intptr_t peer = 0;
77 EXPECT_FALSE(Dart_IsError(result));
78 CanvasPath* path = reinterpret_cast<CanvasPath*>(peer);
80 EXPECT_TRUE(path->path().isVolatile());
81 std::shared_ptr<VolatilePathTracker> tracker =
83 EXPECT_TRUE(tracker);
84 EXPECT_EQ(GetLiveTrackedPathCount(tracker), 1ul);
85 EXPECT_TRUE(path->path().isVolatile());
86
87 tracker->OnFrame();
88 EXPECT_EQ(GetLiveTrackedPathCount(tracker), 1ul);
89 EXPECT_TRUE(path->path().isVolatile());
90
91 // simulate GC
92 path->Release();
93 EXPECT_EQ(GetLiveTrackedPathCount(tracker), 0ul);
94
95 tracker->OnFrame();
96 EXPECT_EQ(GetLiveTrackedPathCount(tracker), 0ul);
97
98 message_latch->Signal();
99 };
100
101 Settings settings = CreateSettingsForFixture();
102 TaskRunners task_runners("test", // label
103 GetCurrentTaskRunner(), // platform
104 CreateNewThread(), // raster
105 CreateNewThread(), // ui
106 CreateNewThread() // io
107 );
108
109 AddNativeCallback("ValidatePath", CREATE_NATIVE_ENTRY(native_validate_path));
110
111 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
112
113 ASSERT_TRUE(shell->IsSetup());
114 auto configuration = RunConfiguration::InferFromSettings(settings);
115 configuration.SetEntrypoint("createPath");
116
117 shell->RunEngine(std::move(configuration), [](auto result) {
119 });
120
121 message_latch->Wait();
122
123 DestroyShell(std::move(shell), task_runners);
124}
125
126// Screen diffing tests use deterministic rendering. Allowing a path to be
127// volatile or not for an individual frame can result in minor pixel differences
128// that cause the test to fail.
129// If deterministic rendering is enabled, the tracker should be disabled and
130// paths should always be non-volatile.
131TEST_F(ShellTest, DeterministicRenderingDisablesPathVolatility) {
132 auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
133
134 auto native_validate_path = [message_latch](Dart_NativeArguments args) {
135 auto handle = Dart_GetNativeArgument(args, 0);
136 intptr_t peer = 0;
138 handle, tonic::DartWrappable::kPeerIndex, &peer);
139 EXPECT_FALSE(Dart_IsError(result));
140 CanvasPath* path = reinterpret_cast<CanvasPath*>(peer);
142 EXPECT_FALSE(path->path().isVolatile());
143 std::shared_ptr<VolatilePathTracker> tracker =
145 EXPECT_TRUE(tracker);
146 EXPECT_FALSE(tracker->enabled());
147
148 for (int i = 0; i < VolatilePathTracker::kFramesOfVolatility; i++) {
149 tracker->OnFrame();
150 EXPECT_FALSE(path->path().isVolatile());
151 }
152 EXPECT_FALSE(path->path().isVolatile());
153 message_latch->Signal();
154 };
155
156 Settings settings = CreateSettingsForFixture();
157 settings.skia_deterministic_rendering_on_cpu = true;
158 TaskRunners task_runners("test", // label
159 GetCurrentTaskRunner(), // platform
160 CreateNewThread(), // raster
161 CreateNewThread(), // ui
162 CreateNewThread() // io
163 );
164
165 AddNativeCallback("ValidatePath", CREATE_NATIVE_ENTRY(native_validate_path));
166
167 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
168
169 ASSERT_TRUE(shell->IsSetup());
170 auto configuration = RunConfiguration::InferFromSettings(settings);
171 configuration.SetEntrypoint("createPath");
172
173 shell->RunEngine(std::move(configuration), [](auto result) {
175 });
176
177 message_latch->Wait();
178
179 DestroyShell(std::move(shell), task_runners);
180}
181
182} // namespace testing
183} // namespace flutter
static RunConfiguration InferFromSettings(const Settings &settings, const fml::RefPtr< fml::TaskRunner > &io_worker=nullptr, IsolateLaunchType launch_type=IsolateLaunchType::kNewGroup)
Attempts to infer a run configuration from the settings object. This tries to create a run configurat...
std::shared_ptr< VolatilePathTracker > GetVolatilePathTracker() const
static UIDartState * Current()
static constexpr int kFramesOfVolatility
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
DART_EXPORT Dart_Handle Dart_GetNativeInstanceField(Dart_Handle obj, int index, intptr_t *value)
struct _Dart_NativeArguments * Dart_NativeArguments
Definition: dart_api.h:3019
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GAsyncResult * result
fml::RefPtr< fml::TaskRunner > CreateNewThread(const std::string &name)
fml::RefPtr< fml::TaskRunner > GetCurrentTaskRunner()
TEST_F(DisplayListTest, Defaults)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
#define CREATE_NATIVE_ENTRY(native_entry)
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678