• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.cpp: Conversion functions and other utility routines.
8 
9 #include "common/utilities.h"
10 #include "GLES3/gl3.h"
11 #include "common/mathutil.h"
12 #include "common/platform.h"
13 
14 #include <set>
15 
16 #if defined(ANGLE_ENABLE_WINDOWS_UWP)
17 #    include <windows.applicationmodel.core.h>
18 #    include <windows.graphics.display.h>
19 #    include <wrl.h>
20 #    include <wrl/wrappers/corewrappers.h>
21 #endif
22 
23 namespace
24 {
25 
26 template <class IndexType>
ComputeTypedIndexRange(const IndexType * indices,size_t count,bool primitiveRestartEnabled,GLuint primitiveRestartIndex)27 gl::IndexRange ComputeTypedIndexRange(const IndexType *indices,
28                                       size_t count,
29                                       bool primitiveRestartEnabled,
30                                       GLuint primitiveRestartIndex)
31 {
32     ASSERT(count > 0);
33 
34     IndexType minIndex                = 0;
35     IndexType maxIndex                = 0;
36     size_t nonPrimitiveRestartIndices = 0;
37 
38     if (primitiveRestartEnabled)
39     {
40         // Find the first non-primitive restart index to initialize the min and max values
41         size_t i = 0;
42         for (; i < count; i++)
43         {
44             if (indices[i] != primitiveRestartIndex)
45             {
46                 minIndex = indices[i];
47                 maxIndex = indices[i];
48                 nonPrimitiveRestartIndices++;
49                 break;
50             }
51         }
52 
53         // Loop over the rest of the indices
54         for (; i < count; i++)
55         {
56             if (indices[i] != primitiveRestartIndex)
57             {
58                 if (minIndex > indices[i])
59                 {
60                     minIndex = indices[i];
61                 }
62                 if (maxIndex < indices[i])
63                 {
64                     maxIndex = indices[i];
65                 }
66                 nonPrimitiveRestartIndices++;
67             }
68         }
69     }
70     else
71     {
72         minIndex                   = indices[0];
73         maxIndex                   = indices[0];
74         nonPrimitiveRestartIndices = count;
75 
76         for (size_t i = 1; i < count; i++)
77         {
78             if (minIndex > indices[i])
79             {
80                 minIndex = indices[i];
81             }
82             if (maxIndex < indices[i])
83             {
84                 maxIndex = indices[i];
85             }
86         }
87     }
88 
89     return gl::IndexRange(static_cast<size_t>(minIndex), static_cast<size_t>(maxIndex),
90                           nonPrimitiveRestartIndices);
91 }
92 
93 }  // anonymous namespace
94 
95 namespace gl
96 {
97 
VariableComponentCount(GLenum type)98 int VariableComponentCount(GLenum type)
99 {
100     return VariableRowCount(type) * VariableColumnCount(type);
101 }
102 
VariableComponentType(GLenum type)103 GLenum VariableComponentType(GLenum type)
104 {
105     switch (type)
106     {
107         case GL_BOOL:
108         case GL_BOOL_VEC2:
109         case GL_BOOL_VEC3:
110         case GL_BOOL_VEC4:
111             return GL_BOOL;
112         case GL_FLOAT:
113         case GL_FLOAT_VEC2:
114         case GL_FLOAT_VEC3:
115         case GL_FLOAT_VEC4:
116         case GL_FLOAT_MAT2:
117         case GL_FLOAT_MAT3:
118         case GL_FLOAT_MAT4:
119         case GL_FLOAT_MAT2x3:
120         case GL_FLOAT_MAT3x2:
121         case GL_FLOAT_MAT2x4:
122         case GL_FLOAT_MAT4x2:
123         case GL_FLOAT_MAT3x4:
124         case GL_FLOAT_MAT4x3:
125             return GL_FLOAT;
126         case GL_INT:
127         case GL_SAMPLER_2D:
128         case GL_SAMPLER_2D_RECT_ANGLE:
129         case GL_SAMPLER_3D:
130         case GL_SAMPLER_CUBE:
131         case GL_SAMPLER_2D_ARRAY:
132         case GL_SAMPLER_EXTERNAL_OES:
133         case GL_SAMPLER_2D_MULTISAMPLE:
134         case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
135         case GL_INT_SAMPLER_2D:
136         case GL_INT_SAMPLER_3D:
137         case GL_INT_SAMPLER_CUBE:
138         case GL_INT_SAMPLER_2D_ARRAY:
139         case GL_INT_SAMPLER_2D_MULTISAMPLE:
140         case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
141         case GL_UNSIGNED_INT_SAMPLER_2D:
142         case GL_UNSIGNED_INT_SAMPLER_3D:
143         case GL_UNSIGNED_INT_SAMPLER_CUBE:
144         case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
145         case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
146         case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
147         case GL_SAMPLER_2D_SHADOW:
148         case GL_SAMPLER_CUBE_SHADOW:
149         case GL_SAMPLER_2D_ARRAY_SHADOW:
150         case GL_INT_VEC2:
151         case GL_INT_VEC3:
152         case GL_INT_VEC4:
153         case GL_IMAGE_2D:
154         case GL_INT_IMAGE_2D:
155         case GL_UNSIGNED_INT_IMAGE_2D:
156         case GL_IMAGE_3D:
157         case GL_INT_IMAGE_3D:
158         case GL_UNSIGNED_INT_IMAGE_3D:
159         case GL_IMAGE_2D_ARRAY:
160         case GL_INT_IMAGE_2D_ARRAY:
161         case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
162         case GL_IMAGE_CUBE:
163         case GL_INT_IMAGE_CUBE:
164         case GL_UNSIGNED_INT_IMAGE_CUBE:
165         case GL_IMAGE_CUBE_MAP_ARRAY:
166         case GL_INT_IMAGE_CUBE_MAP_ARRAY:
167         case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
168         case GL_UNSIGNED_INT_ATOMIC_COUNTER:
169         case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
170             return GL_INT;
171         case GL_UNSIGNED_INT:
172         case GL_UNSIGNED_INT_VEC2:
173         case GL_UNSIGNED_INT_VEC3:
174         case GL_UNSIGNED_INT_VEC4:
175             return GL_UNSIGNED_INT;
176         default:
177             UNREACHABLE();
178     }
179 
180     return GL_NONE;
181 }
182 
VariableComponentSize(GLenum type)183 size_t VariableComponentSize(GLenum type)
184 {
185     switch (type)
186     {
187         case GL_BOOL:
188             return sizeof(GLint);
189         case GL_FLOAT:
190             return sizeof(GLfloat);
191         case GL_INT:
192             return sizeof(GLint);
193         case GL_UNSIGNED_INT:
194             return sizeof(GLuint);
195         default:
196             UNREACHABLE();
197     }
198 
199     return 0;
200 }
201 
VariableInternalSize(GLenum type)202 size_t VariableInternalSize(GLenum type)
203 {
204     // Expanded to 4-element vectors
205     return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
206 }
207 
VariableExternalSize(GLenum type)208 size_t VariableExternalSize(GLenum type)
209 {
210     return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
211 }
212 
GetGLSLTypeString(GLenum type)213 std::string GetGLSLTypeString(GLenum type)
214 {
215     switch (type)
216     {
217         case GL_BOOL:
218             return "bool";
219         case GL_INT:
220             return "int";
221         case GL_UNSIGNED_INT:
222             return "uint";
223         case GL_FLOAT:
224             return "float";
225         case GL_BOOL_VEC2:
226             return "bvec2";
227         case GL_BOOL_VEC3:
228             return "bvec3";
229         case GL_BOOL_VEC4:
230             return "bvec4";
231         case GL_INT_VEC2:
232             return "ivec2";
233         case GL_INT_VEC3:
234             return "ivec3";
235         case GL_INT_VEC4:
236             return "ivec4";
237         case GL_FLOAT_VEC2:
238             return "vec2";
239         case GL_FLOAT_VEC3:
240             return "vec3";
241         case GL_FLOAT_VEC4:
242             return "vec4";
243         case GL_UNSIGNED_INT_VEC2:
244             return "uvec2";
245         case GL_UNSIGNED_INT_VEC3:
246             return "uvec3";
247         case GL_UNSIGNED_INT_VEC4:
248             return "uvec4";
249         case GL_FLOAT_MAT2:
250             return "mat2";
251         case GL_FLOAT_MAT3:
252             return "mat3";
253         case GL_FLOAT_MAT4:
254             return "mat4";
255         default:
256             UNREACHABLE();
257             return nullptr;
258     }
259 }
260 
VariableBoolVectorType(GLenum type)261 GLenum VariableBoolVectorType(GLenum type)
262 {
263     switch (type)
264     {
265         case GL_FLOAT:
266         case GL_INT:
267         case GL_UNSIGNED_INT:
268             return GL_BOOL;
269         case GL_FLOAT_VEC2:
270         case GL_INT_VEC2:
271         case GL_UNSIGNED_INT_VEC2:
272             return GL_BOOL_VEC2;
273         case GL_FLOAT_VEC3:
274         case GL_INT_VEC3:
275         case GL_UNSIGNED_INT_VEC3:
276             return GL_BOOL_VEC3;
277         case GL_FLOAT_VEC4:
278         case GL_INT_VEC4:
279         case GL_UNSIGNED_INT_VEC4:
280             return GL_BOOL_VEC4;
281 
282         default:
283             UNREACHABLE();
284             return GL_NONE;
285     }
286 }
287 
VariableRowCount(GLenum type)288 int VariableRowCount(GLenum type)
289 {
290     switch (type)
291     {
292         case GL_NONE:
293             return 0;
294         case GL_BOOL:
295         case GL_FLOAT:
296         case GL_INT:
297         case GL_UNSIGNED_INT:
298         case GL_BOOL_VEC2:
299         case GL_FLOAT_VEC2:
300         case GL_INT_VEC2:
301         case GL_UNSIGNED_INT_VEC2:
302         case GL_BOOL_VEC3:
303         case GL_FLOAT_VEC3:
304         case GL_INT_VEC3:
305         case GL_UNSIGNED_INT_VEC3:
306         case GL_BOOL_VEC4:
307         case GL_FLOAT_VEC4:
308         case GL_INT_VEC4:
309         case GL_UNSIGNED_INT_VEC4:
310         case GL_SAMPLER_2D:
311         case GL_SAMPLER_3D:
312         case GL_SAMPLER_CUBE:
313         case GL_SAMPLER_2D_ARRAY:
314         case GL_SAMPLER_EXTERNAL_OES:
315         case GL_SAMPLER_2D_RECT_ANGLE:
316         case GL_SAMPLER_2D_MULTISAMPLE:
317         case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
318         case GL_SAMPLER_CUBE_MAP_ARRAY:
319         case GL_INT_SAMPLER_2D:
320         case GL_INT_SAMPLER_3D:
321         case GL_INT_SAMPLER_CUBE:
322         case GL_INT_SAMPLER_2D_ARRAY:
323         case GL_INT_SAMPLER_2D_MULTISAMPLE:
324         case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
325         case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
326         case GL_UNSIGNED_INT_SAMPLER_2D:
327         case GL_UNSIGNED_INT_SAMPLER_3D:
328         case GL_UNSIGNED_INT_SAMPLER_CUBE:
329         case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
330         case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
331         case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
332         case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
333         case GL_SAMPLER_2D_SHADOW:
334         case GL_SAMPLER_CUBE_SHADOW:
335         case GL_SAMPLER_2D_ARRAY_SHADOW:
336         case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
337         case GL_IMAGE_2D:
338         case GL_INT_IMAGE_2D:
339         case GL_UNSIGNED_INT_IMAGE_2D:
340         case GL_IMAGE_2D_ARRAY:
341         case GL_INT_IMAGE_2D_ARRAY:
342         case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
343         case GL_IMAGE_3D:
344         case GL_INT_IMAGE_3D:
345         case GL_UNSIGNED_INT_IMAGE_3D:
346         case GL_IMAGE_CUBE:
347         case GL_INT_IMAGE_CUBE:
348         case GL_UNSIGNED_INT_IMAGE_CUBE:
349         case GL_UNSIGNED_INT_ATOMIC_COUNTER:
350         case GL_IMAGE_CUBE_MAP_ARRAY:
351         case GL_INT_IMAGE_CUBE_MAP_ARRAY:
352         case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
353         case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
354             return 1;
355         case GL_FLOAT_MAT2:
356         case GL_FLOAT_MAT3x2:
357         case GL_FLOAT_MAT4x2:
358             return 2;
359         case GL_FLOAT_MAT3:
360         case GL_FLOAT_MAT2x3:
361         case GL_FLOAT_MAT4x3:
362             return 3;
363         case GL_FLOAT_MAT4:
364         case GL_FLOAT_MAT2x4:
365         case GL_FLOAT_MAT3x4:
366             return 4;
367         default:
368             UNREACHABLE();
369     }
370 
371     return 0;
372 }
373 
VariableColumnCount(GLenum type)374 int VariableColumnCount(GLenum type)
375 {
376     switch (type)
377     {
378         case GL_NONE:
379             return 0;
380         case GL_BOOL:
381         case GL_FLOAT:
382         case GL_INT:
383         case GL_UNSIGNED_INT:
384         case GL_SAMPLER_2D:
385         case GL_SAMPLER_3D:
386         case GL_SAMPLER_CUBE:
387         case GL_SAMPLER_2D_ARRAY:
388         case GL_SAMPLER_2D_MULTISAMPLE:
389         case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
390         case GL_SAMPLER_CUBE_MAP_ARRAY:
391         case GL_INT_SAMPLER_2D:
392         case GL_INT_SAMPLER_3D:
393         case GL_INT_SAMPLER_CUBE:
394         case GL_INT_SAMPLER_2D_ARRAY:
395         case GL_INT_SAMPLER_2D_MULTISAMPLE:
396         case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
397         case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
398         case GL_SAMPLER_EXTERNAL_OES:
399         case GL_SAMPLER_2D_RECT_ANGLE:
400         case GL_UNSIGNED_INT_SAMPLER_2D:
401         case GL_UNSIGNED_INT_SAMPLER_3D:
402         case GL_UNSIGNED_INT_SAMPLER_CUBE:
403         case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
404         case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
405         case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
406         case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
407         case GL_SAMPLER_2D_SHADOW:
408         case GL_SAMPLER_CUBE_SHADOW:
409         case GL_SAMPLER_2D_ARRAY_SHADOW:
410         case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
411         case GL_IMAGE_2D:
412         case GL_INT_IMAGE_2D:
413         case GL_UNSIGNED_INT_IMAGE_2D:
414         case GL_IMAGE_3D:
415         case GL_INT_IMAGE_3D:
416         case GL_UNSIGNED_INT_IMAGE_3D:
417         case GL_IMAGE_2D_ARRAY:
418         case GL_INT_IMAGE_2D_ARRAY:
419         case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
420         case GL_IMAGE_CUBE_MAP_ARRAY:
421         case GL_INT_IMAGE_CUBE_MAP_ARRAY:
422         case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
423         case GL_IMAGE_CUBE:
424         case GL_INT_IMAGE_CUBE:
425         case GL_UNSIGNED_INT_IMAGE_CUBE:
426         case GL_UNSIGNED_INT_ATOMIC_COUNTER:
427         case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
428             return 1;
429         case GL_BOOL_VEC2:
430         case GL_FLOAT_VEC2:
431         case GL_INT_VEC2:
432         case GL_UNSIGNED_INT_VEC2:
433         case GL_FLOAT_MAT2:
434         case GL_FLOAT_MAT2x3:
435         case GL_FLOAT_MAT2x4:
436             return 2;
437         case GL_BOOL_VEC3:
438         case GL_FLOAT_VEC3:
439         case GL_INT_VEC3:
440         case GL_UNSIGNED_INT_VEC3:
441         case GL_FLOAT_MAT3:
442         case GL_FLOAT_MAT3x2:
443         case GL_FLOAT_MAT3x4:
444             return 3;
445         case GL_BOOL_VEC4:
446         case GL_FLOAT_VEC4:
447         case GL_INT_VEC4:
448         case GL_UNSIGNED_INT_VEC4:
449         case GL_FLOAT_MAT4:
450         case GL_FLOAT_MAT4x2:
451         case GL_FLOAT_MAT4x3:
452             return 4;
453         default:
454             UNREACHABLE();
455     }
456 
457     return 0;
458 }
459 
IsSamplerType(GLenum type)460 bool IsSamplerType(GLenum type)
461 {
462     switch (type)
463     {
464         case GL_SAMPLER_2D:
465         case GL_SAMPLER_3D:
466         case GL_SAMPLER_CUBE:
467         case GL_SAMPLER_2D_ARRAY:
468         case GL_SAMPLER_EXTERNAL_OES:
469         case GL_SAMPLER_2D_MULTISAMPLE:
470         case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
471         case GL_SAMPLER_CUBE_MAP_ARRAY:
472         case GL_SAMPLER_2D_RECT_ANGLE:
473         case GL_INT_SAMPLER_2D:
474         case GL_INT_SAMPLER_3D:
475         case GL_INT_SAMPLER_CUBE:
476         case GL_INT_SAMPLER_2D_ARRAY:
477         case GL_INT_SAMPLER_2D_MULTISAMPLE:
478         case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
479         case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
480         case GL_UNSIGNED_INT_SAMPLER_2D:
481         case GL_UNSIGNED_INT_SAMPLER_3D:
482         case GL_UNSIGNED_INT_SAMPLER_CUBE:
483         case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
484         case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
485         case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
486         case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
487         case GL_SAMPLER_2D_SHADOW:
488         case GL_SAMPLER_CUBE_SHADOW:
489         case GL_SAMPLER_2D_ARRAY_SHADOW:
490         case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
491         case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
492             return true;
493     }
494 
495     return false;
496 }
497 
IsSamplerCubeType(GLenum type)498 bool IsSamplerCubeType(GLenum type)
499 {
500     switch (type)
501     {
502         case GL_SAMPLER_CUBE:
503         case GL_INT_SAMPLER_CUBE:
504         case GL_UNSIGNED_INT_SAMPLER_CUBE:
505         case GL_SAMPLER_CUBE_SHADOW:
506             return true;
507     }
508 
509     return false;
510 }
511 
IsImageType(GLenum type)512 bool IsImageType(GLenum type)
513 {
514     switch (type)
515     {
516         case GL_IMAGE_2D:
517         case GL_INT_IMAGE_2D:
518         case GL_UNSIGNED_INT_IMAGE_2D:
519         case GL_IMAGE_3D:
520         case GL_INT_IMAGE_3D:
521         case GL_UNSIGNED_INT_IMAGE_3D:
522         case GL_IMAGE_2D_ARRAY:
523         case GL_INT_IMAGE_2D_ARRAY:
524         case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
525         case GL_IMAGE_CUBE_MAP_ARRAY:
526         case GL_INT_IMAGE_CUBE_MAP_ARRAY:
527         case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
528         case GL_IMAGE_CUBE:
529         case GL_INT_IMAGE_CUBE:
530         case GL_UNSIGNED_INT_IMAGE_CUBE:
531             return true;
532     }
533     return false;
534 }
535 
IsImage2DType(GLenum type)536 bool IsImage2DType(GLenum type)
537 {
538     switch (type)
539     {
540         case GL_IMAGE_2D:
541         case GL_INT_IMAGE_2D:
542         case GL_UNSIGNED_INT_IMAGE_2D:
543             return true;
544         case GL_IMAGE_3D:
545         case GL_INT_IMAGE_3D:
546         case GL_UNSIGNED_INT_IMAGE_3D:
547         case GL_IMAGE_2D_ARRAY:
548         case GL_INT_IMAGE_2D_ARRAY:
549         case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
550         case GL_IMAGE_CUBE_MAP_ARRAY:
551         case GL_INT_IMAGE_CUBE_MAP_ARRAY:
552         case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
553         case GL_IMAGE_CUBE:
554         case GL_INT_IMAGE_CUBE:
555         case GL_UNSIGNED_INT_IMAGE_CUBE:
556             return false;
557         default:
558             UNREACHABLE();
559             return false;
560     }
561 }
562 
IsAtomicCounterType(GLenum type)563 bool IsAtomicCounterType(GLenum type)
564 {
565     return type == GL_UNSIGNED_INT_ATOMIC_COUNTER;
566 }
567 
IsOpaqueType(GLenum type)568 bool IsOpaqueType(GLenum type)
569 {
570     // ESSL 3.10 section 4.1.7 defines opaque types as: samplers, images and atomic counters.
571     return IsImageType(type) || IsSamplerType(type) || IsAtomicCounterType(type);
572 }
573 
IsMatrixType(GLenum type)574 bool IsMatrixType(GLenum type)
575 {
576     return VariableRowCount(type) > 1;
577 }
578 
TransposeMatrixType(GLenum type)579 GLenum TransposeMatrixType(GLenum type)
580 {
581     if (!IsMatrixType(type))
582     {
583         return type;
584     }
585 
586     switch (type)
587     {
588         case GL_FLOAT_MAT2:
589             return GL_FLOAT_MAT2;
590         case GL_FLOAT_MAT3:
591             return GL_FLOAT_MAT3;
592         case GL_FLOAT_MAT4:
593             return GL_FLOAT_MAT4;
594         case GL_FLOAT_MAT2x3:
595             return GL_FLOAT_MAT3x2;
596         case GL_FLOAT_MAT3x2:
597             return GL_FLOAT_MAT2x3;
598         case GL_FLOAT_MAT2x4:
599             return GL_FLOAT_MAT4x2;
600         case GL_FLOAT_MAT4x2:
601             return GL_FLOAT_MAT2x4;
602         case GL_FLOAT_MAT3x4:
603             return GL_FLOAT_MAT4x3;
604         case GL_FLOAT_MAT4x3:
605             return GL_FLOAT_MAT3x4;
606         default:
607             UNREACHABLE();
608             return GL_NONE;
609     }
610 }
611 
MatrixRegisterCount(GLenum type,bool isRowMajorMatrix)612 int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
613 {
614     ASSERT(IsMatrixType(type));
615     return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
616 }
617 
MatrixComponentCount(GLenum type,bool isRowMajorMatrix)618 int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
619 {
620     ASSERT(IsMatrixType(type));
621     return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
622 }
623 
VariableRegisterCount(GLenum type)624 int VariableRegisterCount(GLenum type)
625 {
626     return IsMatrixType(type) ? VariableColumnCount(type) : 1;
627 }
628 
AllocateFirstFreeBits(unsigned int * bits,unsigned int allocationSize,unsigned int bitsSize)629 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
630 {
631     ASSERT(allocationSize <= bitsSize);
632 
633     unsigned int mask = std::numeric_limits<unsigned int>::max() >>
634                         (std::numeric_limits<unsigned int>::digits - allocationSize);
635 
636     for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
637     {
638         if ((*bits & mask) == 0)
639         {
640             *bits |= mask;
641             return i;
642         }
643 
644         mask <<= 1;
645     }
646 
647     return -1;
648 }
649 
ComputeIndexRange(DrawElementsType indexType,const GLvoid * indices,size_t count,bool primitiveRestartEnabled)650 IndexRange ComputeIndexRange(DrawElementsType indexType,
651                              const GLvoid *indices,
652                              size_t count,
653                              bool primitiveRestartEnabled)
654 {
655     switch (indexType)
656     {
657         case DrawElementsType::UnsignedByte:
658             return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
659                                           primitiveRestartEnabled,
660                                           GetPrimitiveRestartIndex(indexType));
661         case DrawElementsType::UnsignedShort:
662             return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
663                                           primitiveRestartEnabled,
664                                           GetPrimitiveRestartIndex(indexType));
665         case DrawElementsType::UnsignedInt:
666             return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
667                                           primitiveRestartEnabled,
668                                           GetPrimitiveRestartIndex(indexType));
669         default:
670             UNREACHABLE();
671             return IndexRange();
672     }
673 }
674 
GetPrimitiveRestartIndex(DrawElementsType indexType)675 GLuint GetPrimitiveRestartIndex(DrawElementsType indexType)
676 {
677     switch (indexType)
678     {
679         case DrawElementsType::UnsignedByte:
680             return 0xFF;
681         case DrawElementsType::UnsignedShort:
682             return 0xFFFF;
683         case DrawElementsType::UnsignedInt:
684             return 0xFFFFFFFF;
685         default:
686             UNREACHABLE();
687             return 0;
688     }
689 }
690 
IsTriangleMode(PrimitiveMode drawMode)691 bool IsTriangleMode(PrimitiveMode drawMode)
692 {
693     switch (drawMode)
694     {
695         case PrimitiveMode::Triangles:
696         case PrimitiveMode::TriangleFan:
697         case PrimitiveMode::TriangleStrip:
698             return true;
699         case PrimitiveMode::Points:
700         case PrimitiveMode::Lines:
701         case PrimitiveMode::LineLoop:
702         case PrimitiveMode::LineStrip:
703             return false;
704         default:
705             UNREACHABLE();
706     }
707 
708     return false;
709 }
710 
IsPolygonMode(PrimitiveMode mode)711 bool IsPolygonMode(PrimitiveMode mode)
712 {
713     switch (mode)
714     {
715         case PrimitiveMode::Points:
716         case PrimitiveMode::Lines:
717         case PrimitiveMode::LineStrip:
718         case PrimitiveMode::LineLoop:
719         case PrimitiveMode::LinesAdjacency:
720         case PrimitiveMode::LineStripAdjacency:
721             return false;
722         default:
723             break;
724     }
725 
726     return true;
727 }
728 
729 namespace priv
730 {
731 const angle::PackedEnumMap<PrimitiveMode, bool> gLineModes = {
732     {{PrimitiveMode::LineLoop, true},
733      {PrimitiveMode::LineStrip, true},
734      {PrimitiveMode::LineStripAdjacency, true},
735      {PrimitiveMode::Lines, true}}};
736 }  // namespace priv
737 
IsIntegerFormat(GLenum unsizedFormat)738 bool IsIntegerFormat(GLenum unsizedFormat)
739 {
740     switch (unsizedFormat)
741     {
742         case GL_RGBA_INTEGER:
743         case GL_RGB_INTEGER:
744         case GL_RG_INTEGER:
745         case GL_RED_INTEGER:
746             return true;
747 
748         default:
749             return false;
750     }
751 }
752 
753 // [OpenGL ES SL 3.00.4] Section 11 p. 120
754 // Vertex Outs/Fragment Ins packing priorities
VariableSortOrder(GLenum type)755 int VariableSortOrder(GLenum type)
756 {
757     switch (type)
758     {
759         // 1. Arrays of mat4 and mat4
760         // Non-square matrices of type matCxR consume the same space as a square
761         // matrix of type matN where N is the greater of C and R
762         case GL_FLOAT_MAT4:
763         case GL_FLOAT_MAT2x4:
764         case GL_FLOAT_MAT3x4:
765         case GL_FLOAT_MAT4x2:
766         case GL_FLOAT_MAT4x3:
767             return 0;
768 
769         // 2. Arrays of mat2 and mat2 (since they occupy full rows)
770         case GL_FLOAT_MAT2:
771             return 1;
772 
773         // 3. Arrays of vec4 and vec4
774         case GL_FLOAT_VEC4:
775         case GL_INT_VEC4:
776         case GL_BOOL_VEC4:
777         case GL_UNSIGNED_INT_VEC4:
778             return 2;
779 
780         // 4. Arrays of mat3 and mat3
781         case GL_FLOAT_MAT3:
782         case GL_FLOAT_MAT2x3:
783         case GL_FLOAT_MAT3x2:
784             return 3;
785 
786         // 5. Arrays of vec3 and vec3
787         case GL_FLOAT_VEC3:
788         case GL_INT_VEC3:
789         case GL_BOOL_VEC3:
790         case GL_UNSIGNED_INT_VEC3:
791             return 4;
792 
793         // 6. Arrays of vec2 and vec2
794         case GL_FLOAT_VEC2:
795         case GL_INT_VEC2:
796         case GL_BOOL_VEC2:
797         case GL_UNSIGNED_INT_VEC2:
798             return 5;
799 
800         // 7. Single component types
801         case GL_FLOAT:
802         case GL_INT:
803         case GL_BOOL:
804         case GL_UNSIGNED_INT:
805         case GL_SAMPLER_2D:
806         case GL_SAMPLER_CUBE:
807         case GL_SAMPLER_EXTERNAL_OES:
808         case GL_SAMPLER_2D_RECT_ANGLE:
809         case GL_SAMPLER_2D_ARRAY:
810         case GL_SAMPLER_2D_MULTISAMPLE:
811         case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
812         case GL_SAMPLER_3D:
813         case GL_INT_SAMPLER_2D:
814         case GL_INT_SAMPLER_3D:
815         case GL_INT_SAMPLER_CUBE:
816         case GL_INT_SAMPLER_2D_ARRAY:
817         case GL_INT_SAMPLER_2D_MULTISAMPLE:
818         case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
819         case GL_UNSIGNED_INT_SAMPLER_2D:
820         case GL_UNSIGNED_INT_SAMPLER_3D:
821         case GL_UNSIGNED_INT_SAMPLER_CUBE:
822         case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
823         case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
824         case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
825         case GL_SAMPLER_2D_SHADOW:
826         case GL_SAMPLER_2D_ARRAY_SHADOW:
827         case GL_SAMPLER_CUBE_SHADOW:
828         case GL_IMAGE_2D:
829         case GL_INT_IMAGE_2D:
830         case GL_UNSIGNED_INT_IMAGE_2D:
831         case GL_IMAGE_3D:
832         case GL_INT_IMAGE_3D:
833         case GL_UNSIGNED_INT_IMAGE_3D:
834         case GL_IMAGE_2D_ARRAY:
835         case GL_INT_IMAGE_2D_ARRAY:
836         case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
837         case GL_IMAGE_CUBE:
838         case GL_INT_IMAGE_CUBE:
839         case GL_UNSIGNED_INT_IMAGE_CUBE:
840         case GL_UNSIGNED_INT_ATOMIC_COUNTER:
841         case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
842             return 6;
843 
844         default:
845             UNREACHABLE();
846             return 0;
847     }
848 }
849 
ParseResourceName(const std::string & name,std::vector<unsigned int> * outSubscripts)850 std::string ParseResourceName(const std::string &name, std::vector<unsigned int> *outSubscripts)
851 {
852     if (outSubscripts)
853     {
854         outSubscripts->clear();
855     }
856     // Strip any trailing array indexing operators and retrieve the subscripts.
857     size_t baseNameLength = name.length();
858     bool hasIndex         = true;
859     while (hasIndex)
860     {
861         size_t open  = name.find_last_of('[', baseNameLength - 1);
862         size_t close = name.find_last_of(']', baseNameLength - 1);
863         hasIndex     = (open != std::string::npos) && (close == baseNameLength - 1);
864         if (hasIndex)
865         {
866             baseNameLength = open;
867             if (outSubscripts)
868             {
869                 int index = atoi(name.substr(open + 1).c_str());
870                 if (index >= 0)
871                 {
872                     outSubscripts->push_back(index);
873                 }
874                 else
875                 {
876                     outSubscripts->push_back(GL_INVALID_INDEX);
877                 }
878             }
879         }
880     }
881 
882     return name.substr(0, baseNameLength);
883 }
884 
StripLastArrayIndex(const std::string & name)885 std::string StripLastArrayIndex(const std::string &name)
886 {
887     size_t strippedNameLength = name.find_last_of('[');
888     if (strippedNameLength != std::string::npos && name.back() == ']')
889     {
890         return name.substr(0, strippedNameLength);
891     }
892     return name;
893 }
894 
SamplerNameContainsNonZeroArrayElement(const std::string & name)895 bool SamplerNameContainsNonZeroArrayElement(const std::string &name)
896 {
897     constexpr char kZERO_ELEMENT[] = "[0]";
898 
899     size_t start = 0;
900     while (true)
901     {
902         start = name.find(kZERO_ELEMENT[0], start);
903         if (start == std::string::npos)
904         {
905             break;
906         }
907         if (name.compare(start, strlen(kZERO_ELEMENT), kZERO_ELEMENT) != 0)
908         {
909             return true;
910         }
911         start++;
912     }
913     return false;
914 }
915 
ArraySizeProduct(const std::vector<unsigned int> & arraySizes)916 unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes)
917 {
918     unsigned int arraySizeProduct = 1u;
919     for (unsigned int arraySize : arraySizes)
920     {
921         arraySizeProduct *= arraySize;
922     }
923     return arraySizeProduct;
924 }
925 
ParseArrayIndex(const std::string & name,size_t * nameLengthWithoutArrayIndexOut)926 unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut)
927 {
928     ASSERT(nameLengthWithoutArrayIndexOut != nullptr);
929 
930     // Strip any trailing array operator and retrieve the subscript
931     size_t open = name.find_last_of('[');
932     if (open != std::string::npos && name.back() == ']')
933     {
934         bool indexIsValidDecimalNumber = true;
935         for (size_t i = open + 1; i < name.length() - 1u; ++i)
936         {
937             if (!isdigit(name[i]))
938             {
939                 indexIsValidDecimalNumber = false;
940                 break;
941             }
942 
943             // Leading zeroes are invalid
944             if ((i == (open + 1)) && (name[i] == '0') && (name[i + 1] != ']'))
945             {
946                 indexIsValidDecimalNumber = false;
947                 break;
948             }
949         }
950         if (indexIsValidDecimalNumber)
951         {
952             errno = 0;  // reset global error flag.
953             unsigned long subscript =
954                 strtoul(name.c_str() + open + 1, /*endptr*/ nullptr, /*radix*/ 10);
955 
956             // Check if resulting integer is out-of-range or conversion error.
957             if (angle::base::IsValueInRangeForNumericType<uint32_t>(subscript) &&
958                 !(subscript == ULONG_MAX && errno == ERANGE) && !(errno != 0 && subscript == 0))
959             {
960                 *nameLengthWithoutArrayIndexOut = open;
961                 return static_cast<unsigned int>(subscript);
962             }
963         }
964     }
965 
966     *nameLengthWithoutArrayIndexOut = name.length();
967     return GL_INVALID_INDEX;
968 }
969 
GetGenericErrorMessage(GLenum error)970 const char *GetGenericErrorMessage(GLenum error)
971 {
972     switch (error)
973     {
974         case GL_NO_ERROR:
975             return "";
976         case GL_INVALID_ENUM:
977             return "Invalid enum.";
978         case GL_INVALID_VALUE:
979             return "Invalid value.";
980         case GL_INVALID_OPERATION:
981             return "Invalid operation.";
982         case GL_STACK_OVERFLOW:
983             return "Stack overflow.";
984         case GL_STACK_UNDERFLOW:
985             return "Stack underflow.";
986         case GL_OUT_OF_MEMORY:
987             return "Out of memory.";
988         case GL_INVALID_FRAMEBUFFER_OPERATION:
989             return "Invalid framebuffer operation.";
990         default:
991             UNREACHABLE();
992             return "Unknown error.";
993     }
994 }
995 
ElementTypeSize(GLenum elementType)996 unsigned int ElementTypeSize(GLenum elementType)
997 {
998     switch (elementType)
999     {
1000         case GL_UNSIGNED_BYTE:
1001             return sizeof(GLubyte);
1002         case GL_UNSIGNED_SHORT:
1003             return sizeof(GLushort);
1004         case GL_UNSIGNED_INT:
1005             return sizeof(GLuint);
1006         default:
1007             UNREACHABLE();
1008             return 0;
1009     }
1010 }
1011 
GetPipelineType(ShaderType type)1012 PipelineType GetPipelineType(ShaderType type)
1013 {
1014     switch (type)
1015     {
1016         case ShaderType::Vertex:
1017         case ShaderType::Fragment:
1018         case ShaderType::Geometry:
1019             return PipelineType::GraphicsPipeline;
1020         case ShaderType::Compute:
1021             return PipelineType::ComputePipeline;
1022         default:
1023             UNREACHABLE();
1024             return PipelineType::GraphicsPipeline;
1025     }
1026 }
1027 
GetDebugMessageSourceString(GLenum source)1028 const char *GetDebugMessageSourceString(GLenum source)
1029 {
1030     switch (source)
1031     {
1032         case GL_DEBUG_SOURCE_API:
1033             return "API";
1034         case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1035             return "Window System";
1036         case GL_DEBUG_SOURCE_SHADER_COMPILER:
1037             return "Shader Compiler";
1038         case GL_DEBUG_SOURCE_THIRD_PARTY:
1039             return "Third Party";
1040         case GL_DEBUG_SOURCE_APPLICATION:
1041             return "Application";
1042         case GL_DEBUG_SOURCE_OTHER:
1043             return "Other";
1044         default:
1045             return "Unknown Source";
1046     }
1047 }
1048 
GetDebugMessageTypeString(GLenum type)1049 const char *GetDebugMessageTypeString(GLenum type)
1050 {
1051     switch (type)
1052     {
1053         case GL_DEBUG_TYPE_ERROR:
1054             return "Error";
1055         case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1056             return "Deprecated behavior";
1057         case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1058             return "Undefined behavior";
1059         case GL_DEBUG_TYPE_PORTABILITY:
1060             return "Portability";
1061         case GL_DEBUG_TYPE_PERFORMANCE:
1062             return "Performance";
1063         case GL_DEBUG_TYPE_OTHER:
1064             return "Other";
1065         case GL_DEBUG_TYPE_MARKER:
1066             return "Marker";
1067         default:
1068             return "Unknown Type";
1069     }
1070 }
1071 
GetDebugMessageSeverityString(GLenum severity)1072 const char *GetDebugMessageSeverityString(GLenum severity)
1073 {
1074     switch (severity)
1075     {
1076         case GL_DEBUG_SEVERITY_HIGH:
1077             return "High";
1078         case GL_DEBUG_SEVERITY_MEDIUM:
1079             return "Medium";
1080         case GL_DEBUG_SEVERITY_LOW:
1081             return "Low";
1082         case GL_DEBUG_SEVERITY_NOTIFICATION:
1083             return "Notification";
1084         default:
1085             return "Unknown Severity";
1086     }
1087 }
1088 }  // namespace gl
1089 
1090 namespace egl
1091 {
1092 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
1093               "Unexpected EGL cube map enum value.");
1094 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
1095               "Unexpected EGL cube map enum value.");
1096 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
1097               "Unexpected EGL cube map enum value.");
1098 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
1099               "Unexpected EGL cube map enum value.");
1100 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
1101               "Unexpected EGL cube map enum value.");
1102 
IsCubeMapTextureTarget(EGLenum target)1103 bool IsCubeMapTextureTarget(EGLenum target)
1104 {
1105     return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
1106 }
1107 
CubeMapTextureTargetToLayerIndex(EGLenum target)1108 size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
1109 {
1110     ASSERT(IsCubeMapTextureTarget(target));
1111     return target - static_cast<size_t>(FirstCubeMapTextureTarget);
1112 }
1113 
LayerIndexToCubeMapTextureTarget(size_t index)1114 EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
1115 {
1116     ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
1117     return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
1118 }
1119 
IsTextureTarget(EGLenum target)1120 bool IsTextureTarget(EGLenum target)
1121 {
1122     switch (target)
1123     {
1124         case EGL_GL_TEXTURE_2D_KHR:
1125         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
1126         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
1127         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
1128         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
1129         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
1130         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
1131         case EGL_GL_TEXTURE_3D_KHR:
1132             return true;
1133 
1134         default:
1135             return false;
1136     }
1137 }
1138 
IsRenderbufferTarget(EGLenum target)1139 bool IsRenderbufferTarget(EGLenum target)
1140 {
1141     return target == EGL_GL_RENDERBUFFER_KHR;
1142 }
1143 
IsExternalImageTarget(EGLenum target)1144 bool IsExternalImageTarget(EGLenum target)
1145 {
1146     switch (target)
1147     {
1148         case EGL_NATIVE_BUFFER_ANDROID:
1149         case EGL_D3D11_TEXTURE_ANGLE:
1150         case EGL_LINUX_DMA_BUF_EXT:
1151             return true;
1152 
1153         default:
1154             return false;
1155     }
1156 }
1157 
GetGenericErrorMessage(EGLint error)1158 const char *GetGenericErrorMessage(EGLint error)
1159 {
1160     switch (error)
1161     {
1162         case EGL_SUCCESS:
1163             return "";
1164         case EGL_NOT_INITIALIZED:
1165             return "Not initialized.";
1166         case EGL_BAD_ACCESS:
1167             return "Bad access.";
1168         case EGL_BAD_ALLOC:
1169             return "Bad allocation.";
1170         case EGL_BAD_ATTRIBUTE:
1171             return "Bad attribute.";
1172         case EGL_BAD_CONFIG:
1173             return "Bad config.";
1174         case EGL_BAD_CONTEXT:
1175             return "Bad context.";
1176         case EGL_BAD_CURRENT_SURFACE:
1177             return "Bad current surface.";
1178         case EGL_BAD_DISPLAY:
1179             return "Bad display.";
1180         case EGL_BAD_MATCH:
1181             return "Bad match.";
1182         case EGL_BAD_NATIVE_WINDOW:
1183             return "Bad native window.";
1184         case EGL_BAD_PARAMETER:
1185             return "Bad parameter.";
1186         case EGL_BAD_SURFACE:
1187             return "Bad surface.";
1188         case EGL_CONTEXT_LOST:
1189             return "Context lost.";
1190         case EGL_BAD_STREAM_KHR:
1191             return "Bad stream.";
1192         case EGL_BAD_STATE_KHR:
1193             return "Bad state.";
1194         case EGL_BAD_DEVICE_EXT:
1195             return "Bad device.";
1196         default:
1197             UNREACHABLE();
1198             return "Unknown error.";
1199     }
1200 }
1201 
1202 }  // namespace egl
1203 
1204 namespace egl_gl
1205 {
EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)1206 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
1207 {
1208     return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
1209 }
1210 }  // namespace egl_gl
1211 
1212 namespace gl_egl
1213 {
GLComponentTypeToEGLColorComponentType(GLenum glComponentType)1214 EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType)
1215 {
1216     switch (glComponentType)
1217     {
1218         case GL_FLOAT:
1219             return EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
1220 
1221         case GL_UNSIGNED_NORMALIZED:
1222             return EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
1223 
1224         default:
1225             UNREACHABLE();
1226             return EGL_NONE;
1227     }
1228 }
1229 
GLObjectHandleToEGLClientBuffer(GLuint handle)1230 EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle)
1231 {
1232     return reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(handle));
1233 }
1234 
1235 }  // namespace gl_egl
1236 
1237 #if !defined(ANGLE_ENABLE_WINDOWS_UWP)
getTempPath()1238 std::string getTempPath()
1239 {
1240 #    ifdef ANGLE_PLATFORM_WINDOWS
1241     char path[MAX_PATH];
1242     DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
1243     if (pathLen == 0)
1244     {
1245         UNREACHABLE();
1246         return std::string();
1247     }
1248 
1249     UINT unique = GetTempFileNameA(path, "sh", 0, path);
1250     if (unique == 0)
1251     {
1252         UNREACHABLE();
1253         return std::string();
1254     }
1255 
1256     return path;
1257 #    else
1258     UNIMPLEMENTED();
1259     return "";
1260 #    endif
1261 }
1262 
writeFile(const char * path,const void * content,size_t size)1263 void writeFile(const char *path, const void *content, size_t size)
1264 {
1265     FILE *file = fopen(path, "w");
1266     if (!file)
1267     {
1268         UNREACHABLE();
1269         return;
1270     }
1271 
1272     fwrite(content, sizeof(char), size, file);
1273     fclose(file);
1274 }
1275 #endif  // !ANGLE_ENABLE_WINDOWS_UWP
1276 
1277 #if defined(ANGLE_PLATFORM_WINDOWS)
1278 
1279 // Causes the thread to relinquish the remainder of its time slice to any
1280 // other thread that is ready to run.If there are no other threads ready
1281 // to run, the function returns immediately, and the thread continues execution.
ScheduleYield()1282 void ScheduleYield()
1283 {
1284     Sleep(0);
1285 }
1286 
1287 #endif
1288