summaryrefslogtreecommitdiffstats
path: root/scene/resources/shader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/shader.cpp')
-rw-r--r--scene/resources/shader.cpp45
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);
+ }
}
////////////