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