1 //
2 // Copyright (c) 2012-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 // 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/bitset_utils.h"
13 #include "libANGLE/Constants.h"
14 #include "libANGLE/Error.h"
15 #include "libANGLE/PackedGLEnums.h"
16 #include "libANGLE/RefCountObject.h"
17 
18 #include <stdint.h>
19 
20 #include <bitset>
21 #include <map>
22 #include <unordered_map>
23 
24 namespace gl
25 {
26 class Buffer;
27 class Texture;
28 
29 enum PrimitiveType
30 {
31     PRIMITIVE_POINTS,
32     PRIMITIVE_LINES,
33     PRIMITIVE_LINE_STRIP,
34     PRIMITIVE_LINE_LOOP,
35     PRIMITIVE_TRIANGLES,
36     PRIMITIVE_TRIANGLE_STRIP,
37     PRIMITIVE_TRIANGLE_FAN,
38     PRIMITIVE_TYPE_MAX,
39 };
40 
41 PrimitiveType GetPrimitiveType(GLenum drawMode);
42 
43 enum SamplerType
44 {
45     SAMPLER_PIXEL,
46     SAMPLER_VERTEX,
47     SAMPLER_COMPUTE
48 };
49 
50 enum ShaderType
51 {
52     SHADER_VERTEX,
53     SHADER_FRAGMENT,
54     SHADER_GEOMETRY,
55     SHADER_COMPUTE,
56     SHADER_TYPE_MAX
57 };
58 
59 struct Rectangle
60 {
RectangleRectangle61     Rectangle() : x(0), y(0), width(0), height(0) {}
RectangleRectangle62     Rectangle(int x_in, int y_in, int width_in, int height_in)
63         : x(x_in), y(y_in), width(width_in), height(height_in)
64     {
65     }
66 
x0Rectangle67     int x0() const { return x; }
y0Rectangle68     int y0() const { return y; }
x1Rectangle69     int x1() const { return x + width; }
y1Rectangle70     int y1() const { return y + height; }
71 
72     int x;
73     int y;
74     int width;
75     int height;
76 };
77 
78 bool operator==(const Rectangle &a, const Rectangle &b);
79 bool operator!=(const Rectangle &a, const Rectangle &b);
80 
81 bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection);
82 
83 struct Offset
84 {
85     int x;
86     int y;
87     int z;
88 
OffsetOffset89     Offset() : x(0), y(0), z(0) { }
OffsetOffset90     Offset(int x_in, int y_in, int z_in) : x(x_in), y(y_in), z(z_in) { }
91 };
92 
93 bool operator==(const Offset &a, const Offset &b);
94 bool operator!=(const Offset &a, const Offset &b);
95 
96 struct Extents
97 {
98     int width;
99     int height;
100     int depth;
101 
ExtentsExtents102     Extents() : width(0), height(0), depth(0) { }
ExtentsExtents103     Extents(int width_, int height_, int depth_) : width(width_), height(height_), depth(depth_) { }
104 
105     Extents(const Extents &other) = default;
106     Extents &operator=(const Extents &other) = default;
107 
emptyExtents108     bool empty() const { return (width * height * depth) == 0; }
109 };
110 
111 bool operator==(const Extents &lhs, const Extents &rhs);
112 bool operator!=(const Extents &lhs, const Extents &rhs);
113 
114 struct Box
115 {
116     int x;
117     int y;
118     int z;
119     int width;
120     int height;
121     int depth;
122 
BoxBox123     Box() : x(0), y(0), z(0), width(0), height(0), depth(0) { }
BoxBox124     Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in) : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in) { }
BoxBox125     Box(const Offset &offset, const Extents &size) : x(offset.x), y(offset.y), z(offset.z), width(size.width), height(size.height), depth(size.depth) { }
126     bool operator==(const Box &other) const;
127     bool operator!=(const Box &other) const;
128 };
129 
130 struct RasterizerState final
131 {
132     // This will zero-initialize the struct, including padding.
133     RasterizerState();
134 
135     bool cullFace;
136     CullFaceMode cullMode;
137     GLenum frontFace;
138 
139     bool polygonOffsetFill;
140     GLfloat polygonOffsetFactor;
141     GLfloat polygonOffsetUnits;
142 
143     bool pointDrawMode;
144     bool multiSample;
145 
146     bool rasterizerDiscard;
147 };
148 
149 bool operator==(const RasterizerState &a, const RasterizerState &b);
150 bool operator!=(const RasterizerState &a, const RasterizerState &b);
151 
152 struct BlendState final
153 {
154     // This will zero-initialize the struct, including padding.
155     BlendState();
156     BlendState(const BlendState &other);
157 
158     bool blend;
159     GLenum sourceBlendRGB;
160     GLenum destBlendRGB;
161     GLenum sourceBlendAlpha;
162     GLenum destBlendAlpha;
163     GLenum blendEquationRGB;
164     GLenum blendEquationAlpha;
165 
166     bool colorMaskRed;
167     bool colorMaskGreen;
168     bool colorMaskBlue;
169     bool colorMaskAlpha;
170 
171     bool sampleAlphaToCoverage;
172 
173     bool dither;
174 };
175 
176 bool operator==(const BlendState &a, const BlendState &b);
177 bool operator!=(const BlendState &a, const BlendState &b);
178 
179 struct DepthStencilState final
180 {
181     // This will zero-initialize the struct, including padding.
182     DepthStencilState();
183     DepthStencilState(const DepthStencilState &other);
184 
185     bool depthTest;
186     GLenum depthFunc;
187     bool depthMask;
188 
189     bool stencilTest;
190     GLenum stencilFunc;
191     GLuint stencilMask;
192     GLenum stencilFail;
193     GLenum stencilPassDepthFail;
194     GLenum stencilPassDepthPass;
195     GLuint stencilWritemask;
196     GLenum stencilBackFunc;
197     GLuint stencilBackMask;
198     GLenum stencilBackFail;
199     GLenum stencilBackPassDepthFail;
200     GLenum stencilBackPassDepthPass;
201     GLuint stencilBackWritemask;
202 };
203 
204 bool operator==(const DepthStencilState &a, const DepthStencilState &b);
205 bool operator!=(const DepthStencilState &a, const DepthStencilState &b);
206 
207 // State from Table 6.10 (state per sampler object)
208 struct SamplerState final
209 {
210     // This will zero-initialize the struct, including padding.
211     SamplerState();
212     SamplerState(const SamplerState &other);
213 
214     static SamplerState CreateDefaultForTarget(GLenum target);
215 
216     GLenum minFilter;
217     GLenum magFilter;
218 
219     GLenum wrapS;
220     GLenum wrapT;
221     GLenum wrapR;
222 
223     // From EXT_texture_filter_anisotropic
224     float maxAnisotropy;
225 
226     GLfloat minLod;
227     GLfloat maxLod;
228 
229     GLenum compareMode;
230     GLenum compareFunc;
231 
232     GLenum sRGBDecode;
233 };
234 
235 bool operator==(const SamplerState &a, const SamplerState &b);
236 bool operator!=(const SamplerState &a, const SamplerState &b);
237 
238 struct DrawArraysIndirectCommand
239 {
240     GLuint count;
241     GLuint instanceCount;
242     GLuint first;
243     GLuint baseInstance;
244 };
245 static_assert(sizeof(DrawArraysIndirectCommand) == 16,
246               "Unexpected size of DrawArraysIndirectCommand");
247 
248 struct DrawElementsIndirectCommand
249 {
250     GLuint count;
251     GLuint primCount;
252     GLuint firstIndex;
253     GLint baseVertex;
254     GLuint baseInstance;
255 };
256 static_assert(sizeof(DrawElementsIndirectCommand) == 20,
257               "Unexpected size of DrawElementsIndirectCommand");
258 
259 struct ImageUnit
260 {
261     ImageUnit();
262     ImageUnit(const ImageUnit &other);
263     ~ImageUnit();
264 
265     BindingPointer<Texture> texture;
266     GLint level;
267     GLboolean layered;
268     GLint layer;
269     GLenum access;
270     GLenum format;
271 };
272 
273 struct PixelStoreStateBase
274 {
275     GLint alignment   = 4;
276     GLint rowLength   = 0;
277     GLint skipRows    = 0;
278     GLint skipPixels  = 0;
279     GLint imageHeight = 0;
280     GLint skipImages  = 0;
281 };
282 
283 struct PixelUnpackState : PixelStoreStateBase
284 {
285 };
286 
287 struct PixelPackState : PixelStoreStateBase
288 {
289     bool reverseRowOrder = false;
290 };
291 
292 // Used in Program and VertexArray.
293 using AttributesMask = angle::BitSet<MAX_VERTEX_ATTRIBS>;
294 
295 // Used in Program
296 using UniformBlockBindingMask = angle::BitSet<IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS>;
297 
298 // Used in Framebuffer
299 using DrawBufferMask = angle::BitSet<IMPLEMENTATION_MAX_DRAW_BUFFERS>;
300 
301 using ContextID = uintptr_t;
302 
303 constexpr size_t CUBE_FACE_COUNT = 6;
304 
305 using TextureMap = std::map<GLenum, BindingPointer<Texture>>;
306 
307 template <typename T>
308 using AttachmentArray = std::array<T, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;
309 
310 template <typename T>
311 using DrawBuffersArray = std::array<T, IMPLEMENTATION_MAX_DRAW_BUFFERS>;
312 
313 }  // namespace gl
314 
315 namespace rx
316 {
317 // A macro that determines whether an object has a given runtime type.
318 #if defined(__clang__)
319 #if __has_feature(cxx_rtti)
320 #define ANGLE_HAS_DYNAMIC_CAST 1
321 #endif
322 #elif !defined(NDEBUG) && (!defined(_MSC_VER) || defined(_CPPRTTI)) && (!defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || defined(__GXX_RTTI))
323 #define ANGLE_HAS_DYNAMIC_CAST 1
324 #endif
325 
326 #ifdef ANGLE_HAS_DYNAMIC_CAST
327 #define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (dynamic_cast<type >(obj) != nullptr)
328 #undef ANGLE_HAS_DYNAMIC_CAST
329 #else
330 #define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (obj != nullptr)
331 #endif
332 
333 // Downcast a base implementation object (EG TextureImpl to TextureD3D)
334 template <typename DestT, typename SrcT>
GetAs(SrcT * src)335 inline DestT *GetAs(SrcT *src)
336 {
337     ASSERT(ANGLE_HAS_DYNAMIC_TYPE(DestT*, src));
338     return static_cast<DestT*>(src);
339 }
340 
341 template <typename DestT, typename SrcT>
GetAs(const SrcT * src)342 inline const DestT *GetAs(const SrcT *src)
343 {
344     ASSERT(ANGLE_HAS_DYNAMIC_TYPE(const DestT*, src));
345     return static_cast<const DestT*>(src);
346 }
347 
348 #undef ANGLE_HAS_DYNAMIC_TYPE
349 
350 // Downcast a GL object to an Impl (EG gl::Texture to rx::TextureD3D)
351 template <typename DestT, typename SrcT>
GetImplAs(SrcT * src)352 inline DestT *GetImplAs(SrcT *src)
353 {
354     return GetAs<DestT>(src->getImplementation());
355 }
356 
357 template <typename DestT, typename SrcT>
SafeGetImplAs(SrcT * src)358 inline DestT *SafeGetImplAs(SrcT *src)
359 {
360     return src != nullptr ? GetAs<DestT>(src->getImplementation()) : nullptr;
361 }
362 
363 }  // namespace rx
364 
365 #include "angletypes.inl"
366 
367 namespace angle
368 {
369 // Zero-based for better array indexing
370 enum FramebufferBinding
371 {
372     FramebufferBindingRead = 0,
373     FramebufferBindingDraw,
374     FramebufferBindingSingletonMax,
375     FramebufferBindingBoth = FramebufferBindingSingletonMax,
376     FramebufferBindingMax,
377     FramebufferBindingUnknown = FramebufferBindingMax,
378 };
379 
EnumToFramebufferBinding(GLenum enumValue)380 inline FramebufferBinding EnumToFramebufferBinding(GLenum enumValue)
381 {
382     switch (enumValue)
383     {
384         case GL_READ_FRAMEBUFFER:
385             return FramebufferBindingRead;
386         case GL_DRAW_FRAMEBUFFER:
387             return FramebufferBindingDraw;
388         case GL_FRAMEBUFFER:
389             return FramebufferBindingBoth;
390         default:
391             UNREACHABLE();
392             return FramebufferBindingUnknown;
393     }
394 }
395 
FramebufferBindingToEnum(FramebufferBinding binding)396 inline GLenum FramebufferBindingToEnum(FramebufferBinding binding)
397 {
398     switch (binding)
399     {
400         case FramebufferBindingRead:
401             return GL_READ_FRAMEBUFFER;
402         case FramebufferBindingDraw:
403             return GL_DRAW_FRAMEBUFFER;
404         case FramebufferBindingBoth:
405             return GL_FRAMEBUFFER;
406         default:
407             UNREACHABLE();
408             return GL_NONE;
409     }
410 }
411 
412 template <typename ObjT, typename ContextT>
413 class DestroyThenDelete
414 {
415   public:
DestroyThenDelete(const ContextT * context)416     DestroyThenDelete(const ContextT *context) : mContext(context) {}
417 
operator()418     void operator()(ObjT *obj)
419     {
420         ANGLE_SWALLOW_ERR(obj->onDestroy(mContext));
421         delete obj;
422     }
423 
424   private:
425     const ContextT *mContext;
426 };
427 
428 // Helper class for wrapping an onDestroy function.
429 template <typename ObjT, typename DeleterT>
430 class UniqueObjectPointerBase : angle::NonCopyable
431 {
432   public:
433     template <typename ContextT>
UniqueObjectPointerBase(const ContextT * context)434     UniqueObjectPointerBase(const ContextT *context) : mObject(nullptr), mDeleter(context)
435     {
436     }
437 
438     template <typename ContextT>
UniqueObjectPointerBase(ObjT * obj,const ContextT * context)439     UniqueObjectPointerBase(ObjT *obj, const ContextT *context) : mObject(obj), mDeleter(context)
440     {
441     }
442 
~UniqueObjectPointerBase()443     ~UniqueObjectPointerBase()
444     {
445         if (mObject)
446         {
447             mDeleter(mObject);
448         }
449     }
450 
451     ObjT *operator->() const { return mObject; }
452 
release()453     ObjT *release()
454     {
455         auto obj = mObject;
456         mObject  = nullptr;
457         return obj;
458     }
459 
get()460     ObjT *get() const { return mObject; }
461 
reset(ObjT * obj)462     void reset(ObjT *obj)
463     {
464         if (mObject)
465         {
466             mDeleter(mObject);
467         }
468         mObject = obj;
469     }
470 
471   private:
472     ObjT *mObject;
473     DeleterT mDeleter;
474 };
475 
476 template <typename ObjT, typename ContextT>
477 using UniqueObjectPointer = UniqueObjectPointerBase<ObjT, DestroyThenDelete<ObjT, ContextT>>;
478 
479 }  // namespace angle
480 
481 namespace gl
482 {
483 class ContextState;
484 
485 }  // namespace gl
486 
487 #endif // LIBANGLE_ANGLETYPES_H_
488