Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/render/osl.cpp')
-rw-r--r--intern/cycles/render/osl.cpp77
1 files changed, 67 insertions, 10 deletions
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index e4ee40d881e..28de56f3a72 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -76,12 +76,12 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
if(progress.get_cancel()) return;
- if(shader->sample_as_light && shader->has_surface_emission)
- scene->light_manager->need_update = true;
-
OSLCompiler compiler((void*)this, (void*)ss, scene->image_manager);
compiler.background = (shader == scene->shaders[scene->default_background]);
compiler.compile(og, shader);
+
+ if(shader->sample_as_light && shader->has_surface_emission)
+ scene->light_manager->need_update = true;
}
/* setup shader engine */
@@ -202,8 +202,14 @@ static string shader_filepath_hash(const string& filepath, uint64_t modified_tim
const char *OSLShaderManager::shader_test_loaded(const string& hash)
{
- set<string>::iterator it = loaded_shaders.find(hash);
- return (it == loaded_shaders.end())? NULL: it->c_str();
+ map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash);
+ return (it == loaded_shaders.end())? NULL: it->first.c_str();
+}
+
+OSLShaderInfo *OSLShaderManager::shader_loaded_info(const string& hash)
+{
+ map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash);
+ return (it == loaded_shaders.end())? NULL: &it->second;
}
const char *OSLShaderManager::shader_load_filepath(string filepath)
@@ -261,18 +267,59 @@ const char *OSLShaderManager::shader_load_filepath(string filepath)
if(!path_read_text(filepath, bytecode)) {
fprintf(stderr, "Cycles shader graph: failed to read file %s\n", filepath.c_str());
- loaded_shaders.insert(bytecode_hash); /* to avoid repeat tries */
+ OSLShaderInfo info;
+ loaded_shaders[bytecode_hash] = info; /* to avoid repeat tries */
return NULL;
}
return shader_load_bytecode(bytecode_hash, bytecode);
}
+/* don't try this at home .. this is a template trick to use either
+ * LoadMemoryShader or LoadMemoryCompiledShader which are the function
+ * names in our custom branch and the official repository. */
+
+template<bool C, typename T = void> struct enable_if { typedef T type; };
+template<typename T> struct enable_if<false, T> { };
+
+template<typename T, typename Sign>
+struct has_LoadMemoryCompiledShader {
+ typedef int yes;
+ typedef char no;
+
+ template<typename U, U> struct type_check;
+ template<typename _1> static yes &chk(type_check<Sign, &_1::LoadMemoryCompiledShader>*);
+ template<typename > static no &chk(...);
+ static bool const value = sizeof(chk<T>(0)) == sizeof(yes);
+};
+
+template<typename T>
+typename enable_if<has_LoadMemoryCompiledShader<T,
+ bool(T::*)(const char*, const char*)>::value, bool>::type
+load_memory_shader(T *ss, const char *name, const char *buffer)
+{
+ return ss->LoadMemoryCompiledShader(name, buffer);
+}
+
+template<typename T>
+typename enable_if<!has_LoadMemoryCompiledShader<T,
+ bool(T::*)(const char*, const char*)>::value, bool>::type
+load_memory_shader(T *ss, const char *name, const char *buffer)
+{
+ return ss->LoadMemoryShader(name, buffer);
+}
+
const char *OSLShaderManager::shader_load_bytecode(const string& hash, const string& bytecode)
{
- ss->LoadMemoryShader(hash.c_str(), bytecode.c_str());
+ load_memory_shader(ss, hash.c_str(), bytecode.c_str());
+
+ /* this is a bit weak, but works */
+ OSLShaderInfo info;
+ info.has_surface_emission = (bytecode.find("\"emission\"") != string::npos);
+ info.has_surface_transparent = (bytecode.find("\"transparent\"") != string::npos);
+ loaded_shaders[hash] = info;
- return loaded_shaders.insert(hash).first->c_str();
+ return loaded_shaders.find(hash)->first.c_str();
}
/* Graph Compiler */
@@ -443,6 +490,16 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
ss->ConnectShaders(id_from.c_str(), param_from.c_str(), id_to.c_str(), param_to.c_str());
}
}
+
+ /* test if we shader contains specific closures */
+ OSLShaderInfo *info = ((OSLShaderManager*)manager)->shader_loaded_info(name);
+
+ if(info) {
+ if(info->has_surface_emission)
+ current_shader->has_surface_emission = true;
+ if(info->has_surface_transparent)
+ current_shader->has_surface_transparent = true;
+ }
}
void OSLCompiler::parameter(const char *name, float f)
@@ -598,9 +655,9 @@ void OSLCompiler::generate_nodes(const set<ShaderNode*>& nodes)
node->compile(*this);
done.insert(node);
- if(node->name == ustring("emission"))
+ if(node->has_surface_emission())
current_shader->has_surface_emission = true;
- if(node->name == ustring("transparent"))
+ if(node->has_surface_transparent())
current_shader->has_surface_transparent = true;
}
else