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/compositor_context.h" |
6 | |
7 | #include "flutter/flow/layers/layer_tree.h" |
8 | #include "third_party/skia/include/core/SkCanvas.h" |
9 | |
10 | namespace flutter { |
11 | |
12 | CompositorContext::CompositorContext(fml::Milliseconds frame_budget) |
13 | : raster_time_(frame_budget), ui_time_(frame_budget) {} |
14 | |
15 | CompositorContext::~CompositorContext() = default; |
16 | |
17 | void CompositorContext::BeginFrame(ScopedFrame& frame, |
18 | bool enable_instrumentation) { |
19 | if (enable_instrumentation) { |
20 | frame_count_.Increment(); |
21 | raster_time_.Start(); |
22 | } |
23 | } |
24 | |
25 | void CompositorContext::EndFrame(ScopedFrame& frame, |
26 | bool enable_instrumentation) { |
27 | raster_cache_.SweepAfterFrame(); |
28 | if (enable_instrumentation) { |
29 | raster_time_.Stop(); |
30 | } |
31 | } |
32 | |
33 | std::unique_ptr<CompositorContext::ScopedFrame> CompositorContext::AcquireFrame( |
34 | GrDirectContext* gr_context, |
35 | SkCanvas* canvas, |
36 | ExternalViewEmbedder* view_embedder, |
37 | const SkMatrix& root_surface_transformation, |
38 | bool instrumentation_enabled, |
39 | bool surface_supports_readback, |
40 | fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) { |
41 | return std::make_unique<ScopedFrame>( |
42 | *this, gr_context, canvas, view_embedder, root_surface_transformation, |
43 | instrumentation_enabled, surface_supports_readback, raster_thread_merger); |
44 | } |
45 | |
46 | CompositorContext::ScopedFrame::ScopedFrame( |
47 | CompositorContext& context, |
48 | GrDirectContext* gr_context, |
49 | SkCanvas* canvas, |
50 | ExternalViewEmbedder* view_embedder, |
51 | const SkMatrix& root_surface_transformation, |
52 | bool instrumentation_enabled, |
53 | bool surface_supports_readback, |
54 | fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) |
55 | : context_(context), |
56 | gr_context_(gr_context), |
57 | canvas_(canvas), |
58 | view_embedder_(view_embedder), |
59 | root_surface_transformation_(root_surface_transformation), |
60 | instrumentation_enabled_(instrumentation_enabled), |
61 | surface_supports_readback_(surface_supports_readback), |
62 | raster_thread_merger_(raster_thread_merger) { |
63 | context_.BeginFrame(*this, instrumentation_enabled_); |
64 | } |
65 | |
66 | CompositorContext::ScopedFrame::~ScopedFrame() { |
67 | context_.EndFrame(*this, instrumentation_enabled_); |
68 | } |
69 | |
70 | RasterStatus CompositorContext::ScopedFrame::Raster( |
71 | flutter::LayerTree& layer_tree, |
72 | bool ignore_raster_cache) { |
73 | TRACE_EVENT0("flutter" , "CompositorContext::ScopedFrame::Raster" ); |
74 | bool root_needs_readback = layer_tree.Preroll(*this, ignore_raster_cache); |
75 | bool needs_save_layer = root_needs_readback && !surface_supports_readback(); |
76 | PostPrerollResult post_preroll_result = PostPrerollResult::kSuccess; |
77 | if (view_embedder_ && raster_thread_merger_) { |
78 | post_preroll_result = |
79 | view_embedder_->PostPrerollAction(raster_thread_merger_); |
80 | } |
81 | |
82 | if (post_preroll_result == PostPrerollResult::kResubmitFrame) { |
83 | return RasterStatus::kResubmit; |
84 | } |
85 | // Clearing canvas after preroll reduces one render target switch when preroll |
86 | // paints some raster cache. |
87 | if (canvas()) { |
88 | if (needs_save_layer) { |
89 | FML_LOG(INFO) << "Using SaveLayer to protect non-readback surface" ; |
90 | SkRect bounds = SkRect::Make(layer_tree.frame_size()); |
91 | SkPaint paint; |
92 | paint.setBlendMode(SkBlendMode::kSrc); |
93 | canvas()->saveLayer(&bounds, &paint); |
94 | } |
95 | canvas()->clear(SK_ColorTRANSPARENT); |
96 | } |
97 | layer_tree.Paint(*this, ignore_raster_cache); |
98 | if (canvas() && needs_save_layer) { |
99 | canvas()->restore(); |
100 | } |
101 | return RasterStatus::kSuccess; |
102 | } |
103 | |
104 | void CompositorContext::OnGrContextCreated() { |
105 | texture_registry_.OnGrContextCreated(); |
106 | raster_cache_.Clear(); |
107 | } |
108 | |
109 | void CompositorContext::OnGrContextDestroyed() { |
110 | texture_registry_.OnGrContextDestroyed(); |
111 | raster_cache_.Clear(); |
112 | } |
113 | |
114 | } // namespace flutter |
115 | |