Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bufferobject.h
Go to the documentation of this file.
1 
18 #ifndef ION_GFX_BUFFEROBJECT_H_
19 #define ION_GFX_BUFFEROBJECT_H_
20 
21 #include "ion/base/datacontainer.h"
22 #include "ion/base/invalid.h"
23 #include "ion/base/referent.h"
25 #include "ion/external/gtest/gunit_prod.h" // For FRIEND_TEST().
26 #include "ion/gfx/resourceholder.h"
27 #include "ion/math/range.h"
28 
29 namespace ion {
30 namespace gfx {
34 
67 class ION_API BufferObject : public ResourceHolder {
68  public:
70  enum Changes {
71  kDataChanged = kNumBaseChanges,
73  kNumChanges
74  };
75 
78  kInvalid, // An invalid spec.
90  kFloatMatrixColumn4
91  };
92 
93  enum Target {
97  kCopyWriteBuffer
98  };
99 
100  enum UsageMode {
104  };
105 
108  struct BufferSubData {
109  BufferSubData() : read_offset(0) {}
110 
111  BufferSubData(const math::Range1ui& range_in,
112  const base::DataContainerPtr& data_in)
113  : range(range_in), data(data_in), read_offset(0) {
114  DCHECK(data_in.Get());
115  }
117  const math::Range1ui& range_in,
118  uint32 read_offset_in)
119  : range(range_in), read_offset(read_offset_in), src(src_in) {}
121  ~BufferSubData();
122 
128  uint32 read_offset;
132  };
133 
135  BufferObject();
136 
138  Target GetTarget() const { return target_; }
139 
140  struct Spec {
143  : component_count(0U),
144  byte_offset(0U),
145  type(kInvalid) {}
146 
147  Spec(const ComponentType type_in, const size_t count_in,
148  const size_t offset_in)
149  : component_count(count_in),
150  byte_offset(offset_in),
151  type(type_in) {}
152 
153  bool operator==(const Spec& other) const {
154  return component_count == other.component_count &&
155  byte_offset == other.byte_offset &&
156  type == other.type;
157  }
158 
162  size_t byte_offset;
165  };
166 
178  size_t AddSpec(const ComponentType type, const size_t component_count,
179  const size_t byte_offset);
180 
183  const Spec& GetSpec(const size_t spec_index) const;
184 
186  size_t GetSpecCount() const { return specs_.size(); }
187 
195  void SetData(const base::DataContainerPtr& data, const size_t struct_size,
196  const size_t count, UsageMode usage) {
197  if (base::DataContainer* old_data = GetData().Get())
198  old_data->RemoveReceiver(this);
199  if (base::DataContainer* new_data = data.Get())
200  new_data->AddReceiver(this);
201  data_.Set(BufferData(data, struct_size, count, usage));
202  }
203 
205  const base::DataContainerPtr& GetData() const { return data_.Get().data; }
206 
211  void SetSubData(const math::Range1ui& byte_range,
212  const base::DataContainerPtr& data) {
213  if (!byte_range.IsEmpty() && data.Get() && data->GetData()) {
214  sub_data_.push_back(BufferSubData(byte_range, data));
216  sub_data_changed_.Set(true);
217  sub_data_changed_.Set(false);
218  }
219  }
226  void CopySubData(const BufferObjectPtr& src,
227  const math::Range1ui& dst_byte_range,
228  uint32 read_offset) {
229  if (src.Get() && !dst_byte_range.IsEmpty()) {
230  sub_data_.push_back(BufferSubData(
232  src.Get() == this ? BufferObjectPtr() : src,
233  dst_byte_range, read_offset));
235  sub_data_changed_.Set(true);
236  sub_data_changed_.Set(false);
237  }
238  }
240  void ClearSubData() const {
241  sub_data_.clear();
242  }
245  return sub_data_;
246  }
247 
250  void* GetMappedPointer() const {
251  return mapped_data_.pointer;
252  }
253 
255  size_t GetStructSize() const { return data_.Get().struct_size; }
257  size_t GetCount() const { return data_.Get().count; }
259  UsageMode GetUsageMode() const { return data_.Get().usage; }
260 
261  protected:
264  explicit BufferObject(Target target);
265 
268  ~BufferObject() override;
269 
270  private:
272  struct BufferData {
274  BufferData()
275  : data(nullptr),
276  struct_size(0U),
277  count(0U),
278  usage(kStaticDraw) {}
279 
280  BufferData(const base::DataContainerPtr& data_in,
281  const size_t struct_size_in,
282  const size_t count_in, const UsageMode usage_in)
283  : data(data_in),
284  struct_size(struct_size_in),
285  count(count_in),
286  usage(usage_in) {}
287 
292  inline bool operator !=(const BufferData& other) const {
293  return true;
294  }
295 
299  size_t struct_size;
301  size_t count;
303  UsageMode usage;
304  };
305 
307  struct MappedBufferData {
308  enum DataSource {
309  kGpuMapped, // Data is mapped by GPU.
310  kAllocated, // Data is allocated from Allocator, needs free.
311  kDataContainer // Data comes from BufferObject's DataContainer, no free.
312  };
313  MappedBufferData()
314  : range(math::Range1ui()),
315  pointer(nullptr),
316  data_source(base::InvalidEnumValue<
317  BufferObject::MappedBufferData::DataSource>()),
318  read_only(true) {}
320  math::Range1ui range;
322  void* pointer;
324  DataSource data_source;
326  bool read_only;
327  };
328 
330  void OnNotify(const base::Notifier* notifier) override;
331 
333  void SetMappedData(const math::Range1ui& range, void* pointer,
334  MappedBufferData::DataSource data_source, bool read_only) {
335  mapped_data_.range = range;
336  mapped_data_.pointer = pointer;
337  mapped_data_.data_source = data_source;
338  mapped_data_.read_only = read_only;
339  }
340 
342  const MappedBufferData& GetMappedData() const {
343  return mapped_data_;
344  }
345 
347  base::AllocVector<Spec> specs_;
348 
350  Field<BufferData> data_;
351 
353  Target target_;
354 
357  mutable base::AllocVector<BufferSubData> sub_data_;
361  Field<bool> sub_data_changed_;
362 
366  MappedBufferData mapped_data_;
367 
369  friend class Renderer;
370 
372  FRIEND_TEST(BufferObjectTest, MappedData);
373  FRIEND_TEST(RendererTest, MappedBuffer);
374 };
375 
381  : buffer_object(nullptr),
382  spec_index(0U) {}
383 
385  const size_t spec_index_in)
386  : buffer_object(buffer_in),
387  spec_index(spec_index_in) {}
388 
389  bool operator==(const BufferObjectElement& other) const {
390  return buffer_object == other.buffer_object &&
391  spec_index == other.spec_index;
392  }
393 
395  const size_t spec_index;
396 };
397 
398 } // namespace gfx
399 } // namespace ion
400 
401 #endif // ION_GFX_BUFFEROBJECT_H_
bool operator==(const BufferObjectElement &other) const
Definition: bufferobject.h:389
ComponentType type
The type of each component.
Definition: bufferobject.h:164
size_t GetSpecCount() const
Gets the number of Specs in the BufferObject.
Definition: bufferobject.h:186
size_t GetCount() const
Gets the number of structs in the buffer.
Definition: bufferobject.h:257
BufferObjectPtr src
Source BufferObject for CopySubData, NULL is interpreted as this BufferObject.
Definition: bufferobject.h:131
std::string type
Definition: printer.cc:353
Changes
Changes that affect the resource.
Definition: bufferobject.h:70
#define DCHECK(expr)
Definition: logging.h:331
size_t byte_offset
The offset of the element defined by this Spec in the data type.
Definition: bufferobject.h:162
Spec(const ComponentType type_in, const size_t count_in, const size_t offset_in)
Definition: bufferobject.h:147
BufferSubData(const math::Range1ui &range_in, const base::DataContainerPtr &data_in)
Definition: bufferobject.h:111
base::DataContainerPtr data
Source data for copy. If NULL source data is taken from src.
Definition: bufferobject.h:126
Range< 1, uint32 > Range1ui
Definition: range.h:364
const BufferObjectPtr buffer_object
Definition: bufferobject.h:394
Structure for clients to use to encapsulate Elements.
Definition: bufferobject.h:378
Spec()
Default constructor for STL.
Definition: bufferobject.h:142
void SetData(const base::DataContainerPtr &data, const size_t struct_size, const size_t count, UsageMode usage)
Sets data container, the size of the structure in bytes, and the number of structures.
Definition: bufferobject.h:195
The DataContainer class encapsulates arbitrary user data passed to Ion.
Definition: datacontainer.h:74
T * Get() const
Returns a raw pointer to the instance, which may be NULL.
Definition: sharedptr.h:89
const void * pointer
Definition: printer.cc:111
BufferObjectElement()
Default constructor for templates.
Definition: bufferobject.h:380
A BufferObject describes a generic array of data used, for example, to describe the vertices in a Sha...
Definition: bufferobject.h:67
const base::DataContainerPtr & GetData() const
Gets the data container.
Definition: bufferobject.h:205
uint32 read_offset
Read offset in bytes into data or src.
Definition: bufferobject.h:128
These are necessary since each column of a matrix must be sent to OpenGL separately and we must know ...
Definition: bufferobject.h:88
size_t GetStructSize() const
Gets the size of one structure, in bytes.
Definition: bufferobject.h:255
Specifies a destination byte range, read byte offset, and source BufferObject or DataContainer for Bu...
Definition: bufferobject.h:108
bool operator==(const Spec &other) const
Definition: bufferobject.h:153
UsageMode GetUsageMode() const
Gets the usage mode of the data.
Definition: bufferobject.h:259
ComponentType
The type of the components of a spec.
Definition: bufferobject.h:77
size_t component_count
The number of components.
Definition: bufferobject.h:160
void CopySubData(const BufferObjectPtr &src, const math::Range1ui &dst_byte_range, uint32 read_offset)
Adds a byte range of data that should be copied from src to this BufferObject.
Definition: bufferobject.h:226
EnumType InvalidEnumValue()
InvalidEnumValue() returns an invalid enum value, assuming that -1 is not a valid value...
Definition: invalid.h:47
Target GetTarget() const
Gets the buffer target.
Definition: bufferobject.h:138
BufferSubData(const BufferObjectPtr &src_in, const math::Range1ui &range_in, uint32 read_offset_in)
Definition: bufferobject.h:116
const base::AllocVector< BufferSubData > & GetSubData() const
Returns all sub-data ranges; may be an empty vector.
Definition: bufferobject.h:244
math::Range1ui range
Destination byte range of copy.
Definition: bufferobject.h:124
bool operator!=(const StlAllocator< T1 > &lhs, const StlAllocator< T2 > &rhs)
Definition: stlallocator.h:242
base::ReferentPtr< DataContainer >::Type DataContainerPtr
Definition: datacontainer.h:38
base::ReferentPtr< BufferObject >::Type BufferObjectPtr
Convenience typedef for shared pointer to a BufferObject.
Definition: bufferobject.h:31
void SetSubData(const math::Range1ui &byte_range, const base::DataContainerPtr &data)
Marks that the specified byte range of the BufferObject's data should be updated with the passed data...
Definition: bufferobject.h:211
void * GetMappedPointer() const
Returns the mapped data pointer of the buffer, which will be NULL if the buffer has not been mapped w...
Definition: bufferobject.h:250
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...
Definition: sharedptr.h:60
void ClearSubData() const
Clears the vector of sub-data.
Definition: bufferobject.h:240
The Renderer class handles rendering ION scene graphs using OpenGL.
Definition: renderer.h:50
BufferObjectElement(const BufferObjectPtr &buffer_in, const size_t spec_index_in)
Definition: bufferobject.h:384
ResourceHolder is an internal base class for objects that hold resources managed by an outside entity...
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