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