| // 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 "compositor_context.h" |
| |
| #include "flutter/flow/layers/layer_tree.h" |
| |
| namespace flutter_runner { |
| |
| class ScopedFrame final : public flutter::CompositorContext::ScopedFrame { |
| public: |
| ScopedFrame(flutter::CompositorContext& context, |
| const SkMatrix& root_surface_transformation, |
| bool instrumentation_enabled, |
| SessionConnection& session_connection) |
| : flutter::CompositorContext::ScopedFrame(context, |
| nullptr, |
| nullptr, |
| nullptr, |
| root_surface_transformation, |
| instrumentation_enabled, |
| true, |
| nullptr), |
| session_connection_(session_connection) {} |
| |
| private: |
| SessionConnection& session_connection_; |
| |
| flutter::RasterStatus Raster(flutter::LayerTree& layer_tree, |
| bool ignore_raster_cache) override { |
| if (!session_connection_.has_metrics()) { |
| return flutter::RasterStatus::kSuccess; |
| } |
| |
| { |
| // Preroll the Flutter layer tree. This allows Flutter to perform |
| // pre-paint optimizations. |
| TRACE_EVENT0("flutter", "Preroll"); |
| layer_tree.Preroll(*this, true /* ignore raster cache */); |
| } |
| |
| { |
| // Traverse the Flutter layer tree so that the necessary session ops to |
| // represent the frame are enqueued in the underlying session. |
| TRACE_EVENT0("flutter", "UpdateScene"); |
| layer_tree.UpdateScene(session_connection_.scene_update_context(), |
| session_connection_.root_node()); |
| } |
| |
| { |
| // Flush all pending session ops. |
| TRACE_EVENT0("flutter", "SessionPresent"); |
| |
| session_connection_.Present(this); |
| } |
| |
| return flutter::RasterStatus::kSuccess; |
| } |
| |
| FML_DISALLOW_COPY_AND_ASSIGN(ScopedFrame); |
| }; |
| |
| CompositorContext::CompositorContext( |
| std::string debug_label, |
| fuchsia::ui::views::ViewToken view_token, |
| scenic::ViewRefPair view_ref_pair, |
| fidl::InterfaceHandle<fuchsia::ui::scenic::Session> session, |
| fml::closure session_error_callback, |
| zx_handle_t vsync_event_handle) |
| : debug_label_(std::move(debug_label)), |
| session_connection_( |
| debug_label_, |
| std::move(view_token), |
| std::move(view_ref_pair), |
| std::move(session), |
| session_error_callback, |
| [](auto) {}, |
| vsync_event_handle) {} |
| |
| void CompositorContext::OnSessionMetricsDidChange( |
| const fuchsia::ui::gfx::Metrics& metrics) { |
| session_connection_.set_metrics(metrics); |
| } |
| |
| void CompositorContext::OnSessionSizeChangeHint(float width_change_factor, |
| float height_change_factor) { |
| session_connection_.OnSessionSizeChangeHint(width_change_factor, |
| height_change_factor); |
| } |
| |
| void CompositorContext::OnWireframeEnabled(bool enabled) { |
| session_connection_.set_enable_wireframe(enabled); |
| } |
| |
| CompositorContext::~CompositorContext() = default; |
| |
| std::unique_ptr<flutter::CompositorContext::ScopedFrame> |
| CompositorContext::AcquireFrame( |
| GrContext* gr_context, |
| SkCanvas* canvas, |
| flutter::ExternalViewEmbedder* view_embedder, |
| const SkMatrix& root_surface_transformation, |
| bool instrumentation_enabled, |
| bool surface_supports_readback, |
| fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) { |
| // TODO: The AcquireFrame interface is too broad and must be refactored to get |
| // rid of the context and canvas arguments as those seem to be only used for |
| // colorspace correctness purposes on the mobile shells. |
| return std::make_unique<flutter_runner::ScopedFrame>( |
| *this, // |
| root_surface_transformation, // |
| instrumentation_enabled, // |
| session_connection_ // |
| ); |
| } |
| |
| } // namespace flutter_runner |