Flutter Engine
 
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
334 int64_t texture_id,
335 const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture) {
336 switch (android_context_->RenderingApi()) {
338 // Impeller GLES.
339 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureGLImpeller>(
340 std::static_pointer_cast<impeller::ContextGLES>(
341 android_context_->GetImpellerContext()), //
342 texture_id, //
343 surface_texture, //
344 jni_facade_ //
345 ));
346 break;
347#if !SLIMPELLER
349 // Legacy GL.
350 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureGLSkia>(
351 texture_id, //
352 surface_texture, //
353 jni_facade_ //
354 ));
355 break;
357 FML_LOG(INFO) << "Software rendering does not support external textures.";
358 break;
359#endif // !SLIMPELLER
361 FML_LOG(IMPORTANT)
362 << "Flutter recommends migrating plugins that create and "
363 "register surface textures to the new surface producer "
364 "API. See https://docs.flutter.dev/release/breaking-changes/"
365 "android-surface-plugins";
366 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureVKImpeller>(
367 std::static_pointer_cast<impeller::ContextVK>(
368 android_context_->GetImpellerContext()), //
369 texture_id, //
370 surface_texture, //
371 jni_facade_ //
372 ));
373 break;
375 default:
376 FML_CHECK(false);
377 break;
378 }
379}
380
382 int64_t texture_id,
383 const fml::jni::ScopedJavaGlobalRef<jobject>& image_texture_entry,
385 switch (android_context_->RenderingApi()) {
386#if !SLIMPELLER
388 // Legacy GL.
389 RegisterTexture(std::make_shared<ImageExternalTextureGLSkia>(
390 std::static_pointer_cast<AndroidContextGLSkia>(android_context_),
391 texture_id, image_texture_entry, jni_facade_, lifecycle));
392 break;
394 FML_LOG(INFO) << "Software rendering does not support external textures.";
395 break;
396#endif // !SLIMPELLER
398 // Impeller GLES.
399 RegisterTexture(std::make_shared<ImageExternalTextureGLImpeller>(
400 std::static_pointer_cast<impeller::ContextGLES>(
401 android_context_->GetImpellerContext()),
402 texture_id, image_texture_entry, jni_facade_, lifecycle));
403 break;
405 RegisterTexture(std::make_shared<ImageExternalTextureVKImpeller>(
406 std::static_pointer_cast<impeller::ContextVK>(
407 android_context_->GetImpellerContext()),
408 texture_id, image_texture_entry, jni_facade_, lifecycle));
409 break;
411 FML_CHECK(false);
412 break;
413 }
414}
415
416// |PlatformView|
417std::unique_ptr<VsyncWaiter> PlatformViewAndroid::CreateVSyncWaiter() {
418 return std::make_unique<VsyncWaiterAndroid>(task_runners_);
419}
420
421// |PlatformView|
422std::unique_ptr<Surface> PlatformViewAndroid::CreateRenderingSurface() {
423 if (!android_surface_) {
424 return nullptr;
425 }
426 return android_surface_->CreateGPUSurface(
427 android_context_->GetMainSkiaContext().get());
428}
429
430// |PlatformView|
431std::shared_ptr<ExternalViewEmbedder>
432PlatformViewAndroid::CreateExternalViewEmbedder() {
433 return std::make_shared<AndroidExternalViewEmbedderWrapper>(
434 android_meets_hcpp_criteria_, *android_context_, jni_facade_,
435 surface_factory_, task_runners_);
436}
437
438// |PlatformView|
439std::unique_ptr<SnapshotSurfaceProducer>
440PlatformViewAndroid::CreateSnapshotSurfaceProducer() {
441 if (!android_surface_) {
442 return nullptr;
443 }
444 return std::make_unique<AndroidSnapshotSurfaceProducer>(*android_surface_);
445}
446
447// |PlatformView|
448sk_sp<GrDirectContext> PlatformViewAndroid::CreateResourceContext() const {
449 if (!android_surface_) {
450 return nullptr;
451 }
452#if !SLIMPELLER
453 sk_sp<GrDirectContext> resource_context;
454 if (android_surface_->ResourceContextMakeCurrent()) {
455 // TODO(chinmaygarde): Currently, this code depends on the fact that only
456 // the OpenGL surface will be able to make a resource context current. If
457 // this changes, this assumption breaks. Handle the same.
459 GrBackendApi::kOpenGL,
461 } else {
462 FML_DLOG(ERROR) << "Could not make the resource context current.";
463 }
464 return resource_context;
465#else
466 android_surface_->ResourceContextMakeCurrent();
467 return nullptr;
468#endif // !SLIMPELLER
469}
470
471// |PlatformView|
472void PlatformViewAndroid::ReleaseResourceContext() const {
473 if (android_surface_) {
474 android_surface_->ResourceContextClearCurrent();
475 }
476}
477
478// |PlatformView|
479std::shared_ptr<impeller::Context> PlatformViewAndroid::GetImpellerContext()
480 const {
481 if (android_surface_) {
482 return android_surface_->GetImpellerContext();
483 }
484 return android_context_->GetImpellerContext();
485}
486
487// |PlatformView|
488std::unique_ptr<std::vector<std::string>>
489PlatformViewAndroid::ComputePlatformResolvedLocales(
490 const std::vector<std::string>& supported_locale_data) {
491 return jni_facade_->FlutterViewComputePlatformResolvedLocale(
492 supported_locale_data);
493}
494
495// |PlatformView|
496void PlatformViewAndroid::RequestDartDeferredLibrary(intptr_t loading_unit_id) {
497 if (jni_facade_->RequestDartDeferredLibrary(loading_unit_id)) {
498 return;
499 }
500 return; // TODO(garyq): Call LoadDartDeferredLibraryFailure()
501}
502
503// |PlatformView|
505 intptr_t loading_unit_id,
506 std::unique_ptr<const fml::Mapping> snapshot_data,
507 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
508 delegate_.LoadDartDeferredLibrary(loading_unit_id, std::move(snapshot_data),
509 std::move(snapshot_instructions));
510}
511
512// |PlatformView|
514 intptr_t loading_unit_id,
515 const std::string error_message,
516 bool transient) {
517 delegate_.LoadDartDeferredLibraryError(loading_unit_id, error_message,
518 transient);
519}
520
521// |PlatformView|
523 std::unique_ptr<AssetResolver> updated_asset_resolver,
525 delegate_.UpdateAssetResolverByType(std::move(updated_asset_resolver), type);
526}
527
528void PlatformViewAndroid::InstallFirstFrameCallback() {
529 // On Platform Task Runner.
532 platform_task_runner = task_runners_.GetPlatformTaskRunner()]() {
533 // On GPU Task Runner.
534 platform_task_runner->PostTask([platform_view]() {
535 // Back on Platform Task Runner.
536 if (platform_view) {
537 reinterpret_cast<PlatformViewAndroid*>(platform_view.get())
538 ->FireFirstFrameCallback();
539 }
540 });
541 });
542}
543
544void PlatformViewAndroid::FireFirstFrameCallback() {
545 jni_facade_->FlutterViewOnFirstFrame();
546}
547
548double PlatformViewAndroid::GetScaledFontSize(double unscaled_font_size,
549 int configuration_id) const {
550 return jni_facade_->FlutterViewGetScaledFontSize(unscaled_font_size,
551 configuration_id);
552}
553
554bool PlatformViewAndroid::IsSurfaceControlEnabled() const {
555 // This needs to know if we're actually using HCPP.
556 return android_meets_hcpp_criteria_ &&
557 android_context_->RenderingApi() ==
558 AndroidRenderingAPI::kImpellerVulkan &&
559 impeller::ContextVK::Cast(*android_context_->GetImpellerContext())
561}
562
563void PlatformViewAndroid::SetupImpellerContext() {
564 android_context_->SetupImpellerContext();
565 android_surface_->SetupImpellerSurface();
566}
567
568} // 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
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS GBytes * message
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