Flutter Engine
compositor_context.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "compositor_context.h"
6 
7 #include <vector>
8 
9 #include "flutter/flow/layers/layer_tree.h"
10 #include "third_party/skia/include/gpu/GrDirectContext.h"
11 
12 namespace flutter_runner {
13 
15  public:
17  GrDirectContext* gr_context,
18  SkCanvas* canvas,
20  const SkMatrix& root_surface_transformation,
21  bool instrumentation_enabled,
23  fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger,
24  SessionConnection& session_connection,
25  VulkanSurfaceProducer& surface_producer,
26  std::shared_ptr<flutter::SceneUpdateContext> scene_update_context)
28  surface_producer.gr_context(),
29  canvas,
30  view_embedder,
31  root_surface_transformation,
32  instrumentation_enabled,
33  surface_supports_readback,
34  raster_thread_merger),
35  session_connection_(session_connection),
36  surface_producer_(surface_producer),
37  scene_update_context_(scene_update_context) {}
38 
39  private:
40  SessionConnection& session_connection_;
41  VulkanSurfaceProducer& surface_producer_;
42  std::shared_ptr<flutter::SceneUpdateContext> scene_update_context_;
43 
44  flutter::RasterStatus Raster(flutter::LayerTree& layer_tree,
45  bool ignore_raster_cache) override {
46  std::vector<flutter::SceneUpdateContext::PaintTask> frame_paint_tasks;
47  std::vector<std::unique_ptr<SurfaceProducerSurface>> frame_surfaces;
48 
49  {
50  // Preroll the Flutter layer tree. This allows Flutter to perform
51  // pre-paint optimizations.
52  TRACE_EVENT0("flutter", "Preroll");
53  layer_tree.Preroll(*this, ignore_raster_cache);
54  }
55 
56  {
57  // Traverse the Flutter layer tree so that the necessary session ops to
58  // represent the frame are enqueued in the underlying session.
59  TRACE_EVENT0("flutter", "UpdateScene");
60  layer_tree.UpdateScene(scene_update_context_);
61  }
62 
63  {
64  // Flush all pending session ops: create surfaces and enqueue session
65  // Image ops for the frame's paint tasks, then Present.
66  TRACE_EVENT0("flutter", "SessionPresent");
67  frame_paint_tasks = scene_update_context_->GetPaintTasks();
68  for (auto& task : frame_paint_tasks) {
69  SkISize physical_size =
70  SkISize::Make(layer_tree.device_pixel_ratio() * task.scale_x *
71  task.paint_bounds.width(),
72  layer_tree.device_pixel_ratio() * task.scale_y *
73  task.paint_bounds.height());
74  if (physical_size.width() == 0 || physical_size.height() == 0) {
75  frame_surfaces.emplace_back(nullptr);
76  continue;
77  }
78 
79  std::unique_ptr<SurfaceProducerSurface> surface =
80  surface_producer_.ProduceSurface(physical_size);
81  if (!surface) {
82  FML_LOG(ERROR)
83  << "Could not acquire a surface from the surface producer "
84  "of size: "
85  << physical_size.width() << "x" << physical_size.height();
86  } else {
87  task.material.SetTexture(*(surface->GetImage()));
88  }
89 
90  frame_surfaces.emplace_back(std::move(surface));
91  }
92 
93  session_connection_.Present();
94  }
95 
96  {
97  // Execute paint tasks in parallel with Scenic's side of the Present, then
98  // signal fences.
99  TRACE_EVENT0("flutter", "ExecutePaintTasks");
100  size_t surface_index = 0;
101  for (auto& task : frame_paint_tasks) {
102  std::unique_ptr<SurfaceProducerSurface>& task_surface =
103  frame_surfaces[surface_index++];
104  if (!task_surface) {
105  continue;
106  }
107 
108  SkCanvas* canvas = task_surface->GetSkiaSurface()->getCanvas();
109  flutter::Layer::PaintContext paint_context = {
110  canvas,
111  canvas,
112  gr_context(),
113  nullptr,
114  context().raster_time(),
115  context().ui_time(),
117  &context().raster_cache(),
118  false,
119  layer_tree.device_pixel_ratio()};
120  canvas->restoreToCount(1);
121  canvas->save();
122  canvas->clear(task.background_color);
123  canvas->scale(layer_tree.device_pixel_ratio() * task.scale_x,
124  layer_tree.device_pixel_ratio() * task.scale_y);
125  canvas->translate(-task.paint_bounds.left(), -task.paint_bounds.top());
126  for (flutter::Layer* layer : task.layers) {
127  layer->Paint(paint_context);
128  }
129  }
130 
131  // Tell the surface producer that a present has occurred so it can perform
132  // book-keeping on buffer caches.
133  surface_producer_.OnSurfacesPresented(std::move(frame_surfaces));
134  }
135 
137  }
138 
139  FML_DISALLOW_COPY_AND_ASSIGN(ScopedFrame);
140 };
141 
143  SessionConnection& session_connection,
144  VulkanSurfaceProducer& surface_producer,
145  std::shared_ptr<flutter::SceneUpdateContext> scene_update_context)
146  : session_connection_(session_connection),
147  surface_producer_(surface_producer),
148  scene_update_context_(scene_update_context) {}
149 
151 
152 std::unique_ptr<flutter::CompositorContext::ScopedFrame>
153 CompositorContext::AcquireFrame(
154  GrDirectContext* gr_context,
155  SkCanvas* canvas,
156  flutter::ExternalViewEmbedder* view_embedder,
157  const SkMatrix& root_surface_transformation,
158  bool instrumentation_enabled,
159  bool surface_supports_readback,
160  fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
161  return std::make_unique<flutter_runner::ScopedFrame>(
162  *this, gr_context, canvas, view_embedder, root_surface_transformation,
163  instrumentation_enabled, surface_supports_readback, raster_thread_merger,
164  session_connection_, surface_producer_, scene_update_context_);
165 }
166 
167 } // namespace flutter_runner
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
const SkMatrix & root_surface_transformation() const
ScopedFrame(CompositorContext &context, GrDirectContext *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, SessionConnection &session_connection, VulkanSurfaceProducer &surface_producer, std::shared_ptr< flutter::SceneUpdateContext > scene_update_context)
CompositorContext(SessionConnection &session_connection, VulkanSurfaceProducer &surface_producer, std::shared_ptr< flutter::SceneUpdateContext > scene_update_context)
#define FML_LOG(severity)
Definition: logging.h:65
void OnSurfacesPresented(std::vector< std::unique_ptr< SurfaceProducerSurface >> surfaces)
bool Preroll(CompositorContext::ScopedFrame &frame, bool ignore_raster_cache=false)
Definition: layer_tree.cc:32
virtual void Paint(PaintContext &context) const =0
std::unique_ptr< SurfaceProducerSurface > ProduceSurface(const SkISize &size) override
float device_pixel_ratio() const
Definition: layer_tree.h:50
TextureRegistry & texture_registry()
const Stopwatch & raster_time() const