28 : attribute_indices_(*this),
29 buffer_attributes_(kAttributeChanged, kAttributeSlotCount, this),
30 simple_attributes_(*this),
31 enables_(kAttributeEnabledChanged, kAttributeSlotCount, this) {
35 const size_t num_attributes = buffer_attributes_.GetCount();
36 for (
size_t i = 0; i < num_attributes; ++i) {
37 const Attribute& a = buffer_attributes_.Get(i);
47 const size_t num_attributes = attribute_indices_.size();
48 for (
size_t i = 0; i < num_attributes; ++i) {
49 const Index& attr_index = attribute_indices_[i];
50 const size_t idx = attr_index.index;
51 const Attribute& a = attribute_indices_[i].type == Index::kBuffer
52 ? buffer_attributes_.Get(idx)
53 : simple_attributes_[idx];
56 if (spec->name == name) {
71 const size_t num_attributes = attribute_indices_.size();
74 for (
size_t i = 0; i < num_attributes; ++i) {
75 const Index& attr_index = attribute_indices_[i];
76 const size_t idx = attr_index.index;
77 const Attribute& a = attribute_indices_[i].type == Index::kBuffer ?
78 buffer_attributes_.Get(idx) : simple_attributes_[idx];
86 Index new_index(Index::kBuffer, buffer_attributes_.GetCount());
87 attribute_indices_.push_back(new_index);
88 buffer_attributes_.Add(attribute);
91 bo->AddReceiver(
this);
95 Index new_index(Index::kSimple, simple_attributes_.size());
96 attribute_indices_.push_back(new_index);
97 simple_attributes_.push_back(attribute);
100 return num_attributes;
108 const size_t num_attributes = attribute_indices_.size();
109 if (index >= num_attributes) {
112 Index& attr_index = attribute_indices_[index];
113 if (attr_index.type == Index::kBuffer) {
117 new_bo->AddReceiver(
this);
119 return buffer_attributes_.Set(attr_index.index, attribute);
122 RemoveAttribute(attr_index);
125 attr_index.index = simple_attributes_.size();
126 attr_index.type = Index::kSimple;
127 simple_attributes_.push_back(attribute);
134 new_bo->AddReceiver(
this);
137 RemoveAttribute(attr_index);
140 attr_index.index = buffer_attributes_.GetCount();
141 attr_index.type = Index::kBuffer;
142 buffer_attributes_.Add(attribute);
149 if (simple_attributes_[attr_index.index] == attribute) {
152 simple_attributes_[attr_index.index] = attribute;
162 if (attribute_index < attribute_indices_.size()) {
163 const Index& attr_index = attribute_indices_[attribute_index];
166 if (attr_index.type == Index::kBuffer)
167 enables_.Set(attr_index.index, enabled);
172 DCHECK_EQ(buffer_attributes_.GetCount(), enables_.GetCount());
173 if (attribute_index < attribute_indices_.size()) {
174 const Index& attr_index = attribute_indices_[attribute_index];
175 return attr_index.type == Index::kSimple ||
176 (enables_.Get(attr_index.index) &&
177 buffer_attributes_.Get(attr_index.index).IsValid());
184 const size_t attribute_index)
const {
185 if (attribute_index < attribute_indices_.size()) {
186 const Index& attr_index = attribute_indices_[attribute_index];
187 if (attr_index.type == Index::kBuffer)
188 return buffer_attributes_.Get(attr_index.index);
190 return simple_attributes_[attr_index.index];
192 return base::InvalidReference<Attribute>();
197 if (attribute_index < attribute_indices_.size()) {
198 const Index& attr_index = attribute_indices_[attribute_index];
199 if (attr_index.type == Index::kBuffer)
208 AttributeArray::Index* AttributeArray::FindIndexOfAttribute(
209 AttributeArray::Index::Type
type,
size_t index) {
210 const Index target(type, index);
212 std::find(attribute_indices_.begin(), attribute_indices_.end(), target);
213 return it == attribute_indices_.end() ? NULL : &(*it);
216 void AttributeArray::RemoveAttribute(
const Index& attr_index) {
217 if (attr_index.type == Index::kBuffer) {
218 DCHECK(buffer_attributes_.GetCount());
224 Index* old_index = FindIndexOfAttribute(
225 Index::kBuffer, buffer_attributes_.GetCount() - 1U);
227 old_index->index = attr_index.index;
231 if (BufferObject* old_bo = buffer_attributes_.Get(attr_index.index)
232 .GetValue<BufferObjectElement>()
233 .buffer_object.Get()) {
236 bool perform_remove =
true;
237 const size_t num_attributes = buffer_attributes_.GetCount();
238 for (
size_t i = 0; i < num_attributes; ++i) {
239 if (i != attr_index.index) {
240 const Attribute& a = buffer_attributes_.Get(i);
242 a.GetValue<BufferObjectElement>().buffer_object.Get();
244 perform_remove =
false;
249 if (perform_remove) old_bo->RemoveReceiver(
this);
251 buffer_attributes_.Remove(attr_index.index);
252 enables_.Remove(attr_index.index);
254 DCHECK(simple_attributes_.size());
260 Index* old_index = FindIndexOfAttribute(
261 Index::kSimple, simple_attributes_.size() - 1U);
263 old_index->index = attr_index.index;
268 simple_attributes_[attr_index.index] = simple_attributes_.back();
269 simple_attributes_.resize(simple_attributes_.size() - 1U);
273 void AttributeArray::OnNotify(
const base::Notifier* notifier) {
276 const size_t num_attributes = buffer_attributes_.GetCount();
277 for (
size_t i = 0; i < num_attributes; ++i) {
278 const Attribute& a = buffer_attributes_.Get(i);
281 a.GetValue<BufferObjectElement>().buffer_object.Get();
const size_t kInvalidIndex
kInvalidIndex is a size_t value that is very unlikely to be a valid index.
Attribute * GetMutableBufferAttribute(const size_t i)
~AttributeArray() override
The destructor is protected because all base::Referent classes must have protected or private destruc...
size_t GetAttributeIndexByName(const std::string &name)
Returns the index of the first Attribute with the passed name.
void EnableAttribute(const size_t attribute_index, bool enabled)
Enables or disables attributes.
Attribute * GetMutableSimpleAttribute(const size_t i)
void OnChanged(int bit) const
Forwards OnChanged to all resources.
const BufferObjectPtr buffer_object
Structure for clients to use to encapsulate Elements.
T * Get() const
Returns a raw pointer to the instance, which may be NULL.
const Attribute & GetAttribute(const size_t attribute_index) const
Returns the Attribute at the passed index.
A BufferObject describes a generic array of data used, for example, to describe the vertices in a Sha...
Attribute * GetMutableAttribute(const size_t attribute_index)
Returns a pointer to the Attribute at the passed index.
void RemoveReceiver(Notifier *receiver)
Removes a Notifier to be notified.
bool IsAttributeEnabled(const size_t attribute_index) const
Returns if the Attribute at the passed index is enabled, or false if an invalid index is passed...
bool ReplaceAttribute(size_t index, const Attribute &attribute)
Replaces the attribute at an index with the supplied Attribute if both the index and the attribute ar...
Copyright 2016 Google Inc.
#define DCHECK_EQ(val1, val2)
int GetResourceCount() const
Returns the number of resources that this holder holds.
size_t AddAttribute(const Attribute &attribute)
Adds an Attribute to this AttributeArray.
This class can be used in place of std::vector to allow an Ion Allocator to be used for memory alloca...