forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathimage_dispose_unittests.cc
More file actions
122 lines (99 loc) · 4.18 KB
/
image_dispose_unittests.cc
File metadata and controls
122 lines (99 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// 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.
#define FML_USED_ON_EMBEDDER
#include "flutter/common/task_runners.h"
#include "flutter/fml/synchronization/count_down_latch.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/lib/ui/painting/canvas.h"
#include "flutter/lib/ui/painting/image.h"
#include "flutter/lib/ui/painting/picture.h"
#include "flutter/lib/ui/painting/picture_recorder.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/shell/common/shell_test.h"
#include "flutter/shell/common/thread_host.h"
#include "flutter/testing/testing.h"
namespace flutter {
namespace testing {
class ImageDisposeTest : public ShellTest {
public:
template <class T>
T* GetNativePeer(Dart_Handle handle) {
intptr_t peer = 0;
auto native_handle = Dart_GetNativeInstanceField(
handle, tonic::DartWrappable::kPeerIndex, &peer);
EXPECT_FALSE(Dart_IsError(native_handle)) << Dart_GetError(native_handle);
return reinterpret_cast<T*>(peer);
}
// Used to wait on Dart callbacks or Shell task runner flushing
fml::AutoResetWaitableEvent message_latch_;
sk_sp<DisplayList> current_display_list_;
sk_sp<DlImage> current_image_;
};
TEST_F(ImageDisposeTest, ImageReleasedAfterFrameAndDisposePictureAndLayer) {
auto native_capture_image_and_picture = [&](Dart_NativeArguments args) {
auto image_handle = Dart_GetNativeArgument(args, 0);
auto native_image_handle =
Dart_GetField(image_handle, Dart_NewStringFromCString("_image"));
ASSERT_FALSE(Dart_IsError(native_image_handle))
<< Dart_GetError(native_image_handle);
ASSERT_FALSE(Dart_IsNull(native_image_handle));
CanvasImage* image = GetNativePeer<CanvasImage>(native_image_handle);
Picture* picture = GetNativePeer<Picture>(Dart_GetNativeArgument(args, 1));
ASSERT_FALSE(image->image()->unique());
ASSERT_FALSE(picture->display_list()->unique());
current_display_list_ = picture->display_list();
current_image_ = image->image();
};
auto native_finish = [&](Dart_NativeArguments args) {
message_latch_.Signal();
};
Settings settings = CreateSettingsForFixture();
fml::CountDownLatch frame_latch{2};
settings.frame_rasterized_callback = [&frame_latch](const FrameTiming& t) {
frame_latch.CountDown();
};
auto task_runner = CreateNewThread();
TaskRunners task_runners("test", // label
GetCurrentTaskRunner(), // platform
task_runner, // raster
task_runner, // ui
task_runner // io
);
AddNativeCallback("CaptureImageAndPicture",
CREATE_NATIVE_ENTRY(native_capture_image_and_picture));
AddNativeCallback("Finish", CREATE_NATIVE_ENTRY(native_finish));
std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
ASSERT_TRUE(shell->IsSetup());
SetViewportMetrics(shell.get(), 800, 600);
shell->GetPlatformView()->NotifyCreated();
auto configuration = RunConfiguration::InferFromSettings(settings);
configuration.SetEntrypoint("pumpImage");
shell->RunEngine(std::move(configuration), [&](auto result) {
ASSERT_EQ(result, Engine::RunStatus::Success);
});
message_latch_.Wait();
ASSERT_TRUE(current_display_list_);
ASSERT_TRUE(current_image_);
// Wait for 2 frames to be rasterized. The 2nd frame releases resources of the
// 1st frame.
frame_latch.Wait();
// Force a drain the SkiaUnrefQueue. The engine does this normally as frames
// pump, but we force it here to make the test more deterministic.
message_latch_.Reset();
task_runner->PostTask([&, io_manager = shell->GetIOManager()]() {
io_manager->GetSkiaUnrefQueue()->Drain();
message_latch_.Signal();
});
message_latch_.Wait();
if (current_display_list_) {
EXPECT_TRUE(current_display_list_->unique());
current_display_list_.reset();
}
EXPECT_TRUE(current_image_->unique());
current_image_.reset();
shell->GetPlatformView()->NotifyDestroyed();
DestroyShell(std::move(shell), task_runners);
}
} // namespace testing
} // namespace flutter