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