Flutter Engine
The Flutter Engine
android_egl_surface.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/android_egl_surface.h"
6
7#include <EGL/eglext.h>
8#include <sys/system_properties.h>
9
10#include <array>
11#include <list>
12
13#include "flutter/fml/trace_event.h"
14
15namespace flutter {
16
18 struct EGLNameErrorPair {
19 const char* name;
20 EGLint code;
21 };
22
23#define _EGL_ERROR_DESC(a) \
24 { #a, a }
25
26 const EGLNameErrorPair pairs[] = {
27 _EGL_ERROR_DESC(EGL_SUCCESS),
28 _EGL_ERROR_DESC(EGL_NOT_INITIALIZED),
29 _EGL_ERROR_DESC(EGL_BAD_ACCESS),
30 _EGL_ERROR_DESC(EGL_BAD_ALLOC),
31 _EGL_ERROR_DESC(EGL_BAD_ATTRIBUTE),
32 _EGL_ERROR_DESC(EGL_BAD_CONTEXT),
33 _EGL_ERROR_DESC(EGL_BAD_CONFIG),
34 _EGL_ERROR_DESC(EGL_BAD_CURRENT_SURFACE),
35 _EGL_ERROR_DESC(EGL_BAD_DISPLAY),
36 _EGL_ERROR_DESC(EGL_BAD_SURFACE),
37 _EGL_ERROR_DESC(EGL_BAD_MATCH),
38 _EGL_ERROR_DESC(EGL_BAD_PARAMETER),
39 _EGL_ERROR_DESC(EGL_BAD_NATIVE_PIXMAP),
40 _EGL_ERROR_DESC(EGL_BAD_NATIVE_WINDOW),
41 _EGL_ERROR_DESC(EGL_CONTEXT_LOST),
42 };
43
44#undef _EGL_ERROR_DESC
45
46 const auto count = sizeof(pairs) / sizeof(EGLNameErrorPair);
47
48 EGLint last_error = eglGetError();
49
50 for (size_t i = 0; i < count; i++) {
51 if (last_error == pairs[i].code) {
52 FML_LOG(ERROR) << "EGL Error: " << pairs[i].name << " (" << pairs[i].code
53 << ")";
54 return;
55 }
56 }
57
58 FML_LOG(ERROR) << "Unknown EGL Error";
59}
60
62 public:
63 void init(EGLDisplay display, EGLContext context) {}
64
65 void SetDamageRegion(EGLDisplay display,
66 EGLSurface surface,
67 const std::optional<SkIRect>& region) {}
68
69 /// This was disabled after discussion in
70 /// https://github.com/flutter/flutter/issues/123353
71 bool SupportsPartialRepaint() const { return false; }
72
73 std::optional<SkIRect> InitialDamage(EGLDisplay display, EGLSurface surface) {
74 return std::nullopt;
75 }
76
77 bool SwapBuffersWithDamage(EGLDisplay display,
78 EGLSurface surface,
79 const std::optional<SkIRect>& damage) {
80 return eglSwapBuffers(display, surface);
81 }
82};
83
85 EGLDisplay display,
86 EGLContext context)
88 display_(display),
89 context_(context),
90 damage_(std::make_unique<AndroidEGLSurfaceDamage>()) {
91 damage_->init(display_, context);
92}
93
95 [[maybe_unused]] auto result = eglDestroySurface(display_, surface_);
96 FML_DCHECK(result == EGL_TRUE);
97}
98
100 return surface_ != EGL_NO_SURFACE;
101}
102
103bool AndroidEGLSurface::IsContextCurrent() const {
104 EGLContext current_egl_context = eglGetCurrentContext();
105 if (context_ != current_egl_context) {
106 return false;
107 }
108
109 EGLDisplay current_egl_display = eglGetCurrentDisplay();
110 if (display_ != current_egl_display) {
111 return false;
112 }
113
114 EGLSurface draw_surface = eglGetCurrentSurface(EGL_DRAW);
115 if (draw_surface != surface_) {
116 return false;
117 }
118
119 EGLSurface read_surface = eglGetCurrentSurface(EGL_READ);
120 if (read_surface != surface_) {
121 return false;
122 }
123
124 return true;
125}
126
128 if (IsContextCurrent()) {
130 }
131 if (eglMakeCurrent(display_, surface_, surface_, context_) != EGL_TRUE) {
132 FML_LOG(ERROR) << "Could not make the context current";
135 }
137}
138
140 const std::optional<SkIRect>& buffer_damage) {
141 damage_->SetDamageRegion(display_, surface_, buffer_damage);
142}
143
145 const fml::TimePoint& presentation_time) {
146 if (presentation_time_proc_) {
147 const auto time_ns = presentation_time.ToEpochDelta().ToNanoseconds();
148 return presentation_time_proc_(display_, surface_, time_ns);
149 } else {
150 return false;
151 }
152}
153
155 const std::optional<SkIRect>& surface_damage) {
156 TRACE_EVENT0("flutter", "AndroidContextGL::SwapBuffers");
157 return damage_->SwapBuffersWithDamage(display_, surface_, surface_damage);
158}
159
161 return damage_->SupportsPartialRepaint();
162}
163
164std::optional<SkIRect> AndroidEGLSurface::InitialDamage() {
165 return damage_->InitialDamage(display_, surface_);
166}
167
169 EGLint width = 0;
170 EGLint height = 0;
171
172 if (!eglQuerySurface(display_, surface_, EGL_WIDTH, &width) ||
173 !eglQuerySurface(display_, surface_, EGL_HEIGHT, &height)) {
174 FML_LOG(ERROR) << "Unable to query EGL surface size";
176 return SkISize::Make(0, 0);
177 }
178 return SkISize::Make(width, height);
179}
180
181} // namespace flutter
int count
Definition: FontMgrTest.cpp:50
#define _EGL_ERROR_DESC(a)
std::optional< SkIRect > InitialDamage(EGLDisplay display, EGLSurface surface)
void SetDamageRegion(EGLDisplay display, EGLSurface surface, const std::optional< SkIRect > &region)
bool SwapBuffersWithDamage(EGLDisplay display, EGLSurface surface, const std::optional< SkIRect > &damage)
void init(EGLDisplay display, EGLContext context)
std::optional< SkIRect > InitialDamage()
This is the minimal area that needs to be repainted to get correct result.
bool SwapBuffers(const std::optional< SkIRect > &surface_damage)
This only applies to on-screen surfaces such as those created by AndroidContextGL::CreateOnscreenSurf...
void SetDamageRegion(const std::optional< SkIRect > &buffer_damage)
Sets the damage region for current surface. Corresponds to.
AndroidEGLSurface(EGLSurface surface, EGLDisplay display, EGLContext context)
bool SetPresentationTime(const fml::TimePoint &presentation_time)
Sets the presentation time for the current surface. This.
AndroidEGLSurfaceMakeCurrentStatus MakeCurrent() const
Binds the EGLContext context to the current rendering thread and to the draw and read surface.
constexpr int64_t ToNanoseconds() const
Definition: time_delta.h:61
TimeDelta ToEpochDelta() const
Definition: time_point.h:52
VkSurfaceKHR surface
Definition: main.cc:49
GAsyncResult * result
#define FML_LOG(severity)
Definition: logging.h:82
#define FML_DCHECK(condition)
Definition: logging.h:103
EGLDisplay display_
EGLSurface surface_
ClipOpAndAA opAA SkRegion region
Definition: SkRecords.h:238
void LogLastEGLError()
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
AndroidEGLSurfaceMakeCurrentStatus
Result of calling MakeCurrent on AndroidEGLSurface.
@ kFailure
Failed to make the egl context for the surface current.
@ kSuccessMadeCurrent
Success, the egl context for the surface made current.
@ kSuccessAlreadyCurrent
Success, the egl context for the surface was already current.
Definition: ref_ptr.h:256
int32_t height
int32_t width
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
#define ERROR(message)
Definition: elf_loader.cc:260
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131