Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
platform_view_android.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
7#include <android/api-level.h>
8#include <sys/system_properties.h>
9#include <memory>
10#include <utility>
11
12#include "common/settings.h"
26
27#if !SLIMPELLER
33#endif // !SLIMPELLER
34
35#include "fml/logging.h"
37#if IMPELLER_ENABLE_VULKAN // b/258506856 for why this is behind an if
40#endif
48
49namespace flutter {
50
51namespace {
52
53static constexpr int kMinAPILevelHCPP = 34;
54static constexpr int64_t kImplicitViewId = 0;
55
56AndroidContext::ContextSettings CreateContextSettings(
57 const Settings& p_settings) {
58 AndroidContext::ContextSettings settings;
59 settings.enable_gpu_tracing = p_settings.enable_vulkan_gpu_tracing;
60 settings.enable_validation = p_settings.enable_vulkan_validation;
61 settings.enable_surface_control = p_settings.enable_surface_control;
62 settings.impeller_flags.lazy_shader_mode =
63 p_settings.impeller_enable_lazy_shader_mode;
64 settings.impeller_flags.antialiased_lines =
65 p_settings.impeller_antialiased_lines;
66 return settings;
67}
68} // namespace
69
71 const std::shared_ptr<AndroidContext>& context,
72 bool enable_impeller,
73 bool lazy_shader_mode)
74 : android_context_(context),
75 enable_impeller_(enable_impeller),
76 lazy_shader_mode_(lazy_shader_mode) {}
77
79
80std::unique_ptr<AndroidSurface> AndroidSurfaceFactoryImpl::CreateSurface() {
81 if (android_context_->IsDynamicSelection()) {
82 auto cast_ptr = std::static_pointer_cast<AndroidContextDynamicImpeller>(
83 android_context_);
84 return std::make_unique<AndroidSurfaceDynamicImpeller>(cast_ptr);
85 }
86 switch (android_context_->RenderingApi()) {
87#if !SLIMPELLER
89 return std::make_unique<AndroidSurfaceSoftware>();
91 return std::make_unique<AndroidSurfaceGLSkia>(
92 std::static_pointer_cast<AndroidContextGLSkia>(android_context_));
93#endif // !SLIMPELLER
95 return std::make_unique<AndroidSurfaceGLImpeller>(
96 std::static_pointer_cast<AndroidContextGLImpeller>(android_context_));
98 return std::make_unique<AndroidSurfaceVKImpeller>(
99 std::static_pointer_cast<AndroidContextVKImpeller>(android_context_));
101 auto cast_ptr = std::static_pointer_cast<AndroidContextDynamicImpeller>(
102 android_context_);
103 return std::make_unique<AndroidSurfaceDynamicImpeller>(cast_ptr);
104 }
105 }
107}
108
109static std::shared_ptr<flutter::AndroidContext> CreateAndroidContext(
110 const flutter::TaskRunners& task_runners,
111 AndroidRenderingAPI android_rendering_api,
112 bool enable_opengl_gpu_tracing,
113 const AndroidContext::ContextSettings& settings) {
114 switch (android_rendering_api) {
115#if !SLIMPELLER
117 return std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
119 return std::make_unique<AndroidContextGLSkia>(
120 fml::MakeRefCounted<AndroidEnvironmentGL>(), //
121 task_runners //
122 );
123#endif // !SLIMPELLER
125 return std::make_unique<AndroidContextVKImpeller>(settings);
127 return std::make_unique<AndroidContextGLImpeller>(
128 std::make_unique<impeller::egl::Display>(),
129 enable_opengl_gpu_tracing);
131 // Determine if we're using GL or Vulkan.
132 return std::make_unique<AndroidContextDynamicImpeller>(settings);
133 }
135}
136
138 PlatformView::Delegate& delegate,
139 const flutter::TaskRunners& task_runners,
140 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
141 AndroidRenderingAPI rendering_api)
143 delegate,
144 task_runners,
145 jni_facade,
147 task_runners,
148 rendering_api,
149 delegate.OnPlatformViewGetSettings().enable_opengl_gpu_tracing,
150 CreateContextSettings(delegate.OnPlatformViewGetSettings()))) {}
151
153 PlatformView::Delegate& delegate,
154 const flutter::TaskRunners& task_runners,
155 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
156 const std::shared_ptr<flutter::AndroidContext>& android_context)
157 : PlatformView(delegate, task_runners),
158 jni_facade_(jni_facade),
159 android_context_(android_context),
160 platform_view_android_delegate_(jni_facade),
161 platform_message_handler_(new PlatformMessageHandlerAndroid(jni_facade)) {
162 if (android_context_) {
163 FML_CHECK(android_context_->IsValid())
164 << "Could not create surface from invalid Android context.";
165 surface_factory_ = std::make_shared<AndroidSurfaceFactoryImpl>(
166 android_context_, //
170 );
171 android_surface_ = surface_factory_->CreateSurface();
172 android_meets_hcpp_criteria_ =
174 android_get_device_api_level() >= kMinAPILevelHCPP &&
176 FML_CHECK(android_surface_ && android_surface_->IsValid())
177 << "Could not create an OpenGL, Vulkan or Software surface to set "
178 "up "
179 "rendering.";
180 }
181}
182
184
186 fml::RefPtr<AndroidNativeWindow> native_window) {
187 if (android_surface_) {
188 InstallFirstFrameCallback();
189
193 [&latch, surface = android_surface_.get(),
194 native_window = std::move(native_window), jni_facade = jni_facade_]() {
195 surface->SetNativeWindow(native_window, jni_facade);
196 latch.Signal();
197 });
198 latch.Wait();
199 }
200
202}
203
205 fml::RefPtr<AndroidNativeWindow> native_window) {
206 if (android_surface_) {
210 [&latch, surface = android_surface_.get(),
211 native_window = std::move(native_window), jni_facade = jni_facade_]() {
212 surface->TeardownOnScreenContext();
213 surface->SetNativeWindow(native_window, jni_facade);
214 latch.Signal();
215 });
216 latch.Wait();
217 }
218
220}
221
224
225 if (android_surface_) {
229 [&latch, surface = android_surface_.get()]() {
230 surface->TeardownOnScreenContext();
231 latch.Signal();
232 });
233 latch.Wait();
234 }
235}
236
238 if (!android_surface_) {
239 return;
240 }
244 [&latch, surface = android_surface_.get(), size]() {
245 surface->OnScreenSurfaceResize(size);
246 latch.Signal();
247 });
248 latch.Wait();
249}
250
252 std::string name,
253 jobject java_message_data,
254 jint java_message_position,
255 jint response_id) {
256 uint8_t* message_data =
257 static_cast<uint8_t*>(env->GetDirectBufferAddress(java_message_data));
259 fml::MallocMapping::Copy(message_data, java_message_position);
260
262 if (response_id) {
263 response = fml::MakeRefCounted<PlatformMessageResponseAndroid>(
264 response_id, jni_facade_, task_runners_.GetPlatformTaskRunner());
265 }
266
268 std::make_unique<flutter::PlatformMessage>(
269 std::move(name), std::move(message), std::move(response)));
270}
271
273 std::string name,
274 jint response_id) {
276 if (response_id) {
277 response = fml::MakeRefCounted<PlatformMessageResponseAndroid>(
278 response_id, jni_facade_, task_runners_.GetPlatformTaskRunner());
279 }
280
282 std::make_unique<flutter::PlatformMessage>(std::move(name),
283 std::move(response)));
284}
285
286// |PlatformView|
287void PlatformViewAndroid::HandlePlatformMessage(
288 std::unique_ptr<flutter::PlatformMessage> message) {
289 // Called from the ui thread.
290 platform_message_handler_->HandlePlatformMessage(std::move(message));
291}
292
293// |PlatformView|
294void PlatformViewAndroid::OnPreEngineRestart() const {
295 jni_facade_->FlutterViewOnPreEngineRestart();
296}
297
299 jint node_id,
300 jint action,
301 jobject args,
302 jint args_position) {
303 // TODO(team-android): Remove implicit view assumption.
304 // https://github.com/flutter/flutter/issues/142845
305 if (env->IsSameObject(args, NULL)) {
307 kImplicitViewId, node_id, static_cast<flutter::SemanticsAction>(action),
309 return;
310 }
311
312 uint8_t* args_data = static_cast<uint8_t*>(env->GetDirectBufferAddress(args));
313 auto args_vector = fml::MallocMapping::Copy(args_data, args_position);
314
316 kImplicitViewId, node_id, static_cast<flutter::SemanticsAction>(action),
317 std::move(args_vector));
318}
319
320// |PlatformView|
321void PlatformViewAndroid::UpdateSemantics(
322 int64_t view_id,
325 platform_view_android_delegate_.UpdateSemantics(update, actions);
326}
327
328// |PlatformView|
329void PlatformViewAndroid::SetApplicationLocale(std::string locale) {
330 jni_facade_->FlutterViewSetApplicationLocale(std::move(locale));
331}
332
333// |PlatformView|
334void PlatformViewAndroid::SetSemanticsTreeEnabled(bool enabled) {
335 jni_facade_->FlutterViewSetSemanticsTreeEnabled(enabled);
336}
337
339 int64_t texture_id,
340 const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture) {
341 switch (android_context_->RenderingApi()) {
343 // Impeller GLES.
344 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureGLImpeller>(
345 std::static_pointer_cast<impeller::ContextGLES>(
346 android_context_->GetImpellerContext()), //
347 texture_id, //
348 surface_texture, //
349 jni_facade_ //
350 ));
351 break;
352#if !SLIMPELLER
354 // Legacy GL.
355 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureGLSkia>(
356 texture_id, //
357 surface_texture, //
358 jni_facade_ //
359 ));
360 break;
362 FML_LOG(INFO) << "Software rendering does not support external textures.";
363 break;
364#endif // !SLIMPELLER
366 FML_LOG(IMPORTANT)
367 << "Flutter recommends migrating plugins that create and "
368 "register surface textures to the new surface producer "
369 "API. See https://docs.flutter.dev/release/breaking-changes/"
370 "android-surface-plugins";
371 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureVKImpeller>(
372 std::static_pointer_cast<impeller::ContextVK>(
373 android_context_->GetImpellerContext()), //
374 texture_id, //
375 surface_texture, //
376 jni_facade_ //
377 ));
378 break;
380 default:
381 FML_CHECK(false);
382 break;
383 }
384}
385
387 int64_t texture_id,
388 const fml::jni::ScopedJavaGlobalRef<jobject>& image_texture_entry,
390 switch (android_context_->RenderingApi()) {
391#if !SLIMPELLER
393 // Legacy GL.
394 RegisterTexture(std::make_shared<ImageExternalTextureGLSkia>(
395 std::static_pointer_cast<AndroidContextGLSkia>(android_context_),
396 texture_id, image_texture_entry, jni_facade_, lifecycle));
397 break;
399 FML_LOG(INFO) << "Software rendering does not support external textures.";
400 break;
401#endif // !SLIMPELLER
403 // Impeller GLES.
404 RegisterTexture(std::make_shared<ImageExternalTextureGLImpeller>(
405 std::static_pointer_cast<impeller::ContextGLES>(
406 android_context_->GetImpellerContext()),
407 texture_id, image_texture_entry, jni_facade_, lifecycle));
408 break;
410 RegisterTexture(std::make_shared<ImageExternalTextureVKImpeller>(
411 std::static_pointer_cast<impeller::ContextVK>(
412 android_context_->GetImpellerContext()),
413 texture_id, image_texture_entry, jni_facade_, lifecycle));
414 break;
416 FML_CHECK(false);
417 break;
418 }
419}
420
421// |PlatformView|
422std::unique_ptr<VsyncWaiter> PlatformViewAndroid::CreateVSyncWaiter() {
423 return std::make_unique<VsyncWaiterAndroid>(task_runners_);
424}
425
426// |PlatformView|
427std::unique_ptr<Surface> PlatformViewAndroid::CreateRenderingSurface() {
428 if (!android_surface_) {
429 return nullptr;
430 }
431 return android_surface_->CreateGPUSurface(
432 android_context_->GetMainSkiaContext().get());
433}
434
435// |PlatformView|
436std::shared_ptr<ExternalViewEmbedder>
437PlatformViewAndroid::CreateExternalViewEmbedder() {
438 return std::make_shared<AndroidExternalViewEmbedderWrapper>(
439 android_meets_hcpp_criteria_, *android_context_, jni_facade_,
440 surface_factory_, task_runners_);
441}
442
443// |PlatformView|
444std::unique_ptr<SnapshotSurfaceProducer>
445PlatformViewAndroid::CreateSnapshotSurfaceProducer() {
446 if (!android_surface_) {
447 return nullptr;
448 }
449 return std::make_unique<AndroidSnapshotSurfaceProducer>(*android_surface_);
450}
451
452// |PlatformView|
453sk_sp<GrDirectContext> PlatformViewAndroid::CreateResourceContext() const {
454 if (!android_surface_) {
455 return nullptr;
456 }
457#if !SLIMPELLER
458 sk_sp<GrDirectContext> resource_context;
459 if (android_surface_->ResourceContextMakeCurrent()) {
460 // TODO(chinmaygarde): Currently, this code depends on the fact that only
461 // the OpenGL surface will be able to make a resource context current. If
462 // this changes, this assumption breaks. Handle the same.
464 GrBackendApi::kOpenGL,
466 } else {
467 FML_DLOG(ERROR) << "Could not make the resource context current.";
468 }
469 return resource_context;
470#else
471 android_surface_->ResourceContextMakeCurrent();
472 return nullptr;
473#endif // !SLIMPELLER
474}
475
476// |PlatformView|
477void PlatformViewAndroid::ReleaseResourceContext() const {
478 if (android_surface_) {
479 android_surface_->ResourceContextClearCurrent();
480 }
481}
482
483// |PlatformView|
484std::shared_ptr<impeller::Context> PlatformViewAndroid::GetImpellerContext()
485 const {
486 if (android_surface_) {
487 return android_surface_->GetImpellerContext();
488 }
489 return android_context_->GetImpellerContext();
490}
491
492// |PlatformView|
493std::unique_ptr<std::vector<std::string>>
494PlatformViewAndroid::ComputePlatformResolvedLocales(
495 const std::vector<std::string>& supported_locale_data) {
496 return jni_facade_->FlutterViewComputePlatformResolvedLocale(
497 supported_locale_data);
498}
499
500// |PlatformView|
501void PlatformViewAndroid::RequestDartDeferredLibrary(intptr_t loading_unit_id) {
502 if (jni_facade_->RequestDartDeferredLibrary(loading_unit_id)) {
503 return;
504 }
505 return; // TODO(garyq): Call LoadDartDeferredLibraryFailure()
506}
507
508// |PlatformView|
510 intptr_t loading_unit_id,
511 std::unique_ptr<const fml::Mapping> snapshot_data,
512 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
513 delegate_.LoadDartDeferredLibrary(loading_unit_id, std::move(snapshot_data),
514 std::move(snapshot_instructions));
515}
516
517// |PlatformView|
519 intptr_t loading_unit_id,
520 const std::string error_message,
521 bool transient) {
522 delegate_.LoadDartDeferredLibraryError(loading_unit_id, error_message,
523 transient);
524}
525
526// |PlatformView|
528 std::unique_ptr<AssetResolver> updated_asset_resolver,
530 delegate_.UpdateAssetResolverByType(std::move(updated_asset_resolver), type);
531}
532
533void PlatformViewAndroid::InstallFirstFrameCallback() {
534 // On Platform Task Runner.
537 platform_task_runner = task_runners_.GetPlatformTaskRunner()]() {
538 // On GPU Task Runner.
539 platform_task_runner->PostTask([platform_view]() {
540 // Back on Platform Task Runner.
541 if (platform_view) {
542 reinterpret_cast<PlatformViewAndroid*>(platform_view.get())
543 ->FireFirstFrameCallback();
544 }
545 });
546 });
547}
548
549void PlatformViewAndroid::FireFirstFrameCallback() {
550 jni_facade_->FlutterViewOnFirstFrame();
551}
552
553double PlatformViewAndroid::GetScaledFontSize(double unscaled_font_size,
554 int configuration_id) const {
555 return jni_facade_->FlutterViewGetScaledFontSize(unscaled_font_size,
556 configuration_id);
557}
558
559bool PlatformViewAndroid::IsSurfaceControlEnabled() const {
560 // This needs to know if we're actually using HCPP.
561 return android_meets_hcpp_criteria_ &&
562 android_context_->RenderingApi() ==
563 AndroidRenderingAPI::kImpellerVulkan &&
564 impeller::ContextVK::Cast(*android_context_->GetImpellerContext())
566}
567
568void PlatformViewAndroid::SetupImpellerContext() {
569 android_context_->SetupImpellerContext();
570 android_surface_->SetupImpellerSurface();
571}
572
573} // namespace flutter
std::unique_ptr< flutter::PlatformViewIOS > platform_view
GLenum type
std::unique_ptr< AndroidSurface > CreateSurface() override
AndroidSurfaceFactoryImpl(const std::shared_ptr< AndroidContext > &context, bool enable_impeller, bool lazy_shader_mode)
AssetResolverType
Identifies the type of AssetResolver an instance is.
static sk_sp< const GrGLInterface > GetDefaultPlatformGLInterface()
ImageLifecycle
Whether the last image should be reset when the context is destroyed.
Used to forward events from the platform view to interested subsystems. This forwarding is done by th...
virtual void UpdateAssetResolverByType(std::unique_ptr< AssetResolver > updated_asset_resolver, AssetResolver::AssetResolverType type)=0
Replaces the asset resolver handled by the engine's AssetManager of the specified type with updated_a...
virtual const Settings & OnPlatformViewGetSettings() const =0
Called by the platform view on the platform thread to get the settings object associated with the pla...
virtual void LoadDartDeferredLibrary(intptr_t loading_unit_id, std::unique_ptr< const fml::Mapping > snapshot_data, std::unique_ptr< const fml::Mapping > snapshot_instructions)=0
Loads the dart shared library into the dart VM. When the dart library is loaded successfully,...
virtual void LoadDartDeferredLibraryError(intptr_t loading_unit_id, const std::string error_message, bool transient)=0
Indicates to the dart VM that the request to load a deferred library with the specified loading unit ...
void UpdateSemantics(const flutter::SemanticsNodeUpdates &update, const flutter::CustomAccessibilityActionUpdates &actions)
void RegisterImageTexture(int64_t texture_id, const fml::jni::ScopedJavaGlobalRef< jobject > &image_texture_entry, ImageExternalTexture::ImageLifecycle lifecycle)
PlatformViewAndroid(PlatformView::Delegate &delegate, const flutter::TaskRunners &task_runners, const std::shared_ptr< PlatformViewAndroidJNI > &jni_facade, AndroidRenderingAPI rendering_api)
void DispatchPlatformMessage(JNIEnv *env, std::string name, jobject message_data, jint message_position, jint response_id)
void RegisterExternalTexture(int64_t texture_id, const fml::jni::ScopedJavaGlobalRef< jobject > &surface_texture)
void NotifySurfaceWindowChanged(fml::RefPtr< AndroidNativeWindow > native_window)
void NotifyChanged(const DlISize &size)
void DispatchEmptyPlatformMessage(JNIEnv *env, std::string name, jint response_id)
void NotifyDestroyed() override
Used by embedders to notify the shell that the platform view has been destroyed. This notification us...
void UpdateAssetResolverByType(std::unique_ptr< AssetResolver > updated_asset_resolver, AssetResolver::AssetResolverType type) override
Replaces the asset resolver handled by the engine's AssetManager of the specified type with updated_a...
void DispatchSemanticsAction(JNIEnv *env, jint id, jint action, jobject args, jint args_position)
void LoadDartDeferredLibraryError(intptr_t loading_unit_id, const std::string error_message, bool transient) override
Indicates to the dart VM that the request to load a deferred library with the specified loading unit ...
void LoadDartDeferredLibrary(intptr_t loading_unit_id, std::unique_ptr< const fml::Mapping > snapshot_data, std::unique_ptr< const fml::Mapping > snapshot_instructions) override
Loads the Dart shared library into the Dart VM. When the Dart library is loaded successfully,...
Platform views are created by the shell on the platform task runner. Unless explicitly specified,...
virtual void NotifyDestroyed()
Used by embedders to notify the shell that the platform view has been destroyed. This notification us...
void SetNextFrameCallback(const fml::closure &closure)
Sets a callback that gets executed when the rasterizer renders the next frame. Due to the asynchronou...
void RegisterTexture(std::shared_ptr< flutter::Texture > texture)
Used by the embedder to specify a texture that it wants the rasterizer to composite within the Flutte...
void DispatchSemanticsAction(int64_t view_id, int32_t node_id, SemanticsAction action, fml::MallocMapping args)
Used by embedders to dispatch an accessibility action to a running isolate hosted by the engine.
void DispatchPlatformMessage(std::unique_ptr< PlatformMessage > message)
Used by embedders to dispatch a platform message to a running root isolate hosted by the engine....
PlatformView::Delegate & delegate_
void NotifyCreated()
Used by embedders to notify the shell that a platform view has been created. This notification is use...
fml::WeakPtr< PlatformView > GetWeakPtr() const
Returns a weak pointer to the platform view. Since the platform view may only be created,...
void ScheduleFrame()
Used by embedders to schedule a frame. In response to this call, the framework may need to start gene...
const TaskRunners task_runners_
static sk_sp< GrDirectContext > CreateCompatibleResourceLoadingContext(GrBackendApi backend, const sk_sp< const GrGLInterface > &gl_interface)
fml::RefPtr< fml::TaskRunner > GetRasterTaskRunner() const
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
A Mapping like NonOwnedMapping, but uses Free as its release proc.
Definition mapping.h:144
static MallocMapping Copy(const T *begin, const T *end)
Definition mapping.h:162
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
static ContextVK & Cast(Context &base)
bool GetShouldEnableSurfaceControlSwapchain() const
Whether the Android Surface control based swapchain should be enabled.
VkSurfaceKHR surface
Definition main.cc:65
const char * message
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS FlutterViewId view_id
#define FML_DLOG(severity)
Definition logging.h:121
#define FML_LOG(severity)
Definition logging.h:101
#define FML_CHECK(condition)
Definition logging.h:104
#define FML_UNREACHABLE()
Definition logging.h:128
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
std::unordered_map< int32_t, CustomAccessibilityAction > CustomAccessibilityActionUpdates
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
DEF_SWITCHES_START aot vmservice shared library name
Definition switch_defs.h:27
constexpr FlutterViewId kImplicitViewId
static std::shared_ptr< flutter::AndroidContext > CreateAndroidContext(const flutter::TaskRunners &task_runners, AndroidRenderingAPI android_rendering_api, bool enable_opengl_gpu_tracing, const AndroidContext::ContextSettings &settings)
bool impeller_enable_lazy_shader_mode
Definition settings.h:239
bool enable_surface_control
Definition settings.h:236
int64_t texture_id