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