From dd2fb3c04bb090915b698266ace8680d2747c9db Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Tue, 18 Jul 2017 11:45:34 -0700 Subject: [PATCH] Accumulate a batch of Skia objects that will be destructed later on the IO thread (#3888) See https://github.com/dart-lang/sdk/issues/29971 --- lib/ui/BUILD.gn | 1 + lib/ui/painting/utils.cc | 48 +++++++++++++++++++++++++ lib/ui/painting/utils.h | 24 +++++++++++-- travis/licenses_golden/licenses_flutter | 1 + 4 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 lib/ui/painting/utils.cc diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index fd02dab359265..8c0dbded343ea 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -42,6 +42,7 @@ source_set("ui") { "painting/rrect.h", "painting/shader.cc", "painting/shader.h", + "painting/utils.cc", "painting/utils.h", "painting/vertices.cc", "painting/vertices.h", diff --git a/lib/ui/painting/utils.cc b/lib/ui/painting/utils.cc new file mode 100644 index 0000000000000..c6ee205fdd2e8 --- /dev/null +++ b/lib/ui/painting/utils.cc @@ -0,0 +1,48 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/common/threads.h" +#include "flutter/lib/ui/painting/utils.h" + +namespace blink { + +namespace { + +constexpr ftl::TimeDelta kDrainDelay = ftl::TimeDelta::FromMilliseconds(250); + +} // anonymous namespace + +SkiaUnrefQueue::SkiaUnrefQueue() + : drain_pending_(false) {} + +SkiaUnrefQueue SkiaUnrefQueue::instance_; + +SkiaUnrefQueue& SkiaUnrefQueue::Get() { + return instance_; +} + +void SkiaUnrefQueue::Unref(SkRefCnt* object) { + ftl::MutexLocker lock(&mutex_); + objects_.push_back(object); + if (!drain_pending_) { + drain_pending_ = true; + Threads::IO()->PostDelayedTask([this] { Drain(); }, + kDrainDelay); + } +} + +void SkiaUnrefQueue::Drain() { + std::deque skia_objects; + { + ftl::MutexLocker lock(&mutex_); + objects_.swap(skia_objects); + drain_pending_ = false; + } + + for (SkRefCnt* skia_object : skia_objects) { + skia_object->unref(); + } +} + +} // namespace blink diff --git a/lib/ui/painting/utils.h b/lib/ui/painting/utils.h index ed194ca82ca36..eedd9f929f967 100644 --- a/lib/ui/painting/utils.h +++ b/lib/ui/painting/utils.h @@ -2,15 +2,35 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/common/threads.h" +#include "lib/ftl/synchronization/mutex.h" #include "third_party/skia/include/core/SkRefCnt.h" +#include + namespace blink { +// A queue that holds Skia objects that must be destructed on the IO thread. +class SkiaUnrefQueue { + public: + static SkiaUnrefQueue& Get(); + + void Unref(SkRefCnt* object); + + private: + SkiaUnrefQueue(); + void Drain(); + + static SkiaUnrefQueue instance_; + + ftl::Mutex mutex_; + std::deque objects_ FTL_GUARDED_BY(mutex_); + bool drain_pending_ FTL_GUARDED_BY(mutex_); +}; + template void SkiaUnrefOnIOThread(sk_sp* sp) { T* object = sp->release(); if (object) { - Threads::IO()->PostTask([object]() { object->unref(); }); + SkiaUnrefQueue::Get().Unref(object); } } diff --git a/travis/licenses_golden/licenses_flutter b/travis/licenses_golden/licenses_flutter index d907d2f71fee4..956cc695f942f 100644 --- a/travis/licenses_golden/licenses_flutter +++ b/travis/licenses_golden/licenses_flutter @@ -1424,6 +1424,7 @@ FILE: ../../../flutter/fml/thread_local_unittests.cc FILE: ../../../flutter/fml/thread_unittests.cc FILE: ../../../flutter/fml/trace_event.cc FILE: ../../../flutter/fml/trace_event.h +FILE: ../../../flutter/lib/ui/painting/utils.cc FILE: ../../../flutter/lib/ui/painting/vertices.cc FILE: ../../../flutter/lib/ui/painting/vertices.h FILE: ../../../flutter/shell/gpu/gpu_surface_software.cc