blob: 14499bdf06ef618d66f4ae1823e9a9f1cabfb548 [file] [log] [blame]
Jamie Madill57a89722013-07-02 11:57:03 -04001//
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// Implementation of the state class for mananging GLES 3 Vertex Array Objects.
7//
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/VertexArray.h"
10#include "libANGLE/Buffer.h"
Jamie Madilldd43e6c2017-03-24 14:18:49 -040011#include "libANGLE/Context.h"
Jamie Madill09463932018-04-04 05:26:59 -040012#include "libANGLE/renderer/BufferImpl.h"
Jamie Madill7aea7e02016-05-10 10:39:45 -040013#include "libANGLE/renderer/GLImplFactory.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050014#include "libANGLE/renderer/VertexArrayImpl.h"
Jamie Madill57a89722013-07-02 11:57:03 -040015
16namespace gl
17{
Jamie Madillbcef3222018-04-13 15:19:11 -040018// VertexArrayState implementation.
Jiawei-Shao2597fb62016-12-09 16:38:02 +080019VertexArrayState::VertexArrayState(size_t maxAttribs, size_t maxAttribBindings)
Jamie Madilld078c682018-01-02 11:50:24 -050020 : mLabel(), mVertexBindings(maxAttribBindings)
Jamie Madill57a89722013-07-02 11:57:03 -040021{
Jiawei-Shao2597fb62016-12-09 16:38:02 +080022 ASSERT(maxAttribs <= maxAttribBindings);
23
24 for (size_t i = 0; i < maxAttribs; i++)
25 {
26 mVertexAttributes.emplace_back(static_cast<GLuint>(i));
27 }
Jamie Madill8e344942015-07-09 14:22:07 -040028}
29
Jamie Madill3f572682016-04-26 13:41:36 -040030VertexArrayState::~VertexArrayState()
Jamie Madill8e344942015-07-09 14:22:07 -040031{
Jamie Madill8e344942015-07-09 14:22:07 -040032}
33
Jamie Madillbcef3222018-04-13 15:19:11 -040034gl::AttributesMask VertexArrayState::getEnabledClientMemoryAttribsMask() const
35{
36 return (mClientMemoryAttribsMask & mEnabledAttributesMask);
37}
38
Jamie Madill51af38b2018-04-15 08:50:56 -040039bool VertexArrayState::hasEnabledNullPointerClientArray() const
40{
41 return (mNullPointerClientMemoryAttribsMask & mEnabledAttributesMask).any();
42}
43
Jamie Madillbcef3222018-04-13 15:19:11 -040044// VertexArray implementation.
Jiawei-Shao2597fb62016-12-09 16:38:02 +080045VertexArray::VertexArray(rx::GLImplFactory *factory,
46 GLuint id,
47 size_t maxAttribs,
48 size_t maxAttribBindings)
49 : mId(id),
50 mState(maxAttribs, maxAttribBindings),
Jamie Madill09463932018-04-04 05:26:59 -040051 mVertexArray(factory->createVertexArray(mState)),
52 mElementArrayBufferObserverBinding(this, maxAttribBindings)
Jamie Madill8e344942015-07-09 14:22:07 -040053{
Jamie Madill09463932018-04-04 05:26:59 -040054 for (size_t attribIndex = 0; attribIndex < maxAttribBindings; ++attribIndex)
55 {
56 mArrayBufferObserverBindings.emplace_back(this, attribIndex);
57 }
Jamie Madill004a6f92013-07-10 15:13:38 -040058}
59
Jamie Madill4928b7c2017-06-20 12:57:39 -040060void VertexArray::onDestroy(const Context *context)
61{
James Darpiniane8a93c62018-01-04 18:02:24 -080062 bool isBound = context->isCurrentVertexArray(this);
Jamie Madillbcef3222018-04-13 15:19:11 -040063 for (VertexBinding &binding : mState.mVertexBindings)
Jamie Madill4928b7c2017-06-20 12:57:39 -040064 {
James Darpiniane8a93c62018-01-04 18:02:24 -080065 binding.setBuffer(context, nullptr, isBound);
Jamie Madill4928b7c2017-06-20 12:57:39 -040066 }
James Darpiniane8a93c62018-01-04 18:02:24 -080067 if (isBound && mState.mElementArrayBuffer.get())
Jamie Madill7267aa62018-04-17 15:28:21 -040068 mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::ElementArray);
Jamie Madill4928b7c2017-06-20 12:57:39 -040069 mState.mElementArrayBuffer.set(context, nullptr);
70 mVertexArray->destroy(context);
71 SafeDelete(mVertexArray);
72 delete this;
73}
74
Jamie Madill004a6f92013-07-10 15:13:38 -040075VertexArray::~VertexArray()
76{
Jamie Madill4928b7c2017-06-20 12:57:39 -040077 ASSERT(!mVertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -040078}
79
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -040080GLuint VertexArray::id() const
81{
82 return mId;
83}
84
Geoff Lang70d0f492015-12-10 17:45:46 -050085void VertexArray::setLabel(const std::string &label)
86{
Jamie Madill3f572682016-04-26 13:41:36 -040087 mState.mLabel = label;
Geoff Lang70d0f492015-12-10 17:45:46 -050088}
89
90const std::string &VertexArray::getLabel() const
91{
Jamie Madill3f572682016-04-26 13:41:36 -040092 return mState.mLabel;
Geoff Lang70d0f492015-12-10 17:45:46 -050093}
94
Jamie Madill4928b7c2017-06-20 12:57:39 -040095void VertexArray::detachBuffer(const Context *context, GLuint bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -040096{
James Darpiniane8a93c62018-01-04 18:02:24 -080097 bool isBound = context->isCurrentVertexArray(this);
Jiawei-Shao2597fb62016-12-09 16:38:02 +080098 for (auto &binding : mState.mVertexBindings)
Jamie Madill57a89722013-07-02 11:57:03 -040099 {
Martin Radevdd5f27e2017-06-07 10:17:09 +0300100 if (binding.getBuffer().id() == bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -0400101 {
James Darpiniane8a93c62018-01-04 18:02:24 -0800102 binding.setBuffer(context, nullptr, isBound);
Jamie Madill57a89722013-07-02 11:57:03 -0400103 }
104 }
105
Jamie Madill3f572682016-04-26 13:41:36 -0400106 if (mState.mElementArrayBuffer.id() == bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -0400107 {
James Darpiniane8a93c62018-01-04 18:02:24 -0800108 if (isBound && mState.mElementArrayBuffer.get())
Jamie Madill7267aa62018-04-17 15:28:21 -0400109 mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::Array);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400110 mState.mElementArrayBuffer.set(context, nullptr);
Jamie Madill57a89722013-07-02 11:57:03 -0400111 }
112}
113
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800114const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const
Jamie Madill57a89722013-07-02 11:57:03 -0400115{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800116 ASSERT(attribIndex < getMaxAttribs());
117 return mState.mVertexAttributes[attribIndex];
118}
119
120const VertexBinding &VertexArray::getVertexBinding(size_t bindingIndex) const
121{
122 ASSERT(bindingIndex < getMaxBindings());
123 return mState.mVertexBindings[bindingIndex];
124}
125
Shaodde78e82017-05-22 14:13:27 +0800126size_t VertexArray::GetVertexIndexFromDirtyBit(size_t dirtyBit)
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800127{
128 static_assert(gl::MAX_VERTEX_ATTRIBS == gl::MAX_VERTEX_ATTRIB_BINDINGS,
129 "The stride of vertex attributes should equal to that of vertex bindings.");
Shao80957d92017-02-20 21:25:59 +0800130 ASSERT(dirtyBit > DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
Jamie Madille858cb12018-03-27 09:44:32 -0400131 return (dirtyBit - DIRTY_BIT_ATTRIB_0) % gl::MAX_VERTEX_ATTRIBS;
132}
133
134void VertexArray::setDirtyAttribBit(size_t attribIndex, DirtyAttribBitType dirtyAttribBit)
135{
136 mDirtyBits.set(DIRTY_BIT_ATTRIB_0 + attribIndex);
137 mDirtyAttribBits[attribIndex].set(dirtyAttribBit);
138}
139
140void VertexArray::setDirtyBindingBit(size_t bindingIndex, DirtyBindingBitType dirtyBindingBit)
141{
142 mDirtyBits.set(DIRTY_BIT_BINDING_0 + bindingIndex);
143 mDirtyBindingBits[bindingIndex].set(dirtyBindingBit);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800144}
145
Shaodde78e82017-05-22 14:13:27 +0800146void VertexArray::bindVertexBufferImpl(const Context *context,
147 size_t bindingIndex,
148 Buffer *boundBuffer,
149 GLintptr offset,
150 GLsizei stride)
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800151{
152 ASSERT(bindingIndex < getMaxBindings());
James Darpiniane8a93c62018-01-04 18:02:24 -0800153 bool isBound = context->isCurrentVertexArray(this);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800154
155 VertexBinding *binding = &mState.mVertexBindings[bindingIndex];
156
James Darpiniane8a93c62018-01-04 18:02:24 -0800157 binding->setBuffer(context, boundBuffer, isBound);
Martin Radevdd5f27e2017-06-07 10:17:09 +0300158 binding->setOffset(offset);
159 binding->setStride(stride);
Jamie Madill09463932018-04-04 05:26:59 -0400160
161 updateObserverBinding(bindingIndex);
Jamie Madill02c9c042018-04-17 13:43:48 -0400162 updateCachedBufferBindingSize(bindingIndex);
Jamie Madill7267aa62018-04-17 15:28:21 -0400163 updateCachedTransformFeedbackBindingValidation(bindingIndex, boundBuffer);
Shaodde78e82017-05-22 14:13:27 +0800164}
165
166void VertexArray::bindVertexBuffer(const Context *context,
167 size_t bindingIndex,
168 Buffer *boundBuffer,
169 GLintptr offset,
170 GLsizei stride)
171{
172 bindVertexBufferImpl(context, bindingIndex, boundBuffer, offset, stride);
Jamie Madille858cb12018-03-27 09:44:32 -0400173 setDirtyBindingBit(bindingIndex, DIRTY_BINDING_BUFFER);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800174}
175
Shaodde78e82017-05-22 14:13:27 +0800176void VertexArray::setVertexAttribBinding(const Context *context,
177 size_t attribIndex,
178 GLuint bindingIndex)
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800179{
180 ASSERT(attribIndex < getMaxAttribs() && bindingIndex < getMaxBindings());
181
Shaodde78e82017-05-22 14:13:27 +0800182 if (mState.mVertexAttributes[attribIndex].bindingIndex != bindingIndex)
183 {
184 // In ES 3.0 contexts, the binding cannot change, hence the code below is unreachable.
185 ASSERT(context->getClientVersion() >= ES_3_1);
186 mState.mVertexAttributes[attribIndex].bindingIndex = bindingIndex;
187
Jamie Madille858cb12018-03-27 09:44:32 -0400188 setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_BINDING);
Shaodde78e82017-05-22 14:13:27 +0800189 }
Jamie Madille858cb12018-03-27 09:44:32 -0400190 mState.mVertexAttributes[attribIndex].bindingIndex = static_cast<GLuint>(bindingIndex);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800191}
192
193void VertexArray::setVertexBindingDivisor(size_t bindingIndex, GLuint divisor)
194{
195 ASSERT(bindingIndex < getMaxBindings());
196
Martin Radevdd5f27e2017-06-07 10:17:09 +0300197 mState.mVertexBindings[bindingIndex].setDivisor(divisor);
Jamie Madille858cb12018-03-27 09:44:32 -0400198 setDirtyBindingBit(bindingIndex, DIRTY_BINDING_DIVISOR);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800199}
200
Shaodde78e82017-05-22 14:13:27 +0800201void VertexArray::setVertexAttribFormatImpl(size_t attribIndex,
202 GLint size,
203 GLenum type,
204 bool normalized,
205 bool pureInteger,
206 GLuint relativeOffset)
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800207{
208 ASSERT(attribIndex < getMaxAttribs());
209
210 VertexAttribute *attrib = &mState.mVertexAttributes[attribIndex];
211
212 attrib->size = size;
213 attrib->type = type;
214 attrib->normalized = normalized;
215 attrib->pureInteger = pureInteger;
216 attrib->relativeOffset = relativeOffset;
Brandon Jonesc405ae72017-12-06 14:15:03 -0800217 mState.mVertexAttributesTypeMask.setIndex(GetVertexAttributeBaseType(*attrib), attribIndex);
Jamie Madill02c9c042018-04-17 13:43:48 -0400218 attrib->updateCachedSizePlusRelativeOffset();
Shaodde78e82017-05-22 14:13:27 +0800219}
220
221void VertexArray::setVertexAttribFormat(size_t attribIndex,
222 GLint size,
223 GLenum type,
224 bool normalized,
225 bool pureInteger,
226 GLuint relativeOffset)
227{
228 setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, relativeOffset);
Jamie Madille858cb12018-03-27 09:44:32 -0400229 setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_FORMAT);
Jamie Madill57a89722013-07-02 11:57:03 -0400230}
231
Shaodde78e82017-05-22 14:13:27 +0800232void VertexArray::setVertexAttribDivisor(const Context *context, size_t attribIndex, GLuint divisor)
Jamie Madill57a89722013-07-02 11:57:03 -0400233{
Shaodde78e82017-05-22 14:13:27 +0800234 ASSERT(attribIndex < getMaxAttribs());
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800235
Shaodde78e82017-05-22 14:13:27 +0800236 setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
237 setVertexBindingDivisor(attribIndex, divisor);
Jamie Madill57a89722013-07-02 11:57:03 -0400238}
239
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800240void VertexArray::enableAttribute(size_t attribIndex, bool enabledState)
Jamie Madill57a89722013-07-02 11:57:03 -0400241{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800242 ASSERT(attribIndex < getMaxAttribs());
Shao80957d92017-02-20 21:25:59 +0800243
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800244 mState.mVertexAttributes[attribIndex].enabled = enabledState;
Brandon Jonesc405ae72017-12-06 14:15:03 -0800245 mState.mVertexAttributesTypeMask.setIndex(
246 GetVertexAttributeBaseType(mState.mVertexAttributes[attribIndex]), attribIndex);
Shaodde78e82017-05-22 14:13:27 +0800247
Jamie Madille858cb12018-03-27 09:44:32 -0400248 setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_ENABLED);
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400249
250 // Update state cache
Jamie Madilld078c682018-01-02 11:50:24 -0500251 mState.mEnabledAttributesMask.set(attribIndex, enabledState);
Jamie Madill57a89722013-07-02 11:57:03 -0400252}
253
Shaodde78e82017-05-22 14:13:27 +0800254void VertexArray::setVertexAttribPointer(const Context *context,
255 size_t attribIndex,
256 gl::Buffer *boundBuffer,
257 GLint size,
258 GLenum type,
259 bool normalized,
260 bool pureInteger,
261 GLsizei stride,
262 const void *pointer)
Jamie Madill57a89722013-07-02 11:57:03 -0400263{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800264 ASSERT(attribIndex < getMaxAttribs());
Jamie Madill8e344942015-07-09 14:22:07 -0400265
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800266 GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0;
Jamie Madill8e344942015-07-09 14:22:07 -0400267
Shaodde78e82017-05-22 14:13:27 +0800268 setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, 0);
269 setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800270
271 VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
Shaodde78e82017-05-22 14:13:27 +0800272
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800273 GLsizei effectiveStride =
274 stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib));
275 attrib.pointer = pointer;
276 attrib.vertexAttribArrayStride = stride;
277
Shaodde78e82017-05-22 14:13:27 +0800278 bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800279
Jamie Madille858cb12018-03-27 09:44:32 -0400280 setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER);
Jamie Madillbcef3222018-04-13 15:19:11 -0400281
282 mState.mClientMemoryAttribsMask.set(attribIndex, boundBuffer == nullptr);
Jamie Madill51af38b2018-04-15 08:50:56 -0400283 mState.mNullPointerClientMemoryAttribsMask.set(attribIndex,
284 boundBuffer == nullptr && pointer == nullptr);
Brandon Jones5bf98292014-06-06 17:19:38 -0700285}
286
Jamie Madill4928b7c2017-06-20 12:57:39 -0400287void VertexArray::setElementArrayBuffer(const Context *context, Buffer *buffer)
Brandon Jones5bf98292014-06-06 17:19:38 -0700288{
James Darpiniane8a93c62018-01-04 18:02:24 -0800289 bool isBound = context->isCurrentVertexArray(this);
290 if (isBound && mState.mElementArrayBuffer.get())
Jamie Madill7267aa62018-04-17 15:28:21 -0400291 mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::ElementArray);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400292 mState.mElementArrayBuffer.set(context, buffer);
James Darpiniane8a93c62018-01-04 18:02:24 -0800293 if (isBound && mState.mElementArrayBuffer.get())
Jamie Madill7267aa62018-04-17 15:28:21 -0400294 mState.mElementArrayBuffer->onBindingChanged(context, true, BufferBinding::ElementArray);
Jamie Madill09463932018-04-04 05:26:59 -0400295 mElementArrayBufferObserverBinding.bind(buffer ? buffer->getImplementation() : nullptr);
Jamie Madill0b9e9032015-08-17 11:51:52 +0000296 mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
297}
298
Frank Henigman0af5b862018-03-27 20:19:33 -0400299gl::Error VertexArray::syncState(const Context *context)
Jamie Madill0b9e9032015-08-17 11:51:52 +0000300{
301 if (mDirtyBits.any())
302 {
Jamie Madill09463932018-04-04 05:26:59 -0400303 mDirtyBitsGuard = mDirtyBits;
Frank Henigman0af5b862018-03-27 20:19:33 -0400304 ANGLE_TRY(
305 mVertexArray->syncState(context, mDirtyBits, mDirtyAttribBits, mDirtyBindingBits));
Jamie Madill0b9e9032015-08-17 11:51:52 +0000306 mDirtyBits.reset();
Jamie Madill09463932018-04-04 05:26:59 -0400307 mDirtyBitsGuard.reset();
Jamie Madille858cb12018-03-27 09:44:32 -0400308
309 // This is a bit of an implementation hack - but since we know the implementation
310 // details of the dirty bit class it should always have the same effect as iterating
311 // individual attribs. We could also look into schemes where iterating the dirty
312 // bit set also resets it as you pass through it.
313 memset(&mDirtyAttribBits, 0, sizeof(mDirtyAttribBits));
314 memset(&mDirtyBindingBits, 0, sizeof(mDirtyBindingBits));
Jamie Madill0b9e9032015-08-17 11:51:52 +0000315 }
Frank Henigman0af5b862018-03-27 20:19:33 -0400316 return gl::NoError();
Jamie Madill57a89722013-07-02 11:57:03 -0400317}
318
Jamie Madill7267aa62018-04-17 15:28:21 -0400319void VertexArray::onBindingChanged(const Context *context, bool bound)
James Darpiniane8a93c62018-01-04 18:02:24 -0800320{
321 if (mState.mElementArrayBuffer.get())
Jamie Madill7267aa62018-04-17 15:28:21 -0400322 mState.mElementArrayBuffer->onBindingChanged(context, bound, BufferBinding::ElementArray);
James Darpiniane8a93c62018-01-04 18:02:24 -0800323 for (auto &binding : mState.mVertexBindings)
324 {
Jamie Madill7267aa62018-04-17 15:28:21 -0400325 binding.onContainerBindingChanged(context, bound);
James Darpiniane8a93c62018-01-04 18:02:24 -0800326 }
327}
328
Jamie Madill09463932018-04-04 05:26:59 -0400329VertexArray::DirtyBitType VertexArray::getDirtyBitFromIndex(bool contentsChanged,
330 angle::SubjectIndex index) const
331{
332 if (index == mArrayBufferObserverBindings.size())
333 {
334 return contentsChanged ? DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA
335 : DIRTY_BIT_ELEMENT_ARRAY_BUFFER;
336 }
337 else
338 {
339 // Note: this currently just gets the top-level dirty bit.
340 ASSERT(index < mArrayBufferObserverBindings.size());
341 return static_cast<DirtyBitType>(
342 (contentsChanged ? DIRTY_BIT_BUFFER_DATA_0 : DIRTY_BIT_BINDING_0) + index);
343 }
344}
345
346void VertexArray::onSubjectStateChange(const gl::Context *context,
347 angle::SubjectIndex index,
348 angle::SubjectMessage message)
349{
Jamie Madill7267aa62018-04-17 15:28:21 -0400350 switch (message)
351 {
352 case angle::SubjectMessage::CONTENTS_CHANGED:
353 setDependentDirtyBit(context, true, index);
354 break;
355
356 case angle::SubjectMessage::STORAGE_CHANGED:
357 setDependentDirtyBit(context, false, index);
358 if (index < mArrayBufferObserverBindings.size())
359 {
360 updateCachedBufferBindingSize(index);
361 }
362 break;
363
364 case angle::SubjectMessage::BINDING_CHANGED:
365 if (index < mArrayBufferObserverBindings.size())
366 {
367 const Buffer *buffer = mState.mVertexBindings[index].getBuffer().get();
368 updateCachedTransformFeedbackBindingValidation(index, buffer);
369 }
370 break;
371
372 default:
373 UNREACHABLE();
374 break;
375 }
376}
377
378void VertexArray::setDependentDirtyBit(const gl::Context *context,
379 bool contentsChanged,
380 angle::SubjectIndex index)
381{
Jamie Madill09463932018-04-04 05:26:59 -0400382 DirtyBitType dirtyBit = getDirtyBitFromIndex(contentsChanged, index);
383 ASSERT(!mDirtyBitsGuard.valid() || mDirtyBitsGuard.value().test(dirtyBit));
384 mDirtyBits.set(dirtyBit);
385 context->getGLState().setVertexArrayDirty(this);
386}
387
388void VertexArray::updateObserverBinding(size_t bindingIndex)
389{
390 Buffer *boundBuffer = mState.mVertexBindings[bindingIndex].getBuffer().get();
391 mArrayBufferObserverBindings[bindingIndex].bind(boundBuffer ? boundBuffer->getImplementation()
392 : nullptr);
393}
394
Jamie Madill02c9c042018-04-17 13:43:48 -0400395void VertexArray::updateCachedVertexAttributeSize(size_t attribIndex)
396{
397 mState.mVertexAttributes[attribIndex].updateCachedSizePlusRelativeOffset();
398}
399
400void VertexArray::updateCachedBufferBindingSize(size_t bindingIndex)
401{
402 mState.mVertexBindings[bindingIndex].updateCachedBufferSizeMinusOffset();
403}
404
Jamie Madill7267aa62018-04-17 15:28:21 -0400405void VertexArray::updateCachedTransformFeedbackBindingValidation(size_t bindingIndex,
406 const Buffer *buffer)
407{
408 const bool hasConflict = buffer && buffer->isBoundForTransformFeedbackAndOtherUse();
409 mCachedTransformFeedbackConflictedBindingsMask.set(bindingIndex, hasConflict);
410}
411
412bool VertexArray::hasTransformFeedbackBindingConflict(const AttributesMask &activeAttribues) const
413{
414 // Fast check first.
415 if (!mCachedTransformFeedbackConflictedBindingsMask.any())
416 {
417 return false;
418 }
419
420 // Slow check. We must ensure that the conflicting attributes are enabled/active.
421 for (size_t attribIndex : activeAttribues)
422 {
423 const VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
424 if (mCachedTransformFeedbackConflictedBindingsMask[attrib.bindingIndex])
425 {
426 return true;
427 }
428 }
429
430 return false;
431}
432
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800433} // namespace gl