diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 9c5a5c473d94c..341dd7cce3f33 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -230,6 +230,7 @@ FILE: ../../../flutter/lib/ui/dart_wrapper.h FILE: ../../../flutter/lib/ui/geometry.dart FILE: ../../../flutter/lib/ui/hash_codes.dart FILE: ../../../flutter/lib/ui/hooks.dart +FILE: ../../../flutter/lib/ui/io_manager.h FILE: ../../../flutter/lib/ui/isolate_name_server.dart FILE: ../../../flutter/lib/ui/isolate_name_server/isolate_name_server.cc FILE: ../../../flutter/lib/ui/isolate_name_server/isolate_name_server.h diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index dcfd483638eca..940b377bad8de 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -15,6 +15,7 @@ source_set("ui") { "dart_ui.cc", "dart_ui.h", "dart_wrapper.h", + "io_manager.h", "isolate_name_server/isolate_name_server.cc", "isolate_name_server/isolate_name_server.h", "isolate_name_server/isolate_name_server_natives.cc", diff --git a/lib/ui/io_manager.h b/lib/ui/io_manager.h new file mode 100644 index 0000000000000..cf260e0abb6b3 --- /dev/null +++ b/lib/ui/io_manager.h @@ -0,0 +1,25 @@ +// 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_LIB_UI_IO_MANAGER_H_ +#define FLUTTER_LIB_UI_IO_MANAGER_H_ + +#include "flutter/flow/skia_gpu_object.h" +#include "flutter/fml/memory/weak_ptr.h" +#include "third_party/skia/include/gpu/GrContext.h" + +namespace blink { +// Interface for methods that manage access to the resource GrContext and Skia +// unref queue. Meant to be implemented by the owner of the resource GrContext, +// i.e. the shell's IOManager. +class IOManager { + public: + virtual fml::WeakPtr GetResourceContext() const = 0; + + virtual fml::RefPtr GetSkiaUnrefQueue() const = 0; +}; + +} // namespace blink + +#endif // FLUTTER_LIB_UI_IO_MANAGER_H_ diff --git a/lib/ui/ui_dart_state.cc b/lib/ui/ui_dart_state.cc index 5d0f0d73c72ec..0e0ed99cc9a61 100644 --- a/lib/ui/ui_dart_state.cc +++ b/lib/ui/ui_dart_state.cc @@ -17,8 +17,7 @@ UIDartState::UIDartState(TaskRunners task_runners, TaskObserverAdd add_callback, TaskObserverRemove remove_callback, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr skia_unref_queue, + fml::WeakPtr io_manager, std::string advisory_script_uri, std::string advisory_script_entrypoint, std::string logger_prefix, @@ -27,11 +26,10 @@ UIDartState::UIDartState(TaskRunners task_runners, add_callback_(std::move(add_callback)), remove_callback_(std::move(remove_callback)), snapshot_delegate_(std::move(snapshot_delegate)), - resource_context_(std::move(resource_context)), + io_manager_(std::move(io_manager)), advisory_script_uri_(std::move(advisory_script_uri)), advisory_script_entrypoint_(std::move(advisory_script_entrypoint)), logger_prefix_(std::move(logger_prefix)), - skia_unref_queue_(std::move(skia_unref_queue)), isolate_name_server_(isolate_name_server) { AddOrRemoveTaskObserver(true /* add */); } @@ -78,7 +76,10 @@ const TaskRunners& UIDartState::GetTaskRunners() const { } fml::RefPtr UIDartState::GetSkiaUnrefQueue() const { - return skia_unref_queue_; + if (!io_manager_) { + return nullptr; + } + return io_manager_->GetSkiaUnrefQueue(); } void UIDartState::ScheduleMicrotask(Dart_Handle closure) { @@ -114,7 +115,10 @@ fml::WeakPtr UIDartState::GetSnapshotDelegate() const { } fml::WeakPtr UIDartState::GetResourceContext() const { - return resource_context_; + if (!io_manager_) { + return {}; + } + return io_manager_->GetResourceContext(); } IsolateNameServer* UIDartState::GetIsolateNameServer() { diff --git a/lib/ui/ui_dart_state.h b/lib/ui/ui_dart_state.h index ce81804937f63..0717983065aaf 100644 --- a/lib/ui/ui_dart_state.h +++ b/lib/ui/ui_dart_state.h @@ -14,6 +14,7 @@ #include "flutter/flow/skia_gpu_object.h" #include "flutter/fml/build_config.h" #include "flutter/fml/memory/weak_ptr.h" +#include "flutter/lib/ui/io_manager.h" #include "flutter/lib/ui/isolate_name_server/isolate_name_server.h" #include "flutter/lib/ui/snapshot_delegate.h" #include "third_party/dart/runtime/include/dart_api.h" @@ -72,8 +73,7 @@ class UIDartState : public tonic::DartState { TaskObserverAdd add_callback, TaskObserverRemove remove_callback, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr skia_unref_queue, + fml::WeakPtr io_manager, std::string advisory_script_uri, std::string advisory_script_entrypoint, std::string logger_prefix, @@ -94,14 +94,13 @@ class UIDartState : public tonic::DartState { const TaskObserverAdd add_callback_; const TaskObserverRemove remove_callback_; fml::WeakPtr snapshot_delegate_; - fml::WeakPtr resource_context_; + fml::WeakPtr io_manager_; const std::string advisory_script_uri_; const std::string advisory_script_entrypoint_; const std::string logger_prefix_; Dart_Port main_port_ = ILLEGAL_PORT; std::string debug_name_; std::unique_ptr window_; - fml::RefPtr skia_unref_queue_; tonic::DartMicrotaskQueue microtask_queue_; IsolateNameServer* isolate_name_server_; diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc index 094746b26d0ed..c3a0a4c80373d 100644 --- a/runtime/dart_isolate.cc +++ b/runtime/dart_isolate.cc @@ -35,8 +35,7 @@ std::weak_ptr DartIsolate::CreateRootIsolate( TaskRunners task_runners, std::unique_ptr window, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr unref_queue, + fml::WeakPtr io_manager, std::string advisory_script_uri, std::string advisory_script_entrypoint, Dart_IsolateFlags* flags) { @@ -56,8 +55,7 @@ std::weak_ptr DartIsolate::CreateRootIsolate( std::move(shared_snapshot), // shared snapshot task_runners, // task runners std::move(snapshot_delegate), // snapshot delegate - std::move(resource_context), // resource context - std::move(unref_queue), // skia unref queue + std::move(io_manager), // IO manager advisory_script_uri, // advisory URI advisory_script_entrypoint, // advisory entrypoint nullptr // child isolate preparer will be set when this isolate is @@ -100,8 +98,7 @@ DartIsolate::DartIsolate(DartVM* vm, fml::RefPtr shared_snapshot, TaskRunners task_runners, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr unref_queue, + fml::WeakPtr io_manager, std::string advisory_script_uri, std::string advisory_script_entrypoint, ChildIsolatePreparer child_isolate_preparer) @@ -109,8 +106,7 @@ DartIsolate::DartIsolate(DartVM* vm, vm->GetSettings().task_observer_add, vm->GetSettings().task_observer_remove, std::move(snapshot_delegate), - std::move(resource_context), - std::move(unref_queue), + std::move(io_manager), advisory_script_uri, advisory_script_entrypoint, vm->GetSettings().log_tag, @@ -534,8 +530,7 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate( null_task_runners, // task runners nullptr, // window {}, // snapshot delegate - {}, // resource context - {}, // unref queue + {}, // IO Manager advisory_script_uri == nullptr ? "" : advisory_script_uri, // script uri advisory_script_entrypoint == nullptr @@ -645,8 +640,7 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair( (*raw_embedder_isolate)->GetSharedSnapshot(), // shared_snapshot null_task_runners, // task_runners fml::WeakPtr{}, // snapshot_delegate - fml::WeakPtr{}, // resource_context - nullptr, // unref_queue + fml::WeakPtr{}, // io_manager advisory_script_uri, // advisory_script_uri advisory_script_entrypoint, // advisory_script_entrypoint (*raw_embedder_isolate)->child_isolate_preparer_)); diff --git a/runtime/dart_isolate.h b/runtime/dart_isolate.h index d79cc6c6b6803..f2e0f4a63afc1 100644 --- a/runtime/dart_isolate.h +++ b/runtime/dart_isolate.h @@ -12,6 +12,7 @@ #include "flutter/fml/compiler_specific.h" #include "flutter/fml/macros.h" #include "flutter/fml/mapping.h" +#include "flutter/lib/ui/io_manager.h" #include "flutter/lib/ui/snapshot_delegate.h" #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/window.h" @@ -46,8 +47,7 @@ class DartIsolate : public UIDartState { TaskRunners task_runners, std::unique_ptr window, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr unref_queue, + fml::WeakPtr io_manager, std::string advisory_script_uri, std::string advisory_script_entrypoint, Dart_IsolateFlags* flags = nullptr); @@ -57,8 +57,7 @@ class DartIsolate : public UIDartState { fml::RefPtr shared_snapshot, TaskRunners task_runners, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr unref_queue, + fml::WeakPtr io_manager, std::string advisory_script_uri, std::string advisory_script_entrypoint, ChildIsolatePreparer child_isolate_preparer); diff --git a/runtime/dart_isolate_unittests.cc b/runtime/dart_isolate_unittests.cc index d99e1bfcdbdbb..a68318bf4b8c9 100644 --- a/runtime/dart_isolate_unittests.cc +++ b/runtime/dart_isolate_unittests.cc @@ -36,8 +36,7 @@ TEST_F(DartIsolateTest, RootIsolateCreationAndShutdown) { std::move(task_runners), // task runners nullptr, // window {}, // snapshot delegate - {}, // resource context - nullptr, // unref qeueue + {}, // io manager "main.dart", // advisory uri "main" // advisory entrypoint ); @@ -66,8 +65,7 @@ TEST_F(DartIsolateTest, IsolateShutdownCallbackIsInIsolateScope) { std::move(task_runners), // task runners nullptr, // window {}, // snapshot delegate - {}, // resource context - nullptr, // unref qeueue + {}, // io manager "main.dart", // advisory uri "main" // advisory entrypoint ); diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 359dcb0d52f15..b57f2232acc47 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -21,8 +21,7 @@ RuntimeController::RuntimeController( fml::RefPtr p_shared_snapshot, TaskRunners p_task_runners, fml::WeakPtr p_snapshot_delegate, - fml::WeakPtr p_resource_context, - fml::RefPtr p_unref_queue, + fml::WeakPtr p_io_manager, std::string p_advisory_script_uri, std::string p_advisory_script_entrypoint, std::function p_idle_notification_callback) @@ -32,8 +31,7 @@ RuntimeController::RuntimeController( std::move(p_shared_snapshot), std::move(p_task_runners), std::move(p_snapshot_delegate), - std::move(p_resource_context), - std::move(p_unref_queue), + std::move(p_io_manager), std::move(p_advisory_script_uri), std::move(p_advisory_script_entrypoint), p_idle_notification_callback, @@ -46,8 +44,7 @@ RuntimeController::RuntimeController( fml::RefPtr p_shared_snapshot, TaskRunners p_task_runners, fml::WeakPtr p_snapshot_delegate, - fml::WeakPtr p_resource_context, - fml::RefPtr p_unref_queue, + fml::WeakPtr p_io_manager, std::string p_advisory_script_uri, std::string p_advisory_script_entrypoint, std::function idle_notification_callback, @@ -58,8 +55,7 @@ RuntimeController::RuntimeController( shared_snapshot_(std::move(p_shared_snapshot)), task_runners_(p_task_runners), snapshot_delegate_(p_snapshot_delegate), - resource_context_(p_resource_context), - unref_queue_(p_unref_queue), + io_manager_(p_io_manager), advisory_script_uri_(p_advisory_script_uri), advisory_script_entrypoint_(p_advisory_script_entrypoint), idle_notification_callback_(idle_notification_callback), @@ -71,8 +67,7 @@ RuntimeController::RuntimeController( task_runners_, std::make_unique(this), snapshot_delegate_, - resource_context_, - unref_queue_, + io_manager_, p_advisory_script_uri, p_advisory_script_entrypoint)) { std::shared_ptr root_isolate = root_isolate_.lock(); @@ -120,8 +115,7 @@ std::unique_ptr RuntimeController::Clone() const { shared_snapshot_, // task_runners_, // snapshot_delegate_, // - resource_context_, // - unref_queue_, // + io_manager_, // advisory_script_uri_, // advisory_script_entrypoint_, // idle_notification_callback_, // diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index 0aacc8289043f..c913795b8eba2 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -11,6 +11,7 @@ #include "flutter/common/task_runners.h" #include "flutter/flow/layers/layer_tree.h" #include "flutter/fml/macros.h" +#include "flutter/lib/ui/io_manager.h" #include "flutter/lib/ui/text/font_collection.h" #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/pointer_data_packet.h" @@ -33,8 +34,7 @@ class RuntimeController final : public WindowClient { fml::RefPtr shared_snapshot, TaskRunners task_runners, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr unref_queue, + fml::WeakPtr io_manager, std::string advisory_script_uri, std::string advisory_script_entrypoint, std::function idle_notification_callback); @@ -122,8 +122,7 @@ class RuntimeController final : public WindowClient { fml::RefPtr shared_snapshot_; TaskRunners task_runners_; fml::WeakPtr snapshot_delegate_; - fml::WeakPtr resource_context_; - fml::RefPtr unref_queue_; + fml::WeakPtr io_manager_; std::string advisory_script_uri_; std::string advisory_script_entrypoint_; std::function idle_notification_callback_; @@ -137,8 +136,7 @@ class RuntimeController final : public WindowClient { fml::RefPtr shared_snapshot, TaskRunners task_runners, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr unref_queue, + fml::WeakPtr io_manager, std::string advisory_script_uri, std::string advisory_script_entrypoint, std::function idle_notification_callback, diff --git a/shell/common/engine.cc b/shell/common/engine.cc index aa88479baa755..4e084fa9079c7 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -42,8 +42,7 @@ Engine::Engine(Delegate& delegate, blink::Settings settings, std::unique_ptr animator, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr unref_queue) + fml::WeakPtr io_manager) : delegate_(delegate), settings_(std::move(settings)), animator_(std::move(animator)), @@ -60,8 +59,7 @@ Engine::Engine(Delegate& delegate, std::move(shared_snapshot), // shared snapshot std::move(task_runners), // task runners std::move(snapshot_delegate), // snapshot delegate - std::move(resource_context), // resource context - std::move(unref_queue), // skia unref queue + std::move(io_manager), // io manager settings_.advisory_script_uri, // advisory script uri settings_.advisory_script_entrypoint, // advisory script entrypoint settings_.idle_notification_callback // idle notification callback diff --git a/shell/common/engine.h b/shell/common/engine.h index 2b72592575526..1c241a57a732a 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -22,6 +22,7 @@ #include "flutter/runtime/runtime_controller.h" #include "flutter/runtime/runtime_delegate.h" #include "flutter/shell/common/animator.h" +#include "flutter/shell/common/io_manager.h" #include "flutter/shell/common/rasterizer.h" #include "flutter/shell/common/run_configuration.h" #include "third_party/skia/include/core/SkPicture.h" @@ -61,8 +62,7 @@ class Engine final : public blink::RuntimeDelegate { blink::Settings settings, std::unique_ptr animator, fml::WeakPtr snapshot_delegate, - fml::WeakPtr resource_context, - fml::RefPtr unref_queue); + fml::WeakPtr io_manager); ~Engine() override; diff --git a/shell/common/io_manager.cc b/shell/common/io_manager.cc index c6ff79b644f30..84bbbdc5c763d 100644 --- a/shell/common/io_manager.cc +++ b/shell/common/io_manager.cc @@ -71,8 +71,19 @@ fml::WeakPtr IOManager::GetResourceContext() const { : fml::WeakPtr(); } +void IOManager::UpdateResourceContext(sk_sp resource_context) { + resource_context_ = std::move(resource_context); + resource_context_weak_factory_ = + resource_context_ ? std::make_unique>( + resource_context_.get()) + : nullptr; +} + fml::RefPtr IOManager::GetSkiaUnrefQueue() const { return unref_queue_; } +fml::WeakPtr IOManager::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} } // namespace shell diff --git a/shell/common/io_manager.h b/shell/common/io_manager.h index 2d6ec241d886d..bb20781bf0d66 100644 --- a/shell/common/io_manager.h +++ b/shell/common/io_manager.h @@ -10,11 +10,12 @@ #include "flutter/flow/skia_gpu_object.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" +#include "flutter/lib/ui/io_manager.h" #include "third_party/skia/include/gpu/GrContext.h" namespace shell { -class IOManager { +class IOManager : public blink::IOManager { public: // Convenience methods for platforms to create a GrContext used to supply to // the IOManager. The platforms may create the context themselves if they so @@ -25,11 +26,15 @@ class IOManager { IOManager(sk_sp resource_context, fml::RefPtr unref_queue_task_runner); - ~IOManager(); + virtual ~IOManager(); - fml::WeakPtr GetResourceContext() const; + fml::WeakPtr GetResourceContext() const override; - fml::RefPtr GetSkiaUnrefQueue() const; + void UpdateResourceContext(sk_sp resource_context); + + fml::RefPtr GetSkiaUnrefQueue() const override; + + fml::WeakPtr GetWeakPtr(); private: // Resource context management. diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 5c1429a477ff3..063533462bef1 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -67,22 +67,16 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( // other subsystems. fml::AutoResetWaitableEvent io_latch; std::unique_ptr io_manager; - fml::WeakPtr resource_context; - fml::RefPtr unref_queue; auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner(); fml::TaskRunner::RunNowOrPostTask( io_task_runner, - [&io_latch, // - &io_manager, // - &resource_context, // - &unref_queue, // - &platform_view, // - io_task_runner // + [&io_latch, // + &io_manager, // + &platform_view, // + io_task_runner // ]() { io_manager = std::make_unique( platform_view->CreateResourceContext(), io_task_runner); - resource_context = io_manager->GetResourceContext(); - unref_queue = io_manager->GetSkiaUnrefQueue(); io_latch.Signal(); }); io_latch.Wait(); @@ -119,8 +113,7 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( shared_snapshot = std::move(shared_snapshot), // vsync_waiter = std::move(vsync_waiter), // snapshot_delegate = std::move(snapshot_delegate), // - resource_context = std::move(resource_context), // - unref_queue = std::move(unref_queue) // + io_manager = io_manager->GetWeakPtr() // ]() mutable { const auto& task_runners = shell->GetTaskRunners(); @@ -137,8 +130,7 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( shell->GetSettings(), // std::move(animator), // std::move(snapshot_delegate), // - std::move(resource_context), // - std::move(unref_queue) // + std::move(io_manager) // ); ui_latch.Signal(); })); @@ -433,7 +425,7 @@ void Shell::OnPlatformViewCreated(std::unique_ptr surface) { if (rasterizer) { rasterizer->Setup(std::move(surface)); } - // Step 2: All done. Signal the latch that the platform thread is waiting + // Step 3: All done. Signal the latch that the platform thread is waiting // on. latch.Signal(); }); @@ -445,14 +437,26 @@ void Shell::OnPlatformViewCreated(std::unique_ptr surface) { if (engine) { engine->OnOutputSurfaceCreated(); } - // Step 1: Next, tell the GPU thread that it should create a surface for its + // Step 2: Next, tell the GPU thread that it should create a surface for its // rasterizer. fml::TaskRunner::RunNowOrPostTask(gpu_task_runner, gpu_task); }; - // Step 0: Post a task onto the UI thread to tell the engine that it has an - // output surface. - fml::TaskRunner::RunNowOrPostTask(task_runners_.GetUITaskRunner(), ui_task); + auto io_task = [io_manager = io_manager_->GetWeakPtr(), + platform_view = platform_view_->GetWeakPtr(), + ui_task_runner = task_runners_.GetUITaskRunner(), ui_task] { + if (io_manager) { + io_manager->UpdateResourceContext( + platform_view ? platform_view->CreateResourceContext() : nullptr); + } + // Step 1: Next, post a task on the UI thread to tell the engine that it has + // an output surface. + fml::TaskRunner::RunNowOrPostTask(ui_task_runner, ui_task); + }; + + // Step 0: Tell the IO thread that the PlatformView has a GLContext that can + // be used to create a resource context. + fml::TaskRunner::RunNowOrPostTask(task_runners_.GetIOTaskRunner(), io_task); latch.Wait(); } diff --git a/testing/dart/canvas_test.dart b/testing/dart/canvas_test.dart index 4a14a92da6624..d79950d1f1703 100644 --- a/testing/dart/canvas_test.dart +++ b/testing/dart/canvas_test.dart @@ -16,7 +16,7 @@ void testCanvas(CanvasCallback callback) { } void main() { - test('canvas APIs should not crash', () { + test('canvas APIs should not crash', () async { final Paint paint = Paint(); final Rect rect = Rect.fromLTRB(double.nan, double.nan, double.nan, double.nan); final RRect rrect = RRect.fromRectAndCorners(rect); @@ -29,7 +29,7 @@ void main() { final Canvas recorderCanvas = Canvas(recorder); recorderCanvas.scale(1.0, 1.0); final Picture picture = recorder.endRecording(); - final Image image = picture.toImage(1, 1); + final Image image = await picture.toImage(1, 1); try { Canvas(null, null); } catch (error) { } // ignore: empty_catches try { Canvas(null, rect); } catch (error) { } // ignore: empty_catches diff --git a/testing/dart/encoding_test.dart b/testing/dart/encoding_test.dart index 81e53046fb68c..5b220b77916aa 100644 --- a/testing/dart/encoding_test.dart +++ b/testing/dart/encoding_test.dart @@ -20,7 +20,8 @@ void main() { group('Image.toByteData', () { group('RGBA format', () { test('works with simple image', () async { - final ByteData data = await Square4x4Image.image.toByteData(); + final Image image = await Square4x4Image.image; + final ByteData data = await image.toByteData(); expect(Uint8List.view(data.buffer), Square4x4Image.bytes); }); @@ -35,7 +36,7 @@ void main() { group('Unmodified format', () { test('works with simple image', () async { - final Image image = Square4x4Image.image; + final Image image = await Square4x4Image.image; final ByteData data = await image.toByteData(format: ImageByteFormat.rawUnmodified); expect(Uint8List.view(data.buffer), Square4x4Image.bytes); }); @@ -51,7 +52,7 @@ void main() { group('PNG format', () { test('works with simple image', () async { - final Image image = Square4x4Image.image; + final Image image = await Square4x4Image.image; final ByteData data = await image.toByteData(format: ImageByteFormat.png); final List expected = await readFile('square.png'); expect(Uint8List.view(data.buffer), expected); @@ -63,7 +64,7 @@ void main() { class Square4x4Image { Square4x4Image._(); - static Image get image { + static Future get image async { final double width = _kWidth.toDouble(); final double radius = _kRadius.toDouble(); final double innerWidth = (_kWidth - 2 * _kRadius).toDouble(); @@ -82,7 +83,7 @@ class Square4x4Image { canvas.drawRect(Rect.fromLTWH(0.0, 0.0, width, width), black); canvas.drawRect( Rect.fromLTWH(radius, radius, innerWidth, innerWidth), green); - return recorder.endRecording().toImage(_kWidth, _kWidth); + return await recorder.endRecording().toImage(_kWidth, _kWidth); } static List get bytes { diff --git a/testing/resources/square.png b/testing/resources/square.png index a042cece55163..8cfac8b9849ad 100644 Binary files a/testing/resources/square.png and b/testing/resources/square.png differ