Flutter Engine
The Flutter Engine
Public Member Functions | List of all members
flutter::AndroidExternalViewEmbedder Class Referencefinal

#include <external_view_embedder.h>

Inheritance diagram for flutter::AndroidExternalViewEmbedder:
flutter::ExternalViewEmbedder

Public Member Functions

 AndroidExternalViewEmbedder (const AndroidContext &android_context, std::shared_ptr< PlatformViewAndroidJNI > jni_facade, std::shared_ptr< AndroidSurfaceFactory > surface_factory, const TaskRunners &task_runners)
 
void PrerollCompositeEmbeddedView (int64_t view_id, std::unique_ptr< flutter::EmbeddedViewParams > params) override
 
DlCanvasCompositeEmbeddedView (int64_t view_id) override
 
void SubmitFlutterView (int64_t flutter_view_id, GrDirectContext *context, const std::shared_ptr< impeller::AiksContext > &aiks_context, std::unique_ptr< SurfaceFrame > frame) override
 
PostPrerollResult PostPrerollAction (const fml::RefPtr< fml::RasterThreadMerger > &raster_thread_merger) override
 
DlCanvasGetRootCanvas () override
 
void BeginFrame (GrDirectContext *context, const fml::RefPtr< fml::RasterThreadMerger > &raster_thread_merger) override
 
void PrepareFlutterView (SkISize frame_size, double device_pixel_ratio) override
 
void CancelFrame () override
 
void EndFrame (bool should_resubmit_frame, const fml::RefPtr< fml::RasterThreadMerger > &raster_thread_merger) override
 
bool SupportsDynamicThreadMerging () override
 
void Teardown () override
 
SkRect GetViewRect (int64_t view_id) const
 
- Public Member Functions inherited from flutter::ExternalViewEmbedder
 ExternalViewEmbedder ()=default
 
virtual ~ExternalViewEmbedder ()=default
 
virtual void CollectView (int64_t view_id)
 
virtual DlCanvasGetRootCanvas ()=0
 
virtual void CancelFrame ()=0
 
virtual void BeginFrame (GrDirectContext *context, const fml::RefPtr< fml::RasterThreadMerger > &raster_thread_merger)=0
 
virtual void PrerollCompositeEmbeddedView (int64_t platform_view_id, std::unique_ptr< EmbeddedViewParams > params)=0
 
virtual PostPrerollResult PostPrerollAction (const fml::RefPtr< fml::RasterThreadMerger > &raster_thread_merger)
 
virtual DlCanvasCompositeEmbeddedView (int64_t platform_view_id)=0
 
virtual void PrepareFlutterView (SkISize frame_size, double device_pixel_ratio)=0
 
virtual void SubmitFlutterView (int64_t flutter_view_id, GrDirectContext *context, const std::shared_ptr< impeller::AiksContext > &aiks_context, std::unique_ptr< SurfaceFrame > frame)
 
virtual void EndFrame (bool should_resubmit_frame, const fml::RefPtr< fml::RasterThreadMerger > &raster_thread_merger)
 
virtual bool SupportsDynamicThreadMerging ()
 
virtual void Teardown ()
 
void SetUsedThisFrame (bool used_this_frame)
 
bool GetUsedThisFrame () const
 
virtual void PushVisitedPlatformView (int64_t platform_view_id)
 
virtual void PushFilterToVisitedPlatformViews (const std::shared_ptr< const DlImageFilter > &filter, const SkRect &filter_rect)
 

Detailed Description

Allows to embed Android views into a Flutter application.

This class calls Java methods via |PlatformViewAndroidJNI| to manage the lifecycle of the Android view corresponding to |flutter::PlatformViewLayer|.

It also orchestrates overlay surfaces. These are Android views that render above (by Z order) the Android view corresponding to |flutter::PlatformViewLayer|.

Definition at line 29 of file external_view_embedder.h.

Constructor & Destructor Documentation

◆ AndroidExternalViewEmbedder()

flutter::AndroidExternalViewEmbedder::AndroidExternalViewEmbedder ( const AndroidContext android_context,
std::shared_ptr< PlatformViewAndroidJNI jni_facade,
std::shared_ptr< AndroidSurfaceFactory surface_factory,
const TaskRunners task_runners 
)

Definition at line 12 of file external_view_embedder.cc.

18 android_context_(android_context),
19 jni_facade_(std::move(jni_facade)),
20 surface_factory_(std::move(surface_factory)),
21 surface_pool_(std::make_unique<SurfacePool>()),
22 task_runners_(task_runners) {}

Member Function Documentation

◆ BeginFrame()

void flutter::AndroidExternalViewEmbedder::BeginFrame ( GrDirectContext context,
const fml::RefPtr< fml::RasterThreadMerger > &  raster_thread_merger 
)
overridevirtual

Implements flutter::ExternalViewEmbedder.

Definition at line 264 of file external_view_embedder.cc.

266 {
267 // JNI method must be called on the platform thread.
268 if (raster_thread_merger->IsOnPlatformThread()) {
269 jni_facade_->FlutterViewBeginFrame();
270 }
271}

◆ CancelFrame()

void flutter::AndroidExternalViewEmbedder::CancelFrame ( )
overridevirtual

Implements flutter::ExternalViewEmbedder.

Definition at line 291 of file external_view_embedder.cc.

291 {
292 Reset();
293}

◆ CompositeEmbeddedView()

DlCanvas * flutter::AndroidExternalViewEmbedder::CompositeEmbeddedView ( int64_t  view_id)
overridevirtual

Implements flutter::ExternalViewEmbedder.

Definition at line 46 of file external_view_embedder.cc.

46 {
47 if (slices_.count(view_id) == 1) {
48 return slices_.at(view_id)->canvas();
49 }
50 return nullptr;
51}

◆ EndFrame()

void flutter::AndroidExternalViewEmbedder::EndFrame ( bool  should_resubmit_frame,
const fml::RefPtr< fml::RasterThreadMerger > &  raster_thread_merger 
)
overridevirtual

Reimplemented from flutter::ExternalViewEmbedder.

Definition at line 296 of file external_view_embedder.cc.

298 {
299 surface_pool_->RecycleLayers();
300 // JNI method must be called on the platform thread.
301 if (raster_thread_merger->IsOnPlatformThread()) {
302 jni_facade_->FlutterViewEndFrame();
303 }
304}

◆ GetRootCanvas()

DlCanvas * flutter::AndroidExternalViewEmbedder::GetRootCanvas ( )
overridevirtual

Implements flutter::ExternalViewEmbedder.

Definition at line 251 of file external_view_embedder.cc.

251 {
252 // On Android, the root surface is created from the on-screen render target.
253 return nullptr;
254}

◆ GetViewRect()

SkRect flutter::AndroidExternalViewEmbedder::GetViewRect ( int64_t  view_id) const

Definition at line 53 of file external_view_embedder.cc.

53 {
54 const EmbeddedViewParams& params = view_params_.at(view_id);
55 // TODO(egarciad): The rect should be computed from the mutator stack.
56 // (Clipping is missing)
57 // https://github.com/flutter/flutter/issues/59821
58 return SkRect::MakeXYWH(params.finalBoundingRect().x(), //
59 params.finalBoundingRect().y(), //
60 params.finalBoundingRect().width(), //
61 params.finalBoundingRect().height() //
62 );
63}
const EmbeddedViewParams * params
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659

◆ PostPrerollAction()

PostPrerollResult flutter::AndroidExternalViewEmbedder::PostPrerollAction ( const fml::RefPtr< fml::RasterThreadMerger > &  raster_thread_merger)
overridevirtual

Reimplemented from flutter::ExternalViewEmbedder.

Definition at line 219 of file external_view_embedder.cc.

220 {
221 if (!FrameHasPlatformLayers()) {
223 }
224 if (!raster_thread_merger->IsMerged()) {
225 // The raster thread merger may be disabled if the rasterizer is being
226 // created or teared down.
227 //
228 // In such cases, the current frame is dropped, and a new frame is attempted
229 // with the same layer tree.
230 //
231 // Eventually, the frame is submitted once this method returns `kSuccess`.
232 // At that point, the raster tasks are handled on the platform thread.
233 CancelFrame();
234 raster_thread_merger->MergeWithLease(kDefaultMergedLeaseDuration);
236 }
237 raster_thread_merger->ExtendLeaseTo(kDefaultMergedLeaseDuration);
238 // Surface switch requires to resubmit the frame.
239 // TODO(egarciad): https://github.com/flutter/flutter/issues/65652
240 if (previous_frame_view_count_ == 0) {
242 }
244}
void ExtendLeaseTo(size_t lease_term)
void MergeWithLease(size_t lease_term)

◆ PrepareFlutterView()

void flutter::AndroidExternalViewEmbedder::PrepareFlutterView ( SkISize  frame_size,
double  device_pixel_ratio 
)
overridevirtual

Implements flutter::ExternalViewEmbedder.

Definition at line 274 of file external_view_embedder.cc.

276 {
277 Reset();
278
279 // The surface size changed. Therefore, destroy existing surfaces as
280 // the existing surfaces in the pool can't be recycled.
281 if (frame_size_ != frame_size) {
282 DestroySurfaces();
283 }
284 surface_pool_->SetFrameSize(frame_size);
285
286 frame_size_ = frame_size;
287 device_pixel_ratio_ = device_pixel_ratio;
288}

◆ PrerollCompositeEmbeddedView()

void flutter::AndroidExternalViewEmbedder::PrerollCompositeEmbeddedView ( int64_t  view_id,
std::unique_ptr< flutter::EmbeddedViewParams params 
)
overridevirtual

Implements flutter::ExternalViewEmbedder.

Definition at line 25 of file external_view_embedder.cc.

27 {
28 TRACE_EVENT0("flutter",
29 "AndroidExternalViewEmbedder::PrerollCompositeEmbeddedView");
30
31 SkRect view_bounds = SkRect::Make(frame_size_);
32 std::unique_ptr<EmbedderViewSlice> view;
33 view = std::make_unique<DisplayListEmbedderViewSlice>(view_bounds);
34 slices_.insert_or_assign(view_id, std::move(view));
35
36 composition_order_.push_back(view_id);
37 // Update params only if they changed.
38 if (view_params_.count(view_id) == 1 &&
39 view_params_.at(view_id) == *params.get()) {
40 return;
41 }
42 view_params_.insert_or_assign(view_id, EmbeddedViewParams(*params.get()));
43}
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131

◆ SubmitFlutterView()

void flutter::AndroidExternalViewEmbedder::SubmitFlutterView ( int64_t  flutter_view_id,
GrDirectContext context,
const std::shared_ptr< impeller::AiksContext > &  aiks_context,
std::unique_ptr< SurfaceFrame frame 
)
overridevirtual

Reimplemented from flutter::ExternalViewEmbedder.

Definition at line 66 of file external_view_embedder.cc.

70 {
71 TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFlutterView");
72 // TODO(dkwingsmt): This class only supports rendering into the implicit view.
73 // Properly support multi-view in the future.
74 FML_DCHECK(flutter_view_id == kFlutterImplicitViewId);
75
76 if (!FrameHasPlatformLayers()) {
77 frame->Submit();
78 return;
79 }
80
81 std::unordered_map<int64_t, SkRect> overlay_layers;
82 DlCanvas* background_canvas = frame->Canvas();
83 auto current_frame_view_count = composition_order_.size();
84
85 // Restore the clip context after exiting this method since it's changed
86 // below.
87 DlAutoCanvasRestore save(background_canvas, /*do_save=*/true);
88
89 for (size_t i = 0; i < current_frame_view_count; i++) {
90 int64_t view_id = composition_order_[i];
91 EmbedderViewSlice* slice = slices_.at(view_id).get();
92 if (slice->canvas() == nullptr) {
93 continue;
94 }
95
96 slice->end_recording();
97
98 SkRect full_joined_rect = SkRect::MakeEmpty();
99
100 // Determinate if Flutter UI intersects with any of the previous
101 // platform views stacked by z position.
102 //
103 // This is done by querying the r-tree that holds the records for the
104 // picture recorder corresponding to the flow layers added after a platform
105 // view layer.
106 for (ssize_t j = i; j >= 0; j--) {
107 int64_t current_view_id = composition_order_[j];
108 SkRect current_view_rect = GetViewRect(current_view_id);
109 // The rect above the `current_view_rect`
110 SkRect partial_joined_rect = SkRect::MakeEmpty();
111 // Each rect corresponds to a native view that renders Flutter UI.
112 std::vector<SkIRect> intersection_rects =
113 slice->region(current_view_rect).getRects();
114
115 // Limit the number of native views, so it doesn't grow forever.
116 //
117 // In this case, the rects are merged into a single one that is the union
118 // of all the rects.
119 for (const SkIRect& rect : intersection_rects) {
120 partial_joined_rect.join(SkRect::Make(rect));
121 }
122 // Get the intersection rect with the `current_view_rect`,
123 partial_joined_rect.intersect(current_view_rect);
124 // Join the `partial_joined_rect` into `full_joined_rect` to get the rect
125 // above the current `slice`
126 full_joined_rect.join(partial_joined_rect);
127 }
128 if (!full_joined_rect.isEmpty()) {
129 // Subpixels in the platform may not align with the canvas subpixels.
130 //
131 // To workaround it, round the floating point bounds and make the rect
132 // slightly larger.
133 //
134 // For example, {0.3, 0.5, 3.1, 4.7} becomes {0, 0, 4, 5}.
135 full_joined_rect.set(full_joined_rect.roundOut());
136 overlay_layers.insert({view_id, full_joined_rect});
137 // Clip the background canvas, so it doesn't contain any of the pixels
138 // drawn on the overlay layer.
139 background_canvas->ClipRect(full_joined_rect,
141 }
142 slice->render_into(background_canvas);
143 }
144
145 // Manually trigger the DlAutoCanvasRestore before we submit the frame
146 save.Restore();
147
148 // Submit the background canvas frame before switching the GL context to
149 // the overlay surfaces.
150 //
151 // Skip a frame if the embedding is switching surfaces, and indicate in
152 // `PostPrerollAction` that this frame must be resubmitted.
153 auto should_submit_current_frame = previous_frame_view_count_ > 0;
154 if (should_submit_current_frame) {
155 frame->Submit();
156 }
157
158 for (int64_t view_id : composition_order_) {
159 SkRect view_rect = GetViewRect(view_id);
160 const EmbeddedViewParams& params = view_params_.at(view_id);
161 // Display the platform view. If it's already displayed, then it's
162 // just positioned and sized.
163 jni_facade_->FlutterViewOnDisplayPlatformView(
164 view_id, //
165 view_rect.x(), //
166 view_rect.y(), //
167 view_rect.width(), //
168 view_rect.height(), //
169 params.sizePoints().width() * device_pixel_ratio_,
170 params.sizePoints().height() * device_pixel_ratio_,
171 params.mutatorsStack() //
172 );
173 std::unordered_map<int64_t, SkRect>::const_iterator overlay =
174 overlay_layers.find(view_id);
175 if (overlay == overlay_layers.end()) {
176 continue;
177 }
178 std::unique_ptr<SurfaceFrame> frame =
179 CreateSurfaceIfNeeded(context, //
180 view_id, //
181 slices_.at(view_id).get(), //
182 overlay->second //
183 );
184 if (should_submit_current_frame) {
185 frame->Submit();
186 }
187 }
188}
SkRect GetViewRect(int64_t view_id) const
double frame
Definition: examples.cpp:31
#define FML_DCHECK(condition)
Definition: logging.h:103
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
constexpr int64_t kFlutterImplicitViewId
Definition: constants.h:35
flutter::DlCanvas DlCanvas
Definition: SkRect.h:32
static constexpr SkRect MakeEmpty()
Definition: SkRect.h:595
bool intersect(const SkRect &r)
Definition: SkRect.cpp:114
constexpr float x() const
Definition: SkRect.h:720
constexpr float y() const
Definition: SkRect.h:727
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241
constexpr float height() const
Definition: SkRect.h:769
constexpr float width() const
Definition: SkRect.h:762
bool isEmpty() const
Definition: SkRect.h:693
void join(const SkRect &r)
Definition: SkRect.cpp:126
void set(const SkIRect &src)
Definition: SkRect.h:849

◆ SupportsDynamicThreadMerging()

bool flutter::AndroidExternalViewEmbedder::SupportsDynamicThreadMerging ( )
overridevirtual

Reimplemented from flutter::ExternalViewEmbedder.

Definition at line 307 of file external_view_embedder.cc.

307 {
308 return true;
309}

◆ Teardown()

void flutter::AndroidExternalViewEmbedder::Teardown ( )
overridevirtual

Reimplemented from flutter::ExternalViewEmbedder.

Definition at line 312 of file external_view_embedder.cc.

312 {
313 DestroySurfaces();
314}

The documentation for this class was generated from the following files: