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.antialiased_lines =
63 p_settings.impeller_antialiased_lines;
64 return settings;
65}
66} // namespace
67
69 const std::shared_ptr<AndroidContext>& context,
70 bool enable_impeller,
71 bool lazy_shader_mode)
72 : android_context_(context),
73 enable_impeller_(enable_impeller),
74 lazy_shader_mode_(lazy_shader_mode) {}
75
77
78std::unique_ptr<AndroidSurface> AndroidSurfaceFactoryImpl::CreateSurface() {
79 if (android_context_->IsDynamicSelection()) {
80 auto cast_ptr = std::static_pointer_cast<AndroidContextDynamicImpeller>(
81 android_context_);
82 return std::make_unique<AndroidSurfaceDynamicImpeller>(cast_ptr);
83 }
84 switch (android_context_->RenderingApi()) {
85#if !SLIMPELLER
87 return std::make_unique<AndroidSurfaceSoftware>();
89 return std::make_unique<AndroidSurfaceGLSkia>(
90 std::static_pointer_cast<AndroidContextGLSkia>(android_context_));
91#endif // !SLIMPELLER
93 return std::make_unique<AndroidSurfaceGLImpeller>(
94 std::static_pointer_cast<AndroidContextGLImpeller>(android_context_));
96 return std::make_unique<AndroidSurfaceVKImpeller>(
97 std::static_pointer_cast<AndroidContextVKImpeller>(android_context_));
99 auto cast_ptr = std::static_pointer_cast<AndroidContextDynamicImpeller>(
100 android_context_);
101 return std::make_unique<AndroidSurfaceDynamicImpeller>(cast_ptr);
102 }
103 }
105}
106
107static std::shared_ptr<flutter::AndroidContext> CreateAndroidContext(
108 const flutter::TaskRunners& task_runners,
109 AndroidRenderingAPI android_rendering_api,
110 bool enable_opengl_gpu_tracing,
111 const AndroidContext::ContextSettings& settings) {
112 switch (android_rendering_api) {
113#if !SLIMPELLER
115 return std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
117 return std::make_unique<AndroidContextGLSkia>(
118 fml::MakeRefCounted<AndroidEnvironmentGL>(), //
119 task_runners //
120 );
121#endif // !SLIMPELLER
123 return std::make_unique<AndroidContextVKImpeller>(settings);
125 return std::make_unique<AndroidContextGLImpeller>(
126 std::make_unique<impeller::egl::Display>(),
127 enable_opengl_gpu_tracing);
129 // Determine if we're using GL or Vulkan.
130 return std::make_unique<AndroidContextDynamicImpeller>(settings);
131 }
133}
134
136 PlatformView::Delegate& delegate,
137 const flutter::TaskRunners& task_runners,
138 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
139 AndroidRenderingAPI rendering_api)
141 delegate,
142 task_runners,
143 jni_facade,
145 task_runners,
146 rendering_api,
147 delegate.OnPlatformViewGetSettings().enable_opengl_gpu_tracing,
148 CreateContextSettings(delegate.OnPlatformViewGetSettings()))) {}
149
151 PlatformView::Delegate& delegate,
152 const flutter::TaskRunners& task_runners,
153 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
154 const std::shared_ptr<flutter::AndroidContext>& android_context)
155 : PlatformView(delegate, task_runners),
156 jni_facade_(jni_facade),
157 android_context_(android_context),
158 platform_view_android_delegate_(jni_facade),
159 platform_message_handler_(new PlatformMessageHandlerAndroid(jni_facade)) {
160 if (android_context_) {
161 FML_CHECK(android_context_->IsValid())
162 << "Could not create surface from invalid Android context.";
163 surface_factory_ = std::make_shared<AndroidSurfaceFactoryImpl>(
164 android_context_, //
168 );
169 android_surface_ = surface_factory_->CreateSurface();
170 android_meets_hcpp_criteria_ =
172 android_get_device_api_level() >= kMinAPILevelHCPP &&
174 FML_CHECK(android_surface_ && android_surface_->IsValid())
175 << "Could not create an OpenGL, Vulkan or Software surface to set "
176 "up "
177 "rendering.";
178 }
179}
180
182
184 fml::RefPtr<AndroidNativeWindow> native_window) {
185 if (android_surface_) {
186 InstallFirstFrameCallback();
187
191 [&latch, surface = android_surface_.get(),
192 native_window = std::move(native_window), jni_facade = jni_facade_]() {
193 surface->SetNativeWindow(native_window, jni_facade);
194 latch.Signal();
195 });
196 latch.Wait();
197 }
198
200}
201
203 fml::RefPtr<AndroidNativeWindow> native_window) {
204 if (android_surface_) {
208 [&latch, surface = android_surface_.get(),
209 native_window = std::move(native_window), jni_facade = jni_facade_]() {
210 surface->TeardownOnScreenContext();
211 surface->SetNativeWindow(native_window, jni_facade);
212 latch.Signal();
213 });
214 latch.Wait();
215 }
216
218}
219
222
223 if (android_surface_) {
227 [&latch, surface = android_surface_.get()]() {
228 surface->TeardownOnScreenContext();
229 latch.Signal();
230 });
231 latch.Wait();
232 }
233}
234
236 if (!android_surface_) {
237 return;
238 }
242 [&latch, surface = android_surface_.get(), size]() {
243 surface->OnScreenSurfaceResize(size);
244 latch.Signal();
245 });
246 latch.Wait();
247}
248
250 std::string name,
251 jobject java_message_data,
252 jint java_message_position,
253 jint response_id) {
254 uint8_t* message_data =
255 static_cast<uint8_t*>(env->GetDirectBufferAddress(java_message_data));
257 fml::MallocMapping::Copy(message_data, java_message_position);
258
260 if (response_id) {
261 response = fml::MakeRefCounted<PlatformMessageResponseAndroid>(
262 response_id, jni_facade_, task_runners_.GetPlatformTaskRunner());
263 }
264
266 std::make_unique<flutter::PlatformMessage>(
267 std::move(name), std::move(message), std::move(response)));
268}
269
271 std::string name,
272 jint response_id) {
274 if (response_id) {
275 response = fml::MakeRefCounted<PlatformMessageResponseAndroid>(
276 response_id, jni_facade_, task_runners_.GetPlatformTaskRunner());
277 }
278
280 std::make_unique<flutter::PlatformMessage>(std::move(name),
281 std::move(response)));
282}
283
284// |PlatformView|
285void PlatformViewAndroid::HandlePlatformMessage(
286 std::unique_ptr<flutter::PlatformMessage> message) {
287 // Called from the ui thread.
288 platform_message_handler_->HandlePlatformMessage(std::move(message));
289}
290
291// |PlatformView|
292void PlatformViewAndroid::OnPreEngineRestart() const {
293 jni_facade_->FlutterViewOnPreEngineRestart();
294}
295
297 jint node_id,
298 jint action,
299 jobject args,
300 jint args_position) {
301 // TODO(team-android): Remove implicit view assumption.
302 // https://github.com/flutter/flutter/issues/142845
303 if (env->IsSameObject(args, NULL)) {
305 kImplicitViewId, node_id, static_cast<flutter::SemanticsAction>(action),
307 return;
308 }
309
310 uint8_t* args_data = static_cast<uint8_t*>(env->GetDirectBufferAddress(args));
311 auto args_vector = fml::MallocMapping::Copy(args_data, args_position);
312
314 kImplicitViewId, node_id, static_cast<flutter::SemanticsAction>(action),
315 std::move(args_vector));
316}
317
318// |PlatformView|
319void PlatformViewAndroid::UpdateSemantics(
320 int64_t view_id,
323 platform_view_android_delegate_.UpdateSemantics(update, actions);
324}
325
326// |PlatformView|
327void PlatformViewAndroid::SetApplicationLocale(std::string locale) {
328 jni_facade_->FlutterViewSetApplicationLocale(std::move(locale));
329}
330
331// |PlatformView|
332void PlatformViewAndroid::SetSemanticsTreeEnabled(bool enabled) {
333 jni_facade_->FlutterViewSetSemanticsTreeEnabled(enabled);
334}
335
337 int64_t texture_id,
338 const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture) {
339 switch (android_context_->RenderingApi()) {
341 // Impeller GLES.
342 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureGLImpeller>(
343 std::static_pointer_cast<impeller::ContextGLES>(
344 android_context_->GetImpellerContext()), //
345 texture_id, //
346 surface_texture, //
347 jni_facade_ //
348 ));
349 break;
350#if !SLIMPELLER
352 // Legacy GL.
353 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureGLSkia>(
354 texture_id, //
355 surface_texture, //
356 jni_facade_ //
357 ));
358 break;
360 FML_LOG(INFO) << "Software rendering does not support external textures.";
361 break;
362#endif // !SLIMPELLER
364 FML_LOG(IMPORTANT)
365 << "Flutter recommends migrating plugins that create and "
366 "register surface textures to the new surface producer "
367 "API. See https://docs.flutter.dev/release/breaking-changes/"
368 "android-surface-plugins";
369 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureVKImpeller>(
370 std::static_pointer_cast<impeller::ContextVK>(
371 android_context_->GetImpellerContext()), //
372 texture_id, //
373 surface_texture, //
374 jni_facade_ //
375 ));
376 break;
378 default:
379 FML_CHECK(false);
380 break;
381 }
382}
383
385 int64_t texture_id,
386 const fml::jni::ScopedJavaGlobalRef<jobject>& image_texture_entry,
388 switch (android_context_->RenderingApi()) {
389#if !SLIMPELLER
391 // Legacy GL.
392 RegisterTexture(std::make_shared<ImageExternalTextureGLSkia>(
393 std::static_pointer_cast<AndroidContextGLSkia>(android_context_),
394 texture_id, image_texture_entry, jni_facade_, lifecycle));
395 break;
397 FML_LOG(INFO) << "Software rendering does not support external textures.";
398 break;
399#endif // !SLIMPELLER
401 // Impeller GLES.
402 RegisterTexture(std::make_shared<ImageExternalTextureGLImpeller>(
403 std::static_pointer_cast<impeller::ContextGLES>(
404 android_context_->GetImpellerContext()),
405 texture_id, image_texture_entry, jni_facade_, lifecycle));
406 break;
408 RegisterTexture(std::make_shared<ImageExternalTextureVKImpeller>(
409 std::static_pointer_cast<impeller::ContextVK>(
410 android_context_->GetImpellerContext()),
411 texture_id, image_texture_entry, jni_facade_, lifecycle));
412 break;
414 FML_CHECK(false);
415 break;
416 }
417}
418
419// |PlatformView|
420std::unique_ptr<VsyncWaiter> PlatformViewAndroid::CreateVSyncWaiter() {
421 return std::make_unique<VsyncWaiterAndroid>(task_runners_);
422}
423
424// |PlatformView|
425std::unique_ptr<Surface> PlatformViewAndroid::CreateRenderingSurface() {
426 if (!android_surface_) {
427 return nullptr;
428 }
429 return android_surface_->CreateGPUSurface(
430 android_context_->GetMainSkiaContext().get());
431}
432
433// |PlatformView|
434std::shared_ptr<ExternalViewEmbedder>
435PlatformViewAndroid::CreateExternalViewEmbedder() {
436 return std::make_shared<AndroidExternalViewEmbedderWrapper>(
437 android_meets_hcpp_criteria_, *android_context_, jni_facade_,
438 surface_factory_, task_runners_);
439}
440
441// |PlatformView|
442std::unique_ptr<SnapshotSurfaceProducer>
443PlatformViewAndroid::CreateSnapshotSurfaceProducer() {
444 if (!android_surface_) {
445 return nullptr;
446 }
447 return std::make_unique<AndroidSnapshotSurfaceProducer>(*android_surface_);
448}
449
450// |PlatformView|
451sk_sp<GrDirectContext> PlatformViewAndroid::CreateResourceContext() const {
452 if (!android_surface_) {
453 return nullptr;
454 }
455#if !SLIMPELLER
456 sk_sp<GrDirectContext> resource_context;
457 if (android_surface_->ResourceContextMakeCurrent()) {
458 // TODO(chinmaygarde): Currently, this code depends on the fact that only
459 // the OpenGL surface will be able to make a resource context current. If
460 // this changes, this assumption breaks. Handle the same.
462 GrBackendApi::kOpenGL,
464 } else {
465 FML_DLOG(ERROR) << "Could not make the resource context current.";
466 }
467 return resource_context;
468#else
469 android_surface_->ResourceContextMakeCurrent();
470 return nullptr;
471#endif // !SLIMPELLER
472}
473
474// |PlatformView|
475void PlatformViewAndroid::ReleaseResourceContext() const {
476 if (android_surface_) {
477 android_surface_->ResourceContextClearCurrent();
478 }
479}
480
481// |PlatformView|
482std::shared_ptr<impeller::Context> PlatformViewAndroid::GetImpellerContext()
483 const {
484 if (android_surface_) {
485 return android_surface_->GetImpellerContext();
486 }
487 return android_context_->GetImpellerContext();
488}
489
490// |PlatformView|
491std::unique_ptr<std::vector<std::string>>
492PlatformViewAndroid::ComputePlatformResolvedLocales(
493 const std::vector<std::string>& supported_locale_data) {
494 return jni_facade_->FlutterViewComputePlatformResolvedLocale(
495 supported_locale_data);
496}
497
498// |PlatformView|
499void PlatformViewAndroid::RequestDartDeferredLibrary(intptr_t loading_unit_id) {
500 if (jni_facade_->RequestDartDeferredLibrary(loading_unit_id)) {
501 return;
502 }
503 return; // TODO(garyq): Call LoadDartDeferredLibraryFailure()
504}
505
506// |PlatformView|
508 intptr_t loading_unit_id,
509 std::unique_ptr<const fml::Mapping> snapshot_data,
510 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
511 delegate_.LoadDartDeferredLibrary(loading_unit_id, std::move(snapshot_data),
512 std::move(snapshot_instructions));
513}
514
515// |PlatformView|
517 intptr_t loading_unit_id,
518 const std::string error_message,
519 bool transient) {
520 delegate_.LoadDartDeferredLibraryError(loading_unit_id, error_message,
521 transient);
522}
523
524// |PlatformView|
526 std::unique_ptr<AssetResolver> updated_asset_resolver,
528 delegate_.UpdateAssetResolverByType(std::move(updated_asset_resolver), type);
529}
530
531void PlatformViewAndroid::InstallFirstFrameCallback() {
532 // On Platform Task Runner.
535 platform_task_runner = task_runners_.GetPlatformTaskRunner()]() {
536 // On GPU Task Runner.
537 platform_task_runner->PostTask([platform_view]() {
538 // Back on Platform Task Runner.
539 if (platform_view) {
540 reinterpret_cast<PlatformViewAndroid*>(platform_view.get())
541 ->FireFirstFrameCallback();
542 }
543 });
544 });
545}
546
547void PlatformViewAndroid::FireFirstFrameCallback() {
548 jni_facade_->FlutterViewOnFirstFrame();
549}
550
551double PlatformViewAndroid::GetScaledFontSize(double unscaled_font_size,
552 int configuration_id) const {
553 return jni_facade_->FlutterViewGetScaledFontSize(unscaled_font_size,
554 configuration_id);
555}
556
557bool PlatformViewAndroid::IsSurfaceControlEnabled() const {
558 // This needs to know if we're actually using HCPP.
559 return android_meets_hcpp_criteria_ &&
560 android_context_->RenderingApi() ==
561 AndroidRenderingAPI::kImpellerVulkan &&
562 impeller::ContextVK::Cast(*android_context_->GetImpellerContext())
564}
565
566void PlatformViewAndroid::SetupImpellerContext() {
567 android_context_->SetupImpellerContext();
568 android_surface_->SetupImpellerSurface();
569}
570
571} // 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