Flutter Engine
 
Loading...
Searching...
No Matches
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
6
7#include <EGL/eglext.h>
8#include <sys/system_properties.h>
9
10#include <array>
11#include <list>
12
14
15namespace flutter {
16
18 struct EGLNameErrorPair {
19 const char* name;
20 EGLint code;
21 };
22
23#define _EGL_ERROR_DESC(a) \
24 { \
25 #a, a \
26 }
27
28 const EGLNameErrorPair pairs[] = {
29 _EGL_ERROR_DESC(EGL_SUCCESS),
30 _EGL_ERROR_DESC(EGL_NOT_INITIALIZED),
31 _EGL_ERROR_DESC(EGL_BAD_ACCESS),
32 _EGL_ERROR_DESC(EGL_BAD_ALLOC),
33 _EGL_ERROR_DESC(EGL_BAD_ATTRIBUTE),
34 _EGL_ERROR_DESC(EGL_BAD_CONTEXT),
35 _EGL_ERROR_DESC(EGL_BAD_CONFIG),
36 _EGL_ERROR_DESC(EGL_BAD_CURRENT_SURFACE),
37 _EGL_ERROR_DESC(EGL_BAD_DISPLAY),
38 _EGL_ERROR_DESC(EGL_BAD_SURFACE),
39 _EGL_ERROR_DESC(EGL_BAD_MATCH),
40 _EGL_ERROR_DESC(EGL_BAD_PARAMETER),
41 _EGL_ERROR_DESC(EGL_BAD_NATIVE_PIXMAP),
42 _EGL_ERROR_DESC(EGL_BAD_NATIVE_WINDOW),
43 _EGL_ERROR_DESC(EGL_CONTEXT_LOST),
44 };
45
46#undef _EGL_ERROR_DESC
47
48 const auto count = sizeof(pairs) / sizeof(EGLNameErrorPair);
49
50 EGLint last_error = eglGetError();
51
52 for (size_t i = 0; i < count; i++) {
53 if (last_error == pairs[i].code) {
54 FML_LOG(ERROR) << "EGL Error: " << pairs[i].name << " (" << pairs[i].code
55 << ")";
56 return;
57 }
58 }
59
60 FML_LOG(ERROR) << "Unknown EGL Error";
61}
62
64 public:
65 void init(EGLDisplay display, EGLContext context) {}
66
67 void SetDamageRegion(EGLDisplay display,
68 EGLSurface surface,
69 const std::optional<DlIRect>& region) {}
70
71 /// This was disabled after discussion in
72 /// https://github.com/flutter/flutter/issues/123353
73 bool SupportsPartialRepaint() const { return false; }
74
75 std::optional<DlIRect> InitialDamage(EGLDisplay display, EGLSurface surface) {
76 return std::nullopt;
77 }
78
79 bool SwapBuffersWithDamage(EGLDisplay display,
80 EGLSurface surface,
81 const std::optional<DlIRect>& damage) {
82 return eglSwapBuffers(display, surface);
83 }
84};
85
87 EGLDisplay display,
88 EGLContext context)
90 display_(display),
91 context_(context),
92 damage_(std::make_unique<AndroidEGLSurfaceDamage>()) {
93 damage_->init(display_, context);
94}
95
97 [[maybe_unused]] auto result = eglDestroySurface(display_, surface_);
98 FML_DCHECK(result == EGL_TRUE);
99}
100
102 return surface_ != EGL_NO_SURFACE;
103}
104
105bool AndroidEGLSurface::IsContextCurrent() const {
106 EGLContext current_egl_context = eglGetCurrentContext();
107 if (context_ != current_egl_context) {
108 return false;
109 }
110
111 EGLDisplay current_egl_display = eglGetCurrentDisplay();
112 if (display_ != current_egl_display) {
113 return false;
114 }
115
116 EGLSurface draw_surface = eglGetCurrentSurface(EGL_DRAW);
117 if (draw_surface != surface_) {
118 return false;
119 }
120
121 EGLSurface read_surface = eglGetCurrentSurface(EGL_READ);
122 if (read_surface != surface_) {
123 return false;
124 }
125
126 return true;
127}
128
130 if (IsContextCurrent()) {
132 }
133 if (eglMakeCurrent(display_, surface_, surface_, context_) != EGL_TRUE) {
134 FML_LOG(ERROR) << "Could not make the context current";
137 }
139}
140
142 const std::optional<DlIRect>& buffer_damage) {
143 damage_->SetDamageRegion(display_, surface_, buffer_damage);
144}
145
147 const fml::TimePoint& presentation_time) {
148 if (presentation_time_proc_) {
149 const auto time_ns = presentation_time.ToEpochDelta().ToNanoseconds();
150 return presentation_time_proc_(display_, surface_, time_ns);
151 } else {
152 return false;
153 }
154}
155
157 const std::optional<DlIRect>& surface_damage) {
158 TRACE_EVENT0("flutter", "AndroidContextGL::SwapBuffers");
159 return damage_->SwapBuffersWithDamage(display_, surface_, surface_damage);
160}
161
163 return damage_->SupportsPartialRepaint();
164}
165
166std::optional<DlIRect> AndroidEGLSurface::InitialDamage() {
167 return damage_->InitialDamage(display_, surface_);
168}
169
171 EGLint width = 0;
172 EGLint height = 0;
173
174 if (!eglQuerySurface(display_, surface_, EGL_WIDTH, &width) ||
175 !eglQuerySurface(display_, surface_, EGL_HEIGHT, &height)) {
176 FML_LOG(ERROR) << "Unable to query EGL surface size";
178 return DlISize();
179 }
180 return DlISize(width, height);
181}
182
183} // namespace flutter
#define _EGL_ERROR_DESC(a)
std::optional< DlIRect > InitialDamage(EGLDisplay display, EGLSurface surface)
void SetDamageRegion(EGLDisplay display, EGLSurface surface, const std::optional< DlIRect > &region)
void init(EGLDisplay display, EGLContext context)
bool SwapBuffersWithDamage(EGLDisplay display, EGLSurface surface, const std::optional< DlIRect > &damage)
std::optional< DlIRect > InitialDamage()
This is the minimal area that needs to be repainted to get correct result.
void SetDamageRegion(const std::optional< DlIRect > &buffer_damage)
Sets the damage region for current surface. Corresponds to.
bool SwapBuffers(const std::optional< DlIRect > &surface_damage)
This only applies to on-screen surfaces such as those created by AndroidContextGL::CreateOnscreenSurf...
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
constexpr TimeDelta ToEpochDelta() const
Definition time_point.h:52
VkSurfaceKHR surface
Definition main.cc:65
#define FML_LOG(severity)
Definition logging.h:101
#define FML_DCHECK(condition)
Definition logging.h:122
const char * name
Definition fuchsia.cc:49
EGLDisplay display_
EGLSurface surface_
void LogLastEGLError()
impeller::ISize32 DlISize
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:261
int32_t height
int32_t width
#define TRACE_EVENT0(category_group, name)