Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
attributearray.cc
Go to the documentation of this file.
1 
18 #include "ion/gfx/attributearray.h"
19 
20 #include "ion/base/invalid.h"
21 #include "ion/base/logging.h"
23 
24 namespace ion {
25 namespace gfx {
26 
28  : attribute_indices_(*this),
29  buffer_attributes_(kAttributeChanged, kAttributeSlotCount, this),
30  simple_attributes_(*this),
31  enables_(kAttributeEnabledChanged, kAttributeSlotCount, this) {
32 }
33 
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);
38  BufferObject* bo =
39  a.GetValue<BufferObjectElement>().buffer_object.Get();
40  if (bo) bo->RemoveReceiver(this);
41  }
42 }
43 
45 size_t AttributeArray::GetAttributeIndexByName(const std::string& name) {
46  size_t index = base::kInvalidIndex;
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];
54  if (const ShaderInputRegistry::AttributeSpec* spec =
56  if (spec->name == name) {
57  index = i;
58  break;
59  }
60  }
61  }
62  return index;
63 }
64 
65 size_t AttributeArray::AddAttribute(const Attribute& attribute) {
66  if (!attribute.IsValid())
67  return base::kInvalidIndex;
68 
71  const size_t num_attributes = attribute_indices_.size();
72  const size_t registry_id = attribute.GetRegistry().GetId();
73  const size_t index = attribute.GetIndexInRegistry();
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];
79  if (a.GetRegistry().GetId() == registry_id &&
80  a.GetIndexInRegistry() == index) {
81  return i;
82  }
83  }
85  if (attribute.GetType() == kBufferObjectElementAttribute) {
86  Index new_index(Index::kBuffer, buffer_attributes_.GetCount());
87  attribute_indices_.push_back(new_index);
88  buffer_attributes_.Add(attribute);
89  if (BufferObject* bo =
91  bo->AddReceiver(this);
93  enables_.Add(true);
94  } else {
95  Index new_index(Index::kSimple, simple_attributes_.size());
96  attribute_indices_.push_back(new_index);
97  simple_attributes_.push_back(attribute);
98  }
100  return num_attributes;
101 }
102 
104  const Attribute& attribute) {
105  if (!attribute.IsValid())
106  return false;
107 
108  const size_t num_attributes = attribute_indices_.size();
109  if (index >= num_attributes) {
110  return false;
111  } else {
112  Index& attr_index = attribute_indices_[index];
113  if (attr_index.type == Index::kBuffer) {
114  if (attribute.GetType() == kBufferObjectElementAttribute) {
115  if (BufferObject* new_bo =
117  new_bo->AddReceiver(this);
119  return buffer_attributes_.Set(attr_index.index, attribute);
120  } else {
122  RemoveAttribute(attr_index);
123 
125  attr_index.index = simple_attributes_.size();
126  attr_index.type = Index::kSimple;
127  simple_attributes_.push_back(attribute);
128  return true;
129  }
130  } else {
131  if (attribute.GetType() == kBufferObjectElementAttribute) {
132  if (BufferObject* new_bo =
134  new_bo->AddReceiver(this);
135 
137  RemoveAttribute(attr_index);
138 
140  attr_index.index = buffer_attributes_.GetCount();
141  attr_index.type = Index::kBuffer;
142  buffer_attributes_.Add(attribute);
144  enables_.Add(true);
145  return true;
146  } else {
149  if (simple_attributes_[attr_index.index] == attribute) {
150  return false;
151  } else {
152  simple_attributes_[attr_index.index] = attribute;
153  return true;
154  }
155  }
156  }
157  }
158 }
159 
160 void AttributeArray::EnableAttribute(const size_t attribute_index,
161  bool enabled) {
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);
168  }
169 }
170 
171 bool AttributeArray::IsAttributeEnabled(const size_t attribute_index) const {
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());
178  } else {
179  return false;
180  }
181 }
182 
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);
189  else
190  return simple_attributes_[attr_index.index];
191  } else {
192  return base::InvalidReference<Attribute>();
193  }
194 }
195 
196 Attribute* AttributeArray::GetMutableAttribute(const size_t attribute_index) {
197  if (attribute_index < attribute_indices_.size()) {
198  const Index& attr_index = attribute_indices_[attribute_index];
199  if (attr_index.type == Index::kBuffer)
200  return GetMutableBufferAttribute(attr_index.index);
201  else
202  return GetMutableSimpleAttribute(attr_index.index);
203  } else {
204  return NULL;
205  }
206 }
207 
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);
214 }
215 
216 void AttributeArray::RemoveAttribute(const Index& attr_index) {
217  if (attr_index.type == Index::kBuffer) {
218  DCHECK(buffer_attributes_.GetCount());
219 
224  Index* old_index = FindIndexOfAttribute(
225  Index::kBuffer, buffer_attributes_.GetCount() - 1U);
226  DCHECK(old_index);
227  old_index->index = attr_index.index;
228 
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);
241  BufferObject* bo =
242  a.GetValue<BufferObjectElement>().buffer_object.Get();
243  if (bo == old_bo) {
244  perform_remove = false;
245  break;
246  }
247  }
248  }
249  if (perform_remove) old_bo->RemoveReceiver(this);
250  }
251  buffer_attributes_.Remove(attr_index.index);
252  enables_.Remove(attr_index.index);
253  } else {
254  DCHECK(simple_attributes_.size());
255 
260  Index* old_index = FindIndexOfAttribute(
261  Index::kSimple, simple_attributes_.size() - 1U);
262  DCHECK(old_index);
263  old_index->index = attr_index.index;
264 
268  simple_attributes_[attr_index.index] = simple_attributes_.back();
269  simple_attributes_.resize(simple_attributes_.size() - 1U);
270  }
271 }
272 
273 void AttributeArray::OnNotify(const base::Notifier* notifier) {
275  if (GetResourceCount()) {
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);
279  DCHECK(a.IsValid());
280  BufferObject* bo =
281  a.GetValue<BufferObjectElement>().buffer_object.Get();
282  if (bo == notifier)
283  OnChanged(static_cast<Changes>(kAttributeChanged + i));
284  }
285  }
286 }
287 
288 } // namespace gfx
289 } // namespace ion
std::string type
Definition: printer.cc:353
This struct is stored for each registered ShaderInput.
const size_t kInvalidIndex
kInvalidIndex is a size_t value that is very unlikely to be a valid index.
Definition: invalid.cc:23
Attribute * GetMutableBufferAttribute(const size_t i)
#define DCHECK(expr)
Definition: logging.h:331
~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.
const ShaderInputRegistry & GetRegistry() const
Returns the ShaderInputRegistry the shader input is defined in.
Definition: shaderinput.h:63
Attribute * GetMutableSimpleAttribute(const size_t i)
void OnChanged(int bit) const
Forwards OnChanged to all resources.
const BufferObjectPtr buffer_object
Definition: bufferobject.h:394
Structure for clients to use to encapsulate Elements.
Definition: bufferobject.h:378
size_t GetId() const
Each ShaderInputRegistry instance is assigned a unique integer ID.
T * Get() const
Returns a raw pointer to the instance, which may be NULL.
Definition: sharedptr.h:89
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...
Definition: bufferobject.h:67
Attribute * GetMutableAttribute(const size_t attribute_index)
Returns a pointer to the Attribute at the passed index.
static const Spec< T > * GetSpec(const T &input)
Convenience function that returns a pointer to the Spec associated with an Attribute or Uniform insta...
std::string name
Definition: printer.cc:324
void RemoveReceiver(Notifier *receiver)
Removes a Notifier to be notified.
Definition: notifier.cc:38
size_t GetIndexInRegistry() const
Returns the index of the shader input within the registry.
Definition: shaderinput.h:67
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)
Definition: logging.h:332
const T & GetValue() const
If this instance contains a value of type T, this returns a const reference to it.
Definition: shaderinput.h:85
int GetResourceCount() const
Returns the number of resources that this holder holds.
bool IsValid() const
Returns true if this is a valid instance created by a ShaderInputRegistry.
Definition: shaderinput.h:59
size_t AddAttribute(const Attribute &attribute)
Adds an Attribute to this AttributeArray.
ValueType GetType() const
Returns the type of the shader input.
Definition: shaderinput.h:80
This class can be used in place of std::vector to allow an Ion Allocator to be used for memory alloca...
Definition: allocvector.h:50