Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
uniform.cc
Go to the documentation of this file.
1 
18 #include "ion/gfx/uniform.h"
19 
20 #include <algorithm>
21 #include <limits>
22 
23 #include "ion/base/logging.h"
24 #include "ion/math/range.h"
25 
26 namespace ion {
27 namespace gfx {
28 
29 namespace {
30 
32 template <typename VectorType>
33 static inline bool AreVectorUniformsEqual(const Uniform& u0,
34  const Uniform& u1) {
35  return VectorType::AreValuesEqual(u0.GetValue<VectorType>(),
36  u1.GetValue<VectorType>());
37 }
38 
40 template <typename T>
41 static inline bool AreUniformArraysEqual(const Uniform& u0,
42  const Uniform& u1) {
44  bool equal = u0.GetCount() == u1.GetCount() && u1.IsArrayOf<T>();
45  if (equal) {
46  const size_t count = u0.GetCount();
47  for (size_t i = 0; i < count; ++i)
48  if (u0.GetValueAt<T>(i) != u1.GetValueAt<T>(i)) {
49  equal = false;
50  break;
51  }
52  }
53  return equal;
54 }
55 
57 template <typename T>
58 static inline bool AreUniformVectorArraysEqual(const Uniform& u0,
59  const Uniform& u1) {
61  bool equal = u0.GetCount() == u1.GetCount() && u1.IsArrayOf<T>();
62  if (equal) {
63  const size_t count = u0.GetCount();
64  for (size_t i = 0; i < count; ++i)
65  if (!T::AreValuesEqual(u0.GetValueAt<T>(i), u1.GetValueAt<T>(i))) {
66  equal = false;
67  break;
68  }
69  }
70  return equal;
71 }
72 } // anonymous namespace
73 
75  return "uniform";
76 }
77 
79  switch (type) {
80  case kCubeMapTextureUniform: return "CubeMapTexture";
81  case kFloatUniform: return "Float";
82  case kIntUniform: return "Int";
83  case kUnsignedIntUniform: return "UnsignedInt";
84  case kTextureUniform: return "Texture";
85  case kFloatVector2Uniform: return "FloatVector2";
86  case kFloatVector3Uniform: return "FloatVector3";
87  case kFloatVector4Uniform: return "FloatVector4";
88  case kIntVector2Uniform: return "IntVector2";
89  case kIntVector3Uniform: return "IntVector3";
90  case kIntVector4Uniform: return "IntVector4";
91  case kUnsignedIntVector2Uniform: return "UnsignedIntVector2";
92  case kUnsignedIntVector3Uniform: return "UnsignedIntVector3";
93  case kUnsignedIntVector4Uniform: return "UnsignedIntVector4";
94  case kMatrix2x2Uniform: return "Matrix2x2";
95  case kMatrix3x3Uniform: return "Matrix3x3";
96  case kMatrix4x4Uniform: return "Matrix4x4";
97  default: return "<UNKNOWN>";
98  }
99 }
100 
103  CHECK(false) << "Unspecialized uniform Uniform::GetTypeByValue() called.";
104  return kIntUniform;
105 }
107 template <> ION_API Uniform::ValueType Uniform::GetTypeByValue<float>() {
108  return kFloatUniform;
109 }
110 template <> ION_API Uniform::ValueType Uniform::GetTypeByValue<int>() {
111  return kIntUniform;
112 }
113 template <> ION_API Uniform::ValueType Uniform::GetTypeByValue<uint32>() {
114  return kUnsignedIntUniform;
115 }
116 template <> ION_API
117 Uniform::ValueType Uniform::GetTypeByValue<CubeMapTexturePtr>() {
118  return kCubeMapTextureUniform;
119 }
120 template <> ION_API
121 Uniform::ValueType Uniform::GetTypeByValue<TexturePtr>() {
122  return kTextureUniform;
123 }
124 template <> ION_API
125 Uniform::ValueType Uniform::GetTypeByValue<math::VectorBase2f>() {
126  return kFloatVector2Uniform;
127 }
128 template <> ION_API
129 Uniform::ValueType Uniform::GetTypeByValue<math::VectorBase3f>() {
130  return kFloatVector3Uniform;
131 }
132 template <> ION_API
133 Uniform::ValueType Uniform::GetTypeByValue<math::VectorBase4f>() {
134  return kFloatVector4Uniform;
135 }
136 template <> ION_API
137 Uniform::ValueType Uniform::GetTypeByValue<math::VectorBase2i>() {
138  return kIntVector2Uniform;
139 }
140 template <> ION_API
141 Uniform::ValueType Uniform::GetTypeByValue<math::VectorBase3i>() {
142  return kIntVector3Uniform;
143 }
144 template <> ION_API
145 Uniform::ValueType Uniform::GetTypeByValue<math::VectorBase4i>() {
146  return kIntVector4Uniform;
147 }
148 template <> ION_API
149 Uniform::ValueType Uniform::GetTypeByValue<math::VectorBase2ui>() {
151 }
152 template <> ION_API
153 Uniform::ValueType Uniform::GetTypeByValue<math::VectorBase3ui>() {
155 }
156 template <> ION_API
157 Uniform::ValueType Uniform::GetTypeByValue<math::VectorBase4ui>() {
159 }
160 template <> ION_API
161 Uniform::ValueType Uniform::GetTypeByValue<math::Matrix2f>() {
162  return kMatrix2x2Uniform;
163 }
164 template <> ION_API
165 Uniform::ValueType Uniform::GetTypeByValue<math::Matrix3f>() {
166  return kMatrix3x3Uniform;
167 }
168 template <> ION_API
169 Uniform::ValueType Uniform::GetTypeByValue<math::Matrix4f>() {
170  return kMatrix4x4Uniform;
171 }
172 
173 template <typename T>
174 void Uniform::MergeValuesInternal(const Uniform& replacement) {
175  typedef math::Range<1, size_t> ArrayRange;
176  Uniform u;
177  const ArrayRange this_range = ArrayRange::BuildWithSize(
178  GetArrayIndex(), GetCount() == 0U ? 0U : GetCount() - 1U);
179  const ArrayRange replacement_range = ArrayRange::BuildWithSize(
180  replacement.GetArrayIndex(),
181  replacement.GetCount() == 0U ? 0U : replacement.GetCount() - 1U);
183  ArrayRange final_range = this_range;
184  final_range.ExtendByRange(replacement_range);
185 
187  u.InitArray<T>(GetRegistry(), GetRegistryId(), GetIndexInRegistry(),
188  final_range.GetMinPoint(), GetType(), NULL,
189  final_range.GetSize() + 1,
191  const T* values = GetCount() ? &GetValueAt<T>(0) : &GetValue<T>();
192  const T* replacement_values = replacement.GetCount() ?
193  &replacement.GetValueAt<T>(0) : &replacement.GetValue<T>();
194  size_t final_index = 0U;
195  for (size_t i = final_range.GetMinPoint();
196  i <= final_range.GetMaxPoint(); ++i) {
197  if (replacement_range.ContainsPoint(i)) {
199  u.SetValueAt<T>(final_index, *replacement_values++);
200  if (this_range.ContainsPoint(i))
201  values++;
202  } else if (this_range.ContainsPoint(i)) {
204  u.SetValueAt<T>(final_index, *values++);
205  }
206  ++final_index;
207  }
208  *this = u;
209 }
210 
211 void Uniform::MergeValuesFrom(const Uniform& other) {
214  if (&GetRegistry() == &other.GetRegistry() &&
215  GetIndexInRegistry() == other.GetIndexInRegistry() &&
216  GetType() == other.GetType() &&
217  &other != this) {
218  if (!GetMerged(*this, other, this)) {
220  *this = other;
221  }
222  }
223 }
224 
226  const Uniform& base, const Uniform& replacement, Uniform* merged) {
228  if (&base == &replacement || !base.IsValid())
229  return false;
230  if (!replacement.IsValid()) {
231  *merged = base;
232  return true;
233  }
235  if (!(&base.GetRegistry() == &replacement.GetRegistry() &&
236  base.GetIndexInRegistry() == replacement.GetIndexInRegistry() &&
237  base.GetType() == replacement.GetType())) {
238  return false;
239  }
241  if (replacement.GetArrayIndex() <= base.GetArrayIndex() &&
242  replacement.GetArrayIndex() + replacement.GetCount() >=
243  base.GetArrayIndex() + base.GetCount()) {
244  return false;
245  }
246  if (merged != &base)
247  *merged = base;
248  switch (base.GetType()) {
249  case kFloatUniform:
250  merged->MergeValuesInternal<float>(replacement);
251  break;
252  case kIntUniform:
253  merged->MergeValuesInternal<int>(replacement);
254  break;
255  case kUnsignedIntUniform:
256  merged->MergeValuesInternal<uint32>(replacement);
257  break;
259  merged->MergeValuesInternal<CubeMapTexturePtr>(replacement);
260  break;
261  case kTextureUniform:
262  merged->MergeValuesInternal<TexturePtr>(replacement);
263  break;
265  merged->MergeValuesInternal<math::VectorBase2f>(replacement);
266  break;
268  merged->MergeValuesInternal<math::VectorBase3f>(replacement);
269  break;
271  merged->MergeValuesInternal<math::VectorBase4f>(replacement);
272  break;
273  case kIntVector2Uniform:
274  merged->MergeValuesInternal<math::VectorBase2i>(replacement);
275  break;
276  case kIntVector3Uniform:
277  merged->MergeValuesInternal<math::VectorBase3i>(replacement);
278  break;
279  case kIntVector4Uniform:
280  merged->MergeValuesInternal<math::VectorBase4i>(replacement);
281  break;
283  merged->MergeValuesInternal<math::VectorBase2ui>(replacement);
284  break;
286  merged->MergeValuesInternal<math::VectorBase3ui>(replacement);
287  break;
289  merged->MergeValuesInternal<math::VectorBase4ui>(replacement);
290  break;
291  case kMatrix2x2Uniform:
292  merged->MergeValuesInternal<math::Matrix2f>(replacement);
293  break;
294  case kMatrix3x3Uniform:
295  merged->MergeValuesInternal<math::Matrix3f>(replacement);
296  break;
297  case kMatrix4x4Uniform:
298  merged->MergeValuesInternal<math::Matrix4f>(replacement);
299  break;
300 #if !defined(ION_COVERAGE) // COV_NF_START
301  default:
303  break;
304 #endif // COV_NF_END
305  }
306  return true;
307 }
308 
309 bool Uniform::operator==(const Uniform& other) const {
310 #define CHECK_UNIFORMS_EQUAL(type) \
311  if (IsArrayOf<type>()) \
312  equal = AreUniformArraysEqual<type>(*this, other); \
313  else \
314  equal = GetValue<type>() == other.GetValue<type>();
315 
316 #define CHECK_VECTOR_UNIFORMS_EQUAL(type) \
317  if (IsArrayOf<type>()) \
318  equal = AreUniformVectorArraysEqual<type>(*this, other); \
319  else \
320  equal = AreVectorUniformsEqual<type>(*this, other);
321 
322  if (&GetRegistry() == &other.GetRegistry() &&
323  GetIndexInRegistry() == other.GetIndexInRegistry() &&
324  GetType() == other.GetType()) {
326  bool equal = true;
327  switch (GetType()) {
328  case kFloatUniform:
329  CHECK_UNIFORMS_EQUAL(float);
330  break;
331  case kIntUniform:
333  break;
334  case kUnsignedIntUniform:
335  CHECK_UNIFORMS_EQUAL(uint32);
336  break;
339  break;
340  case kTextureUniform:
342  break;
344  CHECK_VECTOR_UNIFORMS_EQUAL(math::VectorBase2f);
345  break;
347  CHECK_VECTOR_UNIFORMS_EQUAL(math::VectorBase3f);
348  break;
350  CHECK_VECTOR_UNIFORMS_EQUAL(math::VectorBase4f);
351  break;
352  case kIntVector2Uniform:
353  CHECK_VECTOR_UNIFORMS_EQUAL(math::VectorBase2i);
354  break;
355  case kIntVector3Uniform:
356  CHECK_VECTOR_UNIFORMS_EQUAL(math::VectorBase3i);
357  break;
358  case kIntVector4Uniform:
359  CHECK_VECTOR_UNIFORMS_EQUAL(math::VectorBase4i);
360  break;
362  CHECK_VECTOR_UNIFORMS_EQUAL(math::VectorBase2ui);
363  break;
365  CHECK_VECTOR_UNIFORMS_EQUAL(math::VectorBase3ui);
366  break;
368  CHECK_VECTOR_UNIFORMS_EQUAL(math::VectorBase4ui);
369  break;
370  case kMatrix2x2Uniform:
372  break;
373  case kMatrix3x3Uniform:
375  break;
376  case kMatrix4x4Uniform:
378  break;
379 #if !defined(ION_COVERAGE) // COV_NF_START
380  default:
382  break;
383 #endif // COV_NF_END
384  }
385  return equal;
386  } else {
387  return false;
388  }
389 
390 #undef CHECK_UNIFORMS_EQUAL
391 #undef CHECK_VECTOR_UNIFORMS_EQUAL
392 }
393 } // namespace gfx
394 } // namespace ion
size_t GetRegistryId() const
Returns the id of the owning registry.
Definition: shaderinput.h:71
void MergeValuesFrom(const Uniform &replacement)
Merges the value of this with replacement if both have the same type.
Definition: uniform.cc:211
#define CHECK(expr)
Definition: logging.h:323
std::string type
Definition: printer.cc:353
The Range class defines an N-dimensional interval defined by minimum and maximum N-dimensional endpoi...
Definition: range.h:100
Uniform()
The default constructor creates an invalid Uniform instance, which should never be used as is...
Definition: uniform.h:81
Matrix< 3, float > Matrix3f
Definition: matrix.h:369
#define CHECK_VECTOR_UNIFORMS_EQUAL(type)
const ShaderInputRegistry & GetRegistry() const
Returns the ShaderInputRegistry the shader input is defined in.
Definition: shaderinput.h:63
A Uniform instance represents a uniform shader argument.
Definition: uniform.h:76
static ValueType GetTypeByValue()
Returns the type for a templated value type.
Definition: uniform.cc:101
static const char * GetValueTypeName(const ValueType type)
Returns a string representing a uniform type.
Definition: uniform.cc:78
size_t GetArrayIndex() const
Returns the array index of this input; by default this is 0.
Definition: shaderinput.h:76
Scalar types.
Definition: uniform.h:39
size_t GetCount() const
Returns the number of elements in the held type.
Definition: shaderinput.h:99
static bool GetMerged(const Uniform &base, const Uniform &replacement, Uniform *merged)
Merges replacement and base into merged.
Definition: uniform.cc:225
The Matrix class defines a square N-dimensional matrix.
Definition: matrix.h:35
const base::AllocatorPtr & GetArrayAllocator() const
Returns the allocator used to make array allocations.
Definition: shaderinput.h:207
bool operator==(const Uniform &other) const
Definition: uniform.cc:309
#define CHECK_UNIFORMS_EQUAL(type)
size_t GetIndexInRegistry() const
Returns the index of the shader input within the registry.
Definition: shaderinput.h:67
static const char * GetShaderInputTypeName()
Returns a string containing "uniform".
Definition: uniform.cc:74
Copyright 2016 Google Inc.
Matrix types.
Definition: uniform.h:59
bool IsValid() const
Returns true if this is a valid instance created by a ShaderInputRegistry.
Definition: shaderinput.h:59
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...
Definition: sharedptr.h:60
ValueType GetType() const
Returns the type of the shader input.
Definition: shaderinput.h:80
UniformType
The UniformType enum defines all supported uniform shader argument types.
Definition: uniform.h:37