Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore dirty list for BaseMaterial3D but don't use it on resource loader. #99716

Merged
merged 1 commit into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scene/register_scene_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,7 @@ void register_scene_types() {
GDREGISTER_CLASS(ProceduralSkyMaterial);
GDREGISTER_CLASS(PanoramaSkyMaterial);
GDREGISTER_CLASS(PhysicalSkyMaterial);
SceneTree::add_idle_callback(BaseMaterial3D::flush_changes);
BaseMaterial3D::init_shaders();

GDREGISTER_CLASS(MeshLibrary);
Expand Down
88 changes: 52 additions & 36 deletions scene/resources/material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,13 @@ void Material::_mark_initialized(const Callable &p_add_to_dirty_list, const Call
if (ResourceLoader::is_within_load()) {
DEV_ASSERT(init_state != INIT_STATE_READY);
if (init_state == INIT_STATE_UNINITIALIZED) { // Prevent queueing twice.
init_state = INIT_STATE_INITIALIZING;
callable_mp(this, &Material::_mark_ready).call_deferred();
p_update_shader.call_deferred();
if (p_update_shader.is_valid()) {
init_state = INIT_STATE_INITIALIZING;
callable_mp(this, &Material::_mark_ready).call_deferred();
p_update_shader.call_deferred();
} else {
init_state = INIT_STATE_READY;
}
}
} else {
// Straightforward conditions.
Expand Down Expand Up @@ -578,6 +582,8 @@ ShaderMaterial::~ShaderMaterial() {
HashMap<BaseMaterial3D::MaterialKey, BaseMaterial3D::ShaderData, BaseMaterial3D::MaterialKey> BaseMaterial3D::shader_map;
Mutex BaseMaterial3D::shader_map_mutex;
BaseMaterial3D::ShaderNames *BaseMaterial3D::shader_names = nullptr;
Mutex BaseMaterial3D::material_mutex;
SelfList<BaseMaterial3D>::List BaseMaterial3D::dirty_materials;

void BaseMaterial3D::init_shaders() {
shader_names = memnew(ShaderNames);
Expand Down Expand Up @@ -666,21 +672,13 @@ HashMap<uint64_t, Ref<StandardMaterial3D>> BaseMaterial3D::materials_for_2d;
void BaseMaterial3D::finish_shaders() {
materials_for_2d.clear();

dirty_materials.clear();

memdelete(shader_names);
shader_names = nullptr;
}

void BaseMaterial3D::_mark_dirty() {
dirty = true;
}

void BaseMaterial3D::_update_shader() {
if (!dirty) {
return;
}

dirty = false;

MaterialKey mk = _compute_key();
if (mk == current_key) {
return; //no update required in the end
Expand Down Expand Up @@ -1962,6 +1960,23 @@ void BaseMaterial3D::_check_material_rid() {
}
}

void BaseMaterial3D::flush_changes() {
MutexLock lock(material_mutex);

while (dirty_materials.first()) {
dirty_materials.first()->self()->_update_shader();
dirty_materials.first()->remove_from_list();
}
}

void BaseMaterial3D::_queue_shader_change() {
MutexLock lock(material_mutex);

if (_is_initialized() && !element.in_list()) {
dirty_materials.add(&element);
}
}

void BaseMaterial3D::_material_set_param(const StringName &p_name, const Variant &p_value) {
if (_get_material().is_valid()) {
RS::get_singleton()->material_set_param(_get_material(), p_name, p_value);
Expand Down Expand Up @@ -2171,7 +2186,7 @@ void BaseMaterial3D::set_detail_uv(DetailUV p_detail_uv) {
}

detail_uv = p_detail_uv;
_mark_dirty();
_queue_shader_change();
}

BaseMaterial3D::DetailUV BaseMaterial3D::get_detail_uv() const {
Expand All @@ -2184,7 +2199,7 @@ void BaseMaterial3D::set_blend_mode(BlendMode p_mode) {
}

blend_mode = p_mode;
_mark_dirty();
_queue_shader_change();
}

BaseMaterial3D::BlendMode BaseMaterial3D::get_blend_mode() const {
Expand All @@ -2193,7 +2208,7 @@ BaseMaterial3D::BlendMode BaseMaterial3D::get_blend_mode() const {

void BaseMaterial3D::set_detail_blend_mode(BlendMode p_mode) {
detail_blend_mode = p_mode;
_mark_dirty();
_queue_shader_change();
}

BaseMaterial3D::BlendMode BaseMaterial3D::get_detail_blend_mode() const {
Expand All @@ -2206,7 +2221,7 @@ void BaseMaterial3D::set_transparency(Transparency p_transparency) {
}

transparency = p_transparency;
_mark_dirty();
_queue_shader_change();
notify_property_list_changed();
}

Expand All @@ -2220,7 +2235,7 @@ void BaseMaterial3D::set_alpha_antialiasing(AlphaAntiAliasing p_alpha_aa) {
}

alpha_antialiasing_mode = p_alpha_aa;
_mark_dirty();
_queue_shader_change();
notify_property_list_changed();
}

Expand All @@ -2234,7 +2249,7 @@ void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) {
}

shading_mode = p_shading_mode;
_mark_dirty();
_queue_shader_change();
notify_property_list_changed();
}

Expand All @@ -2248,7 +2263,7 @@ void BaseMaterial3D::set_depth_draw_mode(DepthDrawMode p_mode) {
}

depth_draw_mode = p_mode;
_mark_dirty();
_queue_shader_change();
}

BaseMaterial3D::DepthDrawMode BaseMaterial3D::get_depth_draw_mode() const {
Expand All @@ -2261,7 +2276,7 @@ void BaseMaterial3D::set_cull_mode(CullMode p_mode) {
}

cull_mode = p_mode;
_mark_dirty();
_queue_shader_change();
}

BaseMaterial3D::CullMode BaseMaterial3D::get_cull_mode() const {
Expand All @@ -2274,7 +2289,7 @@ void BaseMaterial3D::set_diffuse_mode(DiffuseMode p_mode) {
}

diffuse_mode = p_mode;
_mark_dirty();
_queue_shader_change();
}

BaseMaterial3D::DiffuseMode BaseMaterial3D::get_diffuse_mode() const {
Expand All @@ -2287,7 +2302,7 @@ void BaseMaterial3D::set_specular_mode(SpecularMode p_mode) {
}

specular_mode = p_mode;
_mark_dirty();
_queue_shader_change();
}

BaseMaterial3D::SpecularMode BaseMaterial3D::get_specular_mode() const {
Expand Down Expand Up @@ -2317,7 +2332,7 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) {
update_configuration_warning();
}

_mark_dirty();
_queue_shader_change();
}

bool BaseMaterial3D::get_flag(Flags p_flag) const {
Expand All @@ -2333,7 +2348,7 @@ void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) {

features[p_feature] = p_enabled;
notify_property_list_changed();
_mark_dirty();
_queue_shader_change();
}

bool BaseMaterial3D::get_feature(Feature p_feature) const {
Expand All @@ -2353,7 +2368,7 @@ void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_t
}

notify_property_list_changed();
_mark_dirty();
_queue_shader_change();
}

Ref<Texture2D> BaseMaterial3D::get_texture(TextureParam p_param) const {
Expand All @@ -2373,7 +2388,7 @@ Ref<Texture2D> BaseMaterial3D::get_texture_by_name(const StringName &p_name) con

void BaseMaterial3D::set_texture_filter(TextureFilter p_filter) {
texture_filter = p_filter;
_mark_dirty();
_queue_shader_change();
}

BaseMaterial3D::TextureFilter BaseMaterial3D::get_texture_filter() const {
Expand Down Expand Up @@ -2610,7 +2625,7 @@ float BaseMaterial3D::get_uv2_triplanar_blend_sharpness() const {

void BaseMaterial3D::set_billboard_mode(BillboardMode p_mode) {
billboard_mode = p_mode;
_mark_dirty();
_queue_shader_change();
notify_property_list_changed();
}

Expand Down Expand Up @@ -2647,7 +2662,7 @@ bool BaseMaterial3D::get_particles_anim_loop() const {

void BaseMaterial3D::set_heightmap_deep_parallax(bool p_enable) {
deep_parallax = p_enable;
_mark_dirty();
_queue_shader_change();
notify_property_list_changed();
}

Expand Down Expand Up @@ -2693,7 +2708,7 @@ bool BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal() const {

void BaseMaterial3D::set_grow_enabled(bool p_enable) {
grow_enabled = p_enable;
_mark_dirty();
_queue_shader_change();
notify_property_list_changed();
}

Expand Down Expand Up @@ -2762,7 +2777,7 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_metallic_texture_channel() co
void BaseMaterial3D::set_roughness_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
roughness_texture_channel = p_channel;
_mark_dirty();
_queue_shader_change();
}

BaseMaterial3D::TextureChannel BaseMaterial3D::get_roughness_texture_channel() const {
Expand Down Expand Up @@ -2844,7 +2859,7 @@ void BaseMaterial3D::set_on_top_of_alpha() {

void BaseMaterial3D::set_proximity_fade_enabled(bool p_enable) {
proximity_fade_enabled = p_enable;
_mark_dirty();
_queue_shader_change();
notify_property_list_changed();
}

Expand Down Expand Up @@ -2881,7 +2896,7 @@ float BaseMaterial3D::get_msdf_outline_size() const {

void BaseMaterial3D::set_distance_fade(DistanceFadeMode p_mode) {
distance_fade = p_mode;
_mark_dirty();
_queue_shader_change();
notify_property_list_changed();
}

Expand Down Expand Up @@ -2912,7 +2927,7 @@ void BaseMaterial3D::set_emission_operator(EmissionOperator p_op) {
return;
}
emission_op = p_op;
_mark_dirty();
_queue_shader_change();
}

BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const {
Expand Down Expand Up @@ -3443,7 +3458,8 @@ void BaseMaterial3D::_bind_methods() {
BIND_ENUM_CONSTANT(DISTANCE_FADE_OBJECT_DITHER);
}

BaseMaterial3D::BaseMaterial3D(bool p_orm) {
BaseMaterial3D::BaseMaterial3D(bool p_orm) :
element(this) {
orm = p_orm;
// Initialize to the same values as the shader
set_albedo(Color(1.0, 1.0, 1.0, 1.0));
Expand Down Expand Up @@ -3510,7 +3526,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) {

current_key.invalid_key = 1;

_mark_dirty();
_mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change), Callable());
}

BaseMaterial3D::~BaseMaterial3D() {
Expand Down
8 changes: 6 additions & 2 deletions scene/resources/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,15 +467,18 @@ class BaseMaterial3D : public Material {
StringName albedo_texture_size;
};

static Mutex material_mutex;
static SelfList<BaseMaterial3D>::List dirty_materials;
static ShaderNames *shader_names;

void _mark_dirty();
SelfList<BaseMaterial3D> element;

void _update_shader();
_FORCE_INLINE_ void _queue_shader_change();
void _check_material_rid();
void _material_set_param(const StringName &p_name, const Variant &p_value);

bool orm;
bool dirty = true;
RID shader_rid;
HashMap<StringName, Variant> pending_params;

Expand Down Expand Up @@ -780,6 +783,7 @@ class BaseMaterial3D : public Material {

static void init_shaders();
static void finish_shaders();
static void flush_changes();

static Ref<Material> get_material_for_2d(bool p_shaded, Transparency p_transparency, bool p_double_sided, bool p_billboard = false, bool p_billboard_y = false, bool p_msdf = false, bool p_no_depth = false, bool p_fixed_size = false, TextureFilter p_filter = TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, AlphaAntiAliasing p_alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF, RID *r_shader_rid = nullptr);

Expand Down