xref: /aosp_15_r20/external/tensorflow/tensorflow/lite/delegates/gpu/gl/gl_errors.cc (revision b6fb3261f9314811a0f4371741dbb8839866f948)
1 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 #include "tensorflow/lite/delegates/gpu/gl/gl_errors.h"
17 
18 #include <string>
19 #include <vector>
20 
21 #include "absl/strings/str_join.h"
22 #include "tensorflow/lite/delegates/gpu/common/status.h"
23 #include "tensorflow/lite/delegates/gpu/gl/portable_egl.h"
24 #include "tensorflow/lite/delegates/gpu/gl/portable_gl31.h"
25 
26 namespace tflite {
27 namespace gpu {
28 namespace gl {
29 namespace {
30 
ErrorToString(GLenum error)31 const char* ErrorToString(GLenum error) {
32   switch (error) {
33     case GL_INVALID_ENUM:
34       return "[GL_INVALID_ENUM]: An unacceptable value is specified for an "
35              "enumerated argument.";
36     case GL_INVALID_VALUE:
37       return "[GL_INVALID_VALUE]: A numeric argument is out of range.";
38     case GL_INVALID_OPERATION:
39       return "[GL_INVALID_OPERATION]: The specified operation is not allowed "
40              "in the current state.";
41     case GL_INVALID_FRAMEBUFFER_OPERATION:
42       return "[GL_INVALID_FRAMEBUFFER_OPERATION]: The framebuffer object is "
43              "not complete.";
44     case GL_OUT_OF_MEMORY:
45       return "[GL_OUT_OF_MEMORY]: There is not enough memory left to execute "
46              "the command.";
47   }
48   return "[UNKNOWN_GL_ERROR]";
49 }
50 
51 struct ErrorFormatter {
operator ()tflite::gpu::gl::__anon6b2029450111::ErrorFormatter52   void operator()(std::string* out, GLenum error) const {
53     absl::StrAppend(out, ErrorToString(error));
54   }
55 };
56 
57 }  // namespace
58 
59 // TODO(akulik): create new error space for GL error.
60 
GetOpenGlErrors()61 absl::Status GetOpenGlErrors() {
62 #ifdef __EMSCRIPTEN__
63   // This check is not recommended on WebGL, since it will force a wait on the
64   // GPU process.
65   return absl::OkStatus();
66 #else
67   auto error = glGetError();
68   if (error == GL_NO_ERROR) {
69     return absl::OkStatus();
70   }
71   auto error2 = glGetError();
72   if (error2 == GL_NO_ERROR) {
73     return absl::InternalError(ErrorToString(error));
74   }
75   std::vector<GLenum> errors = {error, error2};
76   for (error = glGetError(); error != GL_NO_ERROR; error = glGetError()) {
77     errors.push_back(error);
78   }
79   return absl::InternalError(absl::StrJoin(errors, ",", ErrorFormatter()));
80 #endif  // __EMSCRIPTEN__
81 }
82 
GetEglError()83 absl::Status GetEglError() {
84   EGLint error = eglGetError();
85   switch (error) {
86     case EGL_SUCCESS:
87       return absl::OkStatus();
88     case EGL_NOT_INITIALIZED:
89       return absl::InternalError(
90           "EGL is not initialized, or could not be initialized, for the "
91           "specified EGL display connection.");
92     case EGL_BAD_ACCESS:
93       return absl::InternalError(
94           "EGL cannot access a requested resource (for example a context is "
95           "bound in another thread).");
96     case EGL_BAD_ALLOC:
97       return absl::InternalError(
98           "EGL failed to allocate resources for the requested operation.");
99     case EGL_BAD_ATTRIBUTE:
100       return absl::InternalError(
101           "An unrecognized attribute or attribute value was passed in the "
102           "attribute list.");
103     case EGL_BAD_CONTEXT:
104       return absl::InternalError(
105           "An EGLContext argument does not name a valid EGL rendering "
106           "context.");
107     case EGL_BAD_CONFIG:
108       return absl::InternalError(
109           "An EGLConfig argument does not name a valid EGL frame buffer "
110           "configuration.");
111     case EGL_BAD_CURRENT_SURFACE:
112       return absl::InternalError(
113           "The current surface of the calling thread is a window, pixel buffer "
114           "or pixmap that is no longer valid.");
115     case EGL_BAD_DISPLAY:
116       return absl::InternalError(
117           "An EGLDisplay argument does not name a valid EGL display "
118           "connection.");
119     case EGL_BAD_SURFACE:
120       return absl::InternalError(
121           "An EGLSurface argument does not name a valid surface (window, pixel "
122           "buffer or pixmap) configured for GL rendering.");
123     case EGL_BAD_MATCH:
124       return absl::InternalError(
125           "Arguments are inconsistent (for example, a valid context requires "
126           "buffers not supplied by a valid surface).");
127     case EGL_BAD_PARAMETER:
128       return absl::InternalError("One or more argument values are invalid.");
129     case EGL_BAD_NATIVE_PIXMAP:
130       return absl::InternalError(
131           "A NativePixmapType argument does not refer to a valid native "
132           "pixmap.");
133     case EGL_BAD_NATIVE_WINDOW:
134       return absl::InternalError(
135           "A NativeWindowType argument does not refer to a valid native "
136           "window.");
137     case EGL_CONTEXT_LOST:
138       return absl::InternalError(
139           "A power management event has occurred. The application must destroy "
140           "all contexts and reinitialize OpenGL ES state and objects to "
141           "continue rendering.");
142   }
143   return absl::UnknownError("EGL error: " + std::to_string(error));
144 }
145 
146 }  // namespace gl
147 }  // namespace gpu
148 }  // namespace tflite
149