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 // Submit the background canvas frame before switching the GL context to
93 // the overlay surfaces.
94 //
95 // Skip a frame if the embedding is switching surfaces, and indicate in
96 // `PostPrerollAction` that this frame must be resubmitted.
97 auto should_submit_current_frame = previous_frame_view_count_ > 0;
98 if (should_submit_current_frame) {
99 frame->Submit();
100 }
101
102 for (int64_t view_id : composition_order_) {
103 DlRect view_rect = GetViewRect(view_id);
104 const EmbeddedViewParams& params = view_params_.at(view_id);
105 // Display the platform view. If it's already displayed, then it's
106 // just positioned and sized.
107 jni_facade_->FlutterViewOnDisplayPlatformView(
108 view_id, //
109 view_rect.GetX(), //
110 view_rect.GetY(), //
111 view_rect.GetWidth(), //
112 view_rect.GetHeight(), //
113 params.sizePoints().width * device_pixel_ratio_,
114 params.sizePoints().height * device_pixel_ratio_,
115 params.mutatorsStack() //
116 );
117 std::unordered_map<int64_t, DlRect>::const_iterator overlay =
118 overlay_layers.find(view_id);
119 if (overlay == overlay_layers.end()) {
120 continue;
121 }
122 std::unique_ptr<SurfaceFrame> frame =
123 CreateSurfaceIfNeeded(context, //
124 view_id, //
125 slices_.at(view_id).get(), //
126 overlay->second //
127 );
128 if (should_submit_current_frame) {
129 frame->Submit();
130 }
131 }
132}
133
134// |ExternalViewEmbedder|
135std::unique_ptr<SurfaceFrame>
136AndroidExternalViewEmbedder::CreateSurfaceIfNeeded(GrDirectContext* context,
137 int64_t view_id,
138 EmbedderViewSlice* slice,
139 const DlRect& rect) {
140 std::shared_ptr<OverlayLayer> layer = surface_pool_->GetLayer(
141 context, android_context_, jni_facade_, surface_factory_);
142
143 std::unique_ptr<SurfaceFrame> frame =
144 layer->surface->AcquireFrame(frame_size_);
145 // Display the overlay surface. If it's already displayed, then it's
146 // just positioned and sized.
147 jni_facade_->FlutterViewDisplayOverlaySurface(layer->id, //
148 rect.GetX(), //
149 rect.GetY(), //
150 rect.GetWidth(), //
151 rect.GetHeight() //
152 );
153 DlCanvas* overlay_canvas = frame->Canvas();
154 overlay_canvas->Clear(DlColor::kTransparent());
155 // Offset the picture since its absolute position on the scene is determined
156 // by the position of the overlay view.
157 overlay_canvas->Translate(-rect.GetX(), -rect.GetY());
158 slice->render_into(overlay_canvas);
159 return frame;
160}
161
162// |ExternalViewEmbedder|
164 const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger) {
165 if (!FrameHasPlatformLayers()) {
167 }
168 if (!raster_thread_merger->IsMerged()) {
169 // The raster thread merger may be disabled if the rasterizer is being
170 // created or teared down.
171 //
172 // In such cases, the current frame is dropped, and a new frame is attempted
173 // with the same layer tree.
174 //
175 // Eventually, the frame is submitted once this method returns `kSuccess`.
176 // At that point, the raster tasks are handled on the platform thread.
177 CancelFrame();
178 raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
180 }
181 raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
182 // Surface switch requires to resubmit the frame.
183 // TODO(egarciad): https://github.com/flutter/flutter/issues/65652
184 if (previous_frame_view_count_ == 0) {
186 }
188}
189
190bool AndroidExternalViewEmbedder::FrameHasPlatformLayers() {
191 return !composition_order_.empty();
192}
193
194// |ExternalViewEmbedder|
196 // On Android, the root surface is created from the on-screen render target.
197 return nullptr;
198}
199
200void AndroidExternalViewEmbedder::Reset() {
201 previous_frame_view_count_ = composition_order_.size();
202
203 composition_order_.clear();
204 slices_.clear();
205}
206
207// |ExternalViewEmbedder|
209 GrDirectContext* context,
210 const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger) {
211 // JNI method must be called on the platform thread.
212 if (raster_thread_merger->IsOnPlatformThread()) {
213 jni_facade_->FlutterViewBeginFrame();
214 }
215}
216
217// |ExternalViewEmbedder|
219 DlISize frame_size,
220 double device_pixel_ratio) {
221 Reset();
222
223 // The surface size changed. Therefore, destroy existing surfaces as
224 // the existing surfaces in the pool can't be recycled.
225 if (frame_size_ != frame_size) {
226 DestroySurfaces();
227 }
228 surface_pool_->SetFrameSize(frame_size);
229
230 task_runners_.GetPlatformTaskRunner()->PostTask(
231 fml::MakeCopyable([jni_facade = jni_facade_, frame_size = frame_size]() {
232 jni_facade->MaybeResizeSurfaceView(frame_size.width, frame_size.height);
233 }));
234
235 frame_size_ = frame_size;
236 device_pixel_ratio_ = device_pixel_ratio;
237}
238
239// |ExternalViewEmbedder|
243
244// |ExternalViewEmbedder|
246 bool should_resubmit_frame,
247 const fml::RefPtr<fml::RasterThreadMerger>& raster_thread_merger) {
248 surface_pool_->RecycleLayers();
249 // JNI method must be called on the platform thread.
250 if (raster_thread_merger->IsOnPlatformThread()) {
251 jni_facade_->FlutterViewEndFrame();
252 }
253}
254
255// |ExternalViewEmbedder|
259
260// |ExternalViewEmbedder|
262 DestroySurfaces();
263}
264
265// |ExternalViewEmbedder|
266void AndroidExternalViewEmbedder::DestroySurfaces() {
267 if (!surface_pool_->HasLayers()) {
268 return;
269 }
272 [&]() {
273 surface_pool_->DestroyLayers(jni_facade_);
274 latch.Signal();
275 });
276 latch.Wait();
277}
278
279} // 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)
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: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
Type height
Definition size.h:29
Type width
Definition size.h:28
#define TRACE_EVENT0(category_group, name)