1 //
2 // Copyright (c) 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 // This class contains prototypes for representing GLES 3 Vertex Array Objects:
7 //
8 //   The buffer objects that are to be used by the vertex stage of the GL are collected
9 //   together to form a vertex array object. All state related to the definition of data used
10 //   by the vertex processor is encapsulated in a vertex array object.
11 //
12 
13 #ifndef LIBANGLE_VERTEXARRAY_H_
14 #define LIBANGLE_VERTEXARRAY_H_
15 
16 #include "libANGLE/RefCountObject.h"
17 #include "libANGLE/Constants.h"
18 #include "libANGLE/Debug.h"
19 #include "libANGLE/State.h"
20 #include "libANGLE/VertexAttribute.h"
21 
22 #include <vector>
23 
24 namespace rx
25 {
26 class GLImplFactory;
27 class VertexArrayImpl;
28 }  // namespace rx
29 
30 namespace gl
31 {
32 class Buffer;
33 
34 class VertexArrayState final : angle::NonCopyable
35 {
36   public:
37     VertexArrayState(size_t maxAttribs, size_t maxBindings);
38     ~VertexArrayState();
39 
getLabel()40     const std::string &getLabel() const { return mLabel; }
41 
getElementArrayBuffer()42     const BindingPointer<Buffer> &getElementArrayBuffer() const { return mElementArrayBuffer; }
getMaxAttribs()43     size_t getMaxAttribs() const { return mVertexAttributes.size(); }
getMaxBindings()44     size_t getMaxBindings() const { return mVertexBindings.size(); }
getMaxEnabledAttribute()45     size_t getMaxEnabledAttribute() const { return mMaxEnabledAttribute; }
getVertexAttributes()46     const std::vector<VertexAttribute> &getVertexAttributes() const { return mVertexAttributes; }
getVertexAttribute(size_t attribIndex)47     const VertexAttribute &getVertexAttribute(size_t attribIndex) const
48     {
49         return mVertexAttributes[attribIndex];
50     }
getVertexBindings()51     const std::vector<VertexBinding> &getVertexBindings() const { return mVertexBindings; }
getVertexBinding(size_t bindingIndex)52     const VertexBinding &getVertexBinding(size_t bindingIndex) const
53     {
54         return mVertexBindings[bindingIndex];
55     }
getBindingFromAttribIndex(size_t attribIndex)56     const VertexBinding &getBindingFromAttribIndex(size_t attribIndex) const
57     {
58         return mVertexBindings[mVertexAttributes[attribIndex].bindingIndex];
59     }
getBindingIndexFromAttribIndex(size_t attribIndex)60     size_t getBindingIndexFromAttribIndex(size_t attribIndex) const
61     {
62         return mVertexAttributes[attribIndex].bindingIndex;
63     }
64 
65   private:
66     friend class VertexArray;
67     std::string mLabel;
68     std::vector<VertexAttribute> mVertexAttributes;
69     BindingPointer<Buffer> mElementArrayBuffer;
70     std::vector<VertexBinding> mVertexBindings;
71     size_t mMaxEnabledAttribute;
72 };
73 
74 class VertexArray final : public LabeledObject
75 {
76   public:
77     VertexArray(rx::GLImplFactory *factory, GLuint id, size_t maxAttribs, size_t maxAttribBindings);
78 
79     void onDestroy(const Context *context);
80 
81     GLuint id() const;
82 
83     void setLabel(const std::string &label) override;
84     const std::string &getLabel() const override;
85 
86     const VertexBinding &getVertexBinding(size_t bindingIndex) const;
87     const VertexAttribute &getVertexAttribute(size_t attribIndex) const;
getBindingFromAttribIndex(size_t attribIndex)88     const VertexBinding &getBindingFromAttribIndex(size_t attribIndex) const
89     {
90         return mState.getBindingFromAttribIndex(attribIndex);
91     }
92 
93     void detachBuffer(const Context *context, GLuint bufferName);
94     void setVertexAttribDivisor(const Context *context, size_t index, GLuint divisor);
95     void enableAttribute(size_t attribIndex, bool enabledState);
96     void setVertexAttribPointer(const Context *context,
97                                 size_t attribIndex,
98                                 Buffer *boundBuffer,
99                                 GLint size,
100                                 GLenum type,
101                                 bool normalized,
102                                 bool pureInteger,
103                                 GLsizei stride,
104                                 const void *pointer);
105     void setVertexAttribFormat(size_t attribIndex,
106                                GLint size,
107                                GLenum type,
108                                bool normalized,
109                                bool pureInteger,
110                                GLuint relativeOffset);
111     void bindVertexBuffer(const Context *context,
112                           size_t bindingIndex,
113                           Buffer *boundBuffer,
114                           GLintptr offset,
115                           GLsizei stride);
116     void setVertexAttribBinding(const Context *context, size_t attribIndex, GLuint bindingIndex);
117     void setVertexBindingDivisor(size_t bindingIndex, GLuint divisor);
118     void setVertexAttribFormatImpl(size_t attribIndex,
119                                    GLint size,
120                                    GLenum type,
121                                    bool normalized,
122                                    bool pureInteger,
123                                    GLuint relativeOffset);
124     void bindVertexBufferImpl(const Context *context,
125                               size_t bindingIndex,
126                               Buffer *boundBuffer,
127                               GLintptr offset,
128                               GLsizei stride);
129 
130     void setElementArrayBuffer(const Context *context, Buffer *buffer);
131 
getElementArrayBuffer()132     const BindingPointer<Buffer> &getElementArrayBuffer() const
133     {
134         return mState.getElementArrayBuffer();
135     }
getMaxAttribs()136     size_t getMaxAttribs() const { return mState.getMaxAttribs(); }
getMaxBindings()137     size_t getMaxBindings() const { return mState.getMaxBindings(); }
138 
getVertexAttributes()139     const std::vector<VertexAttribute> &getVertexAttributes() const
140     {
141         return mState.getVertexAttributes();
142     }
getVertexBindings()143     const std::vector<VertexBinding> &getVertexBindings() const
144     {
145         return mState.getVertexBindings();
146     }
147 
getImplementation()148     rx::VertexArrayImpl *getImplementation() const { return mVertexArray; }
149 
getMaxEnabledAttribute()150     size_t getMaxEnabledAttribute() const { return mState.getMaxEnabledAttribute(); }
151 
152     enum DirtyBitType
153     {
154         DIRTY_BIT_ELEMENT_ARRAY_BUFFER,
155 
156         // Reserve bits for enabled flags
157         DIRTY_BIT_ATTRIB_0_ENABLED,
158         DIRTY_BIT_ATTRIB_MAX_ENABLED = DIRTY_BIT_ATTRIB_0_ENABLED + gl::MAX_VERTEX_ATTRIBS,
159 
160         // Reserve bits for attrib pointers
161         DIRTY_BIT_ATTRIB_0_POINTER   = DIRTY_BIT_ATTRIB_MAX_ENABLED,
162         DIRTY_BIT_ATTRIB_MAX_POINTER = DIRTY_BIT_ATTRIB_0_POINTER + gl::MAX_VERTEX_ATTRIBS,
163 
164         // Reserve bits for changes to VertexAttribFormat
165         DIRTY_BIT_ATTRIB_0_FORMAT   = DIRTY_BIT_ATTRIB_MAX_POINTER,
166         DIRTY_BIT_ATTRIB_MAX_FORMAT = DIRTY_BIT_ATTRIB_0_FORMAT + gl::MAX_VERTEX_ATTRIBS,
167 
168         // Reserve bits for changes to VertexAttribBinding
169         DIRTY_BIT_ATTRIB_0_BINDING   = DIRTY_BIT_ATTRIB_MAX_FORMAT,
170         DIRTY_BIT_ATTRIB_MAX_BINDING = DIRTY_BIT_ATTRIB_0_BINDING + gl::MAX_VERTEX_ATTRIBS,
171 
172         // Reserve bits for changes to BindVertexBuffer
173         DIRTY_BIT_BINDING_0_BUFFER   = DIRTY_BIT_ATTRIB_MAX_BINDING,
174         DIRTY_BIT_BINDING_MAX_BUFFER = DIRTY_BIT_BINDING_0_BUFFER + gl::MAX_VERTEX_ATTRIB_BINDINGS,
175 
176         // Reserve bits for binding divisors
177         DIRTY_BIT_BINDING_0_DIVISOR = DIRTY_BIT_BINDING_MAX_BUFFER,
178         DIRTY_BIT_BINDING_MAX_DIVISOR =
179             DIRTY_BIT_BINDING_0_DIVISOR + gl::MAX_VERTEX_ATTRIB_BINDINGS,
180 
181         DIRTY_BIT_UNKNOWN = DIRTY_BIT_BINDING_MAX_DIVISOR,
182         DIRTY_BIT_MAX     = DIRTY_BIT_UNKNOWN,
183     };
184 
185     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
186 
187     static size_t GetVertexIndexFromDirtyBit(size_t dirtyBit);
188 
189     void syncState(const Context *context);
hasAnyDirtyBit()190     bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
191 
192   private:
193     ~VertexArray() override;
194 
195     GLuint mId;
196 
197     VertexArrayState mState;
198     DirtyBits mDirtyBits;
199 
200     rx::VertexArrayImpl *mVertexArray;
201 };
202 
203 }  // namespace gl
204 
205 #endif // LIBANGLE_VERTEXARRAY_H_
206