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