Cleanup: DRW: Make Open subdiv evaluator part of a DRW module

This avoids the global variable access with race condition.
Rel #134690

Pull Request: https://projects.blender.org/blender/blender/pulls/134855
This commit is contained in:
Clément Foucault
2025-02-20 15:04:27 +01:00
committed by Clément Foucault
parent 31aa6d9aee
commit 91de4a50ab
6 changed files with 37 additions and 15 deletions

View File

@@ -171,11 +171,9 @@ void DRW_cache_free_old_batches(Main *bmain);
namespace blender::draw {
/* Free garbage collected subdivision data. */
void DRW_cache_free_old_subdiv();
/* For the OpenGL evaluators and garbage collected subdivision data. */
void DRW_subdiv_free();
} // namespace blender::draw
/* Never use this. Only for closing blender. */

View File

@@ -2,6 +2,7 @@
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "draw_manager_c.hh"
#include "draw_subdivision.hh"
#include "DNA_mesh_types.h"
@@ -43,6 +44,7 @@
#include "draw_cache_extract.hh"
#include "draw_cache_impl.hh"
#include "draw_cache_inline.hh"
#include "draw_common_c.hh"
#include "draw_shader.hh"
#include "draw_subdiv_shader_shared.hh"
#include "mesh_extractors/extract_mesh.hh"
@@ -1926,7 +1928,18 @@ void DRW_subdivide_loose_geom(DRWSubdivCache &subdiv_cache, const MeshBufferCach
});
}
static OpenSubdiv_EvaluatorCache *g_evaluator_cache = nullptr;
/**
* OpenSubdiv GPU evaluation module.
*/
struct SubdivModule {
OpenSubdiv_EvaluatorCache *evaluator_cache = openSubdiv_createEvaluatorCache(
OPENSUBDIV_EVALUATOR_GPU);
~SubdivModule()
{
openSubdiv_deleteEvaluatorCache(evaluator_cache);
}
};
void DRW_create_subdivision(Object &ob,
Mesh &mesh,
@@ -1941,8 +1954,9 @@ void DRW_create_subdivision(Object &ob,
const ToolSettings *ts,
const bool use_hide)
{
if (g_evaluator_cache == nullptr) {
g_evaluator_cache = openSubdiv_createEvaluatorCache(OPENSUBDIV_EVALUATOR_GPU);
DRWData &drw_data = *DST.vmempool;
if (drw_data.subdiv_module == nullptr) {
drw_data.subdiv_module = MEM_new<SubdivModule>("SubdivModule");
}
#undef TIME_SUBDIV
@@ -1963,7 +1977,7 @@ void DRW_create_subdivision(Object &ob,
do_cage,
ts,
use_hide,
g_evaluator_cache))
drw_data.subdiv_module->evaluator_cache))
{
return;
}
@@ -1975,16 +1989,18 @@ void DRW_create_subdivision(Object &ob,
#endif
}
void DRW_subdiv_free()
void DRW_subdiv_module_free(SubdivModule *subdiv_module)
{
DRW_cache_free_old_subdiv();
if (g_evaluator_cache) {
openSubdiv_deleteEvaluatorCache(g_evaluator_cache);
g_evaluator_cache = nullptr;
}
MEM_delete(subdiv_module);
}
/**
* The `bke::subdiv::Subdiv` data is being owned the modifier.
* Since the modifier can be freed from any thread (e.g. from depsgraph multithreaded update)
* which may not have a valid GPUContext active, we move the data to discard to this free list
* until a codepath with a active GPUContext is hit.
* This is kindof garbage collection.
*/
static LinkNode *gpu_subdiv_free_queue = nullptr;
static ThreadMutex gpu_subdiv_queue_mutex = BLI_MUTEX_INITIALIZER;

View File

@@ -29,6 +29,7 @@ namespace blender::draw {
class Manager;
struct CurvesModule;
struct PointCloudModule;
struct SubdivModule;
struct VolumeModule;
} // namespace blender::draw
@@ -71,6 +72,10 @@ void DRW_pointcloud_module_free(draw::PointCloudModule *module);
void DRW_volume_init(DRWData *drw_data = nullptr);
void DRW_volume_module_free(draw::VolumeModule *module);
/* draw_cache_impl_subdivision.cc */
void DRW_subdiv_module_free(draw::SubdivModule *module);
} // namespace blender::draw
/* `draw_fluid.cc` */

View File

@@ -355,6 +355,7 @@ void DRW_viewport_data_free(DRWData *drw_data)
DRW_volume_module_free(drw_data->volume_module);
DRW_pointcloud_module_free(drw_data->pointcloud_module);
DRW_curves_module_free(drw_data->curves_module);
DRW_subdiv_module_free(drw_data->subdiv_module);
delete drw_data->default_view;
MEM_freeN(drw_data);
}

View File

@@ -32,6 +32,7 @@ struct Object;
struct Mesh;
namespace blender::draw {
struct CurvesModule;
struct SubdivModule;
struct VolumeModule;
struct PointCloudModule;
struct DRW_Attributes;
@@ -72,6 +73,7 @@ struct DRWData {
DRWViewData *view_data[2];
/** Module storage. */
blender::draw::CurvesModule *curves_module;
blender::draw::SubdivModule *subdiv_module;
blender::draw::VolumeModule *volume_module;
blender::draw::PointCloudModule *pointcloud_module;
/** Default view that feeds every engine. */

View File

@@ -596,7 +596,7 @@ void WM_exit_ex(bContext *C, const bool do_python_exit, const bool do_user_exit_
/* Free the GPU subdivision data after the database to ensure that subdivision structs used by
* the modifiers were garbage collected. */
if (gpu_is_init) {
blender::draw::DRW_subdiv_free();
blender::draw::DRW_cache_free_old_subdiv();
}
ANIM_fcurves_copybuf_free();