From 8becf442f994fcc691ada23dac306988ec29c59c Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Thu, 8 Aug 2019 20:54:43 -0700 Subject: [PATCH] Wire up a concurrent message loop backed SkExecutor for Skia. (#10788) Fixes https://github.com/flutter/flutter/issues/37885 --- ci/licenses_golden/licenses_flutter | 2 ++ runtime/BUILD.gn | 2 ++ runtime/dart_vm.cc | 12 +++++++++++ runtime/dart_vm.h | 2 ++ runtime/skia_concurrent_executor.cc | 26 ++++++++++++++++++++++++ runtime/skia_concurrent_executor.h | 31 +++++++++++++++++++++++++++++ 6 files changed, 75 insertions(+) create mode 100644 runtime/skia_concurrent_executor.cc create mode 100644 runtime/skia_concurrent_executor.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index c44d9bdb7a..15716cf648 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -466,6 +466,8 @@ FILE: ../../../flutter/runtime/runtime_test.cc FILE: ../../../flutter/runtime/runtime_test.h FILE: ../../../flutter/runtime/service_protocol.cc FILE: ../../../flutter/runtime/service_protocol.h +FILE: ../../../flutter/runtime/skia_concurrent_executor.cc +FILE: ../../../flutter/runtime/skia_concurrent_executor.h FILE: ../../../flutter/runtime/start_up.cc FILE: ../../../flutter/runtime/start_up.h FILE: ../../../flutter/runtime/test_font_data.cc diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn index cb404cbee4..87147abde0 100644 --- a/runtime/BUILD.gn +++ b/runtime/BUILD.gn @@ -66,6 +66,8 @@ source_set("runtime") { "runtime_delegate.h", "service_protocol.cc", "service_protocol.h", + "skia_concurrent_executor.cc", + "skia_concurrent_executor.h", "start_up.cc", "start_up.h", ] diff --git a/runtime/dart_vm.cc b/runtime/dart_vm.cc index d68230e172..7606bedeae 100644 --- a/runtime/dart_vm.cc +++ b/runtime/dart_vm.cc @@ -27,6 +27,7 @@ #include "flutter/runtime/ptrace_ios.h" #include "flutter/runtime/start_up.h" #include "third_party/dart/runtime/include/bin/dart_io_api.h" +#include "third_party/skia/include/core/SkExecutor.h" #include "third_party/tonic/converter/dart_converter.h" #include "third_party/tonic/dart_class_library.h" #include "third_party/tonic/dart_class_provider.h" @@ -255,6 +256,9 @@ DartVM::DartVM(std::shared_ptr vm_data, std::shared_ptr isolate_name_server) : settings_(vm_data->GetSettings()), concurrent_message_loop_(fml::ConcurrentMessageLoop::Create()), + skia_concurrent_executor_( + [runner = concurrent_message_loop_->GetTaskRunner()]( + fml::closure work) { runner->PostTask(work); }), vm_data_(vm_data), isolate_name_server_(std::move(isolate_name_server)), service_protocol_(std::make_shared()) { @@ -262,6 +266,10 @@ DartVM::DartVM(std::shared_ptr vm_data, gVMLaunchCount++; + // Setting the executor is not thread safe but Dart VM initialization is. So + // this call is thread-safe. + SkExecutor::SetDefault(&skia_concurrent_executor_); + FML_DCHECK(vm_data_); FML_DCHECK(isolate_name_server_); FML_DCHECK(service_protocol_); @@ -425,6 +433,10 @@ DartVM::DartVM(std::shared_ptr vm_data, } DartVM::~DartVM() { + // Setting the executor is not thread safe but Dart VM shutdown is. So + // this call is thread-safe. + SkExecutor::SetDefault(nullptr); + if (Dart_CurrentIsolate() != nullptr) { Dart_ExitIsolate(); } diff --git a/runtime/dart_vm.h b/runtime/dart_vm.h index 9cc2d811ac..7e8c2a67fd 100644 --- a/runtime/dart_vm.h +++ b/runtime/dart_vm.h @@ -21,6 +21,7 @@ #include "flutter/runtime/dart_snapshot.h" #include "flutter/runtime/dart_vm_data.h" #include "flutter/runtime/service_protocol.h" +#include "flutter/runtime/skia_concurrent_executor.h" #include "third_party/dart/runtime/include/dart_api.h" namespace flutter { @@ -47,6 +48,7 @@ class DartVM { private: const Settings settings_; std::shared_ptr concurrent_message_loop_; + SkiaConcurrentExecutor skia_concurrent_executor_; std::shared_ptr vm_data_; const std::shared_ptr isolate_name_server_; const std::shared_ptr service_protocol_; diff --git a/runtime/skia_concurrent_executor.cc b/runtime/skia_concurrent_executor.cc new file mode 100644 index 0000000000..f8769ba828 --- /dev/null +++ b/runtime/skia_concurrent_executor.cc @@ -0,0 +1,26 @@ +// 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. + +#include "flutter/runtime/skia_concurrent_executor.h" + +#include "flutter/fml/trace_event.h" + +namespace flutter { + +SkiaConcurrentExecutor::SkiaConcurrentExecutor(OnWorkCallback on_work) + : on_work_(on_work) {} + +SkiaConcurrentExecutor::~SkiaConcurrentExecutor() = default; + +void SkiaConcurrentExecutor::add(fml::closure work) { + if (!work) { + return; + } + on_work_([work]() { + TRACE_EVENT0("flutter", "SkiaExecutor"); + work(); + }); +} + +} // namespace flutter diff --git a/runtime/skia_concurrent_executor.h b/runtime/skia_concurrent_executor.h new file mode 100644 index 0000000000..5744726d7d --- /dev/null +++ b/runtime/skia_concurrent_executor.h @@ -0,0 +1,31 @@ +// 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. + +#ifndef FLUTTER_RUNTIME_SKIA_CONCURRENT_EXECUTOR_H_ +#define FLUTTER_RUNTIME_SKIA_CONCURRENT_EXECUTOR_H_ + +#include "flutter/fml/closure.h" +#include "flutter/fml/macros.h" +#include "third_party/skia/include/core/SkExecutor.h" + +namespace flutter { + +class SkiaConcurrentExecutor : public SkExecutor { + public: + using OnWorkCallback = std::function; + SkiaConcurrentExecutor(OnWorkCallback on_work); + + ~SkiaConcurrentExecutor() override; + + void add(fml::closure work) override; + + private: + OnWorkCallback on_work_; + + FML_DISALLOW_COPY_AND_ASSIGN(SkiaConcurrentExecutor); +}; + +} // namespace flutter + +#endif // FLUTTER_RUNTIME_SKIA_CONCURRENT_EXECUTOR_H_ -- GitLab