1 //
2 // Copyright 2012 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 // angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2
8
9 #ifndef LIBANGLE_ANGLETYPES_H_
10 #define LIBANGLE_ANGLETYPES_H_
11
12 #include "common/Color.h"
13 #include "common/FixedVector.h"
14 #include "common/PackedEnums.h"
15 #include "common/bitset_utils.h"
16 #include "common/vector_utils.h"
17 #include "libANGLE/Constants.h"
18 #include "libANGLE/Error.h"
19 #include "libANGLE/RefCountObject.h"
20
21 #include <inttypes.h>
22 #include <stdint.h>
23
24 #include <bitset>
25 #include <map>
26 #include <unordered_map>
27
28 namespace gl
29 {
30 class Buffer;
31 class Texture;
32
33 struct Rectangle
34 {
RectangleRectangle35 Rectangle() : x(0), y(0), width(0), height(0) {}
RectangleRectangle36 constexpr Rectangle(int x_in, int y_in, int width_in, int height_in)
37 : x(x_in), y(y_in), width(width_in), height(height_in)
38 {}
39
x0Rectangle40 int x0() const { return x; }
y0Rectangle41 int y0() const { return y; }
x1Rectangle42 int x1() const { return x + width; }
y1Rectangle43 int y1() const { return y + height; }
44
isReversedXRectangle45 bool isReversedX() const { return width < 0; }
isReversedYRectangle46 bool isReversedY() const { return height < 0; }
47
48 // Returns a rectangle with the same area but flipped in X, Y, neither or both.
49 Rectangle flip(bool flipX, bool flipY) const;
50
51 // Returns a rectangle with the same area but with height and width guaranteed to be positive.
52 Rectangle removeReversal() const;
53
54 bool encloses(const gl::Rectangle &inside) const;
55
56 int x;
57 int y;
58 int width;
59 int height;
60 };
61
62 bool operator==(const Rectangle &a, const Rectangle &b);
63 bool operator!=(const Rectangle &a, const Rectangle &b);
64
65 bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection);
66
67 struct Offset
68 {
OffsetOffset69 constexpr Offset() : x(0), y(0), z(0) {}
OffsetOffset70 constexpr Offset(int x_in, int y_in, int z_in) : x(x_in), y(y_in), z(z_in) {}
71
72 int x;
73 int y;
74 int z;
75 };
76
77 constexpr Offset kOffsetZero(0, 0, 0);
78
79 bool operator==(const Offset &a, const Offset &b);
80 bool operator!=(const Offset &a, const Offset &b);
81
82 struct Extents
83 {
ExtentsExtents84 Extents() : width(0), height(0), depth(0) {}
ExtentsExtents85 Extents(int width_, int height_, int depth_) : width(width_), height(height_), depth(depth_) {}
86
87 Extents(const Extents &other) = default;
88 Extents &operator=(const Extents &other) = default;
89
emptyExtents90 bool empty() const { return (width * height * depth) == 0; }
91
92 int width;
93 int height;
94 int depth;
95 };
96
97 bool operator==(const Extents &lhs, const Extents &rhs);
98 bool operator!=(const Extents &lhs, const Extents &rhs);
99
100 struct Box
101 {
BoxBox102 Box() : x(0), y(0), z(0), width(0), height(0), depth(0) {}
BoxBox103 Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in)
104 : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in)
105 {}
BoxBox106 Box(const Offset &offset, const Extents &size)
107 : x(offset.x),
108 y(offset.y),
109 z(offset.z),
110 width(size.width),
111 height(size.height),
112 depth(size.depth)
113 {}
114 bool operator==(const Box &other) const;
115 bool operator!=(const Box &other) const;
116 Rectangle toRect() const;
117
118 int x;
119 int y;
120 int z;
121 int width;
122 int height;
123 int depth;
124 };
125
126 struct RasterizerState final
127 {
128 // This will zero-initialize the struct, including padding.
129 RasterizerState();
130 RasterizerState(const RasterizerState &other);
131
132 bool cullFace;
133 CullFaceMode cullMode;
134 GLenum frontFace;
135
136 bool polygonOffsetFill;
137 GLfloat polygonOffsetFactor;
138 GLfloat polygonOffsetUnits;
139
140 bool pointDrawMode;
141 bool multiSample;
142
143 bool rasterizerDiscard;
144
145 bool dither;
146 };
147
148 bool operator==(const RasterizerState &a, const RasterizerState &b);
149 bool operator!=(const RasterizerState &a, const RasterizerState &b);
150
151 struct BlendState final
152 {
153 // This will zero-initialize the struct, including padding.
154 BlendState();
155 BlendState(const BlendState &other);
156
157 bool blend;
158 GLenum sourceBlendRGB;
159 GLenum destBlendRGB;
160 GLenum sourceBlendAlpha;
161 GLenum destBlendAlpha;
162 GLenum blendEquationRGB;
163 GLenum blendEquationAlpha;
164
165 bool colorMaskRed;
166 bool colorMaskGreen;
167 bool colorMaskBlue;
168 bool colorMaskAlpha;
169 };
170
171 bool operator==(const BlendState &a, const BlendState &b);
172 bool operator!=(const BlendState &a, const BlendState &b);
173
174 struct DepthStencilState final
175 {
176 // This will zero-initialize the struct, including padding.
177 DepthStencilState();
178 DepthStencilState(const DepthStencilState &other);
179
180 bool depthTest;
181 GLenum depthFunc;
182 bool depthMask;
183
184 bool stencilTest;
185 GLenum stencilFunc;
186 GLuint stencilMask;
187 GLenum stencilFail;
188 GLenum stencilPassDepthFail;
189 GLenum stencilPassDepthPass;
190 GLuint stencilWritemask;
191 GLenum stencilBackFunc;
192 GLuint stencilBackMask;
193 GLenum stencilBackFail;
194 GLenum stencilBackPassDepthFail;
195 GLenum stencilBackPassDepthPass;
196 GLuint stencilBackWritemask;
197 };
198
199 bool operator==(const DepthStencilState &a, const DepthStencilState &b);
200 bool operator!=(const DepthStencilState &a, const DepthStencilState &b);
201
202 // Packs a sampler state for completeness checks:
203 // * minFilter: 5 values (3 bits)
204 // * magFilter: 2 values (1 bit)
205 // * wrapS: 3 values (2 bits)
206 // * wrapT: 3 values (2 bits)
207 // * compareMode: 1 bit (for == GL_NONE).
208 // This makes a total of 9 bits. We can pack this easily into 32 bits:
209 // * minFilter: 8 bits
210 // * magFilter: 8 bits
211 // * wrapS: 8 bits
212 // * wrapT: 4 bits
213 // * compareMode: 4 bits
214
215 struct PackedSamplerCompleteness
216 {
217 uint8_t minFilter;
218 uint8_t magFilter;
219 uint8_t wrapS;
220 uint8_t wrapTCompareMode;
221 };
222
223 static_assert(sizeof(PackedSamplerCompleteness) == sizeof(uint32_t), "Unexpected size");
224
225 // State from Table 6.10 (state per sampler object)
226 class SamplerState final
227 {
228 public:
229 // This will zero-initialize the struct, including padding.
230 SamplerState();
231 SamplerState(const SamplerState &other);
232
233 static SamplerState CreateDefaultForTarget(TextureType type);
234
getMinFilter()235 GLenum getMinFilter() const { return mMinFilter; }
236
237 void setMinFilter(GLenum minFilter);
238
getMagFilter()239 GLenum getMagFilter() const { return mMagFilter; }
240
241 void setMagFilter(GLenum magFilter);
242
getWrapS()243 GLenum getWrapS() const { return mWrapS; }
244
245 void setWrapS(GLenum wrapS);
246
getWrapT()247 GLenum getWrapT() const { return mWrapT; }
248
249 void setWrapT(GLenum wrapT);
250
getWrapR()251 GLenum getWrapR() const { return mWrapR; }
252
253 void setWrapR(GLenum wrapR);
254
getMaxAnisotropy()255 float getMaxAnisotropy() const { return mMaxAnisotropy; }
256
257 void setMaxAnisotropy(float maxAnisotropy);
258
getMinLod()259 GLfloat getMinLod() const { return mMinLod; }
260
261 void setMinLod(GLfloat minLod);
262
getMaxLod()263 GLfloat getMaxLod() const { return mMaxLod; }
264
265 void setMaxLod(GLfloat maxLod);
266
getCompareMode()267 GLenum getCompareMode() const { return mCompareMode; }
268
269 void setCompareMode(GLenum compareMode);
270
getCompareFunc()271 GLenum getCompareFunc() const { return mCompareFunc; }
272
273 void setCompareFunc(GLenum compareFunc);
274
getSRGBDecode()275 GLenum getSRGBDecode() const { return mSRGBDecode; }
276
277 void setSRGBDecode(GLenum sRGBDecode);
278
279 void setBorderColor(const ColorGeneric &color);
280
getBorderColor()281 const ColorGeneric &getBorderColor() const { return mBorderColor; }
282
sameCompleteness(const SamplerState & samplerState)283 bool sameCompleteness(const SamplerState &samplerState) const
284 {
285 return mCompleteness.packed == samplerState.mCompleteness.packed;
286 }
287
288 private:
289 void updateWrapTCompareMode();
290
291 GLenum mMinFilter;
292 GLenum mMagFilter;
293
294 GLenum mWrapS;
295 GLenum mWrapT;
296 GLenum mWrapR;
297
298 // From EXT_texture_filter_anisotropic
299 float mMaxAnisotropy;
300
301 GLfloat mMinLod;
302 GLfloat mMaxLod;
303
304 GLenum mCompareMode;
305 GLenum mCompareFunc;
306
307 GLenum mSRGBDecode;
308
309 ColorGeneric mBorderColor;
310
311 union Completeness
312 {
313 uint32_t packed;
314 PackedSamplerCompleteness typed;
315 };
316
317 Completeness mCompleteness;
318 };
319
320 bool operator==(const SamplerState &a, const SamplerState &b);
321 bool operator!=(const SamplerState &a, const SamplerState &b);
322
323 struct DrawArraysIndirectCommand
324 {
325 GLuint count;
326 GLuint instanceCount;
327 GLuint first;
328 GLuint baseInstance;
329 };
330 static_assert(sizeof(DrawArraysIndirectCommand) == 16,
331 "Unexpected size of DrawArraysIndirectCommand");
332
333 struct DrawElementsIndirectCommand
334 {
335 GLuint count;
336 GLuint primCount;
337 GLuint firstIndex;
338 GLint baseVertex;
339 GLuint baseInstance;
340 };
341 static_assert(sizeof(DrawElementsIndirectCommand) == 20,
342 "Unexpected size of DrawElementsIndirectCommand");
343
344 struct ImageUnit
345 {
346 ImageUnit();
347 ImageUnit(const ImageUnit &other);
348 ~ImageUnit();
349
350 BindingPointer<Texture> texture;
351 GLint level;
352 GLboolean layered;
353 GLint layer;
354 GLenum access;
355 GLenum format;
356 };
357
358 using ImageUnitTextureTypeMap = std::map<unsigned int, gl::TextureType>;
359
360 struct PixelStoreStateBase
361 {
362 GLint alignment = 4;
363 GLint rowLength = 0;
364 GLint skipRows = 0;
365 GLint skipPixels = 0;
366 GLint imageHeight = 0;
367 GLint skipImages = 0;
368 };
369
370 struct PixelUnpackState : PixelStoreStateBase
371 {};
372
373 struct PixelPackState : PixelStoreStateBase
374 {
375 bool reverseRowOrder = false;
376 };
377
378 // Used in Program and VertexArray.
379 using AttributesMask = angle::BitSet<MAX_VERTEX_ATTRIBS>;
380
381 // Used in Program
382 using UniformBlockBindingMask = angle::BitSet<IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS>;
383
384 // Used in Framebuffer / Program
385 using DrawBufferMask = angle::BitSet<IMPLEMENTATION_MAX_DRAW_BUFFERS>;
386
387 class BlendStateExt final
388 {
389 static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS == 8, "Only up to 8 draw buffers supported.");
390
391 public:
392 template <typename ElementType, size_t ElementCount>
393 struct StorageType final
394 {
395 static_assert(ElementCount <= 256, "ElementCount cannot exceed 256.");
396
397 #if defined(ANGLE_IS_64_BIT_CPU)
398 // Always use uint64_t on 64-bit systems
399 static constexpr size_t kBits = 8;
400 #else
401 static constexpr size_t kBits = ElementCount > 16 ? 8 : 4;
402 #endif
403
404 using Type = typename std::conditional<kBits == 8, uint64_t, uint32_t>::type;
405
406 static constexpr Type kMaxValueMask = (kBits == 8) ? 0xFF : 0xF;
407
GetMaskfinal408 static constexpr Type GetMask(const size_t drawBuffers)
409 {
410 ASSERT(drawBuffers <= IMPLEMENTATION_MAX_DRAW_BUFFERS);
411 return static_cast<Type>(0xFFFFFFFFFFFFFFFFull >> (64 - drawBuffers * kBits));
412 }
413
414 // A multiplier that is used to replicate 4- or 8-bit value 8 times.
415 static constexpr Type kReplicator = (kBits == 8) ? 0x0101010101010101ull : 0x11111111;
416
417 // Extract packed `Bits`-bit value of index `index`. `values` variable contains up to 8
418 // packed values.
GetValueIndexedfinal419 static constexpr ElementType GetValueIndexed(const size_t index, const Type values)
420 {
421 ASSERT(index < IMPLEMENTATION_MAX_DRAW_BUFFERS);
422
423 return static_cast<ElementType>((values >> (index * kBits)) & kMaxValueMask);
424 }
425
426 // Replicate `Bits`-bit value 8 times and mask the result.
GetReplicatedValuefinal427 static constexpr Type GetReplicatedValue(const ElementType value, const Type mask)
428 {
429 ASSERT(static_cast<size_t>(value) <= kMaxValueMask);
430 return (static_cast<size_t>(value) * kReplicator) & mask;
431 }
432
433 // Replace `Bits`-bit value of index `index` in `target` with `value`.
SetValueIndexedfinal434 static constexpr void SetValueIndexed(const size_t index,
435 const ElementType value,
436 Type *target)
437 {
438 ASSERT(static_cast<size_t>(value) <= kMaxValueMask);
439 ASSERT(index < IMPLEMENTATION_MAX_DRAW_BUFFERS);
440
441 // Bitmask with set bits that contain the value of index `index`.
442 const Type selector = kMaxValueMask << (index * kBits);
443
444 // Shift the new `value` to its position in the packed value.
445 const Type builtValue = static_cast<Type>(value) << (index * kBits);
446
447 // Mark differing bits of `target` and `builtValue`, then flip the bits on those
448 // positions in `target`.
449 // Taken from https://graphics.stanford.edu/~seander/bithacks.html#MaskedMerge
450 *target = *target ^ ((*target ^ builtValue) & selector);
451 }
452
453 // Compare two packed sets of eight 4-bit values and return an 8-bit diff mask.
GetDiffMaskfinal454 static constexpr DrawBufferMask GetDiffMask(const uint32_t packedValue1,
455 const uint32_t packedValue2)
456 {
457 uint32_t diff = packedValue1 ^ packedValue2;
458
459 // For each 4-bit value that is different between inputs, set the msb to 1 and other
460 // bits to 0.
461 diff = (diff | ((diff & 0x77777777) + 0x77777777)) & 0x88888888;
462
463 // By this point, `diff` looks like a...b...c...d...e...f...g...h... (dots mean zeros).
464 // To get DrawBufferMask, we need to compress this 32-bit value to 8 bits, i.e. abcdefgh
465
466 // Multiplying the lower half of `diff` by 0x249 (0x200 + 0x40 + 0x8 + 0x1) produces:
467 // ................e...f...g...h... +
468 // .............e...f...g...h...... +
469 // ..........e...f...g...h......... +
470 // .......e...f...g...h............
471 // ________________________________ =
472 // .......e..ef.efgefghfgh.gh..h...
473 // ^^^^
474 // Similar operation is applied to the upper word.
475 // This calculation could be replaced with a single PEXT instruction from BMI2 set.
476 diff = ((((diff & 0xFFFF0000) * 0x249) >> 24) & 0xF0) | (((diff * 0x249) >> 12) & 0xF);
477
478 return DrawBufferMask(diff);
479 }
480
481 // Compare two packed sets of eight 8-bit values and return an 8-bit diff mask.
GetDiffMaskfinal482 static constexpr DrawBufferMask GetDiffMask(const uint64_t packedValue1,
483 const uint64_t packedValue2)
484 {
485 uint64_t diff = packedValue1 ^ packedValue2;
486
487 // For each 8-bit value that is different between inputs, set the msb to 1 and other
488 // bits to 0.
489 diff = (diff | ((diff & 0x7F7F7F7F7F7F7F7F) + 0x7F7F7F7F7F7F7F7F)) & 0x8080808080808080;
490
491 // By this point, `diff` looks like (dots mean zeros):
492 // a.......b.......c.......d.......e.......f.......g.......h.......
493 // To get DrawBufferMask, we need to compress this 64-bit value to 8 bits, i.e. abcdefgh
494
495 // Multiplying `diff` by 0x0002040810204081 produces:
496 // a.......b.......c.......d.......e.......f.......g.......h....... +
497 // .b.......c.......d.......e.......f.......g.......h.............. +
498 // ..c.......d.......e.......f.......g.......h..................... +
499 // ...d.......e.......f.......g.......h............................ +
500 // ....e.......f.......g.......h................................... +
501 // .....f.......g.......h.......................................... +
502 // ......g.......h................................................. +
503 // .......h........................................................
504 // ________________________________________________________________ =
505 // abcdefghbcdefgh.cdefgh..defgh...efgh....fgh.....gh......h.......
506 // ^^^^^^^^
507 // This operation could be replaced with a single PEXT instruction from BMI2 set.
508 diff = 0x0002040810204081 * diff >> 56;
509
510 return DrawBufferMask(static_cast<uint32_t>(diff));
511 }
512 };
513
514 using FactorStorage = StorageType<BlendFactorType, angle::EnumSize<BlendFactorType>()>;
515 using EquationStorage = StorageType<BlendEquationType, angle::EnumSize<BlendEquationType>()>;
516 using ColorMaskStorage = StorageType<uint8_t, 16>;
517
518 BlendStateExt(const size_t drawBuffers = 1);
519
520 BlendStateExt &operator=(const BlendStateExt &other);
521
522 ///////// Blending Toggle /////////
523
524 void setEnabled(const bool enabled);
525 void setEnabledIndexed(const size_t index, const bool enabled);
526
527 ///////// Color Write Mask /////////
528
PackColorMask(const bool red,const bool green,const bool blue,const bool alpha)529 static constexpr size_t PackColorMask(const bool red,
530 const bool green,
531 const bool blue,
532 const bool alpha)
533 {
534 return (red ? 1 : 0) | (green ? 2 : 0) | (blue ? 4 : 0) | (alpha ? 8 : 0);
535 }
536
UnpackColorMask(const size_t value,bool * red,bool * green,bool * blue,bool * alpha)537 static constexpr void UnpackColorMask(const size_t value,
538 bool *red,
539 bool *green,
540 bool *blue,
541 bool *alpha)
542 {
543 *red = static_cast<bool>(value & 1);
544 *green = static_cast<bool>(value & 2);
545 *blue = static_cast<bool>(value & 4);
546 *alpha = static_cast<bool>(value & 8);
547 }
548
549 ColorMaskStorage::Type expandColorMaskValue(const bool red,
550 const bool green,
551 const bool blue,
552 const bool alpha) const;
553 ColorMaskStorage::Type expandColorMaskIndexed(const size_t index) const;
554 void setColorMask(const bool red, const bool green, const bool blue, const bool alpha);
555 void setColorMaskIndexed(const size_t index, const uint8_t value);
556 void setColorMaskIndexed(const size_t index,
557 const bool red,
558 const bool green,
559 const bool blue,
560 const bool alpha);
561 uint8_t getColorMaskIndexed(const size_t index) const;
562 void getColorMaskIndexed(const size_t index,
563 bool *red,
564 bool *green,
565 bool *blue,
566 bool *alpha) const;
567 DrawBufferMask compareColorMask(ColorMaskStorage::Type other) const;
568
569 ///////// Blend Equation /////////
570
571 EquationStorage::Type expandEquationValue(const GLenum mode) const;
572 EquationStorage::Type expandEquationColorIndexed(const size_t index) const;
573 EquationStorage::Type expandEquationAlphaIndexed(const size_t index) const;
574 void setEquations(const GLenum modeColor, const GLenum modeAlpha);
575 void setEquationsIndexed(const size_t index, const GLenum modeColor, const GLenum modeAlpha);
576 void setEquationsIndexed(const size_t index,
577 const size_t otherIndex,
578 const BlendStateExt &other);
579 GLenum getEquationColorIndexed(size_t index) const;
580 GLenum getEquationAlphaIndexed(size_t index) const;
581 DrawBufferMask compareEquations(const EquationStorage::Type color,
582 const EquationStorage::Type alpha) const;
583
584 ///////// Blend Factors /////////
585
586 FactorStorage::Type expandFactorValue(const GLenum func) const;
587 FactorStorage::Type expandSrcColorIndexed(const size_t index) const;
588 FactorStorage::Type expandDstColorIndexed(const size_t index) const;
589 FactorStorage::Type expandSrcAlphaIndexed(const size_t index) const;
590 FactorStorage::Type expandDstAlphaIndexed(const size_t index) const;
591 void setFactors(const GLenum srcColor,
592 const GLenum dstColor,
593 const GLenum srcAlpha,
594 const GLenum dstAlpha);
595 void setFactorsIndexed(const size_t index,
596 const GLenum srcColor,
597 const GLenum dstColor,
598 const GLenum srcAlpha,
599 const GLenum dstAlpha);
600 void setFactorsIndexed(const size_t index, const size_t otherIndex, const BlendStateExt &other);
601 GLenum getSrcColorIndexed(size_t index) const;
602 GLenum getDstColorIndexed(size_t index) const;
603 GLenum getSrcAlphaIndexed(size_t index) const;
604 GLenum getDstAlphaIndexed(size_t index) const;
605 DrawBufferMask compareFactors(const FactorStorage::Type srcColor,
606 const FactorStorage::Type dstColor,
607 const FactorStorage::Type srcAlpha,
608 const FactorStorage::Type dstAlpha) const;
609
610 ///////// Data Members /////////
611
612 const FactorStorage::Type mMaxFactorMask;
613 FactorStorage::Type mSrcColor;
614 FactorStorage::Type mDstColor;
615 FactorStorage::Type mSrcAlpha;
616 FactorStorage::Type mDstAlpha;
617
618 const EquationStorage::Type mMaxEquationMask;
619 EquationStorage::Type mEquationColor;
620 EquationStorage::Type mEquationAlpha;
621
622 const ColorMaskStorage::Type mMaxColorMask;
623 ColorMaskStorage::Type mColorMask;
624
625 const DrawBufferMask mMaxEnabledMask;
626 DrawBufferMask mEnabledMask;
627
628 const size_t mMaxDrawBuffers;
629 };
630
631 // Used in StateCache
632 using StorageBuffersMask = angle::BitSet<IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>;
633
634 template <typename T>
635 using TexLevelArray = std::array<T, IMPLEMENTATION_MAX_TEXTURE_LEVELS>;
636
637 enum class ComponentType
638 {
639 Float = 0,
640 Int = 1,
641 UnsignedInt = 2,
642 NoType = 3,
643 EnumCount = 4,
644 InvalidEnum = 4,
645 };
646
GLenumToComponentType(GLenum componentType)647 constexpr ComponentType GLenumToComponentType(GLenum componentType)
648 {
649 switch (componentType)
650 {
651 case GL_FLOAT:
652 return ComponentType::Float;
653 case GL_INT:
654 return ComponentType::Int;
655 case GL_UNSIGNED_INT:
656 return ComponentType::UnsignedInt;
657 case GL_NONE:
658 return ComponentType::NoType;
659 default:
660 return ComponentType::InvalidEnum;
661 }
662 }
663
664 constexpr angle::PackedEnumMap<ComponentType, uint32_t> kComponentMasks = {{
665 {ComponentType::Float, 0x10001},
666 {ComponentType::Int, 0x00001},
667 {ComponentType::UnsignedInt, 0x10000},
668 }};
669
670 constexpr size_t kMaxComponentTypeMaskIndex = 16;
671 using ComponentTypeMask = angle::BitSet<kMaxComponentTypeMaskIndex * 2>;
672
SetComponentTypeMask(ComponentType type,size_t index,ComponentTypeMask * mask)673 ANGLE_INLINE void SetComponentTypeMask(ComponentType type, size_t index, ComponentTypeMask *mask)
674 {
675 ASSERT(index <= kMaxComponentTypeMaskIndex);
676 *mask &= ~(0x10001 << index);
677 *mask |= kComponentMasks[type] << index;
678 }
679
GetComponentTypeMask(const ComponentTypeMask & mask,size_t index)680 ANGLE_INLINE ComponentType GetComponentTypeMask(const ComponentTypeMask &mask, size_t index)
681 {
682 ASSERT(index <= kMaxComponentTypeMaskIndex);
683 uint32_t mask_bits = static_cast<uint32_t>((mask.to_ulong() >> index) & 0x10001);
684 switch (mask_bits)
685 {
686 case 0x10001:
687 return ComponentType::Float;
688 case 0x00001:
689 return ComponentType::Int;
690 case 0x10000:
691 return ComponentType::UnsignedInt;
692 default:
693 return ComponentType::InvalidEnum;
694 }
695 }
696
697 bool ValidateComponentTypeMasks(unsigned long outputTypes,
698 unsigned long inputTypes,
699 unsigned long outputMask,
700 unsigned long inputMask);
701
702 using ContextID = uintptr_t;
703
704 constexpr size_t kCubeFaceCount = 6;
705
706 template <typename T>
707 using TextureTypeMap = angle::PackedEnumMap<TextureType, T>;
708 using TextureMap = TextureTypeMap<BindingPointer<Texture>>;
709
710 // ShaderVector can contain one item per shader. It differs from ShaderMap in that the values are
711 // not indexed by ShaderType.
712 template <typename T>
713 using ShaderVector = angle::FixedVector<T, static_cast<size_t>(ShaderType::EnumCount)>;
714
715 template <typename T>
716 using AttachmentArray = std::array<T, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;
717
718 using AttachmentsMask = angle::BitSet<IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;
719
720 template <typename T>
721 using DrawBuffersArray = std::array<T, IMPLEMENTATION_MAX_DRAW_BUFFERS>;
722
723 template <typename T>
724 using DrawBuffersVector = angle::FixedVector<T, IMPLEMENTATION_MAX_DRAW_BUFFERS>;
725
726 template <typename T>
727 using AttribArray = std::array<T, MAX_VERTEX_ATTRIBS>;
728
729 using ActiveTextureMask = angle::BitSet<IMPLEMENTATION_MAX_ACTIVE_TEXTURES>;
730
731 template <typename T>
732 using ActiveTextureArray = std::array<T, IMPLEMENTATION_MAX_ACTIVE_TEXTURES>;
733
734 using ActiveTextureTypeArray = ActiveTextureArray<TextureType>;
735
736 template <typename T>
737 using UniformBuffersArray = std::array<T, IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS>;
738 template <typename T>
739 using StorageBuffersArray = std::array<T, IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>;
740 template <typename T>
741 using AtomicCounterBuffersArray = std::array<T, IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS>;
742 using AtomicCounterBufferMask = angle::BitSet<IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS>;
743 template <typename T>
744 using ImagesArray = std::array<T, IMPLEMENTATION_MAX_IMAGE_UNITS>;
745
746 using ImageUnitMask = angle::BitSet<IMPLEMENTATION_MAX_IMAGE_UNITS>;
747
748 using SupportedSampleSet = std::set<GLuint>;
749
750 template <typename T>
751 using TransformFeedbackBuffersArray =
752 std::array<T, gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS>;
753
754 constexpr size_t kBarrierVectorDefaultSize = 16;
755
756 template <typename T>
757 using BarrierVector = angle::FastVector<T, kBarrierVectorDefaultSize>;
758
759 using BufferBarrierVector = BarrierVector<Buffer *>;
760
761 struct TextureAndLayout
762 {
763 Texture *texture;
764 GLenum layout;
765 };
766 using TextureBarrierVector = BarrierVector<TextureAndLayout>;
767
768 // OffsetBindingPointer.getSize() returns the size specified by the user, which may be larger than
769 // the size of the bound buffer. This function reduces the returned size to fit the bound buffer if
770 // necessary. Returns 0 if no buffer is bound or if integer overflow occurs.
771 GLsizeiptr GetBoundBufferAvailableSize(const OffsetBindingPointer<Buffer> &binding);
772
773 } // namespace gl
774
775 namespace rx
776 {
777 // A macro that determines whether an object has a given runtime type.
778 #if defined(__clang__)
779 # if __has_feature(cxx_rtti)
780 # define ANGLE_HAS_DYNAMIC_CAST 1
781 # endif
782 #elif !defined(NDEBUG) && (!defined(_MSC_VER) || defined(_CPPRTTI)) && \
783 (!defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || \
784 defined(__GXX_RTTI))
785 # define ANGLE_HAS_DYNAMIC_CAST 1
786 #endif
787
788 #ifdef ANGLE_HAS_DYNAMIC_CAST
789 # define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (dynamic_cast<type>(obj) != nullptr)
790 # undef ANGLE_HAS_DYNAMIC_CAST
791 #else
792 # define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (obj != nullptr)
793 #endif
794
795 // Downcast a base implementation object (EG TextureImpl to TextureD3D)
796 template <typename DestT, typename SrcT>
GetAs(SrcT * src)797 inline DestT *GetAs(SrcT *src)
798 {
799 ASSERT(ANGLE_HAS_DYNAMIC_TYPE(DestT *, src));
800 return static_cast<DestT *>(src);
801 }
802
803 template <typename DestT, typename SrcT>
GetAs(const SrcT * src)804 inline const DestT *GetAs(const SrcT *src)
805 {
806 ASSERT(ANGLE_HAS_DYNAMIC_TYPE(const DestT *, src));
807 return static_cast<const DestT *>(src);
808 }
809
810 #undef ANGLE_HAS_DYNAMIC_TYPE
811
812 // Downcast a GL object to an Impl (EG gl::Texture to rx::TextureD3D)
813 template <typename DestT, typename SrcT>
GetImplAs(SrcT * src)814 inline DestT *GetImplAs(SrcT *src)
815 {
816 return GetAs<DestT>(src->getImplementation());
817 }
818
819 template <typename DestT, typename SrcT>
SafeGetImplAs(SrcT * src)820 inline DestT *SafeGetImplAs(SrcT *src)
821 {
822 return src != nullptr ? GetAs<DestT>(src->getImplementation()) : nullptr;
823 }
824
825 } // namespace rx
826
827 #include "angletypes.inc"
828
829 namespace angle
830 {
831 // Zero-based for better array indexing
832 enum FramebufferBinding
833 {
834 FramebufferBindingRead = 0,
835 FramebufferBindingDraw,
836 FramebufferBindingSingletonMax,
837 FramebufferBindingBoth = FramebufferBindingSingletonMax,
838 FramebufferBindingMax,
839 FramebufferBindingUnknown = FramebufferBindingMax,
840 };
841
EnumToFramebufferBinding(GLenum enumValue)842 inline FramebufferBinding EnumToFramebufferBinding(GLenum enumValue)
843 {
844 switch (enumValue)
845 {
846 case GL_READ_FRAMEBUFFER:
847 return FramebufferBindingRead;
848 case GL_DRAW_FRAMEBUFFER:
849 return FramebufferBindingDraw;
850 case GL_FRAMEBUFFER:
851 return FramebufferBindingBoth;
852 default:
853 UNREACHABLE();
854 return FramebufferBindingUnknown;
855 }
856 }
857
FramebufferBindingToEnum(FramebufferBinding binding)858 inline GLenum FramebufferBindingToEnum(FramebufferBinding binding)
859 {
860 switch (binding)
861 {
862 case FramebufferBindingRead:
863 return GL_READ_FRAMEBUFFER;
864 case FramebufferBindingDraw:
865 return GL_DRAW_FRAMEBUFFER;
866 case FramebufferBindingBoth:
867 return GL_FRAMEBUFFER;
868 default:
869 UNREACHABLE();
870 return GL_NONE;
871 }
872 }
873
874 template <typename ObjT, typename ContextT>
875 class DestroyThenDelete
876 {
877 public:
DestroyThenDelete(const ContextT * context)878 DestroyThenDelete(const ContextT *context) : mContext(context) {}
879
operator()880 void operator()(ObjT *obj)
881 {
882 (void)(obj->onDestroy(mContext));
883 delete obj;
884 }
885
886 private:
887 const ContextT *mContext;
888 };
889
890 // Helper class for wrapping an onDestroy function.
891 template <typename ObjT, typename DeleterT>
892 class UniqueObjectPointerBase : angle::NonCopyable
893 {
894 public:
895 template <typename ContextT>
UniqueObjectPointerBase(const ContextT * context)896 UniqueObjectPointerBase(const ContextT *context) : mObject(nullptr), mDeleter(context)
897 {}
898
899 template <typename ContextT>
UniqueObjectPointerBase(ObjT * obj,const ContextT * context)900 UniqueObjectPointerBase(ObjT *obj, const ContextT *context) : mObject(obj), mDeleter(context)
901 {}
902
~UniqueObjectPointerBase()903 ~UniqueObjectPointerBase()
904 {
905 if (mObject)
906 {
907 mDeleter(mObject);
908 }
909 }
910
911 ObjT *operator->() const { return mObject; }
912
release()913 ObjT *release()
914 {
915 auto obj = mObject;
916 mObject = nullptr;
917 return obj;
918 }
919
get()920 ObjT *get() const { return mObject; }
921
reset(ObjT * obj)922 void reset(ObjT *obj)
923 {
924 if (mObject)
925 {
926 mDeleter(mObject);
927 }
928 mObject = obj;
929 }
930
931 private:
932 ObjT *mObject;
933 DeleterT mDeleter;
934 };
935
936 template <typename ObjT, typename ContextT>
937 using UniqueObjectPointer = UniqueObjectPointerBase<ObjT, DestroyThenDelete<ObjT, ContextT>>;
938
939 } // namespace angle
940
941 namespace gl
942 {
943 class State;
944 } // namespace gl
945
946 #endif // LIBANGLE_ANGLETYPES_H_
947