Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
android_surface_gl_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#if defined(__ANDROID__)
8#include <sys/system_properties.h>
9#endif
10
12#include "flutter/fml/logging.h"
15
16namespace flutter {
17
18namespace {
19
20// On some older MediaTek devices running Android 10 or below (specifically
21// MT6762/Helio P22 and MT6765/Helio P35 with PowerVR Rogue GE8320 GPUs),
22// keeping the EGL context current on the raster thread while the thread is idle
23// triggers a driver-level race condition/crash inside the system RenderThread's
24// eglMakeCurrent call during activity transitions or platform view rendering.
25// Clearing the current context at the end of every frame resolves the conflict
26// and avoids the driver crashes.
27bool ShouldClearContextBetweenFrames() {
28#if defined(__ANDROID__)
29 char sdk_value[PROP_VALUE_MAX];
30 int sdk_version = 0;
31 if (__system_property_get("ro.build.version.sdk", sdk_value) > 0) {
32 sdk_version = atoi(sdk_value);
33 }
34 if (sdk_version == 0 || sdk_version > 29) {
35 return false;
36 }
37
38 auto is_bad_platform = [](const char* name) -> bool {
39 char value[PROP_VALUE_MAX];
40 if (__system_property_get(name, value) > 0) {
41 std::string_view platform(value);
42 if (platform.starts_with("mt6762") || platform.starts_with("mt6765") ||
43 platform.starts_with("MT6762") || platform.starts_with("MT6765")) {
44 return true;
45 }
46 }
47 return false;
48 };
49
50 return is_bad_platform("ro.board.platform") ||
51 is_bad_platform("ro.vendor.mediatek.platform");
52#else
53 return false;
54#endif
55}
56
57class AndroidSwitchableGLContextImpeller : public SwitchableGLContext {
58 public:
59 explicit AndroidSwitchableGLContextImpeller(
60 const std::shared_ptr<AndroidContextGLImpeller>& android_context)
61 : android_context_(android_context) {}
62
63 bool SetCurrent() override { return true; }
64
65 bool RemoveCurrent() override {
66 if (auto context = android_context_.lock()) {
67 return context->OnscreenContextClearCurrent();
68 }
69 return false;
70 }
71
72 private:
73 std::weak_ptr<AndroidContextGLImpeller> android_context_;
74};
75
76} // namespace
77
79 const std::shared_ptr<AndroidContextGLImpeller>& android_context)
80 : android_context_(android_context) {
81 offscreen_surface_ = android_context_->CreateOffscreenSurface();
82
83 if (!offscreen_surface_) {
84 FML_DLOG(ERROR) << "Could not create offscreen surface.";
85 return;
86 }
87
88 // The onscreen surface will be acquired once the native window is set.
89
90 is_valid_ = true;
91}
92
94
95// |AndroidSurface|
97 return is_valid_;
98}
99
100// |AndroidSurface|
102 GrDirectContext* gr_context) {
103 auto surface = std::make_unique<GPUSurfaceGLImpeller>(
104 this, // delegate
105 android_context_->GetImpellerContext(), // context
106 true // render to surface
107 );
108 if (!surface->IsValid()) {
109 return nullptr;
110 }
111 return surface;
112}
113
114// |AndroidSurface|
117 onscreen_surface_.reset();
118}
119
120// |AndroidSurface|
122 // The size is unused. It was added only for iOS where the sizes were
123 // necessary to re-create auxiliary buffers (stencil, depth, etc.).
124 return RecreateOnscreenSurfaceAndMakeOnscreenContextCurrent();
125}
126
127// |AndroidSurface|
129 if (!offscreen_surface_) {
130 return false;
131 }
132 return android_context_->ResourceContextMakeCurrent(offscreen_surface_.get());
133}
134
135// |AndroidSurface|
137 return android_context_->ResourceContextClearCurrent();
138}
139
140// |AndroidSurface|
143 const std::shared_ptr<PlatformViewAndroidJNI>& jni_facade) {
144 native_window_ = std::move(window);
145 return RecreateOnscreenSurfaceAndMakeOnscreenContextCurrent();
146}
147
148// |AndroidSurface|
150 if (!onscreen_surface_ || !onscreen_surface_->IsValid()) {
151 onscreen_surface_ = android_context_->CreateOffscreenSurface();
152 if (!onscreen_surface_) {
153 FML_DLOG(ERROR) << "Could not create offscreen surface for snapshot.";
154 return nullptr;
155 }
156 }
157 // Make the snapshot surface current because constucting a
158 // GPUSurfaceGLImpeller and its AiksContext may invoke graphics APIs.
159 if (!android_context_->OnscreenContextMakeCurrent(onscreen_surface_.get())) {
160 FML_DLOG(ERROR) << "Could not make snapshot surface current.";
161 return nullptr;
162 }
163 return std::make_unique<GPUSurfaceGLImpeller>(
164 this, // delegate
165 android_context_->GetImpellerContext(), // context
166 true // render to surface
167 );
168}
169
170// |AndroidSurface|
171std::shared_ptr<impeller::Context>
173 return android_context_->GetImpellerContext();
174}
175
176// |GPUSurfaceGLDelegate|
177std::unique_ptr<GLContextResult>
179 bool success = OnGLContextMakeCurrent();
180 if (!success) {
181 return std::make_unique<GLContextDefaultResult>(false);
182 }
183 if (!should_clear_context_between_frames_.has_value()) {
184 should_clear_context_between_frames_ = ShouldClearContextBetweenFrames();
185 }
186 if (should_clear_context_between_frames_.value()) {
187 return std::make_unique<GLContextSwitch>(
188 std::make_unique<AndroidSwitchableGLContextImpeller>(android_context_));
189 }
190 return std::make_unique<GLContextDefaultResult>(true);
191}
192
193bool AndroidSurfaceGLImpeller::OnGLContextMakeCurrent() {
194 if (!onscreen_surface_) {
195 return false;
196 }
197
198 return android_context_->OnscreenContextMakeCurrent(onscreen_surface_.get());
199}
200
201// |GPUSurfaceGLDelegate|
203 if (!onscreen_surface_) {
204 return false;
205 }
206
207 return android_context_->OnscreenContextClearCurrent();
208}
209
210// |GPUSurfaceGLDelegate|
213 auto info = SurfaceFrame::FramebufferInfo{};
214 info.supports_readback = true;
215 info.supports_partial_repaint = false;
216 return info;
217}
218
219// |GPUSurfaceGLDelegate|
221 const std::optional<DlIRect>& region) {
222 // Not supported.
223}
224
225// |GPUSurfaceGLDelegate|
227 const GLPresentInfo& present_info) {
228 // The FBO ID is superfluous and was introduced for iOS where the default
229 // framebuffer was not FBO0.
230 if (!onscreen_surface_) {
231 return false;
232 }
233 return onscreen_surface_->Present();
234}
235
236// |GPUSurfaceGLDelegate|
238 // FBO0 is the default window bound framebuffer in EGL environments.
239 return GLFBOInfo{
240 .fbo_id = 0,
241 };
242}
243
244// |GPUSurfaceGLDelegate|
245sk_sp<const GrGLInterface> AndroidSurfaceGLImpeller::GetGLInterface() const {
246 return nullptr;
247}
248
249bool AndroidSurfaceGLImpeller::
250 RecreateOnscreenSurfaceAndMakeOnscreenContextCurrent() {
252 if (!native_window_) {
253 return false;
254 }
255 onscreen_surface_.reset();
256 auto onscreen_surface =
257 android_context_->CreateOnscreenSurface(native_window_->handle());
258 if (!onscreen_surface) {
259 FML_DLOG(ERROR) << "Could not create onscreen surface.";
260 return false;
261 }
262 onscreen_surface_ = std::move(onscreen_surface);
263 return OnGLContextMakeCurrent();
264}
265
266} // namespace flutter
SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() const override
bool SetNativeWindow(fml::RefPtr< AndroidNativeWindow > window, const std::shared_ptr< PlatformViewAndroidJNI > &jni_facade) override
sk_sp< const GrGLInterface > GetGLInterface() const override
bool GLContextPresent(const GLPresentInfo &present_info) override
AndroidSurfaceGLImpeller(const std::shared_ptr< AndroidContextGLImpeller > &android_context)
void GLContextSetDamageRegion(const std::optional< DlIRect > &region) override
GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const override
std::shared_ptr< impeller::Context > GetImpellerContext() override
std::unique_ptr< GLContextResult > GLContextMakeCurrent() override
std::unique_ptr< Surface > CreateSnapshotSurface() override
std::unique_ptr< Surface > CreateGPUSurface(GrDirectContext *gr_context) override
bool OnScreenSurfaceResize(const DlISize &size) override
int32_t value
GLFWwindow * window
Definition main.cc:60
VkSurfaceKHR surface
Definition main.cc:65
#define FML_DLOG(severity)
Definition logging.h:121
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
std::shared_ptr< ContextGLES > context