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