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