• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "flutter/flow/layers/layer_tree.h"
6 
7 #include "flutter/flow/layers/layer.h"
8 #include "flutter/fml/trace_event.h"
9 #include "third_party/skia/include/core/SkPictureRecorder.h"
10 #include "third_party/skia/include/utils/SkNWayCanvas.h"
11 
12 namespace flutter {
13 
LayerTree()14 LayerTree::LayerTree()
15     : frame_size_{},
16       rasterizer_tracing_threshold_(0),
17       checkerboard_raster_cache_images_(false),
18       checkerboard_offscreen_layers_(false) {}
19 
20 LayerTree::~LayerTree() = default;
21 
RecordBuildTime(fml::TimePoint start)22 void LayerTree::RecordBuildTime(fml::TimePoint start) {
23   build_start_ = start;
24   build_finish_ = fml::TimePoint::Now();
25 }
26 
Preroll(CompositorContext::ScopedFrame & frame,bool ignore_raster_cache)27 void LayerTree::Preroll(CompositorContext::ScopedFrame& frame,
28                         bool ignore_raster_cache) {
29   TRACE_EVENT0("flutter", "LayerTree::Preroll");
30   SkColorSpace* color_space =
31       frame.canvas() ? frame.canvas()->imageInfo().colorSpace() : nullptr;
32   frame.context().raster_cache().SetCheckboardCacheImages(
33       checkerboard_raster_cache_images_);
34   MutatorsStack stack;
35   PrerollContext context = {
36       ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
37       frame.gr_context(),
38       frame.view_embedder(),
39       stack,
40       color_space,
41       kGiantRect,
42       frame.context().raster_time(),
43       frame.context().ui_time(),
44       frame.context().texture_registry(),
45       checkerboard_offscreen_layers_};
46 
47   root_layer_->Preroll(&context, frame.root_surface_transformation());
48 }
49 
50 #if defined(OS_FUCHSIA)
UpdateScene(SceneUpdateContext & context,scenic::ContainerNode & container)51 void LayerTree::UpdateScene(SceneUpdateContext& context,
52                             scenic::ContainerNode& container) {
53   TRACE_EVENT0("flutter", "LayerTree::UpdateScene");
54   const auto& metrics = context.metrics();
55   SceneUpdateContext::Transform transform(context,                  // context
56                                           1.0f / metrics->scale_x,  // X
57                                           1.0f / metrics->scale_y,  // Y
58                                           1.0f / metrics->scale_z   // Z
59   );
60   SceneUpdateContext::Frame frame(
61       context,
62       SkRRect::MakeRect(
63           SkRect::MakeWH(frame_size_.width(), frame_size_.height())),
64       SK_ColorTRANSPARENT);
65   if (root_layer_->needs_system_composite()) {
66     root_layer_->UpdateScene(context);
67   }
68   if (root_layer_->needs_painting()) {
69     frame.AddPaintLayer(root_layer_.get());
70   }
71   container.AddChild(transform.entity_node());
72 }
73 #endif
74 
Paint(CompositorContext::ScopedFrame & frame,bool ignore_raster_cache) const75 void LayerTree::Paint(CompositorContext::ScopedFrame& frame,
76                       bool ignore_raster_cache) const {
77   TRACE_EVENT0("flutter", "LayerTree::Paint");
78   SkISize canvas_size = frame.canvas()->getBaseLayerSize();
79   SkNWayCanvas internal_nodes_canvas(canvas_size.width(), canvas_size.height());
80   internal_nodes_canvas.addCanvas(frame.canvas());
81   if (frame.view_embedder() != nullptr) {
82     auto overlay_canvases = frame.view_embedder()->GetCurrentCanvases();
83     for (size_t i = 0; i < overlay_canvases.size(); i++) {
84       internal_nodes_canvas.addCanvas(overlay_canvases[i]);
85     }
86   }
87 
88   Layer::PaintContext context = {
89       (SkCanvas*)&internal_nodes_canvas,
90       frame.canvas(),
91       frame.gr_context(),
92       frame.view_embedder(),
93       frame.context().raster_time(),
94       frame.context().ui_time(),
95       frame.context().texture_registry(),
96       ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
97       checkerboard_offscreen_layers_};
98 
99   if (root_layer_->needs_painting())
100     root_layer_->Paint(context);
101 }
102 
Flatten(const SkRect & bounds)103 sk_sp<SkPicture> LayerTree::Flatten(const SkRect& bounds) {
104   TRACE_EVENT0("flutter", "LayerTree::Flatten");
105 
106   SkPictureRecorder recorder;
107   auto* canvas = recorder.beginRecording(bounds);
108 
109   if (!canvas) {
110     return nullptr;
111   }
112 
113   MutatorsStack unused_stack;
114   const Stopwatch unused_stopwatch;
115   TextureRegistry unused_texture_registry;
116   SkMatrix root_surface_transformation;
117   // No root surface transformation. So assume identity.
118   root_surface_transformation.reset();
119 
120   PrerollContext preroll_context{
121       nullptr,                  // raster_cache (don't consult the cache)
122       nullptr,                  // gr_context  (used for the raster cache)
123       nullptr,                  // external view embedder
124       unused_stack,             // mutator stack
125       nullptr,                  // SkColorSpace* dst_color_space
126       kGiantRect,               // SkRect cull_rect
127       unused_stopwatch,         // frame time (dont care)
128       unused_stopwatch,         // engine time (dont care)
129       unused_texture_registry,  // texture registry (not supported)
130       false,                    // checkerboard_offscreen_layers
131   };
132 
133   SkISize canvas_size = canvas->getBaseLayerSize();
134   SkNWayCanvas internal_nodes_canvas(canvas_size.width(), canvas_size.height());
135   internal_nodes_canvas.addCanvas(canvas);
136 
137   Layer::PaintContext paint_context = {
138       (SkCanvas*)&internal_nodes_canvas,
139       canvas,  // canvas
140       nullptr,
141       nullptr,
142       unused_stopwatch,         // frame time (dont care)
143       unused_stopwatch,         // engine time (dont care)
144       unused_texture_registry,  // texture registry (not supported)
145       nullptr,                  // raster cache
146       false                     // checkerboard offscreen layers
147   };
148 
149   // Even if we don't have a root layer, we still need to create an empty
150   // picture.
151   if (root_layer_) {
152     root_layer_->Preroll(&preroll_context, root_surface_transformation);
153     // The needs painting flag may be set after the preroll. So check it after.
154     if (root_layer_->needs_painting()) {
155       root_layer_->Paint(paint_context);
156     }
157   }
158 
159   return recorder.finishRecordingAsPicture();
160 }
161 
162 }  // namespace flutter
163