Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
shell_io_manager_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/shell/common/shell_io_manager.h"
6
7#include "flutter/common/task_runners.h"
8#include "flutter/fml/mapping.h"
9#include "flutter/lib/ui/painting/multi_frame_codec.h"
10#include "flutter/testing/dart_isolate_runner.h"
11#include "flutter/testing/fixture_test.h"
12#include "flutter/testing/post_task_sync.h"
13#include "flutter/testing/test_gl_surface.h" // nogncheck
14#include "flutter/testing/testing.h"
15
16namespace flutter {
17namespace testing {
18
20
21// Regression test for https://github.com/flutter/engine/pull/32106.
23 ItDoesNotCrashThatSkiaUnrefQueueDrainAfterIOManagerReset) {
24 auto settings = CreateSettingsForFixture();
25 auto vm_ref = DartVMRef::Create(settings);
26 auto vm_data = vm_ref.GetVMData();
27 auto gif_mapping = flutter::testing::OpenFixtureAsSkData("hello_loop_2.gif");
28 ASSERT_TRUE(gif_mapping);
29
31 std::shared_ptr<ImageGenerator> gif_generator =
32 registry.CreateCompatibleGenerator(gif_mapping);
33 ASSERT_TRUE(gif_generator);
34
35 TaskRunners runners(GetCurrentTestName(), // label
36 CreateNewThread("platform"), // platform
37 CreateNewThread("raster"), // raster
38 CreateNewThread("ui"), // ui
39 CreateNewThread("io") // io
40 );
41
42 std::unique_ptr<TestGLSurface> gl_surface;
43 std::unique_ptr<ShellIOManager> io_manager;
45
46 // Setup the IO manager.
47 PostTaskSync(runners.GetIOTaskRunner(), [&]() {
48 gl_surface = std::make_unique<TestGLSurface>(SkISize::Make(1, 1));
49 io_manager = std::make_unique<ShellIOManager>(
50 gl_surface->CreateGrContext(), std::make_shared<fml::SyncSwitch>(),
51 runners.GetIOTaskRunner(), nullptr,
52 fml::TimeDelta::FromMilliseconds(0));
53 });
54
55 auto isolate = RunDartCodeInIsolate(vm_ref, settings, runners, "emptyMain",
57 io_manager->GetWeakIOManager());
58
59 PostTaskSync(runners.GetUITaskRunner(), [&]() {
60 fml::AutoResetWaitableEvent isolate_latch;
61
62 EXPECT_TRUE(isolate->RunInIsolateScope([&]() -> bool {
63 Dart_Handle library = Dart_RootLibrary();
64 if (Dart_IsError(library)) {
65 isolate_latch.Signal();
66 return false;
67 }
68 Dart_Handle closure =
69 Dart_GetField(library, Dart_NewStringFromCString("frameCallback"));
70 if (Dart_IsError(closure) || !Dart_IsClosure(closure)) {
71 isolate_latch.Signal();
72 return false;
73 }
74
75 codec = fml::MakeRefCounted<MultiFrameCodec>(std::move(gif_generator));
76 codec->getNextFrame(closure);
77 isolate_latch.Signal();
78 return true;
79 }));
80 isolate_latch.Wait();
81 });
82
83 // Destroy the IO manager
84 PostTaskSync(runners.GetIOTaskRunner(), [&]() {
85 // 'SkiaUnrefQueue.Drain' will be called after 'io_manager.reset()' in this
86 // test, If the resource context has been destroyed at that time, it will
87 // crash.
88 //
89 // 'Drain()' currently checks whether the weak pointer is still valid or not
90 // before trying to call anything on it.
91 //
92 // However, calling 'unref' on the 'SkImage_Lazy' ends up freeing a
93 // 'GrBackendTexture'. That object seems to assume that something else is
94 // keeping the context alive. This seems like it might be a bad assumption
95 // on Skia's part, but in Skia's defense we're doing something pretty weird
96 // here by keeping GPU resident objects alive without keeping the
97 // 'GrDirectContext' alive ourselves.
98 //
99 // See https://github.com/flutter/flutter/issues/87895
100 io_manager.reset();
101 gl_surface.reset();
102 });
103}
104
105} // namespace testing
106} // namespace flutter
static DartVMRef Create(const Settings &settings, fml::RefPtr< const DartSnapshot > vm_snapshot=nullptr, fml::RefPtr< const DartSnapshot > isolate_snapshot=nullptr)
Keeps a priority-ordered registry of image generator builders to be used when decoding images....
std::shared_ptr< ImageGenerator > CreateCompatibleGenerator(const sk_sp< SkData > &buffer)
Walks the list of image generator builders in descending priority order until a compatible ImageGener...
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
fml::RefPtr< fml::TaskRunner > GetIOTaskRunner() const
std::string GetCurrentTestName()
Gets the name of the currently running test. This is useful in generating logs or assets based on tes...
Definition testing.cc:15
TEST_F(DisplayListTest, Defaults)
void PostTaskSync(const fml::RefPtr< fml::TaskRunner > &task_runner, const std::function< void()> &function)
std::string GetDefaultKernelFilePath()
Returns the default path to kernel_blob.bin. This file is within the directory returned by GetFixture...
Definition testing.cc:19
sk_sp< SkData > OpenFixtureAsSkData(const std::string &fixture_name)
Opens a fixture of the given file name and returns a Skia SkData holding its contents.
Definition testing.cc:64
std::unique_ptr< AutoIsolateShutdown > RunDartCodeInIsolate(DartVMRef &vm_ref, const Settings &settings, const TaskRunners &task_runners, std::string entrypoint, const std::vector< std::string > &args, const std::string &kernel_file_path, fml::WeakPtr< IOManager > io_manager, std::shared_ptr< VolatilePathTracker > volatile_path_tracker, std::unique_ptr< PlatformConfiguration > platform_configuration)