diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 47c7316edfcd6..54d1bd938b4ea 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -48,11 +48,12 @@ source_set("flow") { "matrix_decomposition.h", "paint_utils.cc", "paint_utils.h", - "process_info.h", "raster_cache.cc", "raster_cache.h", "raster_cache_key.cc", "raster_cache_key.h", + "skia_gpu_object.cc", + "skia_gpu_object.h", "texture.cc", "texture.h", ] @@ -61,12 +62,11 @@ source_set("flow") { "//garnet/public/lib/fxl", ] - public_configs = [ - "$flutter_root:config", - ] + public_configs = [ "$flutter_root:config" ] deps = [ "$flutter_root/common", + "$flutter_root/fml", "$flutter_root/glue", "$flutter_root/synchronization", "//third_party/skia", @@ -103,8 +103,8 @@ executable("flow_unittests") { deps = [ ":flow", - "//third_party/dart/runtime:libdart_jit", # for tracing "$flutter_root/testing", + "//third_party/dart/runtime:libdart_jit", # for tracing "//third_party/skia", ] } diff --git a/flow/compositor_context.cc b/flow/compositor_context.cc index e0d17229e7981..53659103be9f1 100644 --- a/flow/compositor_context.cc +++ b/flow/compositor_context.cc @@ -4,12 +4,12 @@ #include "flutter/flow/compositor_context.h" +#include "flutter/flow/layers/layer_tree.h" #include "third_party/skia/include/core/SkCanvas.h" namespace flow { -CompositorContext::CompositorContext(std::unique_ptr info) - : process_info_(std::move(info)) {} +CompositorContext::CompositorContext() = default; CompositorContext::~CompositorContext() = default; @@ -18,10 +18,6 @@ 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()); - } } } @@ -33,11 +29,12 @@ void CompositorContext::EndFrame(ScopedFrame& frame, } } -CompositorContext::ScopedFrame CompositorContext::AcquireFrame( +std::unique_ptr CompositorContext::AcquireFrame( GrContext* gr_context, SkCanvas* canvas, bool instrumentation_enabled) { - return ScopedFrame(*this, gr_context, canvas, instrumentation_enabled); + return std::make_unique(*this, gr_context, canvas, + instrumentation_enabled); } CompositorContext::ScopedFrame::ScopedFrame(CompositorContext& context, @@ -51,18 +48,23 @@ CompositorContext::ScopedFrame::ScopedFrame(CompositorContext& context, context_.BeginFrame(*this, instrumentation_enabled_); } -CompositorContext::ScopedFrame::ScopedFrame(ScopedFrame&& frame) = default; - CompositorContext::ScopedFrame::~ScopedFrame() { context_.EndFrame(*this, instrumentation_enabled_); } +bool CompositorContext::ScopedFrame::Raster(flow::LayerTree& layer_tree, + bool ignore_raster_cache) { + layer_tree.Preroll(*this, ignore_raster_cache); + layer_tree.Paint(*this); + return true; +} + void CompositorContext::OnGrContextCreated() { - texture_registry_->OnGrContextCreated(); + texture_registry_.OnGrContextCreated(); } void CompositorContext::OnGrContextDestroyed() { - texture_registry_->OnGrContextDestroyed(); + texture_registry_.OnGrContextDestroyed(); raster_cache_.Clear(); } diff --git a/flow/compositor_context.h b/flow/compositor_context.h index 2d310422747b7..14c2449dbecd0 100644 --- a/flow/compositor_context.h +++ b/flow/compositor_context.h @@ -9,7 +9,6 @@ #include #include "flutter/flow/instrumentation.h" -#include "flutter/flow/process_info.h" #include "flutter/flow/raster_cache.h" #include "flutter/flow/texture.h" #include "lib/fxl/macros.h" @@ -18,19 +17,26 @@ namespace flow { +class LayerTree; + class CompositorContext { public: class ScopedFrame { public: + ScopedFrame(CompositorContext& context, + GrContext* gr_context, + SkCanvas* canvas, + bool instrumentation_enabled); + + virtual ~ScopedFrame(); + SkCanvas* canvas() { return canvas_; } CompositorContext& context() const { return context_; } GrContext* gr_context() const { return gr_context_; } - ScopedFrame(ScopedFrame&& frame); - - ~ScopedFrame(); + virtual bool Raster(LayerTree& layer_tree, bool ignore_raster_cache); private: CompositorContext& context_; @@ -38,23 +44,17 @@ class CompositorContext { SkCanvas* canvas_; const bool instrumentation_enabled_; - ScopedFrame(CompositorContext& context, - GrContext* gr_context, - SkCanvas* canvas, - bool instrumentation_enabled); - - friend class CompositorContext; - FXL_DISALLOW_COPY_AND_ASSIGN(ScopedFrame); }; - CompositorContext(std::unique_ptr info); + CompositorContext(); - ~CompositorContext(); + virtual ~CompositorContext(); - ScopedFrame AcquireFrame(GrContext* gr_context, - SkCanvas* canvas, - bool instrumentation_enabled = true); + virtual std::unique_ptr AcquireFrame( + GrContext* gr_context, + SkCanvas* canvas, + bool instrumentation_enabled); void OnGrContextCreated(); @@ -62,7 +62,7 @@ class CompositorContext { RasterCache& raster_cache() { return raster_cache_; } - TextureRegistry& texture_registry() { return *texture_registry_; } + TextureRegistry& texture_registry() { return texture_registry_; } const Counter& frame_count() const { return frame_count_; } @@ -70,20 +70,12 @@ class CompositorContext { Stopwatch& engine_time() { return engine_time_; } - const CounterValues& memory_usage() const { return memory_usage_; } - - void SetTextureRegistry(TextureRegistry* textureRegistry) { - texture_registry_ = textureRegistry; - } - private: RasterCache raster_cache_; - TextureRegistry* texture_registry_; - std::unique_ptr process_info_; + TextureRegistry texture_registry_; Counter frame_count_; Stopwatch frame_time_; Stopwatch engine_time_; - CounterValues memory_usage_; void BeginFrame(ScopedFrame& frame, bool enable_instrumentation); diff --git a/flow/debug_print.cc b/flow/debug_print.cc index 0aa5b4b3b7d2d..3311b9c2b43e3 100644 --- a/flow/debug_print.cc +++ b/flow/debug_print.cc @@ -80,3 +80,8 @@ std::ostream& operator<<(std::ostream& os, const flow::RasterCacheKey& k) { ; return os; } + +std::ostream& operator<<(std::ostream& os, const SkISize& size) { + os << size.width() << ", " << size.height(); + return os; +} diff --git a/flow/debug_print.h b/flow/debug_print.h index ca5973eeb0977..78a28fe38562d 100644 --- a/flow/debug_print.h +++ b/flow/debug_print.h @@ -15,14 +15,15 @@ #define DEF_PRINTER(x) std::ostream& operator<<(std::ostream&, const x&); -DEF_PRINTER(flow::RasterCacheKey); DEF_PRINTER(flow::MatrixDecomposition); +DEF_PRINTER(flow::RasterCacheKey); +DEF_PRINTER(SkISize); DEF_PRINTER(SkMatrix); DEF_PRINTER(SkMatrix44); -DEF_PRINTER(SkVector3); -DEF_PRINTER(SkVector4); +DEF_PRINTER(SkPoint); DEF_PRINTER(SkRect); DEF_PRINTER(SkRRect); -DEF_PRINTER(SkPoint); +DEF_PRINTER(SkVector3); +DEF_PRINTER(SkVector4); #endif // FLUTTER_FLOW_DEBUG_PRINT_H_ diff --git a/flow/export_node.cc b/flow/export_node.cc index b6ce18ba7c68d..87cf7509fb762 100644 --- a/flow/export_node.cc +++ b/flow/export_node.cc @@ -4,28 +4,27 @@ #include "flutter/flow/export_node.h" -#include "flutter/common/threads.h" #include "lib/fxl/functional/make_copyable.h" namespace flow { ExportNodeHolder::ExportNodeHolder( + fxl::RefPtr gpu_task_runner, fxl::RefPtr export_token_handle) - : export_node_(std::make_unique(export_token_handle)) { - ASSERT_IS_UI_THREAD; + : gpu_task_runner_(std::move(gpu_task_runner)), + export_node_(std::make_unique(export_token_handle)) { + FXL_DCHECK(gpu_task_runner_); } void ExportNodeHolder::Bind(SceneUpdateContext& context, scenic_lib::ContainerNode& container, const SkPoint& offset, bool hit_testable) { - ASSERT_IS_GPU_THREAD; export_node_->Bind(context, container, offset, hit_testable); } ExportNodeHolder::~ExportNodeHolder() { - ASSERT_IS_UI_THREAD; - blink::Threads::Gpu()->PostTask( + gpu_task_runner_->PostTask( fxl::MakeCopyable([export_node = std::move(export_node_)]() { export_node->Dispose(true); })); @@ -44,8 +43,6 @@ void ExportNode::Bind(SceneUpdateContext& context, scenic_lib::ContainerNode& container, const SkPoint& offset, bool hit_testable) { - ASSERT_IS_GPU_THREAD; - if (export_token_) { // Happens first time we bind. node_.reset(new scenic_lib::EntityNode(container.session())); @@ -67,8 +64,6 @@ void ExportNode::Bind(SceneUpdateContext& context, } void ExportNode::Dispose(bool remove_from_scene_update_context) { - ASSERT_IS_GPU_THREAD; - // If scene_update_context_ is set, then we should still have a node left to // dereference. // If scene_update_context_ is null, then either: diff --git a/flow/export_node.h b/flow/export_node.h index 24f94fcebf20f..e6a11175e561e 100644 --- a/flow/export_node.h +++ b/flow/export_node.h @@ -15,6 +15,7 @@ #include "lib/fxl/macros.h" #include "lib/fxl/memory/ref_counted.h" #include "lib/ui/scenic/client/resources.h" +#include "third_party/flutter/fml/task_runner.h" #include "third_party/skia/include/core/SkPoint.h" namespace flow { @@ -24,7 +25,8 @@ namespace flow { // held by the ExportNode. class ExportNodeHolder : public fxl::RefCountedThreadSafe { public: - ExportNodeHolder(fxl::RefPtr export_token_handle); + ExportNodeHolder(fxl::RefPtr gpu_task_runner, + fxl::RefPtr export_token_handle); ~ExportNodeHolder(); // Calls Bind() on the wrapped ExportNode. @@ -36,6 +38,7 @@ class ExportNodeHolder : public fxl::RefCountedThreadSafe { ExportNode* export_node() { return export_node_.get(); } private: + fxl::RefPtr gpu_task_runner_; std::unique_ptr export_node_; FRIEND_MAKE_REF_COUNTED(ExportNodeHolder); diff --git a/flow/layers/default_layer_builder.cc b/flow/layers/default_layer_builder.cc index 9cf822528f3f9..eb74c24671d10 100644 --- a/flow/layers/default_layer_builder.cc +++ b/flow/layers/default_layer_builder.cc @@ -135,20 +135,20 @@ void DefaultLayerBuilder::PushPerformanceOverlay(uint64_t enabled_options, } void DefaultLayerBuilder::PushPicture(const SkPoint& offset, - sk_sp picture, + SkiaGPUObject picture, bool picture_is_complex, bool picture_will_change) { if (!current_layer_) { return; } - SkRect pictureRect = picture->cullRect(); + SkRect pictureRect = picture.get()->cullRect(); pictureRect.offset(offset.x(), offset.y()); if (!SkRect::Intersects(pictureRect, cull_rects_.top())) { return; } auto layer = std::make_unique(); layer->set_offset(offset); - layer->set_picture(picture); + layer->set_picture(std::move(picture)); layer->set_is_complex(picture_is_complex); layer->set_will_change(picture_will_change); current_layer_->Add(std::move(layer)); diff --git a/flow/layers/default_layer_builder.h b/flow/layers/default_layer_builder.h index a62ec46714d21..cadd173ab5a84 100644 --- a/flow/layers/default_layer_builder.h +++ b/flow/layers/default_layer_builder.h @@ -59,7 +59,7 @@ class DefaultLayerBuilder final : public LayerBuilder { // |flow::LayerBuilder| void PushPicture(const SkPoint& offset, - sk_sp picture, + SkiaGPUObject picture, bool picture_is_complex, bool picture_will_change) override; diff --git a/flow/layers/layer.h b/flow/layers/layer.h index 09b82dddb0265..cf7ad71c36fae 100644 --- a/flow/layers/layer.h +++ b/flow/layers/layer.h @@ -44,9 +44,6 @@ class Layer { virtual ~Layer(); struct PrerollContext { -#if defined(OS_FUCHSIA) - ui::gfx::Metrics* metrics = nullptr; -#endif RasterCache* raster_cache; GrContext* gr_context; SkColorSpace* dst_color_space; @@ -59,7 +56,6 @@ class Layer { SkCanvas& canvas; const Stopwatch& frame_time; const Stopwatch& engine_time; - const CounterValues& memory_usage; TextureRegistry& texture_registry; const bool checkerboard_offscreen_layers; }; diff --git a/flow/layers/layer_builder.h b/flow/layers/layer_builder.h index 91ae13974a23b..a29e959514428 100644 --- a/flow/layers/layer_builder.h +++ b/flow/layers/layer_builder.h @@ -8,6 +8,7 @@ #include #include "flutter/flow/layers/layer.h" +#include "flutter/flow/skia_gpu_object.h" #include "garnet/public/lib/fxl/macros.h" #include "third_party/skia/include/core/SkBlendMode.h" #include "third_party/skia/include/core/SkColor.h" @@ -57,7 +58,7 @@ class LayerBuilder { const SkRect& rect) = 0; virtual void PushPicture(const SkPoint& offset, - sk_sp picture, + SkiaGPUObject picture, bool picture_is_complex, bool picture_will_change) = 0; diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 9a52cb57d7f48..d9fb374194688 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -17,43 +17,18 @@ LayerTree::LayerTree() LayerTree::~LayerTree() = default; -void LayerTree::Raster(CompositorContext::ScopedFrame& frame, -#if defined(OS_FUCHSIA) - ui::gfx::Metrics* metrics, -#endif - bool ignore_raster_cache) { -#if defined(OS_FUCHSIA) - FXL_DCHECK(metrics); -#endif - Preroll(frame, -#if defined(OS_FUCHSIA) - metrics, -#endif - ignore_raster_cache); - Paint(frame); -} - void LayerTree::Preroll(CompositorContext::ScopedFrame& frame, -#if defined(OS_FUCHSIA) - ui::gfx::Metrics* metrics, -#endif bool ignore_raster_cache) { -#if defined(OS_FUCHSIA) - FXL_DCHECK(metrics); -#endif TRACE_EVENT0("flutter", "LayerTree::Preroll"); SkColorSpace* color_space = frame.canvas() ? frame.canvas()->imageInfo().colorSpace() : nullptr; frame.context().raster_cache().SetCheckboardCacheImages( checkerboard_raster_cache_images_); Layer::PrerollContext context = { -#if defined(OS_FUCHSIA) - metrics, -#endif - ignore_raster_cache ? nullptr : &frame.context().raster_cache(), - frame.gr_context(), - color_space, - SkRect::MakeEmpty(), + ignore_raster_cache ? nullptr : &frame.context().raster_cache(), + frame.gr_context(), + color_space, + SkRect::MakeEmpty(), }; root_layer_->Preroll(&context, SkMatrix::I()); @@ -63,9 +38,12 @@ void LayerTree::Preroll(CompositorContext::ScopedFrame& frame, void LayerTree::UpdateScene(SceneUpdateContext& context, scenic_lib::ContainerNode& container) { TRACE_EVENT0("flutter", "LayerTree::UpdateScene"); - - SceneUpdateContext::Transform transform(context, 1.f / device_pixel_ratio_, - 1.f / device_pixel_ratio_, 1.f); + const auto& metrics = context.metrics(); + SceneUpdateContext::Transform transform(context, // context + 1.0f / metrics->scale_x, // X + 1.0f / metrics->scale_y, // Y + 1.0f / metrics->scale_z // Z + ); SceneUpdateContext::Frame frame( context, SkRRect::MakeRect( @@ -82,12 +60,13 @@ void LayerTree::UpdateScene(SceneUpdateContext& context, #endif void LayerTree::Paint(CompositorContext::ScopedFrame& frame) const { - Layer::PaintContext context = {*frame.canvas(), - frame.context().frame_time(), - frame.context().engine_time(), - frame.context().memory_usage(), - frame.context().texture_registry(), - checkerboard_offscreen_layers_}; + Layer::PaintContext context = { + *frame.canvas(), // + frame.context().frame_time(), // + frame.context().engine_time(), // + frame.context().texture_registry(), // + checkerboard_offscreen_layers_ // + }; TRACE_EVENT0("flutter", "LayerTree::Paint"); if (root_layer_->needs_painting()) diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index a040180ad30a7..25a8e072cfa21 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -13,9 +13,6 @@ #include "flutter/flow/layers/layer.h" #include "lib/fxl/macros.h" #include "lib/fxl/time/time_delta.h" -#if defined(OS_FUCHSIA) -#include "lib/ui/scenic/fidl/events.fidl.h" -#endif #include "third_party/skia/include/core/SkSize.h" namespace flow { @@ -26,24 +23,10 @@ class LayerTree { ~LayerTree(); - // Raster includes both Preroll and Paint. - void Raster(CompositorContext::ScopedFrame& frame, -#if defined(OS_FUCHSIA) - ui::gfx::Metrics* metrics, -#endif - bool ignore_raster_cache = false); - void Preroll(CompositorContext::ScopedFrame& frame, -#if defined(OS_FUCHSIA) - ui::gfx::Metrics* metrics, -#endif bool ignore_raster_cache = false); #if defined(OS_FUCHSIA) - void set_device_pixel_ratio(float device_pixel_ratio) { - device_pixel_ratio_ = device_pixel_ratio; - } - void UpdateScene(SceneUpdateContext& context, scenic_lib::ContainerNode& container); #endif @@ -93,10 +76,6 @@ class LayerTree { bool checkerboard_raster_cache_images_; bool checkerboard_offscreen_layers_; -#if defined(OS_FUCHSIA) - float device_pixel_ratio_ = 1.f; -#endif - FXL_DISALLOW_COPY_AND_ASSIGN(LayerTree); }; diff --git a/flow/layers/performance_overlay_layer.cc b/flow/layers/performance_overlay_layer.cc index cc55500115a08..7d871af33b94f 100644 --- a/flow/layers/performance_overlay_layer.cc +++ b/flow/layers/performance_overlay_layer.cc @@ -57,34 +57,6 @@ 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) @@ -111,11 +83,6 @@ void PerformanceOverlayLayer::Paint(PaintContext& context) const { VisualizeStopWatch(context.canvas, context.engine_time, x, y + height, width, height - padding, options_ & kVisualizeEngineStatistics, options_ & kDisplayEngineStatistics, "UI"); - - VisualizeCounterValuesBytes( - context.canvas, context.memory_usage, x, y + (2 * height), width, - height - padding, options_ & kVisualizeMemoryStatistics, - options_ & kDisplayMemoryStatistics, "Memory (Resident)"); } } // namespace flow diff --git a/flow/layers/performance_overlay_layer.h b/flow/layers/performance_overlay_layer.h index e7c3ac530a02a..77448107147a4 100644 --- a/flow/layers/performance_overlay_layer.h +++ b/flow/layers/performance_overlay_layer.h @@ -14,8 +14,6 @@ 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/flow/layers/picture_layer.cc b/flow/layers/picture_layer.cc index 4a99d7d07f75e..552ca0443bd80 100644 --- a/flow/layers/picture_layer.cc +++ b/flow/layers/picture_layer.cc @@ -4,39 +4,30 @@ #include "flutter/flow/layers/picture_layer.h" -#include "flutter/common/threads.h" #include "lib/fxl/logging.h" namespace flow { PictureLayer::PictureLayer() = default; -PictureLayer::~PictureLayer() { - // The picture may contain references to textures that are associated - // with the IO thread's context. - SkPicture* picture = picture_.release(); - if (picture) { - blink::Threads::IO()->PostTask([picture]() { picture->unref(); }); - } -} +PictureLayer::~PictureLayer() = default; void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { + SkPicture* sk_picture = picture(); + if (auto cache = context->raster_cache) { raster_cache_result_ = cache->GetPrerolledImage( - context->gr_context, picture_.get(), matrix, context->dst_color_space, -#if defined(OS_FUCHSIA) - context->metrics, -#endif + context->gr_context, sk_picture, matrix, context->dst_color_space, is_complex_, will_change_); } - SkRect bounds = picture_->cullRect().makeOffset(offset_.x(), offset_.y()); + SkRect bounds = sk_picture->cullRect().makeOffset(offset_.x(), offset_.y()); set_paint_bounds(bounds); } void PictureLayer::Paint(PaintContext& context) const { TRACE_EVENT0("flutter", "PictureLayer::Paint"); - FXL_DCHECK(picture_); + FXL_DCHECK(picture_.get()); FXL_DCHECK(needs_painting()); SkAutoCanvasRestore save(&context.canvas, true); @@ -53,7 +44,7 @@ void PictureLayer::Paint(PaintContext& context) const { SkCanvas::kStrict_SrcRectConstraint // source constraint ); } else { - context.canvas.drawPicture(picture_.get()); + context.canvas.drawPicture(picture()); } } diff --git a/flow/layers/picture_layer.h b/flow/layers/picture_layer.h index 191ef9d7097a2..c67929b7cb455 100644 --- a/flow/layers/picture_layer.h +++ b/flow/layers/picture_layer.h @@ -5,8 +5,11 @@ #ifndef FLUTTER_FLOW_LAYERS_PICTURE_LAYER_H_ #define FLUTTER_FLOW_LAYERS_PICTURE_LAYER_H_ +#include + #include "flutter/flow/layers/layer.h" #include "flutter/flow/raster_cache.h" +#include "flutter/flow/skia_gpu_object.h" namespace flow { @@ -16,12 +19,14 @@ class PictureLayer : public Layer { ~PictureLayer() override; void set_offset(const SkPoint& offset) { offset_ = offset; } - void set_picture(sk_sp picture) { picture_ = std::move(picture); } + void set_picture(SkiaGPUObject picture) { + picture_ = std::move(picture); + } void set_is_complex(bool value) { is_complex_ = value; } void set_will_change(bool value) { will_change_ = value; } - SkPicture* picture() const { return picture_.get(); } + SkPicture* picture() const { return picture_.get().get(); } void Preroll(PrerollContext* frame, const SkMatrix& matrix) override; @@ -29,7 +34,9 @@ class PictureLayer : public Layer { private: SkPoint offset_; - sk_sp picture_; + // Even though pictures themselves are not GPU resources, they may reference + // images that have a reference to a GPU resource. + SkiaGPUObject picture_; bool is_complex_ = false; bool will_change_ = false; RasterCacheResult raster_cache_result_; diff --git a/flow/process_info.h b/flow/process_info.h deleted file mode 100644 index 6623fe7257396..0000000000000 --- a/flow/process_info.h +++ /dev/null @@ -1,31 +0,0 @@ -// 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/fxl/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 ~ProcessInfo() = default; - - 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/flow/raster_cache.cc b/flow/raster_cache.cc index 472dbd6bd9d94..11a86729b489b 100644 --- a/flow/raster_cache.cc +++ b/flow/raster_cache.cc @@ -6,7 +6,6 @@ #include -#include "flutter/common/threads.h" #include "flutter/flow/paint_utils.h" #include "flutter/glue/trace_event.h" #include "lib/fxl/logging.h" @@ -73,9 +72,6 @@ RasterCacheResult RasterizePicture(SkPicture* picture, GrContext* context, const MatrixDecomposition& matrix, SkColorSpace* dst_color_space, -#if defined(OS_FUCHSIA) - ui::gfx::Metrics* metrics, -#endif bool checkerboard) { TRACE_EVENT0("flutter", "RasterCachePopulate"); @@ -83,17 +79,9 @@ RasterCacheResult RasterizePicture(SkPicture* picture, const SkRect logical_rect = picture->cullRect(); -#if defined(OS_FUCHSIA) - float metrics_scale_x = metrics->scale_x; - float metrics_scale_y = metrics->scale_y; -#else - float metrics_scale_x = 1.f; - float metrics_scale_y = 1.f; -#endif - - const SkRect physical_rect = SkRect::MakeWH( - std::fabs(logical_rect.width() * metrics_scale_x * scale.x()), - std::fabs(logical_rect.height() * metrics_scale_y * scale.y())); + const SkRect physical_rect = + SkRect::MakeWH(std::fabs(logical_rect.width() * scale.x()), + std::fabs(logical_rect.height() * scale.y())); const SkImageInfo image_info = SkImageInfo::MakeN32Premul( std::ceil(physical_rect.width()), // physical width @@ -120,8 +108,7 @@ RasterCacheResult RasterizePicture(SkPicture* picture, } canvas->clear(SK_ColorTRANSPARENT); - canvas->scale(std::abs(scale.x() * metrics_scale_x), - std::abs(scale.y() * metrics_scale_y)); + canvas->scale(std::abs(scale.x()), std::abs(scale.y())); canvas->translate(-logical_rect.left(), -logical_rect.top()); canvas->drawPicture(picture); @@ -153,9 +140,6 @@ RasterCacheResult RasterCache::GetPrerolledImage( SkPicture* picture, const SkMatrix& transformation_matrix, SkColorSpace* dst_color_space, -#if defined(OS_FUCHSIA) - ui::gfx::Metrics* metrics, -#endif bool is_complex, bool will_change) { if (!IsPictureWorthRasterizing(picture, will_change, is_complex)) { @@ -172,11 +156,7 @@ RasterCacheResult RasterCache::GetPrerolledImage( return {}; } - RasterCacheKey cache_key(*picture, -#if defined(OS_FUCHSIA) - metrics->scale_x, metrics->scale_y, -#endif - matrix); + RasterCacheKey cache_key(*picture, matrix); Entry& entry = cache_[cache_key]; entry.access_count = ClampSize(entry.access_count + 1, 0, threshold_); @@ -189,9 +169,6 @@ RasterCacheResult RasterCache::GetPrerolledImage( if (!entry.image.is_valid()) { entry.image = RasterizePicture(picture, context, matrix, dst_color_space, -#if defined(OS_FUCHSIA) - metrics, -#endif checkerboard_images_); } diff --git a/flow/raster_cache.h b/flow/raster_cache.h index 3600866190204..3278eb355b030 100644 --- a/flow/raster_cache.h +++ b/flow/raster_cache.h @@ -12,9 +12,6 @@ #include "flutter/flow/raster_cache_key.h" #include "lib/fxl/macros.h" #include "lib/fxl/memory/weak_ptr.h" -#if defined(OS_FUCHSIA) -#include "lib/ui/scenic/fidl/events.fidl.h" -#endif #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkSize.h" @@ -57,9 +54,6 @@ class RasterCache { SkPicture* picture, const SkMatrix& transformation_matrix, SkColorSpace* dst_color_space, -#if defined(OS_FUCHSIA) - ui::gfx::Metrics* metrics, -#endif bool is_complex, bool will_change); diff --git a/flow/raster_cache_key.h b/flow/raster_cache_key.h index 83df52658c981..1f28ea5320d36 100644 --- a/flow/raster_cache_key.h +++ b/flow/raster_cache_key.h @@ -15,30 +15,15 @@ namespace flow { class RasterCacheKey { public: - RasterCacheKey(const SkPicture& picture, -#if defined(OS_FUCHSIA) - float metrics_scale_x, - float metrics_scale_y, -#endif - const MatrixDecomposition& matrix) + RasterCacheKey(const SkPicture& picture, const MatrixDecomposition& matrix) : picture_id_(picture.uniqueID()), -#if defined(OS_FUCHSIA) - metrics_scale_x_(metrics_scale_x), - metrics_scale_y_(metrics_scale_y), -#endif - scale_key_( - SkISize::Make(matrix.scale().x() * 1e3, matrix.scale().y() * 1e3)) { - } + scale_key_(SkISize::Make(matrix.scale().x() * 1e3, + matrix.scale().y() * 1e3)) {} uint32_t picture_id() const { return picture_id_; } const SkISize& scale_key() const { return scale_key_; } -#if defined(OS_FUCHSIA) - float metrics_scale_x() const { return metrics_scale_x_; } - float metrics_scale_y() const { return metrics_scale_y_; } -#endif - struct Hash { std::size_t operator()(RasterCacheKey const& key) const { return key.picture_id_; @@ -49,11 +34,6 @@ class RasterCacheKey { constexpr bool operator()(const RasterCacheKey& lhs, const RasterCacheKey& rhs) const { return lhs.picture_id_ == rhs.picture_id_ && -#if defined(OS_FUCHSIA) - lhs.metrics_scale_x_ == rhs.metrics_scale_x_ && - - lhs.metrics_scale_y_ == rhs.metrics_scale_y_ && -#endif lhs.scale_key_ == rhs.scale_key_; } }; @@ -63,10 +43,6 @@ class RasterCacheKey { private: uint32_t picture_id_; -#if defined(OS_FUCHSIA) - float metrics_scale_x_; - float metrics_scale_y_; -#endif SkISize scale_key_; }; diff --git a/flow/scene_update_context.cc b/flow/scene_update_context.cc index 83883c508b4df..b9d6801cc82ee 100644 --- a/flow/scene_update_context.cc +++ b/flow/scene_update_context.cc @@ -4,7 +4,6 @@ #include "flutter/flow/scene_update_context.h" -#include "flutter/common/threads.h" #include "flutter/flow/export_node.h" #include "flutter/flow/layers/layer.h" #include "flutter/flow/matrix_decomposition.h" @@ -19,9 +18,7 @@ SceneUpdateContext::SceneUpdateContext(scenic_lib::Session* session, } SceneUpdateContext::~SceneUpdateContext() { - ASSERT_IS_GPU_THREAD; - - // Release Scenic session resources for all ExportNodes. + // Release Mozart session resources for all ExportNodes. for (auto export_node : export_nodes_) { export_node->Dispose(false); } @@ -30,21 +27,16 @@ SceneUpdateContext::~SceneUpdateContext() { void SceneUpdateContext::AddChildScene(ExportNode* export_node, SkPoint offset, bool hit_testable) { - ASSERT_IS_GPU_THREAD; FXL_DCHECK(top_entity_); export_node->Bind(*this, top_entity_->entity_node(), offset, hit_testable); } void SceneUpdateContext::AddExportNode(ExportNode* export_node) { - ASSERT_IS_GPU_THREAD; - export_nodes_.insert(export_node); // Might already have been added. } void SceneUpdateContext::RemoveExportNode(ExportNode* export_node) { - ASSERT_IS_GPU_THREAD; - export_nodes_.erase(export_node); } @@ -195,12 +187,9 @@ SceneUpdateContext::ExecutePaintTasks(CompositorContext::ScopedFrame& frame) { for (auto& task : paint_tasks_) { FXL_DCHECK(task.surface); SkCanvas* canvas = task.surface->GetSkiaSurface()->getCanvas(); - Layer::PaintContext context = {*canvas, - frame.context().frame_time(), + Layer::PaintContext context = {*canvas, frame.context().frame_time(), frame.context().engine_time(), - frame.context().memory_usage(), - frame.context().texture_registry(), - false}; + frame.context().texture_registry(), false}; canvas->restoreToCount(1); canvas->save(); canvas->clear(task.background_color); diff --git a/flow/skia_gpu_object.cc b/flow/skia_gpu_object.cc new file mode 100644 index 0000000000000..ce2312f921580 --- /dev/null +++ b/flow/skia_gpu_object.cc @@ -0,0 +1,44 @@ +// Copyright 2017 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/flow/skia_gpu_object.h" + +#include "flutter/fml/message_loop.h" + +namespace flow { + +SkiaUnrefQueue::SkiaUnrefQueue(fxl::RefPtr task_runner, + fxl::TimeDelta delay) + : task_runner_(std::move(task_runner)), + drain_delay_(delay), + drain_pending_(false) {} + +SkiaUnrefQueue::~SkiaUnrefQueue() { + Drain(); +} + +void SkiaUnrefQueue::Unref(SkRefCnt* object) { + std::lock_guard lock(mutex_); + objects_.push_back(object); + if (!drain_pending_) { + drain_pending_ = true; + task_runner_->PostDelayedTask( + [strong = fxl::Ref(this)]() { strong->Drain(); }, drain_delay_); + } +} + +void SkiaUnrefQueue::Drain() { + std::deque skia_objects; + { + std::lock_guard lock(mutex_); + objects_.swap(skia_objects); + drain_pending_ = false; + } + + for (SkRefCnt* skia_object : skia_objects) { + skia_object->unref(); + } +} + +} // namespace flow diff --git a/flow/skia_gpu_object.h b/flow/skia_gpu_object.h new file mode 100644 index 0000000000000..4711f80c6f4fd --- /dev/null +++ b/flow/skia_gpu_object.h @@ -0,0 +1,88 @@ +// Copyright 2017 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_FLOW_SKIA_GPU_OBJECT_H_ +#define FLUTTER_FLOW_SKIA_GPU_OBJECT_H_ + +#include +#include + +#include "flutter/fml/memory/weak_ptr.h" +#include "flutter/fml/task_runner.h" +#include "lib/fxl/memory/ref_ptr.h" +#include "third_party/skia/include/core/SkRefCnt.h" + +namespace flow { + +// A queue that holds Skia objects that must be destructed on the the given task +// runner. +class SkiaUnrefQueue : public fxl::RefCountedThreadSafe { + public: + void Unref(SkRefCnt* object); + + // Usually, the drain is called automatically. However, during IO manager + // shutdown (when the platform side reference to the OpenGL context is about + // to go away), we may need to pre-emptively drain the unref queue. It is the + // responsibility of the caller to ensure that no further unrefs are queued + // after this call. + void Drain(); + + private: + const fxl::RefPtr task_runner_; + const fxl::TimeDelta drain_delay_; + std::mutex mutex_; + std::deque objects_; + bool drain_pending_; + + SkiaUnrefQueue(fxl::RefPtr task_runner, + fxl::TimeDelta delay); + + ~SkiaUnrefQueue(); + + FRIEND_REF_COUNTED_THREAD_SAFE(SkiaUnrefQueue); + FRIEND_MAKE_REF_COUNTED(SkiaUnrefQueue); + FXL_DISALLOW_COPY_AND_ASSIGN(SkiaUnrefQueue); +}; + +/// An object whose deallocation needs to be performed on an specific unref +/// queue. The template argument U need to have a call operator that returns +/// that unref queue. +template +class SkiaGPUObject { + public: + using SkiaObjectType = T; + + SkiaGPUObject() = default; + + SkiaGPUObject(sk_sp object, fxl::RefPtr queue) + : object_(std::move(object)), queue_(std::move(queue)) { + FXL_DCHECK(queue_ && object_); + } + + SkiaGPUObject(SkiaGPUObject&&) = default; + + ~SkiaGPUObject() { reset(); } + + SkiaGPUObject& operator=(SkiaGPUObject&&) = default; + + sk_sp get() const { return object_; } + + void reset() { + if (object_) { + queue_->Unref(object_.release()); + } + queue_ = nullptr; + FXL_DCHECK(object_ == nullptr); + } + + private: + sk_sp object_; + fxl::RefPtr queue_; + + FXL_DISALLOW_COPY_AND_ASSIGN(SkiaGPUObject); +}; + +} // namespace flow + +#endif // FLUTTER_FLOW_SKIA_GPU_OBJECT_H_ diff --git a/flow/texture.cc b/flow/texture.cc index 33a48af989477..d5cc3ae228aa7 100644 --- a/flow/texture.cc +++ b/flow/texture.cc @@ -11,36 +11,32 @@ TextureRegistry::TextureRegistry() = default; TextureRegistry::~TextureRegistry() = default; void TextureRegistry::RegisterTexture(std::shared_ptr texture) { - ASSERT_IS_GPU_THREAD mapping_[texture->Id()] = texture; } void TextureRegistry::UnregisterTexture(int64_t id) { - ASSERT_IS_GPU_THREAD mapping_.erase(id); } void TextureRegistry::OnGrContextCreated() { - ASSERT_IS_GPU_THREAD; for (auto& it : mapping_) { it.second->OnGrContextCreated(); } } void TextureRegistry::OnGrContextDestroyed() { - ASSERT_IS_GPU_THREAD; for (auto& it : mapping_) { it.second->OnGrContextDestroyed(); } } std::shared_ptr TextureRegistry::GetTexture(int64_t id) { - ASSERT_IS_GPU_THREAD auto it = mapping_.find(id); return it != mapping_.end() ? it->second : nullptr; } Texture::Texture(int64_t id) : id_(id) {} + Texture::~Texture() = default; } // namespace flow diff --git a/flow/texture.h b/flow/texture.h index a602a6b45b5b4..1986702f66749 100644 --- a/flow/texture.h +++ b/flow/texture.h @@ -6,7 +6,7 @@ #define FLUTTER_FLOW_TEXTURE_H_ #include -#include "flutter/common/threads.h" + #include "lib/fxl/synchronization/waitable_event.h" #include "third_party/skia/include/core/SkCanvas.h"