| // |
| // Copyright (c) 2002-2013 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 "common/mathutil.h" |
| #include "common/platform.h" |
| |
| #include <set> |
| |
| #if defined(ANGLE_ENABLE_WINDOWS_STORE) |
| # include <wrl.h> |
| # include <wrl/wrappers/corewrappers.h> |
| # include <windows.applicationmodel.core.h> |
| # include <windows.graphics.display.h> |
| #endif |
| |
| 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_3D: |
| case GL_SAMPLER_CUBE: |
| case GL_SAMPLER_2D_ARRAY: |
| case GL_INT_SAMPLER_2D: |
| case GL_INT_SAMPLER_3D: |
| case GL_INT_SAMPLER_CUBE: |
| case GL_INT_SAMPLER_2D_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_SAMPLER_2D_SHADOW: |
| case GL_SAMPLER_CUBE_SHADOW: |
| case GL_SAMPLER_2D_ARRAY_SHADOW: |
| case GL_INT_VEC2: |
| case GL_INT_VEC3: |
| case GL_INT_VEC4: |
| 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); |
| } |
| |
| 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: |
| case GL_STRUCT_ANGLEX: |
| 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_ARB: |
| case GL_INT_SAMPLER_2D: |
| case GL_INT_SAMPLER_3D: |
| case GL_INT_SAMPLER_CUBE: |
| case GL_INT_SAMPLER_2D_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_SAMPLER_2D_SHADOW: |
| case GL_SAMPLER_CUBE_SHADOW: |
| case GL_SAMPLER_2D_ARRAY_SHADOW: |
| 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: |
| case GL_STRUCT_ANGLEX: |
| 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_INT_SAMPLER_2D: |
| case GL_INT_SAMPLER_3D: |
| case GL_INT_SAMPLER_CUBE: |
| case GL_INT_SAMPLER_2D_ARRAY: |
| case GL_SAMPLER_EXTERNAL_OES: |
| case GL_SAMPLER_2D_RECT_ARB: |
| 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_SAMPLER_2D_SHADOW: |
| case GL_SAMPLER_CUBE_SHADOW: |
| case GL_SAMPLER_2D_ARRAY_SHADOW: |
| 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_INT_SAMPLER_2D: |
| case GL_INT_SAMPLER_3D: |
| case GL_INT_SAMPLER_CUBE: |
| case GL_INT_SAMPLER_2D_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_SAMPLER_2D_SHADOW: |
| case GL_SAMPLER_CUBE_SHADOW: |
| case GL_SAMPLER_2D_ARRAY_SHADOW: |
| return true; |
| } |
| |
| return false; |
| } |
| |
| GLenum SamplerTypeToTextureType(GLenum samplerType) |
| { |
| switch (samplerType) |
| { |
| case GL_SAMPLER_2D: |
| case GL_INT_SAMPLER_2D: |
| case GL_UNSIGNED_INT_SAMPLER_2D: |
| case GL_SAMPLER_2D_SHADOW: |
| return GL_TEXTURE_2D; |
| |
| case GL_SAMPLER_CUBE: |
| case GL_INT_SAMPLER_CUBE: |
| case GL_UNSIGNED_INT_SAMPLER_CUBE: |
| case GL_SAMPLER_CUBE_SHADOW: |
| return GL_TEXTURE_CUBE_MAP; |
| |
| case GL_SAMPLER_2D_ARRAY: |
| case GL_INT_SAMPLER_2D_ARRAY: |
| case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: |
| case GL_SAMPLER_2D_ARRAY_SHADOW: |
| return GL_TEXTURE_2D_ARRAY; |
| |
| case GL_SAMPLER_3D: |
| case GL_INT_SAMPLER_3D: |
| case GL_UNSIGNED_INT_SAMPLER_3D: |
| return GL_TEXTURE_3D; |
| |
| default: |
| UNREACHABLE(); |
| return 0; |
| } |
| } |
| |
| 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; |
| } |
| |
| static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1, "Unexpected GL cube map enum value."); |
| static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2, "Unexpected GL cube map enum value."); |
| static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3, "Unexpected GL cube map enum value."); |
| static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4, "Unexpected GL cube map enum value."); |
| static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5, "Unexpected GL cube map enum value."); |
| |
| bool IsCubeMapTextureTarget(GLenum target) |
| { |
| return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget); |
| } |
| |
| size_t CubeMapTextureTargetToLayerIndex(GLenum target) |
| { |
| ASSERT(IsCubeMapTextureTarget(target)); |
| return target - static_cast<size_t>(FirstCubeMapTextureTarget); |
| } |
| |
| GLenum LayerIndexToCubeMapTextureTarget(size_t index) |
| { |
| ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget)); |
| return FirstCubeMapTextureTarget + static_cast<GLenum>(index); |
| } |
| |
| template <class IndexType> |
| static RangeUI ComputeTypedIndexRange(const IndexType *indices, GLsizei count) |
| { |
| ASSERT(count > 0); |
| IndexType minIndex = indices[0]; |
| IndexType maxIndex = indices[0]; |
| |
| for (GLsizei i = 1; i < count; i++) |
| { |
| if (minIndex > indices[i]) minIndex = indices[i]; |
| if (maxIndex < indices[i]) maxIndex = indices[i]; |
| } |
| |
| return RangeUI(static_cast<GLuint>(minIndex), static_cast<GLuint>(maxIndex)); |
| } |
| |
| RangeUI ComputeIndexRange(GLenum indexType, const GLvoid *indices, GLsizei count) |
| { |
| switch (indexType) |
| { |
| case GL_UNSIGNED_BYTE: return ComputeTypedIndexRange(static_cast<const GLubyte*>(indices), count); |
| case GL_UNSIGNED_SHORT: return ComputeTypedIndexRange(static_cast<const GLushort*>(indices), count); |
| case GL_UNSIGNED_INT: return ComputeTypedIndexRange(static_cast<const GLuint*>(indices), count); |
| default: UNREACHABLE(); return RangeUI(0, 0); |
| } |
| } |
| |
| bool IsTriangleMode(GLenum drawMode) |
| { |
| switch (drawMode) |
| { |
| case GL_TRIANGLES: |
| case GL_TRIANGLE_FAN: |
| case GL_TRIANGLE_STRIP: |
| return true; |
| case GL_POINTS: |
| case GL_LINES: |
| case GL_LINE_LOOP: |
| case GL_LINE_STRIP: |
| return false; |
| default: UNREACHABLE(); |
| } |
| |
| 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_ARB: |
| case GL_SAMPLER_2D_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_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_SAMPLER_2D_SHADOW: |
| case GL_SAMPLER_2D_ARRAY_SHADOW: |
| case GL_SAMPLER_CUBE_SHADOW: |
| return 6; |
| |
| default: |
| UNREACHABLE(); |
| return 0; |
| } |
| } |
| |
| std::string ParseUniformName(const std::string &name, size_t *outSubscript) |
| { |
| // Strip any trailing array operator and retrieve the subscript |
| size_t open = name.find_last_of('['); |
| size_t close = name.find_last_of(']'); |
| bool hasIndex = (open != std::string::npos) && (close == name.length() - 1); |
| if (!hasIndex) |
| { |
| if (outSubscript) |
| { |
| *outSubscript = GL_INVALID_INDEX; |
| } |
| return name; |
| } |
| |
| if (outSubscript) |
| { |
| int index = atoi(name.substr(open + 1).c_str()); |
| if (index >= 0) |
| { |
| *outSubscript = index; |
| } |
| else |
| { |
| *outSubscript = GL_INVALID_INDEX; |
| } |
| } |
| |
| return name.substr(0, open); |
| } |
| |
| } |
| |
| 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; |
| } |
| } |
| |
| namespace egl_gl |
| { |
| GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget) |
| { |
| ASSERT(egl::IsCubeMapTextureTarget(eglTarget)); |
| return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget)); |
| } |
| |
| GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget) |
| { |
| switch (eglTarget) |
| { |
| case EGL_GL_TEXTURE_2D_KHR: |
| return GL_TEXTURE_2D; |
| |
| 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: |
| return EGLCubeMapTargetToGLCubeMapTarget(eglTarget); |
| |
| case EGL_GL_TEXTURE_3D_KHR: |
| return GL_TEXTURE_3D; |
| |
| default: |
| UNREACHABLE(); |
| return GL_NONE; |
| } |
| } |
| |
| GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer) |
| { |
| return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer)); |
| } |
| } |
| |
| #if !defined(ANGLE_ENABLE_WINDOWS_STORE) |
| std::string getTempPath() |
| { |
| #ifdef ANGLE_PLATFORM_WINDOWS |
| char path[MAX_PATH]; |
| DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path); |
| if (pathLen == 0) |
| { |
| UNREACHABLE(); |
| return std::string(); |
| } |
| |
| UINT unique = GetTempFileNameA(path, "sh", 0, path); |
| if (unique == 0) |
| { |
| UNREACHABLE(); |
| return std::string(); |
| } |
| |
| return path; |
| #else |
| UNIMPLEMENTED(); |
| return ""; |
| #endif |
| } |
| |
| 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_STORE |
| |
| #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() |
| { |
| #if defined(ANGLE_ENABLE_WINDOWS_STORE) |
| // This implementation of Sleep exists because it is not available prior to Update 4. |
| static HANDLE singletonEvent = nullptr; |
| HANDLE sleepEvent = singletonEvent; |
| if (!sleepEvent) |
| { |
| sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); |
| |
| if (!sleepEvent) |
| return; |
| |
| HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr); |
| |
| if (previousEvent) |
| { |
| // Back out if multiple threads try to demand create at the same time. |
| CloseHandle(sleepEvent); |
| sleepEvent = previousEvent; |
| } |
| } |
| |
| // Emulate sleep by waiting with timeout on an event that is never signalled. |
| WaitForSingleObjectEx(sleepEvent, 0, false); |
| #else |
| if (SwitchToThread() == FALSE) |
| { |
| Sleep(1); |
| } |
| #endif |
| } |
| |
| #endif |