Skip to content

Commit 212fbba

Browse files
authored
Cleanup the IO thread GrContext (flutter#14265)
Fixes flutter#19558 This is tested by the devicelab test fast_scroll_large_images__memory
1 parent 2bd5cc2 commit 212fbba

File tree

4 files changed

+33
-4
lines changed

4 files changed

+33
-4
lines changed

flow/skia_gpu_object.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55
#include "flutter/flow/skia_gpu_object.h"
66

77
#include "flutter/fml/message_loop.h"
8+
#include "flutter/fml/trace_event.h"
89

910
namespace flutter {
1011

1112
SkiaUnrefQueue::SkiaUnrefQueue(fml::RefPtr<fml::TaskRunner> task_runner,
12-
fml::TimeDelta delay)
13+
fml::TimeDelta delay,
14+
fml::WeakPtr<GrContext> context)
1315
: task_runner_(std::move(task_runner)),
1416
drain_delay_(delay),
15-
drain_pending_(false) {}
17+
drain_pending_(false),
18+
context_(context) {}
1619

1720
SkiaUnrefQueue::~SkiaUnrefQueue() {
1821
FML_DCHECK(objects_.empty());
@@ -29,6 +32,7 @@ void SkiaUnrefQueue::Unref(SkRefCnt* object) {
2932
}
3033

3134
void SkiaUnrefQueue::Drain() {
35+
TRACE_EVENT0("flutter", "SkiaUnrefQueue::Drain");
3236
std::deque<SkRefCnt*> skia_objects;
3337
{
3438
std::scoped_lock lock(mutex_);
@@ -39,6 +43,10 @@ void SkiaUnrefQueue::Drain() {
3943
for (SkRefCnt* skia_object : skia_objects) {
4044
skia_object->unref();
4145
}
46+
47+
if (context_ && skia_objects.size() > 0) {
48+
context_->performDeferredCleanup(std::chrono::milliseconds(0));
49+
}
4250
}
4351

4452
} // namespace flutter

flow/skia_gpu_object.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "flutter/fml/memory/weak_ptr.h"
1313
#include "flutter/fml/task_runner.h"
1414
#include "third_party/skia/include/core/SkRefCnt.h"
15+
#include "third_party/skia/include/gpu/GrContext.h"
1516

1617
namespace flutter {
1718

@@ -34,9 +35,14 @@ class SkiaUnrefQueue : public fml::RefCountedThreadSafe<SkiaUnrefQueue> {
3435
std::mutex mutex_;
3536
std::deque<SkRefCnt*> objects_;
3637
bool drain_pending_;
38+
fml::WeakPtr<GrContext> context_;
3739

40+
// The `GrContext* context` is only used for signaling Skia to
41+
// performDeferredCleanup. It can be nullptr when such signaling is not needed
42+
// (e.g., in unit tests).
3843
SkiaUnrefQueue(fml::RefPtr<fml::TaskRunner> task_runner,
39-
fml::TimeDelta delay);
44+
fml::TimeDelta delay,
45+
fml::WeakPtr<GrContext> context = {});
4046

4147
~SkiaUnrefQueue();
4248

flow/skia_gpu_object_unittests.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include "gtest/gtest.h"
1212
#include "third_party/skia/include/core/SkRefCnt.h"
1313

14+
#include <future>
15+
1416
namespace flutter {
1517
namespace testing {
1618

@@ -42,6 +44,18 @@ class SkiaGpuObjectTest : public ThreadTest {
4244
delayed_unref_queue_(fml::MakeRefCounted<SkiaUnrefQueue>(
4345
unref_task_runner(),
4446
fml::TimeDelta::FromSeconds(3))) {
47+
// The unref queues must be created in the same thread of the
48+
// unref_task_runner so the queue can access the same-thread-only WeakPtr of
49+
// the GrContext constructed during the creation.
50+
std::promise<bool> queuesCreated;
51+
unref_task_runner_->PostTask([this, &queuesCreated]() {
52+
unref_queue_ = fml::MakeRefCounted<SkiaUnrefQueue>(
53+
unref_task_runner(), fml::TimeDelta::FromSeconds(0));
54+
delayed_unref_queue_ = fml::MakeRefCounted<SkiaUnrefQueue>(
55+
unref_task_runner(), fml::TimeDelta::FromSeconds(3));
56+
queuesCreated.set_value(true);
57+
});
58+
queuesCreated.get_future().wait();
4559
::testing::FLAGS_gtest_death_test_style = "threadsafe";
4660
}
4761

shell/common/shell_io_manager.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ ShellIOManager::ShellIOManager(
6262
: nullptr),
6363
unref_queue_(fml::MakeRefCounted<flutter::SkiaUnrefQueue>(
6464
std::move(unref_queue_task_runner),
65-
fml::TimeDelta::FromMilliseconds(8))),
65+
fml::TimeDelta::FromMilliseconds(8),
66+
GetResourceContext())),
6667
weak_factory_(this),
6768
is_gpu_disabled_sync_switch_(is_gpu_disabled_sync_switch) {
6869
if (!resource_context_) {

0 commit comments

Comments
 (0)