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 .impeller_flags =
135 {
136 .antialiased_lines =
137 settings.impeller_flags.antialiased_lines,
138 },
139 });
140 if (!vulkan_backend->IsValid()) {
141 return nullptr;
142 }
143 return vulkan_backend;
144}
145} // namespace
146
151
153
163
164std::shared_ptr<impeller::Context>
166 if (vk_context_) {
167 return vk_context_->GetImpellerContext();
168 }
169 if (gl_context_) {
170 return gl_context_->GetImpellerContext();
171 }
172 return nullptr;
173}
174
175std::shared_ptr<AndroidContextGLImpeller>
177 return gl_context_;
178}
179
180std::shared_ptr<AndroidContextVKImpeller>
182 return vk_context_;
183}
184
186 if (vk_context_ || gl_context_) {
187 return;
188 }
189 vk_context_ = GetActualRenderingAPIForImpeller(android_get_device_api_level(),
190 settings_);
191 if (!vk_context_) {
192 gl_context_ = std::make_shared<AndroidContextGLImpeller>(
193 std::make_unique<impeller::egl::Display>(),
194 settings_.enable_gpu_tracing);
195 }
196}
197
198} // namespace flutter
void SetupImpellerContext() override
Perform deferred setup for the impeller Context.
AndroidContextDynamicImpeller(const AndroidContext::ContextSettings &settings)
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