1 //
2 // Copyright (c) 2002-2013 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 "common/mathutil.h"
11 #include "common/platform.h"
12
13 #include <set>
14
15 #if defined(ANGLE_ENABLE_WINDOWS_STORE)
16 # include <wrl.h>
17 # include <wrl/wrappers/corewrappers.h>
18 # include <windows.applicationmodel.core.h>
19 # include <windows.graphics.display.h>
20 #endif
21
22 namespace
23 {
24
25 template <class IndexType>
ComputeTypedIndexRange(const IndexType * indices,size_t count,bool primitiveRestartEnabled,GLuint primitiveRestartIndex)26 gl::IndexRange ComputeTypedIndexRange(const IndexType *indices,
27 size_t count,
28 bool primitiveRestartEnabled,
29 GLuint primitiveRestartIndex)
30 {
31 ASSERT(count > 0);
32
33 IndexType minIndex = 0;
34 IndexType maxIndex = 0;
35 size_t nonPrimitiveRestartIndices = 0;
36
37 if (primitiveRestartEnabled)
38 {
39 // Find the first non-primitive restart index to initialize the min and max values
40 size_t i = 0;
41 for (; i < count; i++)
42 {
43 if (indices[i] != primitiveRestartIndex)
44 {
45 minIndex = indices[i];
46 maxIndex = indices[i];
47 nonPrimitiveRestartIndices++;
48 break;
49 }
50 }
51
52 // Loop over the rest of the indices
53 for (; i < count; i++)
54 {
55 if (indices[i] != primitiveRestartIndex)
56 {
57 if (minIndex > indices[i])
58 {
59 minIndex = indices[i];
60 }
61 if (maxIndex < indices[i])
62 {
63 maxIndex = indices[i];
64 }
65 nonPrimitiveRestartIndices++;
66 }
67 }
68 }
69 else
70 {
71 minIndex = indices[0];
72 maxIndex = indices[0];
73 nonPrimitiveRestartIndices = count;
74
75 for (size_t i = 1; i < count; i++)
76 {
77 if (minIndex > indices[i])
78 {
79 minIndex = indices[i];
80 }
81 if (maxIndex < indices[i])
82 {
83 maxIndex = indices[i];
84 }
85 }
86 }
87
88 return gl::IndexRange(static_cast<size_t>(minIndex), static_cast<size_t>(maxIndex),
89 nonPrimitiveRestartIndices);
90 }
91
92 } // anonymous namespace
93
94 namespace gl
95 {
96
VariableComponentCount(GLenum type)97 int VariableComponentCount(GLenum type)
98 {
99 return VariableRowCount(type) * VariableColumnCount(type);
100 }
101
VariableComponentType(GLenum type)102 GLenum VariableComponentType(GLenum type)
103 {
104 switch(type)
105 {
106 case GL_BOOL:
107 case GL_BOOL_VEC2:
108 case GL_BOOL_VEC3:
109 case GL_BOOL_VEC4:
110 return GL_BOOL;
111 case GL_FLOAT:
112 case GL_FLOAT_VEC2:
113 case GL_FLOAT_VEC3:
114 case GL_FLOAT_VEC4:
115 case GL_FLOAT_MAT2:
116 case GL_FLOAT_MAT3:
117 case GL_FLOAT_MAT4:
118 case GL_FLOAT_MAT2x3:
119 case GL_FLOAT_MAT3x2:
120 case GL_FLOAT_MAT2x4:
121 case GL_FLOAT_MAT4x2:
122 case GL_FLOAT_MAT3x4:
123 case GL_FLOAT_MAT4x3:
124 return GL_FLOAT;
125 case GL_INT:
126 case GL_SAMPLER_2D:
127 case GL_SAMPLER_3D:
128 case GL_SAMPLER_CUBE:
129 case GL_SAMPLER_2D_ARRAY:
130 case GL_SAMPLER_EXTERNAL_OES:
131 case GL_INT_SAMPLER_2D:
132 case GL_INT_SAMPLER_3D:
133 case GL_INT_SAMPLER_CUBE:
134 case GL_INT_SAMPLER_2D_ARRAY:
135 case GL_UNSIGNED_INT_SAMPLER_2D:
136 case GL_UNSIGNED_INT_SAMPLER_3D:
137 case GL_UNSIGNED_INT_SAMPLER_CUBE:
138 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
139 case GL_SAMPLER_2D_SHADOW:
140 case GL_SAMPLER_CUBE_SHADOW:
141 case GL_SAMPLER_2D_ARRAY_SHADOW:
142 case GL_INT_VEC2:
143 case GL_INT_VEC3:
144 case GL_INT_VEC4:
145 return GL_INT;
146 case GL_UNSIGNED_INT:
147 case GL_UNSIGNED_INT_VEC2:
148 case GL_UNSIGNED_INT_VEC3:
149 case GL_UNSIGNED_INT_VEC4:
150 return GL_UNSIGNED_INT;
151 default:
152 UNREACHABLE();
153 }
154
155 return GL_NONE;
156 }
157
VariableComponentSize(GLenum type)158 size_t VariableComponentSize(GLenum type)
159 {
160 switch(type)
161 {
162 case GL_BOOL: return sizeof(GLint);
163 case GL_FLOAT: return sizeof(GLfloat);
164 case GL_INT: return sizeof(GLint);
165 case GL_UNSIGNED_INT: return sizeof(GLuint);
166 default: UNREACHABLE();
167 }
168
169 return 0;
170 }
171
VariableInternalSize(GLenum type)172 size_t VariableInternalSize(GLenum type)
173 {
174 // Expanded to 4-element vectors
175 return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
176 }
177
VariableExternalSize(GLenum type)178 size_t VariableExternalSize(GLenum type)
179 {
180 return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
181 }
182
VariableBoolVectorType(GLenum type)183 GLenum VariableBoolVectorType(GLenum type)
184 {
185 switch (type)
186 {
187 case GL_FLOAT:
188 case GL_INT:
189 case GL_UNSIGNED_INT:
190 return GL_BOOL;
191 case GL_FLOAT_VEC2:
192 case GL_INT_VEC2:
193 case GL_UNSIGNED_INT_VEC2:
194 return GL_BOOL_VEC2;
195 case GL_FLOAT_VEC3:
196 case GL_INT_VEC3:
197 case GL_UNSIGNED_INT_VEC3:
198 return GL_BOOL_VEC3;
199 case GL_FLOAT_VEC4:
200 case GL_INT_VEC4:
201 case GL_UNSIGNED_INT_VEC4:
202 return GL_BOOL_VEC4;
203
204 default:
205 UNREACHABLE();
206 return GL_NONE;
207 }
208 }
209
VariableRowCount(GLenum type)210 int VariableRowCount(GLenum type)
211 {
212 switch (type)
213 {
214 case GL_NONE:
215 case GL_STRUCT_ANGLEX:
216 return 0;
217 case GL_BOOL:
218 case GL_FLOAT:
219 case GL_INT:
220 case GL_UNSIGNED_INT:
221 case GL_BOOL_VEC2:
222 case GL_FLOAT_VEC2:
223 case GL_INT_VEC2:
224 case GL_UNSIGNED_INT_VEC2:
225 case GL_BOOL_VEC3:
226 case GL_FLOAT_VEC3:
227 case GL_INT_VEC3:
228 case GL_UNSIGNED_INT_VEC3:
229 case GL_BOOL_VEC4:
230 case GL_FLOAT_VEC4:
231 case GL_INT_VEC4:
232 case GL_UNSIGNED_INT_VEC4:
233 case GL_SAMPLER_2D:
234 case GL_SAMPLER_3D:
235 case GL_SAMPLER_CUBE:
236 case GL_SAMPLER_2D_ARRAY:
237 case GL_SAMPLER_EXTERNAL_OES:
238 case GL_SAMPLER_2D_RECT_ARB:
239 case GL_INT_SAMPLER_2D:
240 case GL_INT_SAMPLER_3D:
241 case GL_INT_SAMPLER_CUBE:
242 case GL_INT_SAMPLER_2D_ARRAY:
243 case GL_UNSIGNED_INT_SAMPLER_2D:
244 case GL_UNSIGNED_INT_SAMPLER_3D:
245 case GL_UNSIGNED_INT_SAMPLER_CUBE:
246 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
247 case GL_SAMPLER_2D_SHADOW:
248 case GL_SAMPLER_CUBE_SHADOW:
249 case GL_SAMPLER_2D_ARRAY_SHADOW:
250 case GL_IMAGE_2D:
251 case GL_INT_IMAGE_2D:
252 case GL_UNSIGNED_INT_IMAGE_2D:
253 case GL_IMAGE_2D_ARRAY:
254 case GL_INT_IMAGE_2D_ARRAY:
255 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
256 case GL_IMAGE_3D:
257 case GL_INT_IMAGE_3D:
258 case GL_UNSIGNED_INT_IMAGE_3D:
259 case GL_IMAGE_CUBE:
260 case GL_INT_IMAGE_CUBE:
261 case GL_UNSIGNED_INT_IMAGE_CUBE:
262 return 1;
263 case GL_FLOAT_MAT2:
264 case GL_FLOAT_MAT3x2:
265 case GL_FLOAT_MAT4x2:
266 return 2;
267 case GL_FLOAT_MAT3:
268 case GL_FLOAT_MAT2x3:
269 case GL_FLOAT_MAT4x3:
270 return 3;
271 case GL_FLOAT_MAT4:
272 case GL_FLOAT_MAT2x4:
273 case GL_FLOAT_MAT3x4:
274 return 4;
275 default:
276 UNREACHABLE();
277 }
278
279 return 0;
280 }
281
VariableColumnCount(GLenum type)282 int VariableColumnCount(GLenum type)
283 {
284 switch (type)
285 {
286 case GL_NONE:
287 case GL_STRUCT_ANGLEX:
288 return 0;
289 case GL_BOOL:
290 case GL_FLOAT:
291 case GL_INT:
292 case GL_UNSIGNED_INT:
293 case GL_SAMPLER_2D:
294 case GL_SAMPLER_3D:
295 case GL_SAMPLER_CUBE:
296 case GL_SAMPLER_2D_ARRAY:
297 case GL_INT_SAMPLER_2D:
298 case GL_INT_SAMPLER_3D:
299 case GL_INT_SAMPLER_CUBE:
300 case GL_INT_SAMPLER_2D_ARRAY:
301 case GL_SAMPLER_EXTERNAL_OES:
302 case GL_SAMPLER_2D_RECT_ARB:
303 case GL_UNSIGNED_INT_SAMPLER_2D:
304 case GL_UNSIGNED_INT_SAMPLER_3D:
305 case GL_UNSIGNED_INT_SAMPLER_CUBE:
306 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
307 case GL_SAMPLER_2D_SHADOW:
308 case GL_SAMPLER_CUBE_SHADOW:
309 case GL_SAMPLER_2D_ARRAY_SHADOW:
310 return 1;
311 case GL_BOOL_VEC2:
312 case GL_FLOAT_VEC2:
313 case GL_INT_VEC2:
314 case GL_UNSIGNED_INT_VEC2:
315 case GL_FLOAT_MAT2:
316 case GL_FLOAT_MAT2x3:
317 case GL_FLOAT_MAT2x4:
318 return 2;
319 case GL_BOOL_VEC3:
320 case GL_FLOAT_VEC3:
321 case GL_INT_VEC3:
322 case GL_UNSIGNED_INT_VEC3:
323 case GL_FLOAT_MAT3:
324 case GL_FLOAT_MAT3x2:
325 case GL_FLOAT_MAT3x4:
326 return 3;
327 case GL_BOOL_VEC4:
328 case GL_FLOAT_VEC4:
329 case GL_INT_VEC4:
330 case GL_UNSIGNED_INT_VEC4:
331 case GL_FLOAT_MAT4:
332 case GL_FLOAT_MAT4x2:
333 case GL_FLOAT_MAT4x3:
334 return 4;
335 default:
336 UNREACHABLE();
337 }
338
339 return 0;
340 }
341
IsSamplerType(GLenum type)342 bool IsSamplerType(GLenum type)
343 {
344 switch (type)
345 {
346 case GL_SAMPLER_2D:
347 case GL_SAMPLER_3D:
348 case GL_SAMPLER_CUBE:
349 case GL_SAMPLER_2D_ARRAY:
350 case GL_SAMPLER_EXTERNAL_OES:
351 case GL_INT_SAMPLER_2D:
352 case GL_INT_SAMPLER_3D:
353 case GL_INT_SAMPLER_CUBE:
354 case GL_INT_SAMPLER_2D_ARRAY:
355 case GL_UNSIGNED_INT_SAMPLER_2D:
356 case GL_UNSIGNED_INT_SAMPLER_3D:
357 case GL_UNSIGNED_INT_SAMPLER_CUBE:
358 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
359 case GL_SAMPLER_2D_SHADOW:
360 case GL_SAMPLER_CUBE_SHADOW:
361 case GL_SAMPLER_2D_ARRAY_SHADOW:
362 return true;
363 }
364
365 return false;
366 }
367
SamplerTypeToTextureType(GLenum samplerType)368 GLenum SamplerTypeToTextureType(GLenum samplerType)
369 {
370 switch (samplerType)
371 {
372 case GL_SAMPLER_2D:
373 case GL_INT_SAMPLER_2D:
374 case GL_UNSIGNED_INT_SAMPLER_2D:
375 case GL_SAMPLER_2D_SHADOW:
376 return GL_TEXTURE_2D;
377
378 case GL_SAMPLER_EXTERNAL_OES:
379 return GL_TEXTURE_EXTERNAL_OES;
380
381 case GL_SAMPLER_CUBE:
382 case GL_INT_SAMPLER_CUBE:
383 case GL_UNSIGNED_INT_SAMPLER_CUBE:
384 case GL_SAMPLER_CUBE_SHADOW:
385 return GL_TEXTURE_CUBE_MAP;
386
387 case GL_SAMPLER_2D_ARRAY:
388 case GL_INT_SAMPLER_2D_ARRAY:
389 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
390 case GL_SAMPLER_2D_ARRAY_SHADOW:
391 return GL_TEXTURE_2D_ARRAY;
392
393 case GL_SAMPLER_3D:
394 case GL_INT_SAMPLER_3D:
395 case GL_UNSIGNED_INT_SAMPLER_3D:
396 return GL_TEXTURE_3D;
397
398 default:
399 UNREACHABLE();
400 return 0;
401 }
402 }
403
IsMatrixType(GLenum type)404 bool IsMatrixType(GLenum type)
405 {
406 return VariableRowCount(type) > 1;
407 }
408
TransposeMatrixType(GLenum type)409 GLenum TransposeMatrixType(GLenum type)
410 {
411 if (!IsMatrixType(type))
412 {
413 return type;
414 }
415
416 switch (type)
417 {
418 case GL_FLOAT_MAT2: return GL_FLOAT_MAT2;
419 case GL_FLOAT_MAT3: return GL_FLOAT_MAT3;
420 case GL_FLOAT_MAT4: return GL_FLOAT_MAT4;
421 case GL_FLOAT_MAT2x3: return GL_FLOAT_MAT3x2;
422 case GL_FLOAT_MAT3x2: return GL_FLOAT_MAT2x3;
423 case GL_FLOAT_MAT2x4: return GL_FLOAT_MAT4x2;
424 case GL_FLOAT_MAT4x2: return GL_FLOAT_MAT2x4;
425 case GL_FLOAT_MAT3x4: return GL_FLOAT_MAT4x3;
426 case GL_FLOAT_MAT4x3: return GL_FLOAT_MAT3x4;
427 default: UNREACHABLE(); return GL_NONE;
428 }
429 }
430
MatrixRegisterCount(GLenum type,bool isRowMajorMatrix)431 int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
432 {
433 ASSERT(IsMatrixType(type));
434 return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
435 }
436
MatrixComponentCount(GLenum type,bool isRowMajorMatrix)437 int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
438 {
439 ASSERT(IsMatrixType(type));
440 return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
441 }
442
VariableRegisterCount(GLenum type)443 int VariableRegisterCount(GLenum type)
444 {
445 return IsMatrixType(type) ? VariableColumnCount(type) : 1;
446 }
447
AllocateFirstFreeBits(unsigned int * bits,unsigned int allocationSize,unsigned int bitsSize)448 int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
449 {
450 ASSERT(allocationSize <= bitsSize);
451
452 unsigned int mask = std::numeric_limits<unsigned int>::max() >> (std::numeric_limits<unsigned int>::digits - allocationSize);
453
454 for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
455 {
456 if ((*bits & mask) == 0)
457 {
458 *bits |= mask;
459 return i;
460 }
461
462 mask <<= 1;
463 }
464
465 return -1;
466 }
467
468 static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_X - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 1, "Unexpected GL cube map enum value.");
469 static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 2, "Unexpected GL cube map enum value.");
470 static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 3, "Unexpected GL cube map enum value.");
471 static_assert(GL_TEXTURE_CUBE_MAP_POSITIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 4, "Unexpected GL cube map enum value.");
472 static_assert(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z - GL_TEXTURE_CUBE_MAP_POSITIVE_X == 5, "Unexpected GL cube map enum value.");
473
IsCubeMapTextureTarget(GLenum target)474 bool IsCubeMapTextureTarget(GLenum target)
475 {
476 return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
477 }
478
CubeMapTextureTargetToLayerIndex(GLenum target)479 size_t CubeMapTextureTargetToLayerIndex(GLenum target)
480 {
481 ASSERT(IsCubeMapTextureTarget(target));
482 return target - static_cast<size_t>(FirstCubeMapTextureTarget);
483 }
484
LayerIndexToCubeMapTextureTarget(size_t index)485 GLenum LayerIndexToCubeMapTextureTarget(size_t index)
486 {
487 ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
488 return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
489 }
490
ComputeIndexRange(GLenum indexType,const GLvoid * indices,size_t count,bool primitiveRestartEnabled)491 IndexRange ComputeIndexRange(GLenum indexType,
492 const GLvoid *indices,
493 size_t count,
494 bool primitiveRestartEnabled)
495 {
496 switch (indexType)
497 {
498 case GL_UNSIGNED_BYTE:
499 return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
500 primitiveRestartEnabled,
501 GetPrimitiveRestartIndex(indexType));
502 case GL_UNSIGNED_SHORT:
503 return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
504 primitiveRestartEnabled,
505 GetPrimitiveRestartIndex(indexType));
506 case GL_UNSIGNED_INT:
507 return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
508 primitiveRestartEnabled,
509 GetPrimitiveRestartIndex(indexType));
510 default:
511 UNREACHABLE();
512 return IndexRange();
513 }
514 }
515
GetPrimitiveRestartIndex(GLenum indexType)516 GLuint GetPrimitiveRestartIndex(GLenum indexType)
517 {
518 switch (indexType)
519 {
520 case GL_UNSIGNED_BYTE:
521 return 0xFF;
522 case GL_UNSIGNED_SHORT:
523 return 0xFFFF;
524 case GL_UNSIGNED_INT:
525 return 0xFFFFFFFF;
526 default:
527 UNREACHABLE();
528 return 0;
529 }
530 }
531
IsTriangleMode(GLenum drawMode)532 bool IsTriangleMode(GLenum drawMode)
533 {
534 switch (drawMode)
535 {
536 case GL_TRIANGLES:
537 case GL_TRIANGLE_FAN:
538 case GL_TRIANGLE_STRIP:
539 return true;
540 case GL_POINTS:
541 case GL_LINES:
542 case GL_LINE_LOOP:
543 case GL_LINE_STRIP:
544 return false;
545 default: UNREACHABLE();
546 }
547
548 return false;
549 }
550
551 // [OpenGL ES SL 3.00.4] Section 11 p. 120
552 // Vertex Outs/Fragment Ins packing priorities
VariableSortOrder(GLenum type)553 int VariableSortOrder(GLenum type)
554 {
555 switch (type)
556 {
557 // 1. Arrays of mat4 and mat4
558 // Non-square matrices of type matCxR consume the same space as a square
559 // matrix of type matN where N is the greater of C and R
560 case GL_FLOAT_MAT4:
561 case GL_FLOAT_MAT2x4:
562 case GL_FLOAT_MAT3x4:
563 case GL_FLOAT_MAT4x2:
564 case GL_FLOAT_MAT4x3:
565 return 0;
566
567 // 2. Arrays of mat2 and mat2 (since they occupy full rows)
568 case GL_FLOAT_MAT2:
569 return 1;
570
571 // 3. Arrays of vec4 and vec4
572 case GL_FLOAT_VEC4:
573 case GL_INT_VEC4:
574 case GL_BOOL_VEC4:
575 case GL_UNSIGNED_INT_VEC4:
576 return 2;
577
578 // 4. Arrays of mat3 and mat3
579 case GL_FLOAT_MAT3:
580 case GL_FLOAT_MAT2x3:
581 case GL_FLOAT_MAT3x2:
582 return 3;
583
584 // 5. Arrays of vec3 and vec3
585 case GL_FLOAT_VEC3:
586 case GL_INT_VEC3:
587 case GL_BOOL_VEC3:
588 case GL_UNSIGNED_INT_VEC3:
589 return 4;
590
591 // 6. Arrays of vec2 and vec2
592 case GL_FLOAT_VEC2:
593 case GL_INT_VEC2:
594 case GL_BOOL_VEC2:
595 case GL_UNSIGNED_INT_VEC2:
596 return 5;
597
598 // 7. Single component types
599 case GL_FLOAT:
600 case GL_INT:
601 case GL_BOOL:
602 case GL_UNSIGNED_INT:
603 case GL_SAMPLER_2D:
604 case GL_SAMPLER_CUBE:
605 case GL_SAMPLER_EXTERNAL_OES:
606 case GL_SAMPLER_2D_RECT_ARB:
607 case GL_SAMPLER_2D_ARRAY:
608 case GL_SAMPLER_3D:
609 case GL_INT_SAMPLER_2D:
610 case GL_INT_SAMPLER_3D:
611 case GL_INT_SAMPLER_CUBE:
612 case GL_INT_SAMPLER_2D_ARRAY:
613 case GL_UNSIGNED_INT_SAMPLER_2D:
614 case GL_UNSIGNED_INT_SAMPLER_3D:
615 case GL_UNSIGNED_INT_SAMPLER_CUBE:
616 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
617 case GL_SAMPLER_2D_SHADOW:
618 case GL_SAMPLER_2D_ARRAY_SHADOW:
619 case GL_SAMPLER_CUBE_SHADOW:
620 return 6;
621
622 default:
623 UNREACHABLE();
624 return 0;
625 }
626 }
627
ParseUniformName(const std::string & name,size_t * outSubscript)628 std::string ParseUniformName(const std::string &name, size_t *outSubscript)
629 {
630 // Strip any trailing array operator and retrieve the subscript
631 size_t open = name.find_last_of('[');
632 size_t close = name.find_last_of(']');
633 bool hasIndex = (open != std::string::npos) && (close == name.length() - 1);
634 if (!hasIndex)
635 {
636 if (outSubscript)
637 {
638 *outSubscript = GL_INVALID_INDEX;
639 }
640 return name;
641 }
642
643 if (outSubscript)
644 {
645 int index = atoi(name.substr(open + 1).c_str());
646 if (index >= 0)
647 {
648 *outSubscript = index;
649 }
650 else
651 {
652 *outSubscript = GL_INVALID_INDEX;
653 }
654 }
655
656 return name.substr(0, open);
657 }
658
659 template <>
ConvertToGLuint(GLfloat param)660 GLuint ConvertToGLuint(GLfloat param)
661 {
662 return uiround<GLuint>(param);
663 }
664
665 template <>
ConvertToGLint(GLfloat param)666 GLint ConvertToGLint(GLfloat param)
667 {
668 return iround<GLint>(param);
669 }
670
671 template <>
ConvertFromGLfloat(GLfloat param)672 GLint ConvertFromGLfloat(GLfloat param)
673 {
674 return iround<GLint>(param);
675 }
676 template <>
ConvertFromGLfloat(GLfloat param)677 GLuint ConvertFromGLfloat(GLfloat param)
678 {
679 return uiround<GLuint>(param);
680 }
681
ParseAndStripArrayIndex(std::string * name)682 unsigned int ParseAndStripArrayIndex(std::string *name)
683 {
684 unsigned int subscript = GL_INVALID_INDEX;
685
686 // Strip any trailing array operator and retrieve the subscript
687 size_t open = name->find_last_of('[');
688 size_t close = name->find_last_of(']');
689 if (open != std::string::npos && close == name->length() - 1)
690 {
691 subscript = atoi(name->c_str() + open + 1);
692 name->erase(open);
693 }
694
695 return subscript;
696 }
697
698 } // namespace gl
699
700 namespace egl
701 {
702 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
703 "Unexpected EGL cube map enum value.");
704 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
705 "Unexpected EGL cube map enum value.");
706 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
707 "Unexpected EGL cube map enum value.");
708 static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
709 "Unexpected EGL cube map enum value.");
710 static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
711 "Unexpected EGL cube map enum value.");
712
IsCubeMapTextureTarget(EGLenum target)713 bool IsCubeMapTextureTarget(EGLenum target)
714 {
715 return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
716 }
717
CubeMapTextureTargetToLayerIndex(EGLenum target)718 size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
719 {
720 ASSERT(IsCubeMapTextureTarget(target));
721 return target - static_cast<size_t>(FirstCubeMapTextureTarget);
722 }
723
LayerIndexToCubeMapTextureTarget(size_t index)724 EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
725 {
726 ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
727 return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
728 }
729
IsTextureTarget(EGLenum target)730 bool IsTextureTarget(EGLenum target)
731 {
732 switch (target)
733 {
734 case EGL_GL_TEXTURE_2D_KHR:
735 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
736 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
737 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
738 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
739 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
740 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
741 case EGL_GL_TEXTURE_3D_KHR:
742 return true;
743
744 default:
745 return false;
746 }
747 }
748
IsRenderbufferTarget(EGLenum target)749 bool IsRenderbufferTarget(EGLenum target)
750 {
751 return target == EGL_GL_RENDERBUFFER_KHR;
752 }
753 } // namespace egl
754
755 namespace egl_gl
756 {
EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget)757 GLenum EGLCubeMapTargetToGLCubeMapTarget(EGLenum eglTarget)
758 {
759 ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
760 return gl::LayerIndexToCubeMapTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
761 }
762
EGLImageTargetToGLTextureTarget(EGLenum eglTarget)763 GLenum EGLImageTargetToGLTextureTarget(EGLenum eglTarget)
764 {
765 switch (eglTarget)
766 {
767 case EGL_GL_TEXTURE_2D_KHR:
768 return GL_TEXTURE_2D;
769
770 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
771 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
772 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
773 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
774 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
775 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
776 return EGLCubeMapTargetToGLCubeMapTarget(eglTarget);
777
778 case EGL_GL_TEXTURE_3D_KHR:
779 return GL_TEXTURE_3D;
780
781 default:
782 UNREACHABLE();
783 return GL_NONE;
784 }
785 }
786
EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)787 GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
788 {
789 return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
790 }
791 } // namespace egl_gl
792
793 #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
getTempPath()794 std::string getTempPath()
795 {
796 #ifdef ANGLE_PLATFORM_WINDOWS
797 char path[MAX_PATH];
798 DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path);
799 if (pathLen == 0)
800 {
801 UNREACHABLE();
802 return std::string();
803 }
804
805 UINT unique = GetTempFileNameA(path, "sh", 0, path);
806 if (unique == 0)
807 {
808 UNREACHABLE();
809 return std::string();
810 }
811
812 return path;
813 #else
814 UNIMPLEMENTED();
815 return "";
816 #endif
817 }
818
writeFile(const char * path,const void * content,size_t size)819 void writeFile(const char* path, const void* content, size_t size)
820 {
821 FILE* file = fopen(path, "w");
822 if (!file)
823 {
824 UNREACHABLE();
825 return;
826 }
827
828 fwrite(content, sizeof(char), size, file);
829 fclose(file);
830 }
831 #endif // !ANGLE_ENABLE_WINDOWS_STORE
832
833 #if defined (ANGLE_PLATFORM_WINDOWS)
834
835 // Causes the thread to relinquish the remainder of its time slice to any
836 // other thread that is ready to run.If there are no other threads ready
837 // to run, the function returns immediately, and the thread continues execution.
ScheduleYield()838 void ScheduleYield()
839 {
840 Sleep(0);
841 }
842
843 #endif
844