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