Flutter Engine
The 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
5#include "flutter/shell/platform/android/platform_view_android.h"
6
7#include <android/api-level.h>
8#include <memory>
9#include <utility>
10
11#include "flutter/common/graphics/texture.h"
12#include "flutter/fml/synchronization/waitable_event.h"
13#include "flutter/shell/common/shell_io_manager.h"
14#include "flutter/shell/gpu/gpu_surface_gl_delegate.h"
15#include "flutter/shell/platform/android/android_context_gl_impeller.h"
16#include "flutter/shell/platform/android/android_context_gl_skia.h"
17#include "flutter/shell/platform/android/android_context_vulkan_impeller.h"
18#include "flutter/shell/platform/android/android_surface_gl_impeller.h"
19#include "flutter/shell/platform/android/android_surface_gl_skia.h"
20#include "flutter/shell/platform/android/android_surface_software.h"
21#include "flutter/shell/platform/android/image_external_texture_gl.h"
22#include "flutter/shell/platform/android/surface_texture_external_texture_gl.h"
23#include "fml/logging.h"
24#if IMPELLER_ENABLE_VULKAN // b/258506856 for why this is behind an if
25#include "flutter/shell/platform/android/android_surface_vulkan_impeller.h"
26#include "flutter/shell/platform/android/image_external_texture_vk.h"
27#endif
28#include "flutter/shell/platform/android/context/android_context.h"
29#include "flutter/shell/platform/android/external_view_embedder/external_view_embedder.h"
30#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"
31#include "flutter/shell/platform/android/platform_message_response_android.h"
32#include "flutter/shell/platform/android/surface/android_surface.h"
33#include "flutter/shell/platform/android/surface/snapshot_surface_producer.h"
34#include "flutter/shell/platform/android/vsync_waiter_android.h"
35
36namespace flutter {
37
39 const std::shared_ptr<AndroidContext>& context,
40 bool enable_impeller)
41 : android_context_(context), enable_impeller_(enable_impeller) {}
42
44
45std::unique_ptr<AndroidSurface> AndroidSurfaceFactoryImpl::CreateSurface() {
46 switch (android_context_->RenderingApi()) {
48 return std::make_unique<AndroidSurfaceSoftware>();
50 return std::make_unique<AndroidSurfaceGLImpeller>(
51 std::static_pointer_cast<AndroidContextGLImpeller>(android_context_));
53 return std::make_unique<AndroidSurfaceGLSkia>(
54 std::static_pointer_cast<AndroidContextGLSkia>(android_context_));
56 return std::make_unique<AndroidSurfaceVulkanImpeller>(
57 std::static_pointer_cast<AndroidContextVulkanImpeller>(
58 android_context_));
59 }
61}
62
63static std::shared_ptr<flutter::AndroidContext> CreateAndroidContext(
64 bool use_software_rendering,
65 const flutter::TaskRunners& task_runners,
66 uint8_t msaa_samples,
67 AndroidRenderingAPI android_rendering_api,
68 bool enable_vulkan_validation,
69 bool enable_opengl_gpu_tracing,
70 bool enable_vulkan_gpu_tracing) {
71 switch (android_rendering_api) {
73 return std::make_shared<AndroidContext>(AndroidRenderingAPI::kSoftware);
75 return std::make_unique<AndroidContextGLImpeller>(
76 std::make_unique<impeller::egl::Display>(),
77 enable_opengl_gpu_tracing);
79 return std::make_unique<AndroidContextVulkanImpeller>(
80 enable_vulkan_validation, enable_vulkan_gpu_tracing);
82 return std::make_unique<AndroidContextGLSkia>(
83 fml::MakeRefCounted<AndroidEnvironmentGL>(), //
84 task_runners, //
85 msaa_samples //
86 );
87 }
89}
90
92 PlatformView::Delegate& delegate,
93 const flutter::TaskRunners& task_runners,
94 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
95 bool use_software_rendering,
96 uint8_t msaa_samples)
98 delegate,
99 task_runners,
100 jni_facade,
102 use_software_rendering,
103 task_runners,
104 msaa_samples,
105 delegate.OnPlatformViewGetSettings().android_rendering_api,
106 delegate.OnPlatformViewGetSettings().enable_vulkan_validation,
107 delegate.OnPlatformViewGetSettings().enable_opengl_gpu_tracing,
108 delegate.OnPlatformViewGetSettings().enable_vulkan_gpu_tracing)) {
109}
110
112 PlatformView::Delegate& delegate,
113 const flutter::TaskRunners& task_runners,
114 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade,
115 const std::shared_ptr<flutter::AndroidContext>& android_context)
116 : PlatformView(delegate, task_runners),
117 jni_facade_(jni_facade),
118 android_context_(android_context),
119 platform_view_android_delegate_(jni_facade),
120 platform_message_handler_(new PlatformMessageHandlerAndroid(jni_facade)) {
121 if (android_context_) {
122 FML_CHECK(android_context_->IsValid())
123 << "Could not create surface from invalid Android context.";
124 surface_factory_ = std::make_shared<AndroidSurfaceFactoryImpl>(
125 android_context_, //
127 );
128 android_surface_ = surface_factory_->CreateSurface();
129 FML_CHECK(android_surface_ && android_surface_->IsValid())
130 << "Could not create an OpenGL, Vulkan or Software surface to set up "
131 "rendering.";
132 }
133}
134
136
138 fml::RefPtr<AndroidNativeWindow> native_window) {
139 if (android_surface_) {
140 InstallFirstFrameCallback();
141
145 [&latch, surface = android_surface_.get(),
146 native_window = std::move(native_window)]() {
147 surface->SetNativeWindow(native_window);
148 latch.Signal();
149 });
150 latch.Wait();
151 }
152
154}
155
157 fml::RefPtr<AndroidNativeWindow> native_window) {
158 if (android_surface_) {
162 [&latch, surface = android_surface_.get(),
163 native_window = std::move(native_window)]() {
164 surface->TeardownOnScreenContext();
165 surface->SetNativeWindow(native_window);
166 latch.Signal();
167 });
168 latch.Wait();
169 }
170
172}
173
176
177 if (android_surface_) {
181 [&latch, surface = android_surface_.get()]() {
182 surface->TeardownOnScreenContext();
183 latch.Signal();
184 });
185 latch.Wait();
186 }
187}
188
190 if (!android_surface_) {
191 return;
192 }
196 [&latch, surface = android_surface_.get(), size]() {
197 surface->OnScreenSurfaceResize(size);
198 latch.Signal();
199 });
200 latch.Wait();
201}
202
204 std::string name,
205 jobject java_message_data,
206 jint java_message_position,
207 jint response_id) {
208 uint8_t* message_data =
209 static_cast<uint8_t*>(env->GetDirectBufferAddress(java_message_data));
211 fml::MallocMapping::Copy(message_data, java_message_position);
212
214 if (response_id) {
215 response = fml::MakeRefCounted<PlatformMessageResponseAndroid>(
216 response_id, jni_facade_, task_runners_.GetPlatformTaskRunner());
217 }
218
220 std::make_unique<flutter::PlatformMessage>(
221 std::move(name), std::move(message), std::move(response)));
222}
223
225 std::string name,
226 jint response_id) {
228 if (response_id) {
229 response = fml::MakeRefCounted<PlatformMessageResponseAndroid>(
230 response_id, jni_facade_, task_runners_.GetPlatformTaskRunner());
231 }
232
234 std::make_unique<flutter::PlatformMessage>(std::move(name),
235 std::move(response)));
236}
237
238// |PlatformView|
240 std::unique_ptr<flutter::PlatformMessage> message) {
241 // Called from the ui thread.
242 platform_message_handler_->HandlePlatformMessage(std::move(message));
243}
244
245// |PlatformView|
247 jni_facade_->FlutterViewOnPreEngineRestart();
248}
249
251 jint id,
252 jint action,
253 jobject args,
254 jint args_position) {
255 if (env->IsSameObject(args, NULL)) {
257 id, static_cast<flutter::SemanticsAction>(action),
259 return;
260 }
261
262 uint8_t* args_data = static_cast<uint8_t*>(env->GetDirectBufferAddress(args));
263 auto args_vector = fml::MallocMapping::Copy(args_data, args_position);
264
266 id, static_cast<flutter::SemanticsAction>(action),
267 std::move(args_vector));
268}
269
270// |PlatformView|
276
278 int64_t texture_id,
279 const fml::jni::ScopedJavaGlobalRef<jobject>& surface_texture) {
280 switch (android_context_->RenderingApi()) {
282 // Impeller GLES.
283 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureImpellerGL>(
284 std::static_pointer_cast<impeller::ContextGLES>(
285 android_context_->GetImpellerContext()),
286 texture_id, surface_texture, jni_facade_));
287 break;
289 // Legacy GL.
290 RegisterTexture(std::make_shared<SurfaceTextureExternalTextureGL>(
291 texture_id, surface_texture, jni_facade_));
292 break;
295 FML_LOG(INFO)
296 << "Attempted to use a SurfaceTextureExternalTexture with an "
297 "unsupported rendering API.";
298 break;
299 }
300}
301
303 int64_t texture_id,
304 const fml::jni::ScopedJavaGlobalRef<jobject>& image_texture_entry) {
305 switch (android_context_->RenderingApi()) {
307 // Impeller GLES.
308 RegisterTexture(std::make_shared<ImageExternalTextureGLImpeller>(
309 std::static_pointer_cast<impeller::ContextGLES>(
310 android_context_->GetImpellerContext()),
311 texture_id, image_texture_entry, jni_facade_));
312 break;
314 // Legacy GL.
315 RegisterTexture(std::make_shared<ImageExternalTextureGLSkia>(
316 std::static_pointer_cast<AndroidContextGLSkia>(android_context_),
317 texture_id, image_texture_entry, jni_facade_));
318 break;
320 RegisterTexture(std::make_shared<ImageExternalTextureVK>(
321 std::static_pointer_cast<impeller::ContextVK>(
322 android_context_->GetImpellerContext()),
323 texture_id, image_texture_entry, jni_facade_));
324 break;
326 FML_LOG(INFO)
327 << "Attempted to use a SurfaceTextureExternalTexture with an "
328 "unsupported rendering API.";
329 break;
330 }
331}
332
333// |PlatformView|
334std::unique_ptr<VsyncWaiter> PlatformViewAndroid::CreateVSyncWaiter() {
335 return std::make_unique<VsyncWaiterAndroid>(task_runners_);
336}
337
338// |PlatformView|
340 if (!android_surface_) {
341 return nullptr;
342 }
343 return android_surface_->CreateGPUSurface(
344 android_context_->GetMainSkiaContext().get());
345}
346
347// |PlatformView|
348std::shared_ptr<ExternalViewEmbedder>
350 return std::make_shared<AndroidExternalViewEmbedder>(
351 *android_context_, jni_facade_, surface_factory_, task_runners_);
352}
353
354// |PlatformView|
355std::unique_ptr<SnapshotSurfaceProducer>
357 if (!android_surface_) {
358 return nullptr;
359 }
360 return std::make_unique<AndroidSnapshotSurfaceProducer>(*android_surface_);
361}
362
363// |PlatformView|
365 if (!android_surface_) {
366 return nullptr;
367 }
368 sk_sp<GrDirectContext> resource_context;
369 if (android_surface_->ResourceContextMakeCurrent()) {
370 // TODO(chinmaygarde): Currently, this code depends on the fact that only
371 // the OpenGL surface will be able to make a resource context current. If
372 // this changes, this assumption breaks. Handle the same.
376 } else {
377 FML_DLOG(ERROR) << "Could not make the resource context current.";
378 }
379
380 return resource_context;
381}
382
383// |PlatformView|
385 if (android_surface_) {
386 android_surface_->ResourceContextClearCurrent();
387 }
388}
389
390// |PlatformView|
391std::shared_ptr<impeller::Context> PlatformViewAndroid::GetImpellerContext()
392 const {
393 if (android_surface_) {
394 return android_surface_->GetImpellerContext();
395 }
396 return nullptr;
397}
398
399// |PlatformView|
400std::unique_ptr<std::vector<std::string>>
402 const std::vector<std::string>& supported_locale_data) {
403 return jni_facade_->FlutterViewComputePlatformResolvedLocale(
404 supported_locale_data);
405}
406
407// |PlatformView|
409 if (jni_facade_->RequestDartDeferredLibrary(loading_unit_id)) {
410 return;
411 }
412 return; // TODO(garyq): Call LoadDartDeferredLibraryFailure()
413}
414
415// |PlatformView|
417 intptr_t loading_unit_id,
418 std::unique_ptr<const fml::Mapping> snapshot_data,
419 std::unique_ptr<const fml::Mapping> snapshot_instructions) {
420 delegate_.LoadDartDeferredLibrary(loading_unit_id, std::move(snapshot_data),
421 std::move(snapshot_instructions));
422}
423
424// |PlatformView|
426 intptr_t loading_unit_id,
427 const std::string error_message,
428 bool transient) {
429 delegate_.LoadDartDeferredLibraryError(loading_unit_id, error_message,
430 transient);
431}
432
433// |PlatformView|
435 std::unique_ptr<AssetResolver> updated_asset_resolver,
437 delegate_.UpdateAssetResolverByType(std::move(updated_asset_resolver), type);
438}
439
440void PlatformViewAndroid::InstallFirstFrameCallback() {
441 // On Platform Task Runner.
444 platform_task_runner = task_runners_.GetPlatformTaskRunner()]() {
445 // On GPU Task Runner.
446 platform_task_runner->PostTask([platform_view]() {
447 // Back on Platform Task Runner.
448 if (platform_view) {
449 reinterpret_cast<PlatformViewAndroid*>(platform_view.get())
450 ->FireFirstFrameCallback();
451 }
452 });
453 });
454}
455
456void PlatformViewAndroid::FireFirstFrameCallback() {
457 jni_facade_->FlutterViewOnFirstFrame();
458}
459
460double PlatformViewAndroid::GetScaledFontSize(double unscaled_font_size,
461 int configuration_id) const {
462 return jni_facade_->FlutterViewGetScaledFontSize(unscaled_font_size,
463 configuration_id);
464}
465} // namespace flutter
std::unique_ptr< flutter::PlatformViewIOS > platform_view
std::unique_ptr< AndroidSurface > CreateSurface() override
AndroidSurfaceFactoryImpl(const std::shared_ptr< AndroidContext > &context, bool enable_impeller)
AssetResolverType
Identifies the type of AssetResolver an instance is.
static sk_sp< const GrGLInterface > GetDefaultPlatformGLInterface()
void UpdateSemantics(const flutter::SemanticsNodeUpdates &update, const flutter::CustomAccessibilityActionUpdates &actions)
void OnPreEngineRestart() const override
Gives embedders a chance to react to a "cold restart" of the running isolate. The default implementat...
void DispatchPlatformMessage(JNIEnv *env, std::string name, jobject message_data, jint message_position, jint response_id)
sk_sp< GrDirectContext > CreateResourceContext() const override
Used by the shell to obtain a Skia GPU context that is capable of operating on the IO thread....
void NotifyChanged(const SkISize &size)
void RegisterExternalTexture(int64_t texture_id, const fml::jni::ScopedJavaGlobalRef< jobject > &surface_texture)
void NotifySurfaceWindowChanged(fml::RefPtr< AndroidNativeWindow > native_window)
std::unique_ptr< SnapshotSurfaceProducer > CreateSnapshotSurfaceProducer() override
Creates an object that produces surfaces suitable for raster snapshotting. The rasterizer will reques...
std::unique_ptr< std::vector< std::string > > ComputePlatformResolvedLocales(const std::vector< std::string > &supported_locale_data) override
Directly invokes platform-specific APIs to compute the locale the platform would have natively resolv...
PlatformViewAndroid(PlatformView::Delegate &delegate, const flutter::TaskRunners &task_runners, const std::shared_ptr< PlatformViewAndroidJNI > &jni_facade, bool use_software_rendering, uint8_t msaa_samples)
void RegisterImageTexture(int64_t texture_id, const fml::jni::ScopedJavaGlobalRef< jobject > &image_texture_entry)
void ReleaseResourceContext() const override
Used by the shell to notify the embedder that the resource context previously obtained via a call to ...
void DispatchEmptyPlatformMessage(JNIEnv *env, std::string name, jint response_id)
void RequestDartDeferredLibrary(intptr_t loading_unit_id) override
Invoked when the dart VM requests that a deferred library be loaded. Notifies the engine that the def...
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...
std::shared_ptr< ExternalViewEmbedder > CreateExternalViewEmbedder() override
void DispatchSemanticsAction(JNIEnv *env, jint id, jint action, jobject args, jint args_position)
void HandlePlatformMessage(std::unique_ptr< flutter::PlatformMessage > message) override
Overridden by embedders to perform actions in response to platform messages sent from the framework t...
std::unique_ptr< VsyncWaiter > CreateVSyncWaiter() override
Invoked by the shell to obtain a platform specific vsync waiter. It is optional for platforms to over...
std::shared_ptr< impeller::Context > GetImpellerContext() const override
std::unique_ptr< Surface > CreateRenderingSurface() override
void UpdateSemantics(flutter::SemanticsNodeUpdates update, flutter::CustomAccessibilityActionUpdates actions) override
Used by the framework to tell the embedder to apply the specified semantics node updates....
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,...
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 ...
Platform views are created by the shell on the platform task runner. Unless explicitly specified,...
void DispatchPlatformMessage(std::unique_ptr< PlatformMessage > message)
Used by embedders to dispatch a platform message to a running root isolate hosted by the engine....
virtual void NotifyDestroyed()
Used by embedders to notify the shell that the platform view has been destroyed. This notification us...
void DispatchSemanticsAction(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.
PlatformView::Delegate & delegate_
void SetNextFrameCallback(const fml::closure &closure)
Sets a callback that gets executed when the rasterizer renders the next frame. Due to the asynchronou...
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 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 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)
VkSurfaceKHR surface
Definition main.cc:49
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
#define FML_DLOG(severity)
Definition logging.h:102
#define FML_LOG(severity)
Definition logging.h:82
#define FML_CHECK(condition)
Definition logging.h:85
#define FML_UNREACHABLE()
Definition logging.h:109
Win32Message message
Definition __init__.py:1
AndroidRenderingAPI
Definition settings.h:26
std::unordered_map< int32_t, SemanticsNode > SemanticsNodeUpdates
static std::shared_ptr< flutter::AndroidContext > CreateAndroidContext(bool use_software_rendering, const flutter::TaskRunners &task_runners, uint8_t msaa_samples, AndroidRenderingAPI android_rendering_api, bool enable_vulkan_validation, bool enable_opengl_gpu_tracing, bool enable_vulkan_gpu_tracing)
std::unordered_map< int32_t, CustomAccessibilityAction > CustomAccessibilityActionUpdates
DEF_SWITCHES_START aot vmservice shared library name
Definition switches.h:32
it will be possible to load the file into Perfetto s trace viewer 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
Definition switches.h:259
int64_t texture_id
#define ERROR(message)