@@ -124,5 +124,62 @@ TEST_F(ShellTest, PathVolatilityGCRemovesPathFromTracker) {
124124 DestroyShell (std::move (shell), std::move (task_runners));
125125}
126126
127+ // Screen diffing tests use deterministic rendering. Allowing a path to be
128+ // volatile or not for an individual frame can result in minor pixel differences
129+ // that cause the test to fail.
130+ // If deterministic rendering is enabled, the tracker should be disabled and
131+ // paths should always be non-volatile.
132+ TEST_F (ShellTest, DeterministicRenderingDisablesPathVolatility) {
133+ auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();
134+
135+ auto native_validate_path = [message_latch](Dart_NativeArguments args) {
136+ auto handle = Dart_GetNativeArgument (args, 0 );
137+ intptr_t peer = 0 ;
138+ Dart_Handle result = Dart_GetNativeInstanceField (
139+ handle, tonic::DartWrappable::kPeerIndex , &peer);
140+ EXPECT_FALSE (Dart_IsError (result));
141+ CanvasPath* path = reinterpret_cast <CanvasPath*>(peer);
142+ EXPECT_TRUE (path);
143+ EXPECT_FALSE (path->path ().isVolatile ());
144+ std::shared_ptr<VolatilePathTracker> tracker =
145+ UIDartState::Current ()->GetVolatilePathTracker ();
146+ EXPECT_TRUE (tracker);
147+ EXPECT_FALSE (tracker->enabled ());
148+
149+ for (int i = 0 ; i < VolatilePathTracker::kFramesOfVolatility ; i++) {
150+ tracker->OnFrame ();
151+ EXPECT_FALSE (path->path ().isVolatile ());
152+ }
153+ EXPECT_FALSE (path->path ().isVolatile ());
154+ message_latch->Signal ();
155+ };
156+
157+ Settings settings = CreateSettingsForFixture ();
158+ settings.skia_deterministic_rendering_on_cpu = true ;
159+ TaskRunners task_runners (" test" , // label
160+ GetCurrentTaskRunner (), // platform
161+ CreateNewThread (), // raster
162+ CreateNewThread (), // ui
163+ CreateNewThread () // io
164+ );
165+
166+ AddNativeCallback (" ValidatePath" , CREATE_NATIVE_ENTRY (native_validate_path));
167+
168+ std::unique_ptr<Shell> shell =
169+ CreateShell (std::move (settings), std::move (task_runners));
170+
171+ ASSERT_TRUE (shell->IsSetup ());
172+ auto configuration = RunConfiguration::InferFromSettings (settings);
173+ configuration.SetEntrypoint (" createPath" );
174+
175+ shell->RunEngine (std::move (configuration), [](auto result) {
176+ ASSERT_EQ (result, Engine::RunStatus::Success);
177+ });
178+
179+ message_latch->Wait ();
180+
181+ DestroyShell (std::move (shell), std::move (task_runners));
182+ }
183+
127184} // namespace testing
128185} // namespace flutter
0 commit comments