| Flutter Impeller |

proc_table_gles.h
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 #ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_GLES_PROC_TABLE_GLES_H_
6 #define FLUTTER_IMPELLER_RENDERER_BACKEND_GLES_PROC_TABLE_GLES_H_
7
8 #include <functional>
9 #include <string>
10 #include <string_view>
11
12 #include "GLES3/gl3.h"
13 #include "flutter/fml/logging.h"
14 #include "flutter/fml/mapping.h"
15 #include "impeller/renderer/backend/gles/capabilities_gles.h"
16 #include "impeller/renderer/backend/gles/description_gles.h"
17 #include "impeller/renderer/backend/gles/gles.h"
18
19 /// Enable to allow GLES to push/pop labels for usage in GPU traces
20 #define IP_ENABLE_GLES_LABELING false
21
22 namespace impeller {
23
24 std::string_view GLErrorToString(GLenum value);
25 bool GLErrorIsFatal(GLenum value);
26
27 struct AutoErrorCheck {
28 const PFNGLGETERRORPROC error_fn;
29
30 /// Name of the GL call being wrapped.
31 /// should not be stored beyond the caller's lifetime.
32 std::string_view name;
33
34 AutoErrorCheck(PFNGLGETERRORPROC error, std::string_view name)
35 : error_fn(error), name(name) {}
36
37 ~AutoErrorCheck() {
38 if (error_fn) {
39 auto error = error_fn();
40 if (error == GL_NO_ERROR) {
41 return;
42 }
43 if (GLErrorIsFatal(error)) {
44 FML_LOG(FATAL) << "Fatal GL Error " << GLErrorToString(error) << "("
45 << error << ")" << " encountered on call to " << name;
46 } else {
47 FML_LOG(ERROR) << "GL Error " << GLErrorToString(error) << "(" << error
48 << ")" << " encountered on call to " << name;
49 }
50 }
51 }
52 };
53
54 template <typename Type>
55 struct ArgLogger {
56 static void log(std::stringstream& stream, Type arg) { stream << arg; }
57 };
58
59 template <typename R, typename... Args>
60 struct ArgLogger<R (*)(Args...)> {
61 static void log(std::stringstream& stream, R (*val)(Args...)) {
62 stream << reinterpret_cast<void*>(val);
63 }
64 };
65
66 template <class Type>
67 void BuildGLArgumentsStream(std::stringstream& stream, Type arg) {
68 ArgLogger<Type>::log(stream, arg);
69 }
70
71 constexpr void BuildGLArgumentsStream(std::stringstream& stream) {}
72
73 template <class Type, class... Rest>
74 void BuildGLArgumentsStream(std::stringstream& stream,
75 Type arg,
76 Rest... other_args) {
77 BuildGLArgumentsStream(stream, arg);
78 stream << ", ";
79 BuildGLArgumentsStream(stream, other_args...);
80 }
81
82 template <class... Type>
83 [[nodiscard]] std::string BuildGLArguments(Type... args) {
84 std::stringstream stream;
85 stream << "(";
86 BuildGLArgumentsStream(stream, args...);
87 stream << ")";
88 return stream.str();
89 }
90
91 template <class T>
92 struct GLProc {
93 using GLFunctionType = T;
94
95 //----------------------------------------------------------------------------
96 /// The name of the GL function.
97 ///
98 std::string_view name = {};
99
100 //----------------------------------------------------------------------------
101 /// The pointer to the GL function.
102 ///
103 GLFunctionType* function = nullptr;
104
105 //----------------------------------------------------------------------------
106 /// An optional error function. If present, all calls will be followed by an
107 /// error check.
108 ///
109 PFNGLGETERRORPROC error_fn = nullptr;
110
111 //----------------------------------------------------------------------------
112 /// Whether the OpenGL call and its arguments should be logged.
113 ///
114 /// Only works in IMPELLER_DEBUG and for environments where traditional
115 /// tracing is hard. Expect log spam and only use during development.
116 ///
117 bool log_calls = false;
118
119 //----------------------------------------------------------------------------
120 /// @brief Call the GL function with the appropriate parameters. Lookup
121 /// the documentation for the GL function being called to
122 /// understand the arguments and return types. The arguments
123 /// types must match and will be type checked.
124 ///
125 template <class... Args>
126 auto operator()(Args&&... args) const {
127 #if defined(IMPELLER_DEBUG) && !defined(NDEBUG)
128 AutoErrorCheck error(error_fn, name);
129 // We check for the existence of extensions, and reset the function pointer
130 // but it's still called unconditionally below, and will segfault. This
131 // validation log will at least give us a hint as to what's going on.
132 FML_CHECK(IsAvailable()) << "GL function " << name << " is not available. "
133 << "This is likely due to a missing extension.";
134 if (log_calls) {
135 FML_LOG(IMPORTANT) << name << BuildGLArguments(args...);
136 }
137 #endif // defined(IMPELLER_DEBUG) && !defined(NDEBUG)
138 return function(std::forward<Args>(args)...);
139 }
140
141 constexpr bool IsAvailable() const { return function != nullptr; }
142
143 void Reset() {
144 function = nullptr;
145 error_fn = nullptr;
146 }
147 };
148
149 #define FOR_EACH_IMPELLER_PROC(PROC) \
150 PROC(ActiveTexture); \
151 PROC(AttachShader); \
152 PROC(BindAttribLocation); \
153 PROC(BindBuffer); \
154 PROC(BindFramebuffer); \
155 PROC(BindRenderbuffer); \
156 PROC(BindTexture); \
157 PROC(BindVertexArray); \
158 PROC(BlendEquationSeparate); \
159 PROC(BlendFuncSeparate); \
160 PROC(BufferData); \
161 PROC(BufferSubData); \
162 PROC(CheckFramebufferStatus); \
163 PROC(Clear); \
164 PROC(ClearColor); \
165 PROC(ClearStencil); \
166 PROC(ColorMask); \
167 PROC(CompileShader); \
168 PROC(CreateProgram); \
169 PROC(CreateShader); \
170 PROC(CullFace); \
171 PROC(DeleteBuffers); \
172 PROC(DeleteFramebuffers); \
173 PROC(DeleteProgram); \
174 PROC(DeleteRenderbuffers); \
175 PROC(DeleteShader); \
176 PROC(DeleteTextures); \
177 PROC(DeleteVertexArrays); \
178 PROC(DepthFunc); \
179 PROC(DepthMask); \
180 PROC(DetachShader); \
181 PROC(Disable); \
182 PROC(DisableVertexAttribArray); \
183 PROC(DrawArrays); \
184 PROC(DrawElements); \
185 PROC(Enable); \
186 PROC(EnableVertexAttribArray); \
187 PROC(Finish); \
188 PROC(Flush); \
189 PROC(FramebufferRenderbuffer); \
190 PROC(FramebufferTexture2D); \
191 PROC(FrontFace); \
192 PROC(GenBuffers); \
193 PROC(GenerateMipmap); \
194 PROC(GenFramebuffers); \
195 PROC(GenRenderbuffers); \
196 PROC(GenTextures); \
197 PROC(GenVertexArrays); \
198 PROC(GetActiveUniform); \
199 PROC(GetBooleanv); \
200 PROC(GetFloatv); \
201 PROC(GetFramebufferAttachmentParameteriv); \
202 PROC(GetIntegerv); \
203 PROC(GetProgramInfoLog); \
204 PROC(GetProgramiv); \
205 PROC(GetShaderInfoLog); \
206 PROC(GetShaderiv); \
207 PROC(GetString); \
208 PROC(GetStringi); \
209 PROC(GetUniformLocation); \
210 PROC(IsBuffer); \
211 PROC(IsFramebuffer); \
212 PROC(IsProgram); \
213 PROC(IsRenderbuffer); \
214 PROC(IsShader); \
215 PROC(IsTexture); \
216 PROC(LinkProgram); \
217 PROC(PixelStorei); \
218 PROC(RenderbufferStorage); \
219 PROC(Scissor); \
220 PROC(ShaderBinary); \
221 PROC(ShaderSource); \
222 PROC(StencilFuncSeparate); \
223 PROC(StencilMaskSeparate); \
224 PROC(StencilOpSeparate); \
225 PROC(TexImage2D); \
226 PROC(TexSubImage2D); \
227 PROC(TexParameteri); \
228 PROC(TexParameterfv); \
229 PROC(Uniform1fv); \
230 PROC(Uniform1i); \
231 PROC(Uniform2fv); \
232 PROC(Uniform3fv); \
233 PROC(Uniform4fv); \
234 PROC(UniformMatrix4fv); \
235 PROC(UseProgram); \
236 PROC(VertexAttribPointer); \
237 PROC(Viewport); \
238 PROC(GetShaderSource); \
239 PROC(ReadPixels);
240
241 // Calls specific to OpenGLES.
242 void(glClearDepthf)(GLfloat depth);
243 void(glDepthRangef)(GLfloat n, GLfloat f);
244
245 #define FOR_EACH_IMPELLER_ES_ONLY_PROC(PROC) \
246 PROC(ClearDepthf); \
247 PROC(DepthRangef);
248
249 // Calls specific to desktop GL.
250 void(glClearDepth)(GLdouble depth);
251 void(glDepthRange)(GLdouble n, GLdouble f);
252
253 #define FOR_EACH_IMPELLER_DESKTOP_ONLY_PROC(PROC) \
254 PROC(ClearDepth); \
255 PROC(DepthRange);
256
257 #define FOR_EACH_IMPELLER_GLES3_PROC(PROC) \
258 PROC(FenceSync); \
259 PROC(DeleteSync); \
260 PROC(GetActiveUniformBlockiv); \
261 PROC(GetActiveUniformBlockName); \
262 PROC(GetUniformBlockIndex); \
263 PROC(UniformBlockBinding); \
264 PROC(BindBufferRange); \
265 PROC(WaitSync); \
266 PROC(RenderbufferStorageMultisample) \
267 PROC(BlitFramebuffer);
268
269 #define FOR_EACH_IMPELLER_EXT_PROC(PROC) \
270 PROC(DebugMessageControlKHR); \
271 PROC(DebugMessageCallbackKHR); \
272 PROC(DiscardFramebufferEXT); \
273 PROC(FramebufferTexture2DMultisampleEXT); \
274 PROC(PushDebugGroupKHR); \
275 PROC(PopDebugGroupKHR); \
276 PROC(ObjectLabelKHR); \
277 PROC(RenderbufferStorageMultisampleEXT); \
278 PROC(GenQueriesEXT); \
279 PROC(DeleteQueriesEXT); \
280 PROC(GetQueryObjectui64vEXT); \
281 PROC(BeginQueryEXT); \
282 PROC(EndQueryEXT); \
283 PROC(GetQueryObjectuivEXT); \
284 PROC(BlitFramebufferANGLE);
285
286 enum class DebugResourceType {
287 kTexture,
288 kBuffer,
289 kProgram,
290 kShader,
291 kRenderBuffer,
292 kFrameBuffer,
293 kFence,
294 };
295
296 class ProcTableGLES {
297 public:
298 using Resolver = std::function<void*(const char* function_name)>;
299 explicit ProcTableGLES(Resolver resolver);
300 ProcTableGLES(ProcTableGLES&& other) = default;
301
302 ~ProcTableGLES();
303
304 #define IMPELLER_PROC(name) \
305 GLProc<decltype(gl##name)> name = {"gl" #name, nullptr};
306
307 FOR_EACH_IMPELLER_PROC(IMPELLER_PROC);
308 FOR_EACH_IMPELLER_ES_ONLY_PROC(IMPELLER_PROC);
309 FOR_EACH_IMPELLER_DESKTOP_ONLY_PROC(IMPELLER_PROC);
310 FOR_EACH_IMPELLER_GLES3_PROC(IMPELLER_PROC);
311 FOR_EACH_IMPELLER_EXT_PROC(IMPELLER_PROC);
312
313 #undef IMPELLER_PROC
314
315 bool IsValid() const;
316
317 /// @brief Set the source for the attached [shader].
318 ///
319 /// Optionally, [defines] may contain a string value that will be
320 /// append to the shader source after the version marker. This can be used to
321 /// support static specialization. For example, setting "#define Foo 1".
322 void ShaderSourceMapping(GLuint shader,
323 const fml::Mapping& mapping,
324 const std::vector<Scalar>& defines = {}) const;
325
326 const DescriptionGLES* GetDescription() const;
327
328 const std::shared_ptr<const CapabilitiesGLES>& GetCapabilities() const;
329
330 std::string DescribeCurrentFramebuffer() const;
331
332 std::string GetProgramInfoLogString(GLuint program) const;
333
334 // Only check framebuffer status in debug builds.
335 // Prefer this if possible to direct calls to CheckFramebufferStatus,
336 // which can cause CPU<->GPU round-trips.
337 GLenum CheckFramebufferStatusDebug(GLenum target) const;
338
339 bool IsCurrentFramebufferComplete() const;
340
341 bool SupportsDebugLabels() const;
342
343 bool SetDebugLabel(DebugResourceType type,
344 GLint name,
345 std::string_view label) const;
346
347 void PushDebugGroup(const std::string& string) const;
348
349 void PopDebugGroup() const;
350
351 // Visible For testing.
352 std::optional<std::string> ComputeShaderWithDefines(
353 const fml::Mapping& mapping,
354 const std::vector<Scalar>& defines) const;
355
356 private:
357 bool is_valid_ = false;
358 std::unique_ptr<DescriptionGLES> description_;
359 std::shared_ptr<const CapabilitiesGLES> capabilities_;
360 GLint debug_label_max_length_ = 0;
361
362 ProcTableGLES(const ProcTableGLES&) = delete;
363
364 ProcTableGLES& operator=(const ProcTableGLES&) = delete;
365 };
366
367 } // namespace impeller
368
369 #endif // FLUTTER_IMPELLER_RENDERER_BACKEND_GLES_PROC_TABLE_GLES_H_
type
GLenum type
Definition: blit_command_gles.cc:153
capabilities_gles.h
impeller::DescriptionGLES
Definition: description_gles.h:17
impeller::ProcTableGLES
Definition: proc_table_gles.h:296
impeller::ProcTableGLES::FOR_EACH_IMPELLER_ES_ONLY_PROC
FOR_EACH_IMPELLER_ES_ONLY_PROC(IMPELLER_PROC)
impeller::ProcTableGLES::ProcTableGLES
ProcTableGLES(ProcTableGLES &&other)=default
impeller::ProcTableGLES::ComputeShaderWithDefines
std::optional< std::string > ComputeShaderWithDefines(const fml::Mapping &mapping, const std::vector< Scalar > &defines) const
Definition: proc_table_gles.cc:184
impeller::ProcTableGLES::PopDebugGroup
void PopDebugGroup() const
Definition: proc_table_gles.cc:416
impeller::ProcTableGLES::SetDebugLabel
bool SetDebugLabel(DebugResourceType type, GLint name, std::string_view label) const
Definition: proc_table_gles.cc:376
impeller::ProcTableGLES::~ProcTableGLES
~ProcTableGLES()
impeller::ProcTableGLES::FOR_EACH_IMPELLER_GLES3_PROC
FOR_EACH_IMPELLER_GLES3_PROC(IMPELLER_PROC)
impeller::ProcTableGLES::Resolver
std::function< void *(const char *function_name)> Resolver
Definition: proc_table_gles.h:298
impeller::ProcTableGLES::ShaderSourceMapping
void ShaderSourceMapping(GLuint shader, const fml::Mapping &mapping, const std::vector< Scalar > &defines={}) const
Set the source for the attached [shader].
Definition: proc_table_gles.cc:160
impeller::ProcTableGLES::FOR_EACH_IMPELLER_DESKTOP_ONLY_PROC
FOR_EACH_IMPELLER_DESKTOP_ONLY_PROC(IMPELLER_PROC)
impeller::ProcTableGLES::GetProgramInfoLogString
std::string GetProgramInfoLogString(GLuint program) const
Definition: proc_table_gles.cc:426
impeller::ProcTableGLES::CheckFramebufferStatusDebug
GLenum CheckFramebufferStatusDebug(GLenum target) const
Definition: proc_table_gles.cc:450
impeller::ProcTableGLES::SupportsDebugLabels
bool SupportsDebugLabels() const
Definition: proc_table_gles.cc:366
impeller::ProcTableGLES::DescribeCurrentFramebuffer
std::string DescribeCurrentFramebuffer() const
Definition: proc_table_gles.cc:277
impeller::ProcTableGLES::GetCapabilities
const std::shared_ptr< const CapabilitiesGLES > & GetCapabilities() const
Definition: proc_table_gles.cc:212
impeller::ProcTableGLES::IsCurrentFramebufferComplete
bool IsCurrentFramebufferComplete() const
Definition: proc_table_gles.cc:313
impeller::ProcTableGLES::IsValid
bool IsValid() const
Definition: proc_table_gles.cc:156
impeller::ProcTableGLES::ProcTableGLES
ProcTableGLES(Resolver resolver)
Definition: proc_table_gles.cc:75
impeller::ProcTableGLES::FOR_EACH_IMPELLER_PROC
FOR_EACH_IMPELLER_PROC(IMPELLER_PROC)
impeller::ProcTableGLES::FOR_EACH_IMPELLER_EXT_PROC
FOR_EACH_IMPELLER_EXT_PROC(IMPELLER_PROC)
impeller::ProcTableGLES::PushDebugGroup
void PushDebugGroup(const std::string &string) const
Definition: proc_table_gles.cc:399
impeller::ProcTableGLES::GetDescription
const DescriptionGLES * GetDescription() const
Definition: proc_table_gles.cc:208
description_gles.h
value
int32_t value
Definition: dl_golden_unittests.cc:459
impeller
Definition: allocation.cc:12
impeller::glClearDepth
void() glClearDepth(GLdouble depth)
impeller::GLErrorToString
std::string_view GLErrorToString(GLenum value)
Definition: proc_table_gles.cc:19
impeller::GLErrorIsFatal
bool GLErrorIsFatal(GLenum value)
Definition: proc_table_gles.cc:39
impeller::glDepthRangef
void() glDepthRangef(GLfloat n, GLfloat f)
impeller::BuildGLArgumentsStream
void BuildGLArgumentsStream(std::stringstream &stream, Type arg)
Definition: proc_table_gles.h:67
impeller::glDepthRange
void() glDepthRange(GLdouble n, GLdouble f)
impeller::glClearDepthf
void() glClearDepthf(GLfloat depth)
impeller::DebugResourceType
DebugResourceType
Definition: proc_table_gles.h:286
impeller::DebugResourceType::kBuffer
@ kBuffer
impeller::DebugResourceType::kProgram
@ kProgram
impeller::DebugResourceType::kTexture
@ kTexture
impeller::DebugResourceType::kRenderBuffer
@ kRenderBuffer
impeller::DebugResourceType::kFence
@ kFence
impeller::DebugResourceType::kFrameBuffer
@ kFrameBuffer
impeller::DebugResourceType::kShader
@ kShader
impeller::BuildGLArguments
std::string BuildGLArguments(Type... args)
Definition: proc_table_gles.h:83
IMPELLER_PROC
#define IMPELLER_PROC(name)
Definition: proc_table_gles.h:304
gles.h
impeller::ArgLogger< R(*)(Args...)>::log
static void log(std::stringstream &stream, R(*val)(Args...))
Definition: proc_table_gles.h:61
impeller::ArgLogger
Definition: proc_table_gles.h:55
impeller::ArgLogger::log
static void log(std::stringstream &stream, Type arg)
Definition: proc_table_gles.h:56
impeller::AutoErrorCheck
Definition: proc_table_gles.h:27
impeller::AutoErrorCheck::AutoErrorCheck
AutoErrorCheck(PFNGLGETERRORPROC error, std::string_view name)
Definition: proc_table_gles.h:34
impeller::AutoErrorCheck::~AutoErrorCheck
~AutoErrorCheck()
Definition: proc_table_gles.h:37
impeller::AutoErrorCheck::error_fn
const PFNGLGETERRORPROC error_fn
Definition: proc_table_gles.h:28
impeller::AutoErrorCheck::name
std::string_view name
Definition: proc_table_gles.h:32
impeller::GLProc
Definition: proc_table_gles.h:92
impeller::GLProc::log_calls
bool log_calls
Definition: proc_table_gles.h:117
impeller::GLProc::operator()
auto operator()(Args &&... args) const
Call the GL function with the appropriate parameters. Lookup the documentation for the GL function be...
Definition: proc_table_gles.h:126
impeller::GLProc::GLFunctionType
T GLFunctionType
Definition: proc_table_gles.h:93
impeller::GLProc::IsAvailable
constexpr bool IsAvailable() const
Definition: proc_table_gles.h:141
impeller::GLProc::Reset
void Reset()
Definition: proc_table_gles.h:143
impeller::GLProc::name
std::string_view name
Definition: proc_table_gles.h:98
impeller::GLProc::error_fn
PFNGLGETERRORPROC error_fn
Definition: proc_table_gles.h:109