diff options
Diffstat (limited to 'scene/resources/shader.cpp')
-rw-r--r-- | scene/resources/shader.cpp | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 46d38146a6..24d17108d5 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -50,6 +50,14 @@ Shader::Mode Shader::get_mode() const { return mode; } +void Shader::_check_shader_rid() const { + MutexLock lock(shader_rid_mutex); + if (shader_rid.is_null() && !preprocessed_code.is_empty()) { + shader_rid = RenderingServer::get_singleton()->shader_create_from_code(preprocessed_code, get_path()); + preprocessed_code = String(); + } +} + void Shader::_dependency_changed() { // Preprocess and compile the code again because a dependency has changed. It also calls emit_changed() for us. _recompile(); @@ -61,7 +69,10 @@ void Shader::_recompile() { void Shader::set_path(const String &p_path, bool p_take_over) { Resource::set_path(p_path, p_take_over); - RS::get_singleton()->shader_set_path_hint(shader, p_path); + + if (shader_rid.is_valid()) { + RS::get_singleton()->shader_set_path_hint(shader_rid, p_path); + } } void Shader::set_include_path(const String &p_path) { @@ -76,7 +87,7 @@ void Shader::set_code(const String &p_code) { } code = p_code; - String pp_code = p_code; + preprocessed_code = p_code; { String path = get_path(); @@ -88,7 +99,7 @@ void Shader::set_code(const String &p_code) { // 2) Server does not do interaction with Resource filetypes, this is a scene level feature. HashSet<Ref<ShaderInclude>> new_include_dependencies; ShaderPreprocessor preprocessor; - Error result = preprocessor.preprocess(p_code, path, pp_code, nullptr, nullptr, nullptr, &new_include_dependencies); + Error result = preprocessor.preprocess(p_code, path, preprocessed_code, nullptr, nullptr, nullptr, &new_include_dependencies); if (result == OK) { // This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower) include_dependencies = new_include_dependencies; @@ -96,7 +107,7 @@ void Shader::set_code(const String &p_code) { } // Try to get the shader type from the final, fully preprocessed shader code. - String type = ShaderLanguage::get_shader_type(pp_code); + String type = ShaderLanguage::get_shader_type(preprocessed_code); if (type == "canvas_item") { mode = MODE_CANVAS_ITEM; @@ -114,7 +125,10 @@ void Shader::set_code(const String &p_code) { E->connect_changed(callable_mp(this, &Shader::_dependency_changed)); } - RenderingServer::get_singleton()->shader_set_code(shader, pp_code); + if (shader_rid.is_valid()) { + RenderingServer::get_singleton()->shader_set_code(shader_rid, preprocessed_code); + preprocessed_code = String(); + } emit_changed(); } @@ -126,9 +140,10 @@ String Shader::get_code() const { void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_groups) const { _update_shader(); + _check_shader_rid(); List<PropertyInfo> local; - RenderingServer::get_singleton()->get_shader_parameter_list(shader, &local); + RenderingServer::get_singleton()->get_shader_parameter_list(shader_rid, &local); #ifdef TOOLS_ENABLED DocData::ClassDoc class_doc; @@ -182,17 +197,20 @@ void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_gr RID Shader::get_rid() const { _update_shader(); + _check_shader_rid(); - return shader; + return shader_rid; } void Shader::set_default_texture_parameter(const StringName &p_name, const Ref<Texture> &p_texture, int p_index) { + _check_shader_rid(); + if (p_texture.is_valid()) { if (!default_textures.has(p_name)) { default_textures[p_name] = HashMap<int, Ref<Texture>>(); } default_textures[p_name][p_index] = p_texture; - RS::get_singleton()->shader_set_default_texture_parameter(shader, p_name, p_texture->get_rid(), p_index); + RS::get_singleton()->shader_set_default_texture_parameter(shader_rid, p_name, p_texture->get_rid(), p_index); } else { if (default_textures.has(p_name) && default_textures[p_name].has(p_index)) { default_textures[p_name].erase(p_index); @@ -201,7 +219,7 @@ void Shader::set_default_texture_parameter(const StringName &p_name, const Ref<T default_textures.erase(p_name); } } - RS::get_singleton()->shader_set_default_texture_parameter(shader, p_name, RID(), p_index); + RS::get_singleton()->shader_set_default_texture_parameter(shader_rid, p_name, RID(), p_index); } emit_changed(); @@ -225,6 +243,7 @@ bool Shader::is_text_shader() const { } void Shader::_update_shader() const { + // Base implementation does nothing. } Array Shader::_get_shader_uniform_list(bool p_get_groups) { @@ -258,12 +277,14 @@ void Shader::_bind_methods() { } Shader::Shader() { - shader = RenderingServer::get_singleton()->shader_create(); + // Shader RID will be empty until it is required. } Shader::~Shader() { - ERR_FAIL_NULL(RenderingServer::get_singleton()); - RenderingServer::get_singleton()->free(shader); + if (shader_rid.is_valid()) { + ERR_FAIL_NULL(RenderingServer::get_singleton()); + RenderingServer::get_singleton()->free(shader_rid); + } } //////////// |