18 #ifndef ION_GFX_SHADERINPUTREGISTRY_H_
19 #define ION_GFX_SHADERINPUTREGISTRY_H_
26 #include "base/macros.h"
92 kUniformAdded = kNumBaseChanges,
110 template <
typename T>
112 typedef std::function<const T(const T& old_value, const T& new_value)>
Type;
124 template <
typename T>
126 typedef std::function<std::vector<T>(
const T& current_value)>
Type;
130 template <
typename T>
132 Spec(
const std::string& name_in = std::string(),
133 typename T::ValueType value_type_in =
134 static_cast<typename T::ValueType>(0),
135 const std::string& doc_string_in = std::string(),
139 value_type(value_type_in),
140 doc_string(doc_string_in),
144 combine_function(combine_function_in),
145 generate_function(generate_function_in) {}
169 size_t GetId()
const {
return id_; }
181 bool IncludeGlobalRegistry();
190 bool CheckInputsAreUnique()
const;
195 size_t array_index = 0;
197 if (Contains(spec.
name)) {
198 LOG(
WARNING) <<
"Can't add " << T::GetShaderInputTypeName() <<
" spec"
199 <<
" for '" << spec.
name <<
"': already present in registry"
200 <<
" or its includes";
202 }
else if (!ParseShaderInputName(spec.
name, &name, &array_index)) {
203 LOG(
WARNING) <<
"Can't add " << T::GetShaderInputTypeName() <<
" spec"
204 <<
" for '" << spec.
name <<
"': invalid input name.";
209 const size_t index = specs.size();
210 specs.push_back(spec);
211 specs.back().index = index;
212 specs.back().registry_id = id_;
213 specs.back().registry =
this;
214 UpdateLargestRegistrySize(specs.size());
216 spec_map_[spec.
name] = SpecMapEntry(T::GetTag(), index, id_);
223 bool Contains(
const std::string&
name)
const;
228 const size_t num_includes = includes_.size();
229 for (
size_t i = 0; i < num_includes; ++i) {
234 const SpecMapType::const_iterator it = spec_map_.find(name);
235 if (it == spec_map_.end()) {
239 }
else if (it->second.tag != T::GetTag()) {
245 return &GetSpecs<T>()[it->second.index];
257 template <
typename ShaderInputType,
typename T>
258 const ShaderInputType
Create(
const std::string& name_in,
const T&
value) {
261 typename ShaderInputType::HolderType,
T>::Type StoredType;
262 typename ShaderInputType::ValueType value_type =
263 ShaderInputType::template GetTypeByValue<StoredType>();
265 ShaderInputType input;
266 size_t index = 0, registry_id = 0, array_index = 0;
268 if (ParseShaderInputName(name_in, &name, &array_index)) {
269 if (!Find<ShaderInputType>(name))
271 if (ValidateNameAndType<ShaderInputType>(name, value_type, 0U, ®istry,
272 ®istry_id, &index))
273 input.template Init<T>(*registry, registry_id, index, array_index,
278 template <
typename ShaderInputType,
typename T>
279 const ShaderInputType
Create(
const std::string& name_in,
283 typename ShaderInputType::HolderType,
T>::Type StoredType;
284 typename ShaderInputType::ValueType value_type =
285 ShaderInputType::template GetTypeByValue<StoredType>();
287 ShaderInputType input;
288 size_t index = 0, registry_id = 0, array_index = 0;
290 if (ParseShaderInputName(name_in, &name, &array_index) &&
291 ValidateNameAndType<ShaderInputType>(
name, value_type, 0U, ®istry,
292 ®istry_id, &index))
293 input.template Init<T>(*registry, registry_id, index, array_index,
305 template <
typename T>
313 size_t index = 0, registry_id = 0, array_index = 0;
315 UniformType value_type = Uniform::GetTypeByValue<StoredType>();
317 if (ParseShaderInputName(name_in, &name, &array_index)) {
318 if (!Find<Uniform>(name)) Add<Uniform>(
Spec<Uniform>(name, value_type));
319 ValidateNameAndType<Uniform>(
name, value_type, count, ®istry,
320 ®istry_id, &index);
321 input.template InitArray<T>(*registry, registry_id, index, array_index,
322 value_type, values, count, allocator);
326 template <
typename T>
334 size_t index = 0, registry_id = 0, array_index = 0;
336 UniformType value_type = Uniform::GetTypeByValue<StoredType>();
338 if (ParseShaderInputName(name_in, &name, &array_index) &&
339 ValidateNameAndType<Uniform>(
name, value_type, count, ®istry,
340 ®istry_id, &index))
341 input.template InitArray<T>(*registry, registry_id, index, array_index,
342 value_type, values, count, allocator);
349 template <
typename T>
351 return !input.IsValid() ? NULL :
352 &input.GetRegistry().template GetSpecs<T>()[input.GetIndexInRegistry()];
371 class StaticGlobalRegistryData;
375 static StaticData* GetStaticData();
379 static StaticGlobalRegistryData* GetStaticGlobalRegistryData();
382 static void UpdateLargestRegistrySize(
size_t size);
384 struct SpecMapEntry {
391 size_t registry_id_in)
394 registry_id(registry_id_in) {}
400 typedef base::AllocMap<const std::string, SpecMapEntry> SpecMapType;
403 const SpecMapType GetAllSpecEntries()
const;
406 template <
typename T>
407 base::AllocDeque<Spec<T> >* GetMutableSpecs();
414 template <
typename T>
415 bool ValidateNameAndType(
const std::string&
name,
416 const typename T::ValueType value_type,
size_t size,
417 ShaderInputRegistry** registry,
size_t* registry_id,
418 size_t* index)
const {
420 if (
const Spec<T>* spec = Find<T>(name)) {
421 if (spec->value_type == value_type) {
422 *index = spec->index;
423 *registry_id = spec->registry_id;
424 *registry = spec->registry;
427 LOG(
ERROR) <<
"Can't create " << T::GetShaderInputTypeName() <<
" '"
428 << name <<
"': wrong value_type (got "
429 << T::GetValueTypeName(value_type) <<
", expected "
430 << T::GetValueTypeName(spec->value_type) <<
")";
434 LOG(
ERROR) <<
"Can't create " << T::GetShaderInputTypeName() <<
" '"
435 << name <<
"': no Spec exists for this name, did you forget "
443 bool ParseShaderInputName(
const std::string& input, std::string* name,
444 size_t* index)
const {
448 const size_t open_pos = input.find(
"[");
449 const size_t close_pos = input.find(
"]");
450 if (open_pos != std::string::npos && close_pos != std::string::npos &&
451 close_pos > open_pos + 1U) {
454 if (tokens.size() > 1 && !tokens[1].empty())
456 }
else if (open_pos == std::string::npos &&
457 close_pos == std::string::npos) {
467 Field<base::AllocDeque<UniformSpec> > uniform_specs_;
468 base::AllocDeque<AttributeSpec> attribute_specs_;
471 base::AllocVector<ShaderInputRegistryPtr> includes_;
474 SpecMapType spec_map_;
480 DISALLOW_COPY_AND_ASSIGN(ShaderInputRegistry);
486 #endif // ION_GFX_SHADERINPUTREGISTRY_H_
internal::ResolverHelper< VariantType, TypeToResolve, TypeToResolve >::Type Type
The VariantTypeResolver struct allows users of the Variant class to determine which type defined by a...
#define LOG(severity)
Logs the streamed message unconditionally with a severity of severity.
std::vector< std::string > ION_API SplitString(const std::string &str, const std::string &delimiters)
Splits a string into a vector of substrings, given a set of delimiter characters (expressed as a stri...
int32 ION_API StringToInt32(const std::string &str)
Extracts and returns an integral value from str.
This class can be used in place of std::deque to allow an Ion Allocator to be used for memory allocat...
Copyright 2016 Google Inc.
base::ReferentPtr< ShaderInputRegistry >::Type ShaderInputRegistryPtr
Convenience typedef for shared pointer to a ShaderInputRegistry.
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...
ResourceHolder is an internal base class for objects that hold resources managed by an outside entity...
UniformType
The UniformType enum defines all supported uniform shader argument types.
This class can be used in place of std::vector to allow an Ion Allocator to be used for memory alloca...