ShaderMaster::ref ShadingSystemImpl::loadshader (string_view cname) { if (Strutil::ends_with (cname, ".oso")) cname.remove_suffix (4); // strip superfluous .oso if (! cname.size()) { error ("Attempt to load shader with empty name \"\"."); return NULL; } ++m_stat_shaders_requested; ustring name (cname); lock_guard guard (m_mutex); // Thread safety ShaderNameMap::const_iterator found = m_shader_masters.find (name); if (found != m_shader_masters.end()) { // if (debug()) // info ("Found %s in shader_masters", name.c_str()); // Already loaded this shader, return its reference return (*found).second; } // Not found in the map OSOReaderToMaster oso (*this); std::string filename = OIIO::Filesystem::searchpath_find (name.string() + ".oso", m_searchpath_dirs); if (filename.empty ()) { error ("No .oso file could be found for shader \"%s\"", name.c_str()); return NULL; } OIIO::Timer timer; bool ok = oso.parse_file (filename); ShaderMaster::ref r = ok ? oso.master() : nullptr; m_shader_masters[name] = r; double loadtime = timer(); { spin_lock lock (m_stat_mutex); m_stat_master_load_time += loadtime; } if (ok) { ++m_stat_shaders_loaded; info ("Loaded \"%s\" (took %s)", filename.c_str(), Strutil::timeintervalformat(loadtime, 2).c_str()); ASSERT (r); r->resolve_syms (); // if (debug()) { // std::string s = r->print (); // if (s.length()) // info ("%s", s.c_str()); // } } else { error ("Unable to read \"%s\"", filename.c_str()); } return r; }
void rtrim(string_view& s) noexcept { const auto pos = s.find_last_not_of(Space); s.remove_suffix(s.size() - (pos != string_view::npos ? pos + 1 : 0)); }
// Add the attribute -- figure out the type void parse_param(string_view paramname, string_view val, ImageSpec& spec) { TypeDesc type; // start out unknown // If the param string starts with a type name, that's what it is if (size_t typeportion = type.fromstring(paramname)) { paramname.remove_prefix(typeportion); Strutil::skip_whitespace(paramname); } // If the value string starts with a type name, that's what it is else if (size_t typeportion = type.fromstring(val)) { val.remove_prefix(typeportion); Strutil::skip_whitespace(val); } if (type.basetype == TypeDesc::UNKNOWN) { // If we didn't find a type name, try to guess if (val.size() >= 2 && val.front() == '\"' && val.back() == '\"') { // Surrounded by quotes? it's a string (strip off the quotes) val.remove_prefix(1); val.remove_suffix(1); type = TypeDesc::TypeString; } else if (Strutil::string_is<int>(val)) { // Looks like an int, is an int type = TypeDesc::TypeInt; } else if (Strutil::string_is<float>(val)) { // Looks like a float, is a float type = TypeDesc::TypeFloat; } else { // Everything else is assumed a string type = TypeDesc::TypeString; } } // Read the values and set the attribute int n = type.numelements() * type.aggregate; if (type.basetype == TypeDesc::INT) { std::vector<int> values(n); for (int i = 0; i < n; ++i) { Strutil::parse_int(val, values[i]); Strutil::parse_char(val, ','); // optional } if (n > 0) spec.attribute(paramname, type, &values[0]); } if (type.basetype == TypeDesc::FLOAT) { std::vector<float> values(n); for (int i = 0; i < n; ++i) { Strutil::parse_float(val, values[i]); Strutil::parse_char(val, ','); // optional } if (n > 0) spec.attribute(paramname, type, &values[0]); } else if (type.basetype == TypeDesc::STRING) { std::vector<ustring> values(n); for (int i = 0; i < n; ++i) { string_view v; Strutil::parse_string(val, v); Strutil::parse_char(val, ','); // optional values[i] = v; } if (n > 0) spec.attribute(paramname, type, &values[0]); } }