Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
android_context_dynamic_impeller.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 <cstdlib>
10#include <memory>
11
14
15namespace fs = std::filesystem;
16
17namespace flutter {
18
19namespace {
20
21static const constexpr char* kAndroidHuawei = "android-huawei";
22
23static constexpr const char* kBadSocs[] = {
24 // Most Exynos Series SoC. These are SoCs that crash when using AHB imports.
25 "exynos7870", //
26 "exynos7880", //
27 "exynos7872", //
28 "exynos7884", //
29 "exynos7885", //
30 "exynos7904", //
31 // Mongoose line.
32 "exynos8890", //
33 "exynos8895", //
34 "exynos9609", //
35 "exynos9610", //
36 "exynos9611", //
37 "exynos9810", //
38 // `exynos9820` and `exynos9825` have graphical errors:
39 // https://github.com/flutter/flutter/issues/171992.
40 "exynos9820", //
41 "exynos9825", //
42 "rk30sdk" // https://github.com/flutter/flutter/issues/183510
43};
44
45static bool IsDeviceEmulator() {
46 char property[PROP_VALUE_MAX];
47
48 __system_property_get("ro.hardware", property);
49 std::string_view hardware_prop(property);
50 if (hardware_prop == "goldfish" || hardware_prop == "ranchu" ||
51 hardware_prop == "qemu") {
52 return true;
53 }
54
55 __system_property_get("ro.product.model", property);
56 std::string_view model_prop(property);
57 if (model_prop.find("gphone") != std::string::npos) {
58 return true;
59 }
60
61 if (::access("/dev/qemu_pipe", F_OK) == 0) {
62 return true;
63 }
64
65 return false;
66}
67
68static bool IsKnownBadSOC(std::string_view hardware) {
69 // TODO(jonahwilliams): if the list gets too long (> 16), convert
70 // to a hash map first.
71 for (const auto& board : kBadSocs) {
72 if (strcmp(board, hardware.data()) == 0) {
73 return true;
74 }
75 }
76 return false;
77}
78
79static std::shared_ptr<AndroidContextVKImpeller>
80GetActualRenderingAPIForImpeller(
81 int api_level,
82 const AndroidContext::ContextSettings& settings) {
83 constexpr int kMinimumAndroidApiLevelForMediaTekVulkan = 32;
84
85 // have requisite features to support platform views.
86 //
87 // Even if this check returns true, Impeller may determine it cannot use
88 // Vulkan for some other reason, such as a missing required extension or
89 // feature. In these cases it will use OpenGLES.
90 if (IsDeviceEmulator()) {
91 // Avoid using Vulkan on known emulators.
92 return nullptr;
93 }
94
95 char property[PROP_VALUE_MAX];
96 __system_property_get("ro.com.google.clientidbase", property);
97 if (strcmp(property, kAndroidHuawei) == 0) {
98 // Avoid using Vulkan on Huawei as AHB imports do not
99 // consistently work.
100 return nullptr;
101 }
102
103 int vendor_api_level = api_level;
104 if (__system_property_get("ro.vendor.build.version.sdk", property) > 0) {
105 vendor_api_level = std::atoi(property);
106 }
107
108 if (vendor_api_level < kMinimumAndroidApiLevelForMediaTekVulkan &&
109 __system_property_find("ro.vendor.mediatek.platform") != nullptr) {
110 // Probably MediaTek. Avoid Vulkan if older than 32 to work around
111 // crashes when importing AHB.
112 return nullptr;
113 }
114
115 __system_property_get("ro.product.board", property);
116 if (IsKnownBadSOC(property)) {
117 FML_LOG(INFO)
118 << "Known bad Vulkan driver encountered, falling back to OpenGLES.";
119 return nullptr;
120 }
121
122 // Determine if Vulkan is supported by creating a Vulkan context and
123 // checking if it is valid.
124 impeller::ScopedValidationDisable disable_validation;
125 auto vulkan_backend = std::make_shared<AndroidContextVKImpeller>(
126 AndroidContext::ContextSettings{
127#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
128 .enable_validation = settings.enable_validation,
129#else
130 .enable_validation = false,
131#endif // FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
132 .enable_gpu_tracing = settings.enable_gpu_tracing,
133 .enable_surface_control = settings.enable_surface_control,
134 });
135 if (!vulkan_backend->IsValid()) {
136 return nullptr;
137 }
138 return vulkan_backend;
139}
140} // namespace
141
143 const AndroidContext::ContextSettings& settings,
144 std::shared_ptr<fml::BasicTaskRunner> io_task_runner)
146 settings_(settings),
147 io_task_runner_(std::move(io_task_runner)) {}
148
150
160
161std::shared_ptr<impeller::Context>
163 if (vk_context_) {
164 return vk_context_->GetImpellerContext();
165 }
166 if (gl_context_) {
167 return gl_context_->GetImpellerContext();
168 }
169 return nullptr;
170}
171
172std::shared_ptr<AndroidContextGLImpeller>
174 return gl_context_;
175}
176
177std::shared_ptr<AndroidContextVKImpeller>
179 return vk_context_;
180}
181
183 if (vk_context_ || gl_context_) {
184 return;
185 }
186 vk_context_ = GetActualRenderingAPIForImpeller(android_get_device_api_level(),
187 settings_);
188 if (!vk_context_) {
189 gl_context_ = std::make_shared<AndroidContextGLImpeller>(
190 std::make_unique<impeller::egl::Display>(),
191 settings_.enable_gpu_tracing, io_task_runner_);
192 }
193}
194
195} // namespace flutter
void SetupImpellerContext() override
Perform deferred setup for the impeller Context.
AndroidContextDynamicImpeller(const AndroidContext::ContextSettings &settings, std::shared_ptr< fml::BasicTaskRunner > io_task_runner)
std::shared_ptr< AndroidContextVKImpeller > GetVKContext() const
Retrieve the VK context if it was created, or nullptr.
std::shared_ptr< AndroidContextGLImpeller > GetGLContext() const
Retrieve the GL Context if it was created, or nullptr.
std::shared_ptr< impeller::Context > GetImpellerContext() const override
Accessor for the Impeller context associated with AndroidSurfaces and the raster thread.
Holds state that is shared across Android surfaces.
Settings settings_
#define FML_LOG(severity)
Definition logging.h:101
Definition ref_ptr.h:261