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