summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/common/utilities.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/common/utilities.cpp')
-rw-r--r--gfx/angle/checkout/src/common/utilities.cpp1509
1 files changed, 1509 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/common/utilities.cpp b/gfx/angle/checkout/src/common/utilities.cpp
new file mode 100644
index 0000000000..f08774523c
--- /dev/null
+++ b/gfx/angle/checkout/src/common/utilities.cpp
@@ -0,0 +1,1509 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// utilities.cpp: Conversion functions and other utility routines.
+
+#include "common/utilities.h"
+#include "GLES3/gl3.h"
+#include "common/mathutil.h"
+#include "common/platform.h"
+#include "common/string_utils.h"
+
+#include <set>
+
+#if defined(ANGLE_ENABLE_WINDOWS_UWP)
+# include <windows.applicationmodel.core.h>
+# include <windows.graphics.display.h>
+# include <wrl.h>
+# include <wrl/wrappers/corewrappers.h>
+#endif
+
+namespace
+{
+
+template <class IndexType>
+gl::IndexRange ComputeTypedIndexRange(const IndexType *indices,
+ size_t count,
+ bool primitiveRestartEnabled,
+ GLuint primitiveRestartIndex)
+{
+ ASSERT(count > 0);
+
+ IndexType minIndex = 0;
+ IndexType maxIndex = 0;
+ size_t nonPrimitiveRestartIndices = 0;
+
+ if (primitiveRestartEnabled)
+ {
+ // Find the first non-primitive restart index to initialize the min and max values
+ size_t i = 0;
+ for (; i < count; i++)
+ {
+ if (indices[i] != primitiveRestartIndex)
+ {
+ minIndex = indices[i];
+ maxIndex = indices[i];
+ nonPrimitiveRestartIndices++;
+ break;
+ }
+ }
+
+ // Loop over the rest of the indices
+ for (; i < count; i++)
+ {
+ if (indices[i] != primitiveRestartIndex)
+ {
+ if (minIndex > indices[i])
+ {
+ minIndex = indices[i];
+ }
+ if (maxIndex < indices[i])
+ {
+ maxIndex = indices[i];
+ }
+ nonPrimitiveRestartIndices++;
+ }
+ }
+ }
+ else
+ {
+ minIndex = indices[0];
+ maxIndex = indices[0];
+ nonPrimitiveRestartIndices = count;
+
+ for (size_t i = 1; i < count; i++)
+ {
+ if (minIndex > indices[i])
+ {
+ minIndex = indices[i];
+ }
+ if (maxIndex < indices[i])
+ {
+ maxIndex = indices[i];
+ }
+ }
+ }
+
+ return gl::IndexRange(static_cast<size_t>(minIndex), static_cast<size_t>(maxIndex),
+ nonPrimitiveRestartIndices);
+}
+
+} // anonymous namespace
+
+namespace gl
+{
+
+int VariableComponentCount(GLenum type)
+{
+ return VariableRowCount(type) * VariableColumnCount(type);
+}
+
+GLenum VariableComponentType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BOOL:
+ case GL_BOOL_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_BOOL_VEC4:
+ return GL_BOOL;
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT3x2:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT4x2:
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x3:
+ return GL_FLOAT;
+ case GL_INT:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_2D_RECT_ANGLE:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_EXTERNAL_OES:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_BUFFER:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_INT_VEC2:
+ case GL_INT_VEC3:
+ case GL_INT_VEC4:
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_IMAGE_BUFFER:
+ case GL_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_ATOMIC_COUNTER:
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return GL_INT;
+ case GL_UNSIGNED_INT:
+ case GL_UNSIGNED_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC4:
+ return GL_UNSIGNED_INT;
+ default:
+ UNREACHABLE();
+ }
+
+ return GL_NONE;
+}
+
+size_t VariableComponentSize(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BOOL:
+ return sizeof(GLint);
+ case GL_FLOAT:
+ return sizeof(GLfloat);
+ case GL_INT:
+ return sizeof(GLint);
+ case GL_UNSIGNED_INT:
+ return sizeof(GLuint);
+ default:
+ UNREACHABLE();
+ }
+
+ return 0;
+}
+
+size_t VariableInternalSize(GLenum type)
+{
+ // Expanded to 4-element vectors
+ return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
+}
+
+size_t VariableExternalSize(GLenum type)
+{
+ return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
+}
+
+std::string GetGLSLTypeString(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BOOL:
+ return "bool";
+ case GL_INT:
+ return "int";
+ case GL_UNSIGNED_INT:
+ return "uint";
+ case GL_FLOAT:
+ return "float";
+ case GL_BOOL_VEC2:
+ return "bvec2";
+ case GL_BOOL_VEC3:
+ return "bvec3";
+ case GL_BOOL_VEC4:
+ return "bvec4";
+ case GL_INT_VEC2:
+ return "ivec2";
+ case GL_INT_VEC3:
+ return "ivec3";
+ case GL_INT_VEC4:
+ return "ivec4";
+ case GL_FLOAT_VEC2:
+ return "vec2";
+ case GL_FLOAT_VEC3:
+ return "vec3";
+ case GL_FLOAT_VEC4:
+ return "vec4";
+ case GL_UNSIGNED_INT_VEC2:
+ return "uvec2";
+ case GL_UNSIGNED_INT_VEC3:
+ return "uvec3";
+ case GL_UNSIGNED_INT_VEC4:
+ return "uvec4";
+ case GL_FLOAT_MAT2:
+ return "mat2";
+ case GL_FLOAT_MAT3:
+ return "mat3";
+ case GL_FLOAT_MAT4:
+ return "mat4";
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+GLenum VariableBoolVectorType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ return GL_BOOL;
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC2:
+ return GL_BOOL_VEC2;
+ case GL_FLOAT_VEC3:
+ case GL_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC3:
+ return GL_BOOL_VEC3;
+ case GL_FLOAT_VEC4:
+ case GL_INT_VEC4:
+ case GL_UNSIGNED_INT_VEC4:
+ return GL_BOOL_VEC4;
+
+ default:
+ UNREACHABLE();
+ return GL_NONE;
+ }
+}
+
+int VariableRowCount(GLenum type)
+{
+ switch (type)
+ {
+ case GL_NONE:
+ return 0;
+ case GL_BOOL:
+ case GL_FLOAT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_BOOL_VEC2:
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_FLOAT_VEC3:
+ case GL_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC3:
+ case GL_BOOL_VEC4:
+ case GL_FLOAT_VEC4:
+ case GL_INT_VEC4:
+ case GL_UNSIGNED_INT_VEC4:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_EXTERNAL_OES:
+ case GL_SAMPLER_2D_RECT_ANGLE:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_SAMPLER_BUFFER:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_ATOMIC_COUNTER:
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_IMAGE_BUFFER:
+ case GL_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return 1;
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT3x2:
+ case GL_FLOAT_MAT4x2:
+ return 2;
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT4x3:
+ return 3;
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT3x4:
+ return 4;
+ default:
+ UNREACHABLE();
+ }
+
+ return 0;
+}
+
+int VariableColumnCount(GLenum type)
+{
+ switch (type)
+ {
+ case GL_NONE:
+ return 0;
+ case GL_BOOL:
+ case GL_FLOAT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_SAMPLER_BUFFER:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_SAMPLER_EXTERNAL_OES:
+ case GL_SAMPLER_2D_RECT_ANGLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_IMAGE_BUFFER:
+ case GL_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_ATOMIC_COUNTER:
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return 1;
+ case GL_BOOL_VEC2:
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC2:
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT2x4:
+ return 2;
+ case GL_BOOL_VEC3:
+ case GL_FLOAT_VEC3:
+ case GL_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC3:
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT3x2:
+ case GL_FLOAT_MAT3x4:
+ return 3;
+ case GL_BOOL_VEC4:
+ case GL_FLOAT_VEC4:
+ case GL_INT_VEC4:
+ case GL_UNSIGNED_INT_VEC4:
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT4x2:
+ case GL_FLOAT_MAT4x3:
+ return 4;
+ default:
+ UNREACHABLE();
+ }
+
+ return 0;
+}
+
+bool IsSamplerType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_EXTERNAL_OES:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_SAMPLER_BUFFER:
+ case GL_SAMPLER_2D_RECT_ANGLE:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return true;
+ }
+
+ return false;
+}
+
+bool IsSamplerCubeType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_SAMPLER_CUBE_SHADOW:
+ return true;
+ }
+
+ return false;
+}
+
+bool IsSamplerYUVType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool IsImageType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_IMAGE_BUFFER:
+ case GL_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ return true;
+ }
+ return false;
+}
+
+bool IsImage2DType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ return true;
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ case GL_IMAGE_BUFFER:
+ case GL_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ return false;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool IsAtomicCounterType(GLenum type)
+{
+ return type == GL_UNSIGNED_INT_ATOMIC_COUNTER;
+}
+
+bool IsOpaqueType(GLenum type)
+{
+ // ESSL 3.10 section 4.1.7 defines opaque types as: samplers, images and atomic counters.
+ return IsImageType(type) || IsSamplerType(type) || IsAtomicCounterType(type);
+}
+
+bool IsMatrixType(GLenum type)
+{
+ return VariableRowCount(type) > 1;
+}
+
+GLenum TransposeMatrixType(GLenum type)
+{
+ if (!IsMatrixType(type))
+ {
+ return type;
+ }
+
+ switch (type)
+ {
+ case GL_FLOAT_MAT2:
+ return GL_FLOAT_MAT2;
+ case GL_FLOAT_MAT3:
+ return GL_FLOAT_MAT3;
+ case GL_FLOAT_MAT4:
+ return GL_FLOAT_MAT4;
+ case GL_FLOAT_MAT2x3:
+ return GL_FLOAT_MAT3x2;
+ case GL_FLOAT_MAT3x2:
+ return GL_FLOAT_MAT2x3;
+ case GL_FLOAT_MAT2x4:
+ return GL_FLOAT_MAT4x2;
+ case GL_FLOAT_MAT4x2:
+ return GL_FLOAT_MAT2x4;
+ case GL_FLOAT_MAT3x4:
+ return GL_FLOAT_MAT4x3;
+ case GL_FLOAT_MAT4x3:
+ return GL_FLOAT_MAT3x4;
+ default:
+ UNREACHABLE();
+ return GL_NONE;
+ }
+}
+
+int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
+{
+ ASSERT(IsMatrixType(type));
+ return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
+}
+
+int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
+{
+ ASSERT(IsMatrixType(type));
+ return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
+}
+
+int VariableRegisterCount(GLenum type)
+{
+ return IsMatrixType(type) ? VariableColumnCount(type) : 1;
+}
+
+int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
+{
+ ASSERT(allocationSize <= bitsSize);
+
+ unsigned int mask = std::numeric_limits<unsigned int>::max() >>
+ (std::numeric_limits<unsigned int>::digits - allocationSize);
+
+ for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
+ {
+ if ((*bits & mask) == 0)
+ {
+ *bits |= mask;
+ return i;
+ }
+
+ mask <<= 1;
+ }
+
+ return -1;
+}
+
+IndexRange ComputeIndexRange(DrawElementsType indexType,
+ const GLvoid *indices,
+ size_t count,
+ bool primitiveRestartEnabled)
+{
+ switch (indexType)
+ {
+ case DrawElementsType::UnsignedByte:
+ return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
+ primitiveRestartEnabled,
+ GetPrimitiveRestartIndex(indexType));
+ case DrawElementsType::UnsignedShort:
+ return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
+ primitiveRestartEnabled,
+ GetPrimitiveRestartIndex(indexType));
+ case DrawElementsType::UnsignedInt:
+ return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
+ primitiveRestartEnabled,
+ GetPrimitiveRestartIndex(indexType));
+ default:
+ UNREACHABLE();
+ return IndexRange();
+ }
+}
+
+GLuint GetPrimitiveRestartIndex(DrawElementsType indexType)
+{
+ switch (indexType)
+ {
+ case DrawElementsType::UnsignedByte:
+ return 0xFF;
+ case DrawElementsType::UnsignedShort:
+ return 0xFFFF;
+ case DrawElementsType::UnsignedInt:
+ return 0xFFFFFFFF;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+bool IsTriangleMode(PrimitiveMode drawMode)
+{
+ switch (drawMode)
+ {
+ case PrimitiveMode::Triangles:
+ case PrimitiveMode::TriangleFan:
+ case PrimitiveMode::TriangleStrip:
+ return true;
+ case PrimitiveMode::Points:
+ case PrimitiveMode::Lines:
+ case PrimitiveMode::LineLoop:
+ case PrimitiveMode::LineStrip:
+ return false;
+ default:
+ UNREACHABLE();
+ }
+
+ return false;
+}
+
+bool IsPolygonMode(PrimitiveMode mode)
+{
+ switch (mode)
+ {
+ case PrimitiveMode::Points:
+ case PrimitiveMode::Lines:
+ case PrimitiveMode::LineStrip:
+ case PrimitiveMode::LineLoop:
+ case PrimitiveMode::LinesAdjacency:
+ case PrimitiveMode::LineStripAdjacency:
+ return false;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+namespace priv
+{
+const angle::PackedEnumMap<PrimitiveMode, bool> gLineModes = {
+ {{PrimitiveMode::LineLoop, true},
+ {PrimitiveMode::LineStrip, true},
+ {PrimitiveMode::LineStripAdjacency, true},
+ {PrimitiveMode::Lines, true}}};
+} // namespace priv
+
+bool IsIntegerFormat(GLenum unsizedFormat)
+{
+ switch (unsizedFormat)
+ {
+ case GL_RGBA_INTEGER:
+ case GL_RGB_INTEGER:
+ case GL_RG_INTEGER:
+ case GL_RED_INTEGER:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+// [OpenGL ES SL 3.00.4] Section 11 p. 120
+// Vertex Outs/Fragment Ins packing priorities
+int VariableSortOrder(GLenum type)
+{
+ switch (type)
+ {
+ // 1. Arrays of mat4 and mat4
+ // Non-square matrices of type matCxR consume the same space as a square
+ // matrix of type matN where N is the greater of C and R
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x2:
+ case GL_FLOAT_MAT4x3:
+ return 0;
+
+ // 2. Arrays of mat2 and mat2 (since they occupy full rows)
+ case GL_FLOAT_MAT2:
+ return 1;
+
+ // 3. Arrays of vec4 and vec4
+ case GL_FLOAT_VEC4:
+ case GL_INT_VEC4:
+ case GL_BOOL_VEC4:
+ case GL_UNSIGNED_INT_VEC4:
+ return 2;
+
+ // 4. Arrays of mat3 and mat3
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT3x2:
+ return 3;
+
+ // 5. Arrays of vec3 and vec3
+ case GL_FLOAT_VEC3:
+ case GL_INT_VEC3:
+ case GL_BOOL_VEC3:
+ case GL_UNSIGNED_INT_VEC3:
+ return 4;
+
+ // 6. Arrays of vec2 and vec2
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_BOOL_VEC2:
+ case GL_UNSIGNED_INT_VEC2:
+ return 5;
+
+ // 7. Single component types
+ case GL_FLOAT:
+ case GL_INT:
+ case GL_BOOL:
+ case GL_UNSIGNED_INT:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_EXTERNAL_OES:
+ case GL_SAMPLER_2D_RECT_ANGLE:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_3D:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_ATOMIC_COUNTER:
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return 6;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::string ParseResourceName(const std::string &name, std::vector<unsigned int> *outSubscripts)
+{
+ if (outSubscripts)
+ {
+ outSubscripts->clear();
+ }
+ // Strip any trailing array indexing operators and retrieve the subscripts.
+ size_t baseNameLength = name.length();
+ bool hasIndex = true;
+ while (hasIndex)
+ {
+ size_t open = name.find_last_of('[', baseNameLength - 1);
+ size_t close = name.find_last_of(']', baseNameLength - 1);
+ hasIndex = (open != std::string::npos) && (close == baseNameLength - 1);
+ if (hasIndex)
+ {
+ baseNameLength = open;
+ if (outSubscripts)
+ {
+ int index = atoi(name.substr(open + 1).c_str());
+ if (index >= 0)
+ {
+ outSubscripts->push_back(index);
+ }
+ else
+ {
+ outSubscripts->push_back(GL_INVALID_INDEX);
+ }
+ }
+ }
+ }
+
+ return name.substr(0, baseNameLength);
+}
+
+bool IsBuiltInName(const char *name)
+{
+ return angle::BeginsWith(name, "gl_");
+}
+
+std::string StripLastArrayIndex(const std::string &name)
+{
+ size_t strippedNameLength = name.find_last_of('[');
+ if (strippedNameLength != std::string::npos && name.back() == ']')
+ {
+ return name.substr(0, strippedNameLength);
+ }
+ return name;
+}
+
+bool SamplerNameContainsNonZeroArrayElement(const std::string &name)
+{
+ constexpr char kZERO_ELEMENT[] = "[0]";
+
+ size_t start = 0;
+ while (true)
+ {
+ start = name.find(kZERO_ELEMENT[0], start);
+ if (start == std::string::npos)
+ {
+ break;
+ }
+ if (name.compare(start, strlen(kZERO_ELEMENT), kZERO_ELEMENT) != 0)
+ {
+ return true;
+ }
+ start++;
+ }
+ return false;
+}
+
+unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes)
+{
+ unsigned int arraySizeProduct = 1u;
+ for (unsigned int arraySize : arraySizes)
+ {
+ arraySizeProduct *= arraySize;
+ }
+ return arraySizeProduct;
+}
+
+unsigned int InnerArraySizeProduct(const std::vector<unsigned int> &arraySizes)
+{
+ unsigned int arraySizeProduct = 1u;
+ for (size_t index = 0; index + 1 < arraySizes.size(); ++index)
+ {
+ arraySizeProduct *= arraySizes[index];
+ }
+ return arraySizeProduct;
+}
+
+unsigned int OutermostArraySize(const std::vector<unsigned int> &arraySizes)
+{
+ return arraySizes.empty() || arraySizes.back() == 0 ? 1 : arraySizes.back();
+}
+
+unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut)
+{
+ ASSERT(nameLengthWithoutArrayIndexOut != nullptr);
+
+ // Strip any trailing array operator and retrieve the subscript
+ size_t open = name.find_last_of('[');
+ if (open != std::string::npos && name.back() == ']')
+ {
+ bool indexIsValidDecimalNumber = true;
+ for (size_t i = open + 1; i < name.length() - 1u; ++i)
+ {
+ if (!isdigit(name[i]))
+ {
+ indexIsValidDecimalNumber = false;
+ break;
+ }
+
+ // Leading zeroes are invalid
+ if ((i == (open + 1)) && (name[i] == '0') && (name[i + 1] != ']'))
+ {
+ indexIsValidDecimalNumber = false;
+ break;
+ }
+ }
+ if (indexIsValidDecimalNumber)
+ {
+ errno = 0; // reset global error flag.
+ unsigned long subscript =
+ strtoul(name.c_str() + open + 1, /*endptr*/ nullptr, /*radix*/ 10);
+
+ // Check if resulting integer is out-of-range or conversion error.
+ if (angle::base::IsValueInRangeForNumericType<uint32_t>(subscript) &&
+ !(subscript == ULONG_MAX && errno == ERANGE) && !(errno != 0 && subscript == 0))
+ {
+ *nameLengthWithoutArrayIndexOut = open;
+ return static_cast<unsigned int>(subscript);
+ }
+ }
+ }
+
+ *nameLengthWithoutArrayIndexOut = name.length();
+ return GL_INVALID_INDEX;
+}
+
+const char *GetGenericErrorMessage(GLenum error)
+{
+ switch (error)
+ {
+ case GL_NO_ERROR:
+ return "";
+ case GL_INVALID_ENUM:
+ return "Invalid enum.";
+ case GL_INVALID_VALUE:
+ return "Invalid value.";
+ case GL_INVALID_OPERATION:
+ return "Invalid operation.";
+ case GL_STACK_OVERFLOW:
+ return "Stack overflow.";
+ case GL_STACK_UNDERFLOW:
+ return "Stack underflow.";
+ case GL_OUT_OF_MEMORY:
+ return "Out of memory.";
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ return "Invalid framebuffer operation.";
+ default:
+ UNREACHABLE();
+ return "Unknown error.";
+ }
+}
+
+unsigned int ElementTypeSize(GLenum elementType)
+{
+ switch (elementType)
+ {
+ case GL_UNSIGNED_BYTE:
+ return sizeof(GLubyte);
+ case GL_UNSIGNED_SHORT:
+ return sizeof(GLushort);
+ case GL_UNSIGNED_INT:
+ return sizeof(GLuint);
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+bool IsMipmapFiltered(GLenum minFilterMode)
+{
+ switch (minFilterMode)
+ {
+ case GL_NEAREST:
+ case GL_LINEAR:
+ return false;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ case GL_LINEAR_MIPMAP_NEAREST:
+ case GL_NEAREST_MIPMAP_LINEAR:
+ case GL_LINEAR_MIPMAP_LINEAR:
+ return true;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+PipelineType GetPipelineType(ShaderType type)
+{
+ switch (type)
+ {
+ case ShaderType::Vertex:
+ case ShaderType::Fragment:
+ case ShaderType::Geometry:
+ return PipelineType::GraphicsPipeline;
+ case ShaderType::Compute:
+ return PipelineType::ComputePipeline;
+ default:
+ UNREACHABLE();
+ return PipelineType::GraphicsPipeline;
+ }
+}
+
+const char *GetDebugMessageSourceString(GLenum source)
+{
+ switch (source)
+ {
+ case GL_DEBUG_SOURCE_API:
+ return "API";
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
+ return "Window System";
+ case GL_DEBUG_SOURCE_SHADER_COMPILER:
+ return "Shader Compiler";
+ case GL_DEBUG_SOURCE_THIRD_PARTY:
+ return "Third Party";
+ case GL_DEBUG_SOURCE_APPLICATION:
+ return "Application";
+ case GL_DEBUG_SOURCE_OTHER:
+ return "Other";
+ default:
+ return "Unknown Source";
+ }
+}
+
+const char *GetDebugMessageTypeString(GLenum type)
+{
+ switch (type)
+ {
+ case GL_DEBUG_TYPE_ERROR:
+ return "Error";
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
+ return "Deprecated behavior";
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
+ return "Undefined behavior";
+ case GL_DEBUG_TYPE_PORTABILITY:
+ return "Portability";
+ case GL_DEBUG_TYPE_PERFORMANCE:
+ return "Performance";
+ case GL_DEBUG_TYPE_OTHER:
+ return "Other";
+ case GL_DEBUG_TYPE_MARKER:
+ return "Marker";
+ default:
+ return "Unknown Type";
+ }
+}
+
+const char *GetDebugMessageSeverityString(GLenum severity)
+{
+ switch (severity)
+ {
+ case GL_DEBUG_SEVERITY_HIGH:
+ return "High";
+ case GL_DEBUG_SEVERITY_MEDIUM:
+ return "Medium";
+ case GL_DEBUG_SEVERITY_LOW:
+ return "Low";
+ case GL_DEBUG_SEVERITY_NOTIFICATION:
+ return "Notification";
+ default:
+ return "Unknown Severity";
+ }
+}
+
+ShaderType GetShaderTypeFromBitfield(size_t singleShaderType)
+{
+ switch (singleShaderType)
+ {
+ case GL_VERTEX_SHADER_BIT:
+ return ShaderType::Vertex;
+ case GL_FRAGMENT_SHADER_BIT:
+ return ShaderType::Fragment;
+ case GL_COMPUTE_SHADER_BIT:
+ return ShaderType::Compute;
+ case GL_GEOMETRY_SHADER_BIT:
+ return ShaderType::Geometry;
+ case GL_TESS_CONTROL_SHADER_BIT:
+ return ShaderType::TessControl;
+ case GL_TESS_EVALUATION_SHADER_BIT:
+ return ShaderType::TessEvaluation;
+ default:
+ return ShaderType::InvalidEnum;
+ }
+}
+
+GLbitfield GetBitfieldFromShaderType(ShaderType shaderType)
+{
+ switch (shaderType)
+ {
+ case ShaderType::Vertex:
+ return GL_VERTEX_SHADER_BIT;
+ case ShaderType::Fragment:
+ return GL_FRAGMENT_SHADER_BIT;
+ case ShaderType::Compute:
+ return GL_COMPUTE_SHADER_BIT;
+ case ShaderType::Geometry:
+ return GL_GEOMETRY_SHADER_BIT;
+ case ShaderType::TessControl:
+ return GL_TESS_CONTROL_SHADER_BIT;
+ case ShaderType::TessEvaluation:
+ return GL_TESS_EVALUATION_SHADER_BIT;
+ default:
+ UNREACHABLE();
+ return GL_ZERO;
+ }
+}
+
+bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType)
+{
+ switch (shaderType)
+ {
+ case ShaderType::Vertex:
+ case ShaderType::Geometry:
+ case ShaderType::TessEvaluation:
+ return true;
+ default:
+ return false;
+ }
+}
+
+ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes)
+{
+ shaderTypes.reset(ShaderType::Fragment);
+ shaderTypes.reset(ShaderType::Compute);
+ return shaderTypes.any() ? shaderTypes.last() : ShaderType::InvalidEnum;
+}
+} // namespace gl
+
+namespace egl
+{
+static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
+ "Unexpected EGL cube map enum value.");
+static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
+ "Unexpected EGL cube map enum value.");
+static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
+ "Unexpected EGL cube map enum value.");
+static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
+ "Unexpected EGL cube map enum value.");
+static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
+ "Unexpected EGL cube map enum value.");
+
+bool IsCubeMapTextureTarget(EGLenum target)
+{
+ return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
+}
+
+size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
+{
+ ASSERT(IsCubeMapTextureTarget(target));
+ return target - static_cast<size_t>(FirstCubeMapTextureTarget);
+}
+
+EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
+{
+ ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
+ return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
+}
+
+bool IsTextureTarget(EGLenum target)
+{
+ switch (target)
+ {
+ case EGL_GL_TEXTURE_2D_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
+ case EGL_GL_TEXTURE_3D_KHR:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool IsRenderbufferTarget(EGLenum target)
+{
+ return target == EGL_GL_RENDERBUFFER_KHR;
+}
+
+bool IsExternalImageTarget(EGLenum target)
+{
+ switch (target)
+ {
+ case EGL_NATIVE_BUFFER_ANDROID:
+ case EGL_D3D11_TEXTURE_ANGLE:
+ case EGL_LINUX_DMA_BUF_EXT:
+ case EGL_METAL_TEXTURE_ANGLE:
+ case EGL_VULKAN_IMAGE_ANGLE:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+const char *GetGenericErrorMessage(EGLint error)
+{
+ switch (error)
+ {
+ case EGL_SUCCESS:
+ return "";
+ case EGL_NOT_INITIALIZED:
+ return "Not initialized.";
+ case EGL_BAD_ACCESS:
+ return "Bad access.";
+ case EGL_BAD_ALLOC:
+ return "Bad allocation.";
+ case EGL_BAD_ATTRIBUTE:
+ return "Bad attribute.";
+ case EGL_BAD_CONFIG:
+ return "Bad config.";
+ case EGL_BAD_CONTEXT:
+ return "Bad context.";
+ case EGL_BAD_CURRENT_SURFACE:
+ return "Bad current surface.";
+ case EGL_BAD_DISPLAY:
+ return "Bad display.";
+ case EGL_BAD_MATCH:
+ return "Bad match.";
+ case EGL_BAD_NATIVE_WINDOW:
+ return "Bad native window.";
+ case EGL_BAD_NATIVE_PIXMAP:
+ return "Bad native pixmap.";
+ case EGL_BAD_PARAMETER:
+ return "Bad parameter.";
+ case EGL_BAD_SURFACE:
+ return "Bad surface.";
+ case EGL_CONTEXT_LOST:
+ return "Context lost.";
+ case EGL_BAD_STREAM_KHR:
+ return "Bad stream.";
+ case EGL_BAD_STATE_KHR:
+ return "Bad state.";
+ case EGL_BAD_DEVICE_EXT:
+ return "Bad device.";
+ default:
+ UNREACHABLE();
+ return "Unknown error.";
+ }
+}
+
+} // namespace egl
+
+namespace egl_gl
+{
+GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
+{
+ return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
+}
+} // namespace egl_gl
+
+namespace gl_egl
+{
+EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType)
+{
+ switch (glComponentType)
+ {
+ case GL_FLOAT:
+ return EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
+
+ case GL_UNSIGNED_NORMALIZED:
+ return EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
+
+ default:
+ UNREACHABLE();
+ return EGL_NONE;
+ }
+}
+
+EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle)
+{
+ return reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(handle));
+}
+
+} // namespace gl_egl
+
+namespace angle
+{
+bool IsDrawEntryPoint(EntryPoint entryPoint)
+{
+ switch (entryPoint)
+ {
+ case EntryPoint::GLDrawArrays:
+ case EntryPoint::GLDrawArraysIndirect:
+ case EntryPoint::GLDrawArraysInstanced:
+ case EntryPoint::GLDrawArraysInstancedANGLE:
+ case EntryPoint::GLDrawArraysInstancedBaseInstance:
+ case EntryPoint::GLDrawArraysInstancedBaseInstanceANGLE:
+ case EntryPoint::GLDrawArraysInstancedEXT:
+ case EntryPoint::GLDrawElements:
+ case EntryPoint::GLDrawElementsBaseVertex:
+ case EntryPoint::GLDrawElementsBaseVertexEXT:
+ case EntryPoint::GLDrawElementsBaseVertexOES:
+ case EntryPoint::GLDrawElementsIndirect:
+ case EntryPoint::GLDrawElementsInstanced:
+ case EntryPoint::GLDrawElementsInstancedANGLE:
+ case EntryPoint::GLDrawElementsInstancedBaseInstance:
+ case EntryPoint::GLDrawElementsInstancedBaseVertex:
+ case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstance:
+ case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstanceANGLE:
+ case EntryPoint::GLDrawElementsInstancedBaseVertexEXT:
+ case EntryPoint::GLDrawElementsInstancedBaseVertexOES:
+ case EntryPoint::GLDrawElementsInstancedEXT:
+ case EntryPoint::GLDrawPixels:
+ case EntryPoint::GLDrawRangeElements:
+ case EntryPoint::GLDrawRangeElementsBaseVertex:
+ case EntryPoint::GLDrawRangeElementsBaseVertexEXT:
+ case EntryPoint::GLDrawRangeElementsBaseVertexOES:
+ case EntryPoint::GLDrawTexfOES:
+ case EntryPoint::GLDrawTexfvOES:
+ case EntryPoint::GLDrawTexiOES:
+ case EntryPoint::GLDrawTexivOES:
+ case EntryPoint::GLDrawTexsOES:
+ case EntryPoint::GLDrawTexsvOES:
+ case EntryPoint::GLDrawTexxOES:
+ case EntryPoint::GLDrawTexxvOES:
+ case EntryPoint::GLDrawTransformFeedback:
+ case EntryPoint::GLDrawTransformFeedbackInstanced:
+ case EntryPoint::GLDrawTransformFeedbackStream:
+ case EntryPoint::GLDrawTransformFeedbackStreamInstanced:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsDispatchEntryPoint(EntryPoint entryPoint)
+{
+ switch (entryPoint)
+ {
+ case EntryPoint::GLDispatchCompute:
+ case EntryPoint::GLDispatchComputeIndirect:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsClearEntryPoint(EntryPoint entryPoint)
+{
+ switch (entryPoint)
+ {
+ case EntryPoint::GLClear:
+ case EntryPoint::GLClearBufferfi:
+ case EntryPoint::GLClearBufferfv:
+ case EntryPoint::GLClearBufferiv:
+ case EntryPoint::GLClearBufferuiv:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsQueryEntryPoint(EntryPoint entryPoint)
+{
+ switch (entryPoint)
+ {
+ case EntryPoint::GLBeginQuery:
+ case EntryPoint::GLBeginQueryEXT:
+ case EntryPoint::GLBeginQueryIndexed:
+ case EntryPoint::GLEndQuery:
+ case EntryPoint::GLEndQueryEXT:
+ case EntryPoint::GLEndQueryIndexed:
+ return true;
+ default:
+ return false;
+ }
+}
+} // namespace angle
+
+#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
+void writeFile(const char *path, const void *content, size_t size)
+{
+ FILE *file = fopen(path, "w");
+ if (!file)
+ {
+ UNREACHABLE();
+ return;
+ }
+
+ fwrite(content, sizeof(char), size, file);
+ fclose(file);
+}
+#endif // !ANGLE_ENABLE_WINDOWS_UWP
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+
+// Causes the thread to relinquish the remainder of its time slice to any
+// other thread that is ready to run.If there are no other threads ready
+// to run, the function returns immediately, and the thread continues execution.
+void ScheduleYield()
+{
+ Sleep(0);
+}
+
+#endif