Flutter Engine
 
Loading...
Searching...
No Matches
external_view_embedder.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
6#include "flow/view_slicer.h"
10
11namespace flutter {
12
14 const AndroidContext& android_context,
15 std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
16 std::shared_ptr<AndroidSurfaceFactory> surface_factory,
17 const TaskRunners& task_runners)
19 android_context_(android_context),
20 jni_facade_(std::move(jni_facade)),
21 surface_factory_(std::move(surface_factory)),
22 surface_pool_(
23 std::make_unique<SurfacePool>(/*use_new_surface_methods=*/false)),
24 task_runners_(task_runners) {}
25
26// |ExternalViewEmbedder|
28 int64_t view_id,
29 std::unique_ptr<EmbeddedViewParams> params) {
30 TRACE_EVENT0("flutter",
31 "AndroidExternalViewEmbedder::PrerollCompositeEmbeddedView");
32
33 DlRect view_bounds = DlRect::MakeSize(frame_size_);
34 std::unique_ptr<EmbedderViewSlice> view;
35 view = std::make_unique<DisplayListEmbedderViewSlice>(view_bounds);
36 slices_.insert_or_assign(view_id, std::move(view));
37
38 composition_order_.push_back(view_id);
39 // Update params only if they changed.
40 if (view_params_.count(view_id) == 1 &&
41 view_params_.at(view_id) == *params.get()) {
42 return;
43 }
44 view_params_.insert_or_assign(view_id, EmbeddedViewParams(*params.get()));
45}
46
47// |ExternalViewEmbedder|
49 if (slices_.count(view_id) == 1) {
50 return slices_.at(view_id)->canvas();
51 }
52 return nullptr;
53}
54
56 const EmbeddedViewParams& params = view_params_.at(view_id);
57 // TODO(egarciad): The rect should be computed from the mutator stack.
58 // (Clipping is missing)
59 // https://github.com/flutter/flutter/issues/59821
60 return params.finalBoundingRect();
61}
62
63// |ExternalViewEmbedder|
65 int64_t flutter_view_id,
66 GrDirectContext* context,
67 const std::shared_ptr<impeller::AiksContext>& aiks_context,
68 std::unique_ptr<SurfaceFrame> frame) {
69 TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFlutterView");
70 // TODO(dkwingsmt): This class only supports rendering into the implicit view.
71 // Properly support multi-view in the future.
72 FML_DCHECK(flutter_view_id == kFlutterImplicitViewId);
73
74 if (!FrameHasPlatformLayers()) {
75 frame->Submit();
76 return;
77 }
78
79 std::unordered_map<int64_t, DlRect> view_rects;
80 for (auto platform_id : composition_order_) {
81 view_rects[platform_id] = GetViewRect(platform_id);
82 }
83
84 std::unordered_map<int64_t, DlRect> overlay_layers =
85 SliceViews(frame->Canvas(), //
86 composition_order_, //
87 slices_, //
88 view_rects //
89 );
90
91 // Submit the background canvas frame before switching the GL context to
92 // the overlay surfaces.
93 //
94 // Skip a frame if the embedding is switching surfaces, and indicate in
95 // `PostPrerollAction` that this frame must be resubmitted.
96 auto should_submit_current_frame = previous_frame_view_count_ > 0;
97 if (should_submit_current_frame) {
98 frame->Submit();
99 }
100
101 for (int64_t view_id : composition_order_) {
102 DlRect view_rect = GetViewRect(view_id);
103 const EmbeddedViewParams& params = view_params_.at(view_id);
104 // Display the platform view. If it's already displayed, then it's
105 // just positioned and sized.
106 jni_facade_->FlutterViewOnDisplayPlatformView(
107 view_id, //
108 view_rect.GetX(), //
109 view_rect.GetY(), //
110 view_rect.GetWidth(), //
111 view_rect.GetHeight(), //
112 params.sizePoints().width * device_pixel_ratio_,
113 params.sizePoints().height * device_pixel_ratio_,
114 params.mutatorsStack() //
115 );
116 std::unordered_map<int64_t, DlRect>::const_iterator overlay =
117 overlay_layers.find(view_id);
118 if (overlay == overlay_layers.end()) {
119 continue;
120 }
121 std::unique_ptr<SurfaceFrame> frame =
122 CreateSurfaceIfNeeded(context, //
123 view_id, //
124 slices_.at(view_id).get(), //
125 overlay->second //
126 );
127 if (should_submit_current_frame) {
128 frame->Submit();
129 }
130 }
131}
132
133// |ExternalViewEmbedder|
134std::unique_ptr<SurfaceFrame>
135AndroidExternalViewEmbedder::CreateSurfaceIfNeeded(GrDirectContext* context,
136 int64_t view_id,
137 EmbedderViewSlice* slice,
138 const DlRect& rect) {
139 std::shared_ptr<OverlayLayer> layer = surface_pool_->GetLayer(
140 context, android_context_, jni_facade_, surface_factory_);
141
142 std::unique_ptr<SurfaceFrame> frame =
143 layer->surface->AcquireFrame(frame_size_);
144 // Display the overlay surface. If it's already displayed, then it's
145 // just positioned and sized.
146 jni_facade_->FlutterViewDisplayOverlaySurface(layer->id, //
147 rect.GetX(), //
148 rect.GetY(), //
149 rect.GetWidth(), //
150 rect.GetHeight() //
151 );
152 DlCanvas* overlay_canvas = frame->Canvas();
153 overlay_canvas->Clear(DlColor::kTransparent());
154 // Offset the picture since its absolute position on the scene is determined
155 // by the position of the overlay view.
156 overlay_canvas->Translate(-rect.GetX(), -rect.GetY());
157 slice->render_into(overlay_canvas);
158 return frame;
159}
160
161// |ExternalViewEmbedder|
163 const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger) {
164 if (!FrameHasPlatformLayers()) {
166 }
167 if (!raster_thread_merger->IsMerged()) {
168 // The raster thread merger may be disabled if the rasterizer is being
169 // created or teared down.
170 //
171 // In such cases, the current frame is dropped, and a new frame is attempted
172 // with the same layer tree.
173 //
174 // Eventually, the frame is submitted once this method returns `kSuccess`.
175 // At that point, the raster tasks are handled on the platform thread.
176 CancelFrame();
177 raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
179 }
180 raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
181 // Surface switch requires to resubmit the frame.
182 // TODO(egarciad): https://github.com/flutter/flutter/issues/65652
183 if (previous_frame_view_count_ == 0) {
185 }
187}
188
189bool AndroidExternalViewEmbedder::FrameHasPlatformLayers() {
190 return !composition_order_.empty();
191}
192
193// |ExternalViewEmbedder|
195 // On Android, the root surface is created from the on-screen render target.
196 return nullptr;
197}
198
199void AndroidExternalViewEmbedder::Reset() {
200 previous_frame_view_count_ = composition_order_.size();
201
202 composition_order_.clear();
203 slices_.clear();
204}
205
206// |ExternalViewEmbedder|
208 GrDirectContext* context,
209 const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger) {
210 // JNI method must be called on the platform thread.
211 if (raster_thread_merger->IsOnPlatformThread()) {
212 jni_facade_->FlutterViewBeginFrame();
213 }
214}
215
216// |ExternalViewEmbedder|
218 DlISize frame_size,
219 double device_pixel_ratio) {
220 Reset();
221
222 // The surface size changed. Therefore, destroy existing surfaces as
223 // the existing surfaces in the pool can't be recycled.
224 if (frame_size_ != frame_size) {
225 DestroySurfaces();
226 }
227 surface_pool_->SetFrameSize(frame_size);
228
229 frame_size_ = frame_size;
230 device_pixel_ratio_ = device_pixel_ratio;
231}
232
233// |ExternalViewEmbedder|
237
238// |ExternalViewEmbedder|
240 bool should_resubmit_frame,
241 const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger) {
242 surface_pool_->RecycleLayers();
243 // JNI method must be called on the platform thread.
244 if (raster_thread_merger->IsOnPlatformThread()) {
245 jni_facade_->FlutterViewEndFrame();
246 }
247}
248
249// |ExternalViewEmbedder|
253
254// |ExternalViewEmbedder|
256 DestroySurfaces();
257}
258
259// |ExternalViewEmbedder|
260void AndroidExternalViewEmbedder::DestroySurfaces() {
261 if (!surface_pool_->HasLayers()) {
262 return;
263 }
266 [&]() {
267 surface_pool_->DestroyLayers(jni_facade_);
268 latch.Signal();
269 });
270 latch.Wait();
271}
272
273} // namespace flutter
Holds state that is shared across Android surfaces.
void EndFrame(bool should_resubmit_frame, const fml::RefPtr< fml::RasterThreadMerger > &raster_thread_merger) override
PostPrerollResult PostPrerollAction(const fml::RefPtr< fml::RasterThreadMerger > &raster_thread_merger) override
void PrerollCompositeEmbeddedView(int64_t view_id, std::unique_ptr< flutter::EmbeddedViewParams > params) override
void SubmitFlutterView(int64_t flutter_view_id, GrDirectContext *context, const std::shared_ptr< impeller::AiksContext > &aiks_context, std::unique_ptr< SurfaceFrame > frame) override
DlCanvas * CompositeEmbeddedView(int64_t view_id) override
void BeginFrame(GrDirectContext *context, const fml::RefPtr< fml::RasterThreadMerger > &raster_thread_merger) override
void PrepareFlutterView(DlISize frame_size, double device_pixel_ratio) override
AndroidExternalViewEmbedder(const AndroidContext &android_context, std::shared_ptr< PlatformViewAndroidJNI > jni_facade, std::shared_ptr< AndroidSurfaceFactory > surface_factory, const TaskRunners &task_runners)
DlRect GetViewRect(int64_t view_id) const
Developer-facing API for rendering anything within the engine.
Definition dl_canvas.h:32
virtual void Translate(DlScalar tx, DlScalar ty)=0
void Clear(DlColor color)
Definition dl_canvas.h:104
virtual void render_into(DlCanvas *canvas)=0
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
const EmbeddedViewParams * params
TaskRunners task_runners_
FlView * view
G_BEGIN_DECLS FlutterViewId view_id
#define FML_DCHECK(condition)
Definition logging.h:122
constexpr int64_t kFlutterImplicitViewId
Definition constants.h:35
std::unordered_map< int64_t, DlRect > SliceViews(DlCanvas *background_canvas, const std::vector< int64_t > &composition_order, const std::unordered_map< int64_t, std::unique_ptr< EmbedderViewSlice > > &slices, const std::unordered_map< int64_t, DlRect > &view_rects)
Compute the required overlay layers and clip the view slices according to the size and position of th...
Definition ref_ptr.h:261
static constexpr DlColor kTransparent()
Definition dl_color.h:68
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition rect.h:337
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition rect.h:347
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition rect.h:333
static constexpr TRect MakeSize(const TSize< U > &size)
Definition rect.h:150
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition rect.h:341
#define TRACE_EVENT0(category_group, name)