blob: 4cc474d277c4a62a68c7526486ef8ce385652cc1 [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())
James Darpinian09303e42018-06-22 17:53:57 -070068 mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::ElementArray,
69 false);
Jamie Madill4928b7c2017-06-20 12:57:39 -040070 mState.mElementArrayBuffer.set(context, nullptr);
71 mVertexArray->destroy(context);
72 SafeDelete(mVertexArray);
73 delete this;
74}
75
Jamie Madill004a6f92013-07-10 15:13:38 -040076VertexArray::~VertexArray()
77{
Jamie Madill4928b7c2017-06-20 12:57:39 -040078 ASSERT(!mVertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -040079}
80
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -040081GLuint VertexArray::id() const
82{
83 return mId;
84}
85
Geoff Lang70d0f492015-12-10 17:45:46 -050086void VertexArray::setLabel(const std::string &label)
87{
Jamie Madill3f572682016-04-26 13:41:36 -040088 mState.mLabel = label;
Geoff Lang70d0f492015-12-10 17:45:46 -050089}
90
91const std::string &VertexArray::getLabel() const
92{
Jamie Madill3f572682016-04-26 13:41:36 -040093 return mState.mLabel;
Geoff Lang70d0f492015-12-10 17:45:46 -050094}
95
Jamie Madill4928b7c2017-06-20 12:57:39 -040096void VertexArray::detachBuffer(const Context *context, GLuint bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -040097{
James Darpiniane8a93c62018-01-04 18:02:24 -080098 bool isBound = context->isCurrentVertexArray(this);
Jiawei-Shao2597fb62016-12-09 16:38:02 +080099 for (auto &binding : mState.mVertexBindings)
Jamie Madill57a89722013-07-02 11:57:03 -0400100 {
Martin Radevdd5f27e2017-06-07 10:17:09 +0300101 if (binding.getBuffer().id() == bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -0400102 {
James Darpiniane8a93c62018-01-04 18:02:24 -0800103 binding.setBuffer(context, nullptr, isBound);
Jamie Madill57a89722013-07-02 11:57:03 -0400104 }
105 }
106
Jamie Madill3f572682016-04-26 13:41:36 -0400107 if (mState.mElementArrayBuffer.id() == bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -0400108 {
James Darpiniane8a93c62018-01-04 18:02:24 -0800109 if (isBound && mState.mElementArrayBuffer.get())
James Darpinian09303e42018-06-22 17:53:57 -0700110 mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::Array,
111 false);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400112 mState.mElementArrayBuffer.set(context, nullptr);
Jamie Madill57a89722013-07-02 11:57:03 -0400113 }
114}
115
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800116const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const
Jamie Madill57a89722013-07-02 11:57:03 -0400117{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800118 ASSERT(attribIndex < getMaxAttribs());
119 return mState.mVertexAttributes[attribIndex];
120}
121
122const VertexBinding &VertexArray::getVertexBinding(size_t bindingIndex) const
123{
124 ASSERT(bindingIndex < getMaxBindings());
125 return mState.mVertexBindings[bindingIndex];
126}
127
Shaodde78e82017-05-22 14:13:27 +0800128size_t VertexArray::GetVertexIndexFromDirtyBit(size_t dirtyBit)
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800129{
130 static_assert(gl::MAX_VERTEX_ATTRIBS == gl::MAX_VERTEX_ATTRIB_BINDINGS,
131 "The stride of vertex attributes should equal to that of vertex bindings.");
Shao80957d92017-02-20 21:25:59 +0800132 ASSERT(dirtyBit > DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
Jamie Madille858cb12018-03-27 09:44:32 -0400133 return (dirtyBit - DIRTY_BIT_ATTRIB_0) % gl::MAX_VERTEX_ATTRIBS;
134}
135
136void VertexArray::setDirtyAttribBit(size_t attribIndex, DirtyAttribBitType dirtyAttribBit)
137{
138 mDirtyBits.set(DIRTY_BIT_ATTRIB_0 + attribIndex);
139 mDirtyAttribBits[attribIndex].set(dirtyAttribBit);
140}
141
142void VertexArray::setDirtyBindingBit(size_t bindingIndex, DirtyBindingBitType dirtyBindingBit)
143{
144 mDirtyBits.set(DIRTY_BIT_BINDING_0 + bindingIndex);
145 mDirtyBindingBits[bindingIndex].set(dirtyBindingBit);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800146}
147
Shaodde78e82017-05-22 14:13:27 +0800148void VertexArray::bindVertexBufferImpl(const Context *context,
149 size_t bindingIndex,
150 Buffer *boundBuffer,
151 GLintptr offset,
152 GLsizei stride)
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800153{
154 ASSERT(bindingIndex < getMaxBindings());
James Darpiniane8a93c62018-01-04 18:02:24 -0800155 bool isBound = context->isCurrentVertexArray(this);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800156
157 VertexBinding *binding = &mState.mVertexBindings[bindingIndex];
158
James Darpiniane8a93c62018-01-04 18:02:24 -0800159 binding->setBuffer(context, boundBuffer, isBound);
Martin Radevdd5f27e2017-06-07 10:17:09 +0300160 binding->setOffset(offset);
161 binding->setStride(stride);
Jamie Madill09463932018-04-04 05:26:59 -0400162
163 updateObserverBinding(bindingIndex);
Jamie Madill02c9c042018-04-17 13:43:48 -0400164 updateCachedBufferBindingSize(bindingIndex);
Jamie Madill7267aa62018-04-17 15:28:21 -0400165 updateCachedTransformFeedbackBindingValidation(bindingIndex, boundBuffer);
Shaodde78e82017-05-22 14:13:27 +0800166}
167
168void VertexArray::bindVertexBuffer(const Context *context,
169 size_t bindingIndex,
170 Buffer *boundBuffer,
171 GLintptr offset,
172 GLsizei stride)
173{
174 bindVertexBufferImpl(context, bindingIndex, boundBuffer, offset, stride);
Jamie Madille858cb12018-03-27 09:44:32 -0400175 setDirtyBindingBit(bindingIndex, DIRTY_BINDING_BUFFER);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800176}
177
Shaodde78e82017-05-22 14:13:27 +0800178void VertexArray::setVertexAttribBinding(const Context *context,
179 size_t attribIndex,
180 GLuint bindingIndex)
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800181{
182 ASSERT(attribIndex < getMaxAttribs() && bindingIndex < getMaxBindings());
183
Shaodde78e82017-05-22 14:13:27 +0800184 if (mState.mVertexAttributes[attribIndex].bindingIndex != bindingIndex)
185 {
186 // In ES 3.0 contexts, the binding cannot change, hence the code below is unreachable.
187 ASSERT(context->getClientVersion() >= ES_3_1);
188 mState.mVertexAttributes[attribIndex].bindingIndex = bindingIndex;
189
Jamie Madille858cb12018-03-27 09:44:32 -0400190 setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_BINDING);
Shaodde78e82017-05-22 14:13:27 +0800191 }
Jamie Madille858cb12018-03-27 09:44:32 -0400192 mState.mVertexAttributes[attribIndex].bindingIndex = static_cast<GLuint>(bindingIndex);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800193}
194
195void VertexArray::setVertexBindingDivisor(size_t bindingIndex, GLuint divisor)
196{
197 ASSERT(bindingIndex < getMaxBindings());
198
Martin Radevdd5f27e2017-06-07 10:17:09 +0300199 mState.mVertexBindings[bindingIndex].setDivisor(divisor);
Jamie Madille858cb12018-03-27 09:44:32 -0400200 setDirtyBindingBit(bindingIndex, DIRTY_BINDING_DIVISOR);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800201}
202
Shaodde78e82017-05-22 14:13:27 +0800203void VertexArray::setVertexAttribFormatImpl(size_t attribIndex,
204 GLint size,
205 GLenum type,
206 bool normalized,
207 bool pureInteger,
208 GLuint relativeOffset)
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800209{
210 ASSERT(attribIndex < getMaxAttribs());
211
212 VertexAttribute *attrib = &mState.mVertexAttributes[attribIndex];
213
214 attrib->size = size;
215 attrib->type = type;
216 attrib->normalized = normalized;
217 attrib->pureInteger = pureInteger;
218 attrib->relativeOffset = relativeOffset;
Brandon Jonesc405ae72017-12-06 14:15:03 -0800219 mState.mVertexAttributesTypeMask.setIndex(GetVertexAttributeBaseType(*attrib), attribIndex);
Jamie Madill02c9c042018-04-17 13:43:48 -0400220 attrib->updateCachedSizePlusRelativeOffset();
Shaodde78e82017-05-22 14:13:27 +0800221}
222
223void VertexArray::setVertexAttribFormat(size_t attribIndex,
224 GLint size,
225 GLenum type,
226 bool normalized,
227 bool pureInteger,
228 GLuint relativeOffset)
229{
230 setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, relativeOffset);
Jamie Madille858cb12018-03-27 09:44:32 -0400231 setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_FORMAT);
Jamie Madill57a89722013-07-02 11:57:03 -0400232}
233
Shaodde78e82017-05-22 14:13:27 +0800234void VertexArray::setVertexAttribDivisor(const Context *context, size_t attribIndex, GLuint divisor)
Jamie Madill57a89722013-07-02 11:57:03 -0400235{
Shaodde78e82017-05-22 14:13:27 +0800236 ASSERT(attribIndex < getMaxAttribs());
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800237
Shaodde78e82017-05-22 14:13:27 +0800238 setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
239 setVertexBindingDivisor(attribIndex, divisor);
Jamie Madill57a89722013-07-02 11:57:03 -0400240}
241
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800242void VertexArray::enableAttribute(size_t attribIndex, bool enabledState)
Jamie Madill57a89722013-07-02 11:57:03 -0400243{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800244 ASSERT(attribIndex < getMaxAttribs());
Shao80957d92017-02-20 21:25:59 +0800245
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800246 mState.mVertexAttributes[attribIndex].enabled = enabledState;
Brandon Jonesc405ae72017-12-06 14:15:03 -0800247 mState.mVertexAttributesTypeMask.setIndex(
248 GetVertexAttributeBaseType(mState.mVertexAttributes[attribIndex]), attribIndex);
Shaodde78e82017-05-22 14:13:27 +0800249
Jamie Madille858cb12018-03-27 09:44:32 -0400250 setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_ENABLED);
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400251
252 // Update state cache
Jamie Madilld078c682018-01-02 11:50:24 -0500253 mState.mEnabledAttributesMask.set(attribIndex, enabledState);
Jamie Madill57a89722013-07-02 11:57:03 -0400254}
255
Shaodde78e82017-05-22 14:13:27 +0800256void VertexArray::setVertexAttribPointer(const Context *context,
257 size_t attribIndex,
258 gl::Buffer *boundBuffer,
259 GLint size,
260 GLenum type,
261 bool normalized,
262 bool pureInteger,
263 GLsizei stride,
264 const void *pointer)
Jamie Madill57a89722013-07-02 11:57:03 -0400265{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800266 ASSERT(attribIndex < getMaxAttribs());
Jamie Madill8e344942015-07-09 14:22:07 -0400267
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800268 GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0;
Jamie Madill8e344942015-07-09 14:22:07 -0400269
Shaodde78e82017-05-22 14:13:27 +0800270 setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, 0);
271 setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800272
273 VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
Shaodde78e82017-05-22 14:13:27 +0800274
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800275 GLsizei effectiveStride =
276 stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib));
277 attrib.pointer = pointer;
278 attrib.vertexAttribArrayStride = stride;
279
Shaodde78e82017-05-22 14:13:27 +0800280 bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800281
Jamie Madille858cb12018-03-27 09:44:32 -0400282 setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER);
Jamie Madillbcef3222018-04-13 15:19:11 -0400283
284 mState.mClientMemoryAttribsMask.set(attribIndex, boundBuffer == nullptr);
Jamie Madill51af38b2018-04-15 08:50:56 -0400285 mState.mNullPointerClientMemoryAttribsMask.set(attribIndex,
286 boundBuffer == nullptr && pointer == nullptr);
Brandon Jones5bf98292014-06-06 17:19:38 -0700287}
288
Jamie Madill4928b7c2017-06-20 12:57:39 -0400289void VertexArray::setElementArrayBuffer(const Context *context, Buffer *buffer)
Brandon Jones5bf98292014-06-06 17:19:38 -0700290{
James Darpiniane8a93c62018-01-04 18:02:24 -0800291 bool isBound = context->isCurrentVertexArray(this);
292 if (isBound && mState.mElementArrayBuffer.get())
James Darpinian09303e42018-06-22 17:53:57 -0700293 mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::ElementArray,
294 false);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400295 mState.mElementArrayBuffer.set(context, buffer);
James Darpiniane8a93c62018-01-04 18:02:24 -0800296 if (isBound && mState.mElementArrayBuffer.get())
James Darpinian09303e42018-06-22 17:53:57 -0700297 mState.mElementArrayBuffer->onBindingChanged(context, true, BufferBinding::ElementArray,
298 false);
Jamie Madill09463932018-04-04 05:26:59 -0400299 mElementArrayBufferObserverBinding.bind(buffer ? buffer->getImplementation() : nullptr);
Jamie Madill0b9e9032015-08-17 11:51:52 +0000300 mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
301}
302
Frank Henigman0af5b862018-03-27 20:19:33 -0400303gl::Error VertexArray::syncState(const Context *context)
Jamie Madill0b9e9032015-08-17 11:51:52 +0000304{
305 if (mDirtyBits.any())
306 {
Jamie Madill09463932018-04-04 05:26:59 -0400307 mDirtyBitsGuard = mDirtyBits;
Frank Henigman0af5b862018-03-27 20:19:33 -0400308 ANGLE_TRY(
309 mVertexArray->syncState(context, mDirtyBits, mDirtyAttribBits, mDirtyBindingBits));
Jamie Madill0b9e9032015-08-17 11:51:52 +0000310 mDirtyBits.reset();
Jamie Madill09463932018-04-04 05:26:59 -0400311 mDirtyBitsGuard.reset();
Jamie Madille858cb12018-03-27 09:44:32 -0400312
313 // This is a bit of an implementation hack - but since we know the implementation
314 // details of the dirty bit class it should always have the same effect as iterating
315 // individual attribs. We could also look into schemes where iterating the dirty
316 // bit set also resets it as you pass through it.
317 memset(&mDirtyAttribBits, 0, sizeof(mDirtyAttribBits));
318 memset(&mDirtyBindingBits, 0, sizeof(mDirtyBindingBits));
Jamie Madill0b9e9032015-08-17 11:51:52 +0000319 }
Frank Henigman0af5b862018-03-27 20:19:33 -0400320 return gl::NoError();
Jamie Madill57a89722013-07-02 11:57:03 -0400321}
322
Jamie Madill7267aa62018-04-17 15:28:21 -0400323void VertexArray::onBindingChanged(const Context *context, bool bound)
James Darpiniane8a93c62018-01-04 18:02:24 -0800324{
325 if (mState.mElementArrayBuffer.get())
James Darpinian09303e42018-06-22 17:53:57 -0700326 mState.mElementArrayBuffer->onBindingChanged(context, bound, BufferBinding::ElementArray,
327 false);
James Darpiniane8a93c62018-01-04 18:02:24 -0800328 for (auto &binding : mState.mVertexBindings)
329 {
Jamie Madill7267aa62018-04-17 15:28:21 -0400330 binding.onContainerBindingChanged(context, bound);
James Darpiniane8a93c62018-01-04 18:02:24 -0800331 }
332}
333
Jamie Madill09463932018-04-04 05:26:59 -0400334VertexArray::DirtyBitType VertexArray::getDirtyBitFromIndex(bool contentsChanged,
335 angle::SubjectIndex index) const
336{
337 if (index == mArrayBufferObserverBindings.size())
338 {
339 return contentsChanged ? DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA
340 : DIRTY_BIT_ELEMENT_ARRAY_BUFFER;
341 }
342 else
343 {
344 // Note: this currently just gets the top-level dirty bit.
345 ASSERT(index < mArrayBufferObserverBindings.size());
346 return static_cast<DirtyBitType>(
347 (contentsChanged ? DIRTY_BIT_BUFFER_DATA_0 : DIRTY_BIT_BINDING_0) + index);
348 }
349}
350
351void VertexArray::onSubjectStateChange(const gl::Context *context,
352 angle::SubjectIndex index,
353 angle::SubjectMessage message)
354{
Jamie Madill7267aa62018-04-17 15:28:21 -0400355 switch (message)
356 {
357 case angle::SubjectMessage::CONTENTS_CHANGED:
358 setDependentDirtyBit(context, true, index);
359 break;
360
361 case angle::SubjectMessage::STORAGE_CHANGED:
362 setDependentDirtyBit(context, false, index);
363 if (index < mArrayBufferObserverBindings.size())
364 {
365 updateCachedBufferBindingSize(index);
366 }
367 break;
368
369 case angle::SubjectMessage::BINDING_CHANGED:
370 if (index < mArrayBufferObserverBindings.size())
371 {
372 const Buffer *buffer = mState.mVertexBindings[index].getBuffer().get();
373 updateCachedTransformFeedbackBindingValidation(index, buffer);
374 }
375 break;
376
377 default:
378 UNREACHABLE();
379 break;
380 }
381}
382
383void VertexArray::setDependentDirtyBit(const gl::Context *context,
384 bool contentsChanged,
385 angle::SubjectIndex index)
386{
Jamie Madill09463932018-04-04 05:26:59 -0400387 DirtyBitType dirtyBit = getDirtyBitFromIndex(contentsChanged, index);
388 ASSERT(!mDirtyBitsGuard.valid() || mDirtyBitsGuard.value().test(dirtyBit));
389 mDirtyBits.set(dirtyBit);
390 context->getGLState().setVertexArrayDirty(this);
391}
392
393void VertexArray::updateObserverBinding(size_t bindingIndex)
394{
395 Buffer *boundBuffer = mState.mVertexBindings[bindingIndex].getBuffer().get();
396 mArrayBufferObserverBindings[bindingIndex].bind(boundBuffer ? boundBuffer->getImplementation()
397 : nullptr);
398}
399
Jamie Madill02c9c042018-04-17 13:43:48 -0400400void VertexArray::updateCachedVertexAttributeSize(size_t attribIndex)
401{
402 mState.mVertexAttributes[attribIndex].updateCachedSizePlusRelativeOffset();
403}
404
405void VertexArray::updateCachedBufferBindingSize(size_t bindingIndex)
406{
407 mState.mVertexBindings[bindingIndex].updateCachedBufferSizeMinusOffset();
408}
409
Jamie Madill7267aa62018-04-17 15:28:21 -0400410void VertexArray::updateCachedTransformFeedbackBindingValidation(size_t bindingIndex,
411 const Buffer *buffer)
412{
413 const bool hasConflict = buffer && buffer->isBoundForTransformFeedbackAndOtherUse();
414 mCachedTransformFeedbackConflictedBindingsMask.set(bindingIndex, hasConflict);
415}
416
417bool VertexArray::hasTransformFeedbackBindingConflict(const AttributesMask &activeAttribues) const
418{
419 // Fast check first.
420 if (!mCachedTransformFeedbackConflictedBindingsMask.any())
421 {
422 return false;
423 }
424
425 // Slow check. We must ensure that the conflicting attributes are enabled/active.
426 for (size_t attribIndex : activeAttribues)
427 {
428 const VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
429 if (mCachedTransformFeedbackConflictedBindingsMask[attrib.bindingIndex])
430 {
431 return true;
432 }
433 }
434
435 return false;
436}
437
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800438} // namespace gl