1 //
2 // Copyright 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 // Helper structures about Generic Vertex Attribute.
7 //
8 
9 #ifndef LIBANGLE_VERTEXATTRIBUTE_H_
10 #define LIBANGLE_VERTEXATTRIBUTE_H_
11 
12 #include "libANGLE/Buffer.h"
13 #include "libANGLE/angletypes.h"
14 #include "libANGLE/renderer/Format.h"
15 
16 namespace gl
17 {
18 class VertexArray;
19 
20 //
21 // Implementation of Generic Vertex Attribute Bindings for ES3.1. The members are intentionally made
22 // private in order to hide implementation details.
23 //
24 class VertexBinding final : angle::NonCopyable
25 {
26   public:
27     VertexBinding();
28     explicit VertexBinding(GLuint boundAttribute);
29     VertexBinding(VertexBinding &&binding);
30     ~VertexBinding();
31     VertexBinding &operator=(VertexBinding &&binding);
32 
getStride()33     GLuint getStride() const { return mStride; }
setStride(GLuint strideIn)34     void setStride(GLuint strideIn) { mStride = strideIn; }
35 
getDivisor()36     GLuint getDivisor() const { return mDivisor; }
setDivisor(GLuint divisorIn)37     void setDivisor(GLuint divisorIn) { mDivisor = divisorIn; }
38 
getOffset()39     GLintptr getOffset() const { return mOffset; }
setOffset(GLintptr offsetIn)40     void setOffset(GLintptr offsetIn) { mOffset = offsetIn; }
41 
getBuffer()42     const BindingPointer<Buffer> &getBuffer() const { return mBuffer; }
43 
setBuffer(const gl::Context * context,Buffer * bufferIn)44     ANGLE_INLINE void setBuffer(const gl::Context *context, Buffer *bufferIn)
45     {
46         mBuffer.set(context, bufferIn);
47     }
48 
49     // Skips ref counting for better inlined performance.
assignBuffer(Buffer * bufferIn)50     ANGLE_INLINE void assignBuffer(Buffer *bufferIn) { mBuffer.assign(bufferIn); }
51 
52     void onContainerBindingChanged(const Context *context, int incr) const;
53 
getBoundAttributesMask()54     const AttributesMask &getBoundAttributesMask() const { return mBoundAttributesMask; }
55 
setBoundAttribute(size_t index)56     void setBoundAttribute(size_t index) { mBoundAttributesMask.set(index); }
57 
resetBoundAttribute(size_t index)58     void resetBoundAttribute(size_t index) { mBoundAttributesMask.reset(index); }
59 
60   private:
61     GLuint mStride;
62     GLuint mDivisor;
63     GLintptr mOffset;
64 
65     BindingPointer<Buffer> mBuffer;
66 
67     // Mapping from this binding to all of the attributes that are using this binding.
68     AttributesMask mBoundAttributesMask;
69 };
70 
71 //
72 // Implementation of Generic Vertex Attributes for ES3.1
73 //
74 struct VertexAttribute final : private angle::NonCopyable
75 {
76     explicit VertexAttribute(GLuint bindingIndex);
77     VertexAttribute(VertexAttribute &&attrib);
78     VertexAttribute &operator=(VertexAttribute &&attrib);
79 
80     // Called from VertexArray.
81     void updateCachedElementLimit(const VertexBinding &binding);
getCachedElementLimitfinal82     GLint64 getCachedElementLimit() const { return mCachedElementLimit; }
83 
84     bool enabled;  // For glEnable/DisableVertexAttribArray
85     const angle::Format *format;
86 
87     const void *pointer;
88     GLuint relativeOffset;
89 
90     GLuint vertexAttribArrayStride;  // ONLY for queries of VERTEX_ATTRIB_ARRAY_STRIDE
91     GLuint bindingIndex;
92 
93     // Special value for the cached element limit on the integer overflow case.
94     static constexpr GLint64 kIntegerOverflow = std::numeric_limits<GLint64>::min();
95 
96   private:
97     // This is kept in sync by the VertexArray. It is used to optimize draw call validation.
98     GLint64 mCachedElementLimit;
99 };
100 
ComputeVertexAttributeTypeSize(const VertexAttribute & attrib)101 ANGLE_INLINE size_t ComputeVertexAttributeTypeSize(const VertexAttribute &attrib)
102 {
103     ASSERT(attrib.format);
104     return attrib.format->pixelBytes;
105 }
106 
107 // Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
108 size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding);
109 
110 // Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
111 GLintptr ComputeVertexAttributeOffset(const VertexAttribute &attrib, const VertexBinding &binding);
112 
113 size_t ComputeVertexBindingElementCount(GLuint divisor, size_t drawCount, size_t instanceCount);
114 
115 struct VertexAttribCurrentValueData
116 {
117     union
118     {
119         GLfloat FloatValues[4];
120         GLint IntValues[4];
121         GLuint UnsignedIntValues[4];
122     } Values;
123     VertexAttribType Type;
124 
125     VertexAttribCurrentValueData();
126 
127     void setFloatValues(const GLfloat floatValues[4]);
128     void setIntValues(const GLint intValues[4]);
129     void setUnsignedIntValues(const GLuint unsignedIntValues[4]);
130 };
131 
132 bool operator==(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b);
133 bool operator!=(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b);
134 
135 }  // namespace gl
136 
137 #include "VertexAttribute.inc"
138 
139 #endif  // LIBANGLE_VERTEXATTRIBUTE_H_
140