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