• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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