diff --git a/engine/src/flutter/flow/BUILD.gn b/engine/src/flutter/flow/BUILD.gn index c2c1d06ab6..495d736deb 100644 --- a/engine/src/flutter/flow/BUILD.gn +++ b/engine/src/flutter/flow/BUILD.gn @@ -36,6 +36,7 @@ source_set("flow") { "layers/shader_mask_layer.h", "layers/transform_layer.cc", "layers/transform_layer.h", + "process_info.h", "raster_cache.cc", "raster_cache.h", "scene_update_context.cc", diff --git a/engine/src/flutter/flow/compositor_context.cc b/engine/src/flutter/flow/compositor_context.cc index b5b1c2daf3..2229301246 100644 --- a/engine/src/flutter/flow/compositor_context.cc +++ b/engine/src/flutter/flow/compositor_context.cc @@ -8,7 +8,8 @@ namespace flow { -CompositorContext::CompositorContext() = default; +CompositorContext::CompositorContext(std::unique_ptr info) + : process_info_(std::move(info)) {} CompositorContext::~CompositorContext() = default; @@ -17,6 +18,10 @@ void CompositorContext::BeginFrame(ScopedFrame& frame, if (enable_instrumentation) { frame_count_.Increment(); frame_time_.Start(); + + if (process_info_ && process_info_->SampleNow()) { + memory_usage_.Add(process_info_->GetResidentMemorySize()); + } } } diff --git a/engine/src/flutter/flow/compositor_context.h b/engine/src/flutter/flow/compositor_context.h index a981f75847..c441f11dd3 100644 --- a/engine/src/flutter/flow/compositor_context.h +++ b/engine/src/flutter/flow/compositor_context.h @@ -9,6 +9,7 @@ #include #include "flutter/flow/instrumentation.h" +#include "flutter/flow/process_info.h" #include "flutter/flow/raster_cache.h" #include "lib/ftl/macros.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -46,7 +47,7 @@ class CompositorContext { FTL_DISALLOW_COPY_AND_ASSIGN(ScopedFrame); }; - CompositorContext(); + CompositorContext(std::unique_ptr info); ~CompositorContext(); @@ -62,13 +63,17 @@ class CompositorContext { const Stopwatch& frame_time() const { return frame_time_; } - Stopwatch& engine_time() { return engine_time_; }; + Stopwatch& engine_time() { return engine_time_; } + + const CounterValues& memory_usage() const { return memory_usage_; } private: RasterCache raster_cache_; + std::unique_ptr process_info_; Counter frame_count_; Stopwatch frame_time_; Stopwatch engine_time_; + CounterValues memory_usage_; void BeginFrame(ScopedFrame& frame, bool enable_instrumentation); diff --git a/engine/src/flutter/flow/instrumentation.cc b/engine/src/flutter/flow/instrumentation.cc index 83f8136487..bff1d8120e 100644 --- a/engine/src/flutter/flow/instrumentation.cc +++ b/engine/src/flutter/flow/instrumentation.cc @@ -5,6 +5,7 @@ #include "flutter/flow/instrumentation.h" #include +#include #include "third_party/skia/include/core/SkPath.h" @@ -18,6 +19,8 @@ Stopwatch::Stopwatch() : start_(ftl::TimePoint::Now()), current_sample_(0) { laps_.resize(kMaxSamples, delta); } +Stopwatch::~Stopwatch() = default; + void Stopwatch::Start() { start_ = ftl::TimePoint::Now(); current_sample_ = (current_sample_ + 1) % kMaxSamples; @@ -153,6 +156,93 @@ void Stopwatch::Visualize(SkCanvas& canvas, const SkRect& rect) const { bottom, paint); } -Stopwatch::~Stopwatch() = default; +CounterValues::CounterValues() : current_sample_(kMaxSamples - 1) { + values_.resize(kMaxSamples, 0); +} + +CounterValues::~CounterValues() = default; + +void CounterValues::Add(int64_t value) { + current_sample_ = (current_sample_ + 1) % kMaxSamples; + values_[current_sample_] = value; +} + +void CounterValues::Visualize(SkCanvas& canvas, const SkRect& rect) const { + size_t max_bytes = GetMaxValue(); + + if (max_bytes == 0) { + // The backend for this counter probably did not fill in any values. + return; + } + + size_t min_bytes = GetMinValue(); + + SkPaint paint; + + // Paint the background. + paint.setColor(0x99FFFFFF); + canvas.drawRect(rect, paint); + + // Establish the graph position. + const SkScalar x = rect.x(); + const SkScalar y = rect.y(); + const SkScalar width = rect.width(); + const SkScalar height = rect.height(); + const SkScalar bottom = y + height; + const SkScalar right = x + width; + + // Prepare a path for the data. + SkPath path; + path.moveTo(x, bottom); + + for (size_t i = 0; i < kMaxSamples; ++i) { + int64_t current_bytes = values_[i]; + double ratio = + (double)(current_bytes - min_bytes) / (max_bytes - min_bytes); + path.lineTo(x + (((double)(i) / (double)kMaxSamples) * width), + y + ((1.0 - ratio) * height)); + } + + path.rLineTo(100, 0); + path.lineTo(right, bottom); + path.close(); + + // Draw the graph. + paint.setColor(0xAA0000FF); + canvas.drawPath(path, paint); + + // Paint the vertical marker for the current frame. + const double sample_unit_width = (1.0 / kMaxSamples); + const double sample_margin_unit_width = sample_unit_width / 6.0; + const double sample_margin_width = width * sample_margin_unit_width; + paint.setStyle(SkPaint::Style::kFill_Style); + paint.setColor(SK_ColorGRAY); + double sample_x = + x + width * (static_cast(current_sample_) / kMaxSamples) - + sample_margin_width; + canvas.drawRectCoords(sample_x, y, sample_x + width * sample_unit_width + + sample_margin_width * 2, + bottom, paint); +} + +int64_t CounterValues::GetCurrentValue() const { + return values_[current_sample_]; +} + +int64_t CounterValues::GetMaxValue() const { + auto max = std::numeric_limits::min(); + for (size_t i = 0; i < kMaxSamples; ++i) { + max = std::max(max, values_[i]); + } + return max; +} + +int64_t CounterValues::GetMinValue() const { + auto min = std::numeric_limits::max(); + for (size_t i = 0; i < kMaxSamples; ++i) { + min = std::min(min, values_[i]); + } + return min; +} } // namespace flow diff --git a/engine/src/flutter/flow/instrumentation.h b/engine/src/flutter/flow/instrumentation.h index d4a8c2b82b..95ff658484 100644 --- a/engine/src/flutter/flow/instrumentation.h +++ b/engine/src/flutter/flow/instrumentation.h @@ -18,29 +18,22 @@ static const double kOneFrameMS = 1e3 / 60.0; class Stopwatch { public: - class ScopedLap { - public: - explicit ScopedLap(Stopwatch& stopwatch) : stopwatch_(stopwatch) { - stopwatch_.Start(); - } + Stopwatch(); - ~ScopedLap() { stopwatch_.Stop(); } - - private: - Stopwatch& stopwatch_; - - FTL_DISALLOW_COPY_AND_ASSIGN(ScopedLap); - }; - - explicit Stopwatch(); ~Stopwatch(); const ftl::TimeDelta& LastLap() const; + ftl::TimeDelta CurrentLap() const { return ftl::TimePoint::Now() - start_; } + ftl::TimeDelta MaxDelta() const; + void Visualize(SkCanvas& canvas, const SkRect& rect) const; + void Start(); + void Stop(); + void SetLapTime(const ftl::TimeDelta& delta); private: @@ -53,10 +46,12 @@ class Stopwatch { class Counter { public: - explicit Counter() : count_(0) {} + Counter() : count_(0) {} size_t count() const { return count_; } + void Reset(size_t count = 0) { count_ = count; } + void Increment(size_t count = 1) { count_ += count; } private: @@ -65,6 +60,29 @@ class Counter { FTL_DISALLOW_COPY_AND_ASSIGN(Counter); }; +class CounterValues { + public: + CounterValues(); + + ~CounterValues(); + + void Add(int64_t value); + + void Visualize(SkCanvas& canvas, const SkRect& rect) const; + + int64_t GetCurrentValue() const; + + int64_t GetMaxValue() const; + + int64_t GetMinValue() const; + + private: + std::vector values_; + size_t current_sample_; + + FTL_DISALLOW_COPY_AND_ASSIGN(CounterValues); +}; + } // namespace flow #endif // FLUTTER_FLOW_INSTRUMENTATION_H_ diff --git a/engine/src/flutter/flow/layers/layer.h b/engine/src/flutter/flow/layers/layer.h index f55320d24e..c7db218f12 100644 --- a/engine/src/flutter/flow/layers/layer.h +++ b/engine/src/flutter/flow/layers/layer.h @@ -21,8 +21,8 @@ #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkPicture.h" -#include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkRRect.h" +#include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkXfermode.h" namespace flow { @@ -45,6 +45,7 @@ class Layer { SkCanvas& canvas; const Stopwatch& frame_time; const Stopwatch& engine_time; + const CounterValues& memory_usage; }; virtual void Paint(PaintContext& context) = 0; diff --git a/engine/src/flutter/flow/layers/layer_tree.cc b/engine/src/flutter/flow/layers/layer_tree.cc index c40090967c..367daa8933 100644 --- a/engine/src/flutter/flow/layers/layer_tree.cc +++ b/engine/src/flutter/flow/layers/layer_tree.cc @@ -51,7 +51,8 @@ void LayerTree::UpdateScene(SceneUpdateContext& context, void LayerTree::Paint(CompositorContext::ScopedFrame& frame) { Layer::PaintContext context = {frame.canvas(), frame.context().frame_time(), - frame.context().engine_time()}; + frame.context().engine_time(), + frame.context().memory_usage()}; TRACE_EVENT0("flutter", "LayerTree::Paint"); root_layer_->Paint(context); } diff --git a/engine/src/flutter/flow/layers/performance_overlay_layer.cc b/engine/src/flutter/flow/layers/performance_overlay_layer.cc index 66aa349bcb..df9e06a6b4 100644 --- a/engine/src/flutter/flow/layers/performance_overlay_layer.cc +++ b/engine/src/flutter/flow/layers/performance_overlay_layer.cc @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include -#include #include +#include +#include #include "flutter/flow/layers/performance_overlay_layer.h" @@ -57,6 +57,34 @@ void VisualizeStopWatch(SkCanvas& canvas, } } +void VisualizeCounterValuesBytes(SkCanvas& canvas, + const CounterValues& counter_values, + SkScalar x, + SkScalar y, + SkScalar width, + SkScalar height, + bool show_graph, + bool show_labels, + const std::string& label_prefix) { + const int label_x = 8; // distance from x + const int label_y = -10; // distance from y+height + + if (show_graph) { + SkRect visualization_rect = SkRect::MakeXYWH(x, y, width, height); + counter_values.Visualize(canvas, visualization_rect); + } + + auto current_usage = counter_values.GetCurrentValue(); + + if (show_labels && current_usage > 0) { + std::stringstream stream; + stream.setf(std::ios::fixed | std::ios::showpoint); + stream << std::setprecision(2); + stream << label_prefix << " " << current_usage * 1e-6 << " MB"; + DrawStatisticsText(canvas, stream.str(), x + label_x, y + height + label_y); + } +} + } // namespace PerformanceOverlayLayer::PerformanceOverlayLayer(uint64_t options) @@ -80,6 +108,11 @@ void PerformanceOverlayLayer::Paint(PaintContext& context) { VisualizeStopWatch(context.canvas, context.engine_time, x, y + height, width, height, options_ & kVisualizeEngineStatistics, options_ & kDisplayEngineStatistics, "Engine"); + + VisualizeCounterValuesBytes( + context.canvas, context.memory_usage, x, y + (2 * height), width, height, + options_ & kVisualizeMemoryStatistics, + options_ & kDisplayMemoryStatistics, "Memory (Resident)"); } } // namespace flow diff --git a/engine/src/flutter/flow/layers/performance_overlay_layer.h b/engine/src/flutter/flow/layers/performance_overlay_layer.h index 1eaeb7c9a2..913cbd2d59 100644 --- a/engine/src/flutter/flow/layers/performance_overlay_layer.h +++ b/engine/src/flutter/flow/layers/performance_overlay_layer.h @@ -10,10 +10,12 @@ namespace flow { -const int kDisplayRasterizerStatistics = 0x01; -const int kVisualizeRasterizerStatistics = 0x02; -const int kDisplayEngineStatistics = 0x04; -const int kVisualizeEngineStatistics = 0x08; +const int kDisplayRasterizerStatistics = 1 << 0; +const int kVisualizeRasterizerStatistics = 1 << 1; +const int kDisplayEngineStatistics = 1 << 2; +const int kVisualizeEngineStatistics = 1 << 3; +const int kDisplayMemoryStatistics = 1 << 4; +const int kVisualizeMemoryStatistics = 1 << 5; class PerformanceOverlayLayer : public Layer { public: diff --git a/engine/src/flutter/flow/process_info.h b/engine/src/flutter/flow/process_info.h new file mode 100644 index 0000000000..e009c6a042 --- /dev/null +++ b/engine/src/flutter/flow/process_info.h @@ -0,0 +1,29 @@ +// Copyright 2016 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. + +#ifndef FLUTTER_FLOW_PROCESS_INFO_H_ +#define FLUTTER_FLOW_PROCESS_INFO_H_ + +#include "lib/ftl/macros.h" + +namespace flow { + +/// The CompositorContext attempts to collect information from the process for +/// instrumentation purposes. The compositor does not have the platform +/// specific capabilities to collect this information on its own. The platform +/// can choose to provide this information however. +class ProcessInfo { + public: + virtual bool SampleNow() = 0; + + /// Virtual memory size in bytes. + virtual size_t GetVirtualMemorySize() = 0; + + /// Resident memory size in bytes. + virtual size_t GetResidentMemorySize() = 0; +}; + +} // namespace flow + +#endif // FLUTTER_FLOW_PROCESS_INFO_H_ diff --git a/engine/src/flutter/shell/common/diagnostic/diagnostic_server.cc b/engine/src/flutter/shell/common/diagnostic/diagnostic_server.cc index 8c850b40c9..2fc0c3cfc4 100644 --- a/engine/src/flutter/shell/common/diagnostic/diagnostic_server.cc +++ b/engine/src/flutter/shell/common/diagnostic/diagnostic_server.cc @@ -10,9 +10,9 @@ #include "flutter/flow/compositor_context.h" #include "flutter/runtime/embedder_resources.h" #include "flutter/shell/common/engine.h" +#include "flutter/shell/common/picture_serializer.h" #include "flutter/shell/common/rasterizer.h" #include "flutter/shell/common/shell.h" -#include "flutter/shell/common/picture_serializer.h" #include "lib/ftl/logging.h" #include "lib/tonic/dart_binding_macros.h" #include "lib/tonic/dart_library_natives.h" @@ -125,7 +125,7 @@ void DiagnosticServer::SkiaPictureTask(Dart_Port port_id) { recorder.beginRecording(SkRect::MakeWH(layer_tree->frame_size().width(), layer_tree->frame_size().height())); - flow::CompositorContext compositor_context; + flow::CompositorContext compositor_context(nullptr); flow::CompositorContext::ScopedFrame frame = compositor_context.AcquireFrame( nullptr, recorder.getRecordingCanvas(), false); layer_tree->Raster(frame); diff --git a/engine/src/flutter/shell/common/platform_view_service_protocol.cc b/engine/src/flutter/shell/common/platform_view_service_protocol.cc index b54a52da8b..288c1c310c 100644 --- a/engine/src/flutter/shell/common/platform_view_service_protocol.cc +++ b/engine/src/flutter/shell/common/platform_view_service_protocol.cc @@ -304,7 +304,7 @@ void PlatformViewServiceProtocol::ScreenshotGpuTask(SkBitmap* bitmap) { sk_sp surface = SkSurface::MakeRasterDirect( bitmap->info(), bitmap->getPixels(), bitmap->rowBytes()); - flow::CompositorContext compositor_context; + flow::CompositorContext compositor_context(nullptr); SkCanvas* canvas = surface->getCanvas(); flow::CompositorContext::ScopedFrame frame = compositor_context.AcquireFrame(nullptr, canvas, false); diff --git a/engine/src/flutter/shell/gpu/gpu_rasterizer.cc b/engine/src/flutter/shell/gpu/gpu_rasterizer.cc index 03c55e3853..d351dc700f 100644 --- a/engine/src/flutter/shell/gpu/gpu_rasterizer.cc +++ b/engine/src/flutter/shell/gpu/gpu_rasterizer.cc @@ -16,7 +16,8 @@ namespace shell { -GPURasterizer::GPURasterizer() : weak_factory_(this) { +GPURasterizer::GPURasterizer(std::unique_ptr info) + : compositor_context_(std::move(info)), weak_factory_(this) { auto weak_ptr = weak_factory_.GetWeakPtr(); blink::Threads::Gpu()->PostTask( [weak_ptr]() { Shell::Shared().AddRasterizer(weak_ptr); }); diff --git a/engine/src/flutter/shell/gpu/gpu_rasterizer.h b/engine/src/flutter/shell/gpu/gpu_rasterizer.h index a60e2af36f..4e9699c3d4 100644 --- a/engine/src/flutter/shell/gpu/gpu_rasterizer.h +++ b/engine/src/flutter/shell/gpu/gpu_rasterizer.h @@ -16,7 +16,7 @@ class Surface; class GPURasterizer : public Rasterizer { public: - GPURasterizer(); + GPURasterizer(std::unique_ptr info); ~GPURasterizer() override; diff --git a/engine/src/flutter/shell/platform/android/platform_view_android.cc b/engine/src/flutter/shell/platform/android/platform_view_android.cc index 8dd350f5ef..8abb5cb286 100644 --- a/engine/src/flutter/shell/platform/android/platform_view_android.cc +++ b/engine/src/flutter/shell/platform/android/platform_view_android.cc @@ -62,7 +62,7 @@ class PlatformMessageResponseAndroid : public blink::PlatformMessageResponse { } // namespace PlatformViewAndroid::PlatformViewAndroid() - : PlatformView(std::make_unique()) { + : PlatformView(std::make_unique(nullptr)) { CreateEngine(); // Create the GL surface so that we can setup the resource context. @@ -497,7 +497,7 @@ void PlatformViewAndroid::GetBitmapGpuTask(jobject* pixels_out, sk_sp surface = SkSurface::MakeRasterDirect( image_info, pixels, frame_size.width() * sizeof(jint)); - flow::CompositorContext compositor_context; + flow::CompositorContext compositor_context(nullptr); SkCanvas* canvas = surface->getCanvas(); flow::CompositorContext::ScopedFrame frame = compositor_context.AcquireFrame(nullptr, canvas, false); diff --git a/engine/src/flutter/shell/platform/darwin/common/BUILD.gn b/engine/src/flutter/shell/platform/darwin/common/BUILD.gn index 4ee1941652..27e04c829c 100644 --- a/engine/src/flutter/shell/platform/darwin/common/BUILD.gn +++ b/engine/src/flutter/shell/platform/darwin/common/BUILD.gn @@ -9,8 +9,10 @@ source_set("common") { sources = [ "platform_mac.h", "platform_mac.mm", - "string_conversions.mm", + "process_info_mac.cc", + "process_info_mac.h", "string_conversions.h", + "string_conversions.mm", ] set_sources_assignment_filter(sources_assignment_filter) @@ -19,6 +21,7 @@ source_set("common") { "//base:i18n", "//dart/runtime:libdart", "//flutter/common", + "//flutter/flow", "//flutter/runtime", "//flutter/shell/common", "//flutter/shell/gpu", diff --git a/engine/src/flutter/shell/platform/darwin/common/process_info_mac.cc b/engine/src/flutter/shell/platform/darwin/common/process_info_mac.cc new file mode 100644 index 0000000000..11f70f305a --- /dev/null +++ b/engine/src/flutter/shell/platform/darwin/common/process_info_mac.cc @@ -0,0 +1,36 @@ +// Copyright 2016 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/shell/platform/darwin/common/process_info_mac.h" + +namespace shell { + +ProcessInfoMac::ProcessInfoMac() = default; + +ProcessInfoMac::~ProcessInfoMac() = default; + +bool ProcessInfoMac::SampleNow() { + mach_msg_type_number_t size = MACH_TASK_BASIC_INFO_COUNT; + kern_return_t result = + task_info(mach_task_self(), // + MACH_TASK_BASIC_INFO, // + reinterpret_cast(&last_sample_), // + &size); + if (result == KERN_SUCCESS) { + return true; + } + + last_sample_ = {}; + return false; +} + +size_t ProcessInfoMac::GetVirtualMemorySize() { + return last_sample_.virtual_size; +} + +size_t ProcessInfoMac::GetResidentMemorySize() { + return last_sample_.resident_size; +} + +} // namespace shell diff --git a/engine/src/flutter/shell/platform/darwin/common/process_info_mac.h b/engine/src/flutter/shell/platform/darwin/common/process_info_mac.h new file mode 100644 index 0000000000..b42e93d12a --- /dev/null +++ b/engine/src/flutter/shell/platform/darwin/common/process_info_mac.h @@ -0,0 +1,36 @@ +// Copyright 2016 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. + +#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_COMMON_PROCESS_INFO_MAC_H_ +#define FLUTTER_SHELL_PLATFORM_DARWIN_COMMON_PROCESS_INFO_MAC_H_ + +#include +#include +#include +#include "flutter/flow/process_info.h" +#include "lib/ftl/macros.h" + +namespace shell { + +class ProcessInfoMac : public flow::ProcessInfo { + public: + ProcessInfoMac(); + + ~ProcessInfoMac(); + + bool SampleNow() override; + + size_t GetVirtualMemorySize() override; + + size_t GetResidentMemorySize() override; + + private: + struct mach_task_basic_info last_sample_; + + FTL_DISALLOW_COPY_AND_ASSIGN(ProcessInfoMac); +}; + +} // namespace shell + +#endif // FLUTTER_SHELL_PLATFORM_DARWIN_COMMON_PROCESS_INFO_MAC_H_ diff --git a/engine/src/flutter/shell/platform/darwin/desktop/platform_view_mac.mm b/engine/src/flutter/shell/platform/darwin/desktop/platform_view_mac.mm index 5288ce7cb9..271b4180f1 100644 --- a/engine/src/flutter/shell/platform/darwin/desktop/platform_view_mac.mm +++ b/engine/src/flutter/shell/platform/darwin/desktop/platform_view_mac.mm @@ -13,13 +13,15 @@ #include "flutter/shell/common/switches.h" #include "flutter/shell/gpu/gpu_rasterizer.h" #include "flutter/shell/platform/darwin/common/platform_mac.h" +#include "flutter/shell/platform/darwin/common/process_info_mac.h" #include "flutter/shell/platform/darwin/desktop/vsync_waiter_mac.h" #include "lib/ftl/synchronization/waitable_event.h" namespace shell { PlatformViewMac::PlatformViewMac(NSOpenGLView* gl_view) - : PlatformView(std::make_unique()), + : PlatformView( + std::make_unique(std::make_unique())), opengl_view_([gl_view retain]), resource_loading_context_([[NSOpenGLContext alloc] initWithFormat:gl_view.pixelFormat diff --git a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterView.mm b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterView.mm index d08199fcf9..161157f077 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterView.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/framework/Source/FlutterView.mm @@ -72,7 +72,7 @@ void SnapshotRasterizer(ftl::WeakPtr rasterizer, SkCanvas canvas(bitmap); { - flow::CompositorContext compositor_context; + flow::CompositorContext compositor_context(nullptr); auto frame = compositor_context.AcquireFrame(nullptr, &canvas, false /* instrumentation */); layer_tree->Raster(frame, false /* ignore raster cache. */); diff --git a/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.mm b/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.mm index 8082382c46..b17001fd3b 100644 --- a/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.mm +++ b/engine/src/flutter/shell/platform/darwin/ios/platform_view_ios.mm @@ -14,6 +14,7 @@ #include "base/trace_event/trace_event.h" #include "flutter/common/threads.h" #include "flutter/shell/gpu/gpu_rasterizer.h" +#include "flutter/shell/platform/darwin/common/process_info_mac.h" #include "flutter/shell/platform/darwin/ios/framework/Source/vsync_waiter_ios.h" #include "lib/ftl/synchronization/waitable_event.h" @@ -271,7 +272,8 @@ class IOSGLContext { }; PlatformViewIOS::PlatformViewIOS(CAEAGLLayer* layer) - : PlatformView(std::make_unique()), + : PlatformView( + std::make_unique(std::make_unique())), context_(std::make_unique(surface_config_, layer)), weak_factory_(this) { CreateEngine();