1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // utilities.h: Conversion functions and other utility routines.
8 
9 #ifndef COMMON_UTILITIES_H_
10 #define COMMON_UTILITIES_H_
11 
12 #include <EGL/egl.h>
13 #include <EGL/eglext.h>
14 
15 #include <math.h>
16 #include <string>
17 #include <vector>
18 
19 #include "angle_gl.h"
20 
21 #include "common/PackedEnums.h"
22 #include "common/mathutil.h"
23 #include "common/platform.h"
24 
25 namespace sh
26 {
27 struct ShaderVariable;
28 }
29 
30 namespace gl
31 {
32 
33 int VariableComponentCount(GLenum type);
34 GLenum VariableComponentType(GLenum type);
35 size_t VariableComponentSize(GLenum type);
36 size_t VariableInternalSize(GLenum type);
37 size_t VariableExternalSize(GLenum type);
38 int VariableRowCount(GLenum type);
39 int VariableColumnCount(GLenum type);
40 bool IsSamplerType(GLenum type);
41 bool IsSamplerCubeType(GLenum type);
42 bool IsSamplerYUVType(GLenum type);
43 bool IsImageType(GLenum type);
44 bool IsImage2DType(GLenum type);
45 bool IsAtomicCounterType(GLenum type);
46 bool IsOpaqueType(GLenum type);
47 bool IsMatrixType(GLenum type);
48 GLenum TransposeMatrixType(GLenum type);
49 int VariableRegisterCount(GLenum type);
50 int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix);
51 int MatrixComponentCount(GLenum type, bool isRowMajorMatrix);
52 int VariableSortOrder(GLenum type);
53 GLenum VariableBoolVectorType(GLenum type);
54 std::string GetGLSLTypeString(GLenum type);
55 
56 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
57 
58 // Parse the base resource name and array indices. Returns the base name of the resource.
59 // If the provided name doesn't index an array, the outSubscripts vector will be empty.
60 // If the provided name indexes an array, the outSubscripts vector will contain indices with
61 // outermost array indices in the back. If an array index is invalid, GL_INVALID_INDEX is added to
62 // outSubscripts.
63 std::string ParseResourceName(const std::string &name, std::vector<unsigned int> *outSubscripts);
64 
65 bool IsBuiltInName(const char *name);
IsBuiltInName(const std::string & name)66 ANGLE_INLINE bool IsBuiltInName(const std::string &name)
67 {
68     return IsBuiltInName(name.c_str());
69 }
70 
71 // Strips only the last array index from a resource name.
72 std::string StripLastArrayIndex(const std::string &name);
73 
74 bool SamplerNameContainsNonZeroArrayElement(const std::string &name);
75 
76 // Find the range of index values in the provided indices pointer.  Primitive restart indices are
77 // only counted in the range if primitive restart is disabled.
78 IndexRange ComputeIndexRange(DrawElementsType indexType,
79                              const GLvoid *indices,
80                              size_t count,
81                              bool primitiveRestartEnabled);
82 
83 // Get the primitive restart index value for the given index type.
84 GLuint GetPrimitiveRestartIndex(DrawElementsType indexType);
85 
86 // Get the primitive restart index value with the given C++ type.
87 template <typename T>
GetPrimitiveRestartIndexFromType()88 constexpr T GetPrimitiveRestartIndexFromType()
89 {
90     return std::numeric_limits<T>::max();
91 }
92 
93 static_assert(GetPrimitiveRestartIndexFromType<uint8_t>() == 0xFF,
94               "verify restart index for uint8_t values");
95 static_assert(GetPrimitiveRestartIndexFromType<uint16_t>() == 0xFFFF,
96               "verify restart index for uint8_t values");
97 static_assert(GetPrimitiveRestartIndexFromType<uint32_t>() == 0xFFFFFFFF,
98               "verify restart index for uint8_t values");
99 
100 bool IsTriangleMode(PrimitiveMode drawMode);
101 bool IsPolygonMode(PrimitiveMode mode);
102 
103 namespace priv
104 {
105 extern const angle::PackedEnumMap<PrimitiveMode, bool> gLineModes;
106 }  // namespace priv
107 
IsLineMode(PrimitiveMode primitiveMode)108 ANGLE_INLINE bool IsLineMode(PrimitiveMode primitiveMode)
109 {
110     return priv::gLineModes[primitiveMode];
111 }
112 
113 bool IsIntegerFormat(GLenum unsizedFormat);
114 
115 // Returns the product of the sizes in the vector, or 1 if the vector is empty. Doesn't currently
116 // perform overflow checks.
117 unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes);
118 // Returns the product of the sizes in the vector except for the outermost dimension, or 1 if the
119 // vector is empty.
120 unsigned int InnerArraySizeProduct(const std::vector<unsigned int> &arraySizes);
121 // Returns the outermost array dimension, or 1 if the vector is empty.
122 unsigned int OutermostArraySize(const std::vector<unsigned int> &arraySizes);
123 
124 // Return the array index at the end of name, and write the length of name before the final array
125 // index into nameLengthWithoutArrayIndexOut. In case name doesn't include an array index, return
126 // GL_INVALID_INDEX and write the length of the original string.
127 unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut);
128 
129 enum class SamplerFormat : uint8_t
130 {
131     Float    = 0,
132     Unsigned = 1,
133     Signed   = 2,
134     Shadow   = 3,
135 
136     InvalidEnum = 4,
137     EnumCount   = 4,
138 };
139 
140 struct UniformTypeInfo final : angle::NonCopyable
141 {
142     inline constexpr UniformTypeInfo(GLenum type,
143                                      GLenum componentType,
144                                      GLenum textureType,
145                                      GLenum transposedMatrixType,
146                                      GLenum boolVectorType,
147                                      SamplerFormat samplerFormat,
148                                      int rowCount,
149                                      int columnCount,
150                                      int componentCount,
151                                      size_t componentSize,
152                                      size_t internalSize,
153                                      size_t externalSize,
154                                      bool isSampler,
155                                      bool isMatrixType,
156                                      bool isImageType);
157 
158     GLenum type;
159     GLenum componentType;
160     GLenum textureType;
161     GLenum transposedMatrixType;
162     GLenum boolVectorType;
163     SamplerFormat samplerFormat;
164     int rowCount;
165     int columnCount;
166     int componentCount;
167     size_t componentSize;
168     size_t internalSize;
169     size_t externalSize;
170     bool isSampler;
171     bool isMatrixType;
172     bool isImageType;
173 };
174 
UniformTypeInfo(GLenum type,GLenum componentType,GLenum textureType,GLenum transposedMatrixType,GLenum boolVectorType,SamplerFormat samplerFormat,int rowCount,int columnCount,int componentCount,size_t componentSize,size_t internalSize,size_t externalSize,bool isSampler,bool isMatrixType,bool isImageType)175 inline constexpr UniformTypeInfo::UniformTypeInfo(GLenum type,
176                                                   GLenum componentType,
177                                                   GLenum textureType,
178                                                   GLenum transposedMatrixType,
179                                                   GLenum boolVectorType,
180                                                   SamplerFormat samplerFormat,
181                                                   int rowCount,
182                                                   int columnCount,
183                                                   int componentCount,
184                                                   size_t componentSize,
185                                                   size_t internalSize,
186                                                   size_t externalSize,
187                                                   bool isSampler,
188                                                   bool isMatrixType,
189                                                   bool isImageType)
190     : type(type),
191       componentType(componentType),
192       textureType(textureType),
193       transposedMatrixType(transposedMatrixType),
194       boolVectorType(boolVectorType),
195       samplerFormat(samplerFormat),
196       rowCount(rowCount),
197       columnCount(columnCount),
198       componentCount(componentCount),
199       componentSize(componentSize),
200       internalSize(internalSize),
201       externalSize(externalSize),
202       isSampler(isSampler),
203       isMatrixType(isMatrixType),
204       isImageType(isImageType)
205 {}
206 
207 const UniformTypeInfo &GetUniformTypeInfo(GLenum uniformType);
208 
209 const char *GetGenericErrorMessage(GLenum error);
210 
211 unsigned int ElementTypeSize(GLenum elementType);
212 
213 template <typename T>
GetClampedVertexCount(size_t vertexCount)214 T GetClampedVertexCount(size_t vertexCount)
215 {
216     static constexpr size_t kMax = static_cast<size_t>(std::numeric_limits<T>::max());
217     return static_cast<T>(vertexCount > kMax ? kMax : vertexCount);
218 }
219 
220 enum class PipelineType
221 {
222     GraphicsPipeline = 0,
223     ComputePipeline  = 1,
224 };
225 
226 PipelineType GetPipelineType(ShaderType shaderType);
227 
228 // For use with KHR_debug.
229 const char *GetDebugMessageSourceString(GLenum source);
230 const char *GetDebugMessageTypeString(GLenum type);
231 const char *GetDebugMessageSeverityString(GLenum severity);
232 
233 // For use with EXT_texture_format_sRGB_override and EXT_texture_sRGB_decode
234 // A texture may be forced to decode to a nonlinear colorspace, to a linear colorspace, or to the
235 // default colorspace of its current format.
236 //
237 // Default corresponds to "the texture should use the imageview that corresponds to its format"
238 // Linear corresponds to "the texture has sRGB decoding disabled by extension, and should use a
239 // linear imageview even if it is in a nonlinear format" NonLinear corresponds to "the texture has
240 // sRGB override enabled by extension, and should use a nonlinear imageview even if it is in a
241 // linear format"
242 enum class SrgbOverride
243 {
244     Default = 0,
245     SRGB,
246     Linear
247 };
248 
249 // For use with EXT_sRGB_write_control
250 // A render target may be forced to convert to a linear colorspace, or may be allowed to do whatever
251 // colorspace conversion is appropriate for its format. There is no option to force linear->sRGB, it
252 // can only convert from sRGB->linear
253 enum class SrgbWriteControlMode
254 {
255     Default = 0,
256     Linear  = 1
257 };
258 
259 ShaderType GetShaderTypeFromBitfield(size_t singleShaderType);
260 GLbitfield GetBitfieldFromShaderType(ShaderType shaderType);
261 bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType);
262 // Given a set of shader stages, returns the last vertex processing stage.  This is the stage that
263 // interfaces the fragment shader.
264 ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes);
265 
266 }  // namespace gl
267 
268 namespace egl
269 {
270 static const EGLenum FirstCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
271 static const EGLenum LastCubeMapTextureTarget  = EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR;
272 bool IsCubeMapTextureTarget(EGLenum target);
273 size_t CubeMapTextureTargetToLayerIndex(EGLenum target);
274 EGLenum LayerIndexToCubeMapTextureTarget(size_t index);
275 bool IsTextureTarget(EGLenum target);
276 bool IsRenderbufferTarget(EGLenum target);
277 bool IsExternalImageTarget(EGLenum target);
278 
279 const char *GetGenericErrorMessage(EGLint error);
280 }  // namespace egl
281 
282 namespace egl_gl
283 {
284 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer);
285 }
286 
287 namespace gl_egl
288 {
289 EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType);
290 EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle);
291 }  // namespace gl_egl
292 
293 #if !defined(ANGLE_ENABLE_WINDOWS_UWP)
294 std::string getTempPath();
295 void writeFile(const char *path, const void *data, size_t size);
296 #endif
297 
298 #if defined(ANGLE_PLATFORM_WINDOWS)
299 void ScheduleYield();
300 #endif
301 
302 // Get the underlying type. Useful for indexing into arrays with enum values by avoiding the clutter
303 // of the extraneous static_cast<>() calls.
304 // https://stackoverflow.com/a/8357462
305 template <typename E>
ToUnderlying(E e)306 constexpr typename std::underlying_type<E>::type ToUnderlying(E e) noexcept
307 {
308     return static_cast<typename std::underlying_type<E>::type>(e);
309 }
310 
311 #endif  // COMMON_UTILITIES_H_
312