diff --git a/source/blender/draw/engines/eevee/eevee_material.cc b/source/blender/draw/engines/eevee/eevee_material.cc index 2ac37ab8476..129e86bc8a0 100644 --- a/source/blender/draw/engines/eevee/eevee_material.cc +++ b/source/blender/draw/engines/eevee/eevee_material.cc @@ -150,9 +150,9 @@ MaterialModule::~MaterialModule() delete mat; mat = nullptr; } - for (DRWShadingGroup **shgroup : shader_map_.values()) { - delete shgroup; - shgroup = nullptr; + for (ShadingGroupInfo &info : shader_map_.values()) { + delete info.grp; + info.grp = nullptr; } BKE_id_free(nullptr, glossy_mat_); BKE_id_free(nullptr, diffuse_mat_); @@ -166,8 +166,8 @@ void MaterialModule::begin_sync(void) for (Material *mat : material_map_.values()) { mat->init = false; } - for (DRWShadingGroup **shgroup : shader_map_.values()) { - *shgroup = nullptr; + for (ShadingGroupInfo &info : shader_map_.values()) { + info.grp = nullptr; } } @@ -219,22 +219,21 @@ MaterialPass MaterialModule::material_pass_get(::Material *blender_mat, else { ShaderKey shader_key(matpass.gpumat, geometry_type, pipeline_type); - /* TODO(fclem) allocate in blocks to avoid memory fragmentation. */ - auto add_cb = [&]() { return new DRWShadingGroup *(); }; - DRWShadingGroup *&grp = *shader_map_.lookup_or_add_cb(shader_key, add_cb); + ShadingGroupInfo &info = shader_map_.lookup_or_add_default(shader_key); - if (grp == nullptr) { + if (!info.was_initialized) { /* First time encountering this shader. Create a shading group. */ - grp = inst_.shading_passes.material_add(blender_mat, matpass.gpumat, pipeline_type); + info.grp = inst_.shading_passes.material_add(blender_mat, matpass.gpumat, pipeline_type); + info.was_initialized = true; } - if (grp != nullptr) { + if (info.grp != nullptr) { /* Shading group for this shader already exists. Create a sub one for this material. */ /* IMPORTANT: We always create a subgroup so that all subgroups are inserted after the * first "empty" shgroup. This avoids messing the order of subgroups when there is more * nested subgroup (i.e: hair drawing). */ /* TODO(fclem) Remove material resource binding from the first group creation. */ - matpass.shgrp = DRW_shgroup_create_sub(grp); + matpass.shgrp = DRW_shgroup_create_sub(info.grp); DRW_shgroup_add_material_resources(matpass.shgrp, matpass.gpumat); } } @@ -318,4 +317,4 @@ Material &MaterialModule::material_get(Object *ob, int mat_nr, eMaterialGeometry /** \} */ -} // namespace blender::eevee \ No newline at end of file +} // namespace blender::eevee diff --git a/source/blender/draw/engines/eevee/eevee_material.hh b/source/blender/draw/engines/eevee/eevee_material.hh index 2e2c79d0083..e68db0844d1 100644 --- a/source/blender/draw/engines/eevee/eevee_material.hh +++ b/source/blender/draw/engines/eevee/eevee_material.hh @@ -76,7 +76,13 @@ class MaterialModule { Instance &inst_; Map material_map_; - Map shader_map_; + + struct ShadingGroupInfo { + DRWShadingGroup *grp = nullptr; + bool was_initialized = false; + }; + + Map shader_map_; MaterialArray material_array_; @@ -106,4 +112,4 @@ class MaterialModule { /** \} */ -} // namespace blender::eevee \ No newline at end of file +} // namespace blender::eevee