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 
ParseArrayIndex(const std::string & name,size_t * nameLengthWithoutArrayIndexOut)970 unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut)
971 {
972     ASSERT(nameLengthWithoutArrayIndexOut != nullptr);
973 
974     // Strip any trailing array operator and retrieve the subscript
975     size_t open = name.find_last_of('[');
976     if (open != std::string::npos && name.back() == ']')
977     {
978         bool indexIsValidDecimalNumber = true;
979         for (size_t i = open + 1; i < name.length() - 1u; ++i)
980         {
981             if (!isdigit(name[i]))
982             {
983                 indexIsValidDecimalNumber = false;
984                 break;
985             }
986 
987             // Leading zeroes are invalid
988             if ((i == (open + 1)) && (name[i] == '0') && (name[i + 1] != ']'))
989             {
990                 indexIsValidDecimalNumber = false;
991                 break;
992             }
993         }
994         if (indexIsValidDecimalNumber)
995         {
996             errno = 0;  // reset global error flag.
997             unsigned long subscript =
998                 strtoul(name.c_str() + open + 1, /*endptr*/ nullptr, /*radix*/ 10);
999 
1000             // Check if resulting integer is out-of-range or conversion error.
1001             if (angle::base::IsValueInRangeForNumericType<uint32_t>(subscript) &&
1002                 !(subscript == ULONG_MAX && errno == ERANGE) && !(errno != 0 && subscript == 0))
1003             {
1004                 *nameLengthWithoutArrayIndexOut = open;
1005                 return static_cast<unsigned int>(subscript);
1006             }
1007         }
1008     }
1009 
1010     *nameLengthWithoutArrayIndexOut = name.length();
1011     return GL_INVALID_INDEX;
1012 }
1013 
GetGenericErrorMessage(GLenum error)1014 const char *GetGenericErrorMessage(GLenum error)
1015 {
1016     switch (error)
1017     {
1018         case GL_NO_ERROR:
1019             return "";
1020         case GL_INVALID_ENUM:
1021             return "Invalid enum.";
1022         case GL_INVALID_VALUE:
1023             return "Invalid value.";
1024         case GL_INVALID_OPERATION:
1025             return "Invalid operation.";
1026         case GL_STACK_OVERFLOW:
1027             return "Stack overflow.";
1028         case GL_STACK_UNDERFLOW:
1029             return "Stack underflow.";
1030         case GL_OUT_OF_MEMORY:
1031             return "Out of memory.";
1032         case GL_INVALID_FRAMEBUFFER_OPERATION:
1033             return "Invalid framebuffer operation.";
1034         default:
1035             UNREACHABLE();
1036             return "Unknown error.";
1037     }
1038 }
1039 
ElementTypeSize(GLenum elementType)1040 unsigned int ElementTypeSize(GLenum elementType)
1041 {
1042     switch (elementType)
1043     {
1044         case GL_UNSIGNED_BYTE:
1045             return sizeof(GLubyte);
1046         case GL_UNSIGNED_SHORT:
1047             return sizeof(GLushort);
1048         case GL_UNSIGNED_INT:
1049             return sizeof(GLuint);
1050         default:
1051             UNREACHABLE();
1052             return 0;
1053     }
1054 }
1055 
GetPipelineType(ShaderType type)1056 PipelineType GetPipelineType(ShaderType type)
1057 {
1058     switch (type)
1059     {
1060         case ShaderType::Vertex:
1061         case ShaderType::Fragment:
1062         case ShaderType::Geometry:
1063             return PipelineType::GraphicsPipeline;
1064         case ShaderType::Compute:
1065             return PipelineType::ComputePipeline;
1066         default:
1067             UNREACHABLE();
1068             return PipelineType::GraphicsPipeline;
1069     }
1070 }
1071 
GetDebugMessageSourceString(GLenum source)1072 const char *GetDebugMessageSourceString(GLenum source)
1073 {
1074     switch (source)
1075     {
1076         case GL_DEBUG_SOURCE_API:
1077             return "API";
1078         case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1079             return "Window System";
1080         case GL_DEBUG_SOURCE_SHADER_COMPILER:
1081             return "Shader Compiler";
1082         case GL_DEBUG_SOURCE_THIRD_PARTY:
1083             return "Third Party";
1084         case GL_DEBUG_SOURCE_APPLICATION:
1085             return "Application";
1086         case GL_DEBUG_SOURCE_OTHER:
1087             return "Other";
1088         default:
1089             return "Unknown Source";
1090     }
1091 }
1092 
GetDebugMessageTypeString(GLenum type)1093 const char *GetDebugMessageTypeString(GLenum type)
1094 {
1095     switch (type)
1096     {
1097         case GL_DEBUG_TYPE_ERROR:
1098             return "Error";
1099         case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1100             return "Deprecated behavior";
1101         case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1102             return "Undefined behavior";
1103         case GL_DEBUG_TYPE_PORTABILITY:
1104             return "Portability";
1105         case GL_DEBUG_TYPE_PERFORMANCE:
1106             return "Performance";
1107         case GL_DEBUG_TYPE_OTHER:
1108             return "Other";
1109         case GL_DEBUG_TYPE_MARKER:
1110             return "Marker";
1111         default:
1112             return "Unknown Type";
1113     }
1114 }
1115 
GetDebugMessageSeverityString(GLenum severity)1116 const char *GetDebugMessageSeverityString(GLenum severity)
1117 {
1118     switch (severity)
1119     {
1120         case GL_DEBUG_SEVERITY_HIGH:
1121             return "High";
1122         case GL_DEBUG_SEVERITY_MEDIUM:
1123             return "Medium";
1124         case GL_DEBUG_SEVERITY_LOW:
1125             return "Low";
1126         case GL_DEBUG_SEVERITY_NOTIFICATION:
1127             return "Notification";
1128         default:
1129             return "Unknown Severity";
1130     }
1131 }
1132 
GetShaderTypeFromBitfield(size_t singleShaderType)1133 ShaderType GetShaderTypeFromBitfield(size_t singleShaderType)
1134 {
1135     switch (singleShaderType)
1136     {
1137         case GL_VERTEX_SHADER_BIT:
1138             return ShaderType::Vertex;
1139         case GL_FRAGMENT_SHADER_BIT:
1140             return ShaderType::Fragment;
1141         case GL_COMPUTE_SHADER_BIT:
1142             return ShaderType::Compute;
1143         case GL_GEOMETRY_SHADER_BIT:
1144             return ShaderType::Geometry;
1145         case GL_TESS_CONTROL_SHADER_BIT:
1146             return ShaderType::TessControl;
1147         case GL_TESS_EVALUATION_SHADER_BIT:
1148             return ShaderType::TessEvaluation;
1149         default:
1150             return ShaderType::InvalidEnum;
1151     }
1152 }
1153 
GetBitfieldFromShaderType(ShaderType shaderType)1154 GLbitfield GetBitfieldFromShaderType(ShaderType shaderType)
1155 {
1156     switch (shaderType)
1157     {
1158         case ShaderType::Vertex:
1159             return GL_VERTEX_SHADER_BIT;
1160         case ShaderType::Fragment:
1161             return GL_FRAGMENT_SHADER_BIT;
1162         case ShaderType::Compute:
1163             return GL_COMPUTE_SHADER_BIT;
1164         case ShaderType::Geometry:
1165             return GL_GEOMETRY_SHADER_BIT;
1166         case ShaderType::TessControl:
1167             return GL_TESS_CONTROL_SHADER_BIT;
1168         case ShaderType::TessEvaluation:
1169             return GL_TESS_EVALUATION_SHADER_BIT;
1170         default:
1171             UNREACHABLE();
1172             return GL_ZERO;
1173     }
1174 }
1175 
ShaderTypeSupportsTransformFeedback(ShaderType shaderType)1176 bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType)
1177 {
1178     switch (shaderType)
1179     {
1180         case ShaderType::Vertex:
1181         case ShaderType::Geometry:
1182         case ShaderType::TessEvaluation:
1183             return true;
1184         default:
1185             return false;
1186     }
1187 }
1188 
GetLastPreFragmentStage(ShaderBitSet shaderTypes)1189 ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes)
1190 {
1191     shaderTypes.reset(ShaderType::Fragment);
1192     shaderTypes.reset(ShaderType::Compute);
1193     return shaderTypes.any() ? shaderTypes.last() : ShaderType::InvalidEnum;
1194 }
1195 }  // namespace gl
1196 
1197 namespace egl
1198 {
1199 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
1200               "Unexpected EGL cube map enum value.");
1201 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
1202               "Unexpected EGL cube map enum value.");
1203 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
1204               "Unexpected EGL cube map enum value.");
1205 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
1206               "Unexpected EGL cube map enum value.");
1207 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
1208               "Unexpected EGL cube map enum value.");
1209 
IsCubeMapTextureTarget(EGLenum target)1210 bool IsCubeMapTextureTarget(EGLenum target)
1211 {
1212     return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
1213 }
1214 
CubeMapTextureTargetToLayerIndex(EGLenum target)1215 size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
1216 {
1217     ASSERT(IsCubeMapTextureTarget(target));
1218     return target - static_cast<size_t>(FirstCubeMapTextureTarget);
1219 }
1220 
LayerIndexToCubeMapTextureTarget(size_t index)1221 EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
1222 {
1223     ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
1224     return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
1225 }
1226 
IsTextureTarget(EGLenum target)1227 bool IsTextureTarget(EGLenum target)
1228 {
1229     switch (target)
1230     {
1231         case EGL_GL_TEXTURE_2D_KHR:
1232         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
1233         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
1234         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
1235         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
1236         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
1237         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
1238         case EGL_GL_TEXTURE_3D_KHR:
1239             return true;
1240 
1241         default:
1242             return false;
1243     }
1244 }
1245 
IsRenderbufferTarget(EGLenum target)1246 bool IsRenderbufferTarget(EGLenum target)
1247 {
1248     return target == EGL_GL_RENDERBUFFER_KHR;
1249 }
1250 
IsExternalImageTarget(EGLenum target)1251 bool IsExternalImageTarget(EGLenum target)
1252 {
1253     switch (target)
1254     {
1255         case EGL_NATIVE_BUFFER_ANDROID:
1256         case EGL_D3D11_TEXTURE_ANGLE:
1257         case EGL_LINUX_DMA_BUF_EXT:
1258         case EGL_METAL_TEXTURE_ANGLE:
1259             return true;
1260 
1261         default:
1262             return false;
1263     }
1264 }
1265 
GetGenericErrorMessage(EGLint error)1266 const char *GetGenericErrorMessage(EGLint error)
1267 {
1268     switch (error)
1269     {
1270         case EGL_SUCCESS:
1271             return "";
1272         case EGL_NOT_INITIALIZED:
1273             return "Not initialized.";
1274         case EGL_BAD_ACCESS:
1275             return "Bad access.";
1276         case EGL_BAD_ALLOC:
1277             return "Bad allocation.";
1278         case EGL_BAD_ATTRIBUTE:
1279             return "Bad attribute.";
1280         case EGL_BAD_CONFIG:
1281             return "Bad config.";
1282         case EGL_BAD_CONTEXT:
1283             return "Bad context.";
1284         case EGL_BAD_CURRENT_SURFACE:
1285             return "Bad current surface.";
1286         case EGL_BAD_DISPLAY:
1287             return "Bad display.";
1288         case EGL_BAD_MATCH:
1289             return "Bad match.";
1290         case EGL_BAD_NATIVE_WINDOW:
1291             return "Bad native window.";
1292         case EGL_BAD_NATIVE_PIXMAP:
1293             return "Bad native pixmap.";
1294         case EGL_BAD_PARAMETER:
1295             return "Bad parameter.";
1296         case EGL_BAD_SURFACE:
1297             return "Bad surface.";
1298         case EGL_CONTEXT_LOST:
1299             return "Context lost.";
1300         case EGL_BAD_STREAM_KHR:
1301             return "Bad stream.";
1302         case EGL_BAD_STATE_KHR:
1303             return "Bad state.";
1304         case EGL_BAD_DEVICE_EXT:
1305             return "Bad device.";
1306         default:
1307             UNREACHABLE();
1308             return "Unknown error.";
1309     }
1310 }
1311 
1312 }  // namespace egl
1313 
1314 namespace egl_gl
1315 {
EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)1316 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
1317 {
1318     return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
1319 }
1320 }  // namespace egl_gl
1321 
1322 namespace gl_egl
1323 {
GLComponentTypeToEGLColorComponentType(GLenum glComponentType)1324 EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType)
1325 {
1326     switch (glComponentType)
1327     {
1328         case GL_FLOAT:
1329             return EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
1330 
1331         case GL_UNSIGNED_NORMALIZED:
1332             return EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
1333 
1334         default:
1335             UNREACHABLE();
1336             return EGL_NONE;
1337     }
1338 }
1339 
GLObjectHandleToEGLClientBuffer(GLuint handle)1340 EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle)
1341 {
1342     return reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(handle));
1343 }
1344 
1345 }  // namespace gl_egl
1346 
1347 #if !defined(ANGLE_ENABLE_WINDOWS_UWP)
getTempPath()1348 std::string getTempPath()
1349 {
1350 #    ifdef ANGLE_PLATFORM_WINDOWS
1351     char path[MAX_PATH];
1352     DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
1353     if (pathLen == 0)
1354     {
1355         UNREACHABLE();
1356         return std::string();
1357     }
1358 
1359     UINT unique = GetTempFileNameA(path, "sh", 0, path);
1360     if (unique == 0)
1361     {
1362         UNREACHABLE();
1363         return std::string();
1364     }
1365 
1366     return path;
1367 #    else
1368     UNIMPLEMENTED();
1369     return "";
1370 #    endif
1371 }
1372 
writeFile(const char * path,const void * content,size_t size)1373 void writeFile(const char *path, const void *content, size_t size)
1374 {
1375     FILE *file = fopen(path, "w");
1376     if (!file)
1377     {
1378         UNREACHABLE();
1379         return;
1380     }
1381 
1382     fwrite(content, sizeof(char), size, file);
1383     fclose(file);
1384 }
1385 #endif  // !ANGLE_ENABLE_WINDOWS_UWP
1386 
1387 #if defined(ANGLE_PLATFORM_WINDOWS)
1388 
1389 // Causes the thread to relinquish the remainder of its time slice to any
1390 // other thread that is ready to run.If there are no other threads ready
1391 // to run, the function returns immediately, and the thread continues execution.
ScheduleYield()1392 void ScheduleYield()
1393 {
1394     Sleep(0);
1395 }
1396 
1397 #endif
1398