Skip to content

Commit 0a17152

Browse files
committed
Collect deleted scene objects pending deletion into a trashbin
This commit aims at avoiding dangling references in rendering threads when scene is updated while rendering engine is running Warning: this commit is not complete as, the trashbin is never emptied (TODO).
1 parent 2e3bc62 commit 0a17152

15 files changed

Lines changed: 183 additions & 85 deletions

File tree

include/luxrays/core/namedobjectvector.h

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,23 @@ class NamedObjectVector {
9494
return std::make_tuple(std::ref(newDerivedRef), std::move(oldDerivedPtr));
9595
}
9696

97+
/// Delete a named object from the container.
98+
///
99+
/// Please not the name object is just removed, not
100+
/// destroyed. The object holder (unique_ptr) is returned
101+
/// to caller for further finalization
102+
template<typename T>
103+
std::unique_ptr<T> DeleteObj(const std::string &name) {
104+
105+
auto oldObjPtr = DeleteObj<NamedObject>(name);
106+
auto oldDerivedPtr = oldObjPtr ?
107+
dynamic_uptr_cast<T>(std::move(oldObjPtr)) :
108+
std::unique_ptr<T>();
109+
return std::move(oldDerivedPtr);
110+
111+
}
112+
113+
void DeleteObjs(const std::vector<std::string> &names);
97114

98115
bool IsObjDefined(const std::string &name) const;
99116

@@ -131,8 +148,6 @@ class NamedObjectVector {
131148
return std::vector<std::reference_wrapper<NamedObject>>(view.begin(), view.end());
132149
}
133150

134-
void DeleteObj(const std::string &name);
135-
void DeleteObjs(const std::vector<std::string> &names);
136151

137152
std::string ToString() const;
138153

@@ -164,7 +179,11 @@ template<>
164179
std::tuple< NamedObject&, std::unique_ptr<NamedObject> >
165180
NamedObjectVector::DefineObj(std::unique_ptr<NamedObject>&& obj);
166181

167-
}
182+
183+
template<>
184+
NamedObjectUPtr NamedObjectVector::DeleteObj(const std::string &name);
185+
186+
} // Namespace luxrays
168187

169188
#endif /* _LUXRAYS_NAMEDOBJECTVECTOR_H */
170189
// vim: autoindent noexpandtab tabstop=4 shiftwidth=4

include/slg/lights/lightsourcedefs.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "slg/lights/light.h"
2727
#include "slg/lights/trianglelight.h"
2828
#include "slg/lights/strategies/lightstrategy.h"
29+
#include "slg/usings.h"
2930

3031
namespace slg {
3132

@@ -45,7 +46,7 @@ class LightSourceDefinitions {
4546

4647
void UpdateVisibilityMaps(SceneConstRef scene, const bool useRTMode);
4748

48-
void DefineLightSource(LightSourceUPtr&& l);
49+
LightSourceUPtr DefineLightSource(LightSourceUPtr&& l);
4950
bool IsLightSourceDefined(const std::string &name) const;
5051

5152
LightSourceRef GetLightSource(const std::string &name);
@@ -56,9 +57,9 @@ class LightSourceDefinitions {
5657
u_int GetSize() const { return static_cast<u_int>(lightsByName.size()); }
5758
std::vector<std::string> GetLightSourceNames() const;
5859

59-
void DeleteLightSource(const std::string &name);
60-
void DeleteLightSourceStartWith(const std::string &namePrefix);
61-
void DeleteLightSourceByMaterial(MaterialConstRef mat);
60+
LightSourceUPtr DeleteLightSource(const std::string &name);
61+
std::vector<LightSourceUPtr> DeleteLightSourceStartWith(const std::string &namePrefix);
62+
std::vector<LightSourceUPtr> DeleteLightSourceByMaterial(MaterialConstRef mat);
6263

6364
void UpdateVolumeReferences(VolumeConstRef oldVol, VolumeRef newVol);
6465

include/slg/materials/materialdefs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ class MaterialDefinitions {
7575
return mats.GetNames();
7676
}
7777

78-
void DeleteMaterial(const std::string &name) {
79-
mats.DeleteObj(name);
78+
MaterialUPtr DeleteMaterial(const std::string &name) {
79+
return mats.DeleteObj<Material>(name);
8080
}
8181

8282
void UpdateTextureReferences(TextureConstRef oldTex, TextureRef newTex);

include/slg/scene/extmeshcache.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "luxrays/core/context.h"
2727
#include "luxrays/core/exttrianglemesh.h"
2828
#include "luxrays/core/namedobjectvector.h"
29+
#include "luxrays/usings.h"
2930
#include "luxrays/utils/serializationutils.h"
3031
#include "slg/core/sdl.h"
3132

@@ -52,7 +53,7 @@ class ExtMeshCache {
5253

5354
// Note: before calls to DeleteExtMesh, be sure to not have any instance referencing
5455
// the geometry
55-
void DeleteExtMesh(const std::string &meshName);
56+
ExtMeshUPtr DeleteExtMesh(const std::string &meshName);
5657

5758
u_int GetSize() const;
5859
auto GetExtMeshNames() const {

include/slg/scene/scene.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include "luxrays/core/exttrianglemesh.h"
2727
#include "luxrays/core/geometry/bsphere.h"
28+
#include "luxrays/core/namedobjectvector.h"
2829
#include "luxrays/usings.h"
2930
#include "slg/imagemap/imagemap.h"
3031
#include "slg/usings.h"
@@ -183,7 +184,8 @@ class Scene {
183184
const unsigned int index, float *data);
184185

185186
// Strands shape
186-
void DefineStrands(const std::string &shapeName, const luxrays::cyHairFile &strandsFile,
187+
Scene::ReturnType<ExtTriangleMesh> DefineStrands(
188+
const std::string &shapeName, const luxrays::cyHairFile &strandsFile,
187189
const StrendsShape::TessellationType tesselType,
188190
const u_int adaptiveMaxDepth, const float adaptiveError,
189191
const u_int solidSideCount, const bool solidCapBottom, const bool solidCapTop,
@@ -259,12 +261,17 @@ class Scene {
259261

260262
void SetEnableParsePrint(bool status) { enableParsePrint = status; }
261263

264+
void moveToTrash(luxrays::NamedObjectUPtr&&);
265+
void emptyTrash();
266+
262267
// Serialization
263268
static SceneUPtr LoadSerialized(const std::string &fileName);
264269
static void SaveSerialized(const std::string &fileName, SceneUPtr&& scene);
265270

266271
static std::string EncodeTriangleLightNamePrefix(const std::string &objectName);
267272

273+
//
274+
268275
protected:
269276
//--------------------------------------------------------------------------
270277

@@ -280,9 +287,17 @@ class Scene {
280287
SceneObjectDefinitions objDefs; // SceneObject definitions
281288
LightSourceDefinitions lightDefs; // LightSource definitions
282289

283-
// DataSet ownership is not very clear, we keep a shared at
284-
// the moment
290+
// The trash bin container collects items that are pending deletion, in
291+
// order to avoid dangling references in real time rendering when the scene
292+
// is updated while the render engine is running. Trash bin allows to keep
293+
// the deleted objects alive while they are still in use in rendering. It
294+
// is up to the rendering engine to empty trash bin.
295+
std::vector<luxrays::NamedObjectUPtr> trashBin;
296+
mutable std::mutex trashMtx;
297+
298+
// DataSet ownership is not very clear, we keep it shared
285299
luxrays::DataSetSPtr dataSet;
300+
286301
// The bounding sphere of the scene (including the camera)
287302
luxrays::BSphere sceneBSphere;
288303

include/slg/scene/sceneobjectdefs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ class SceneObjectDefinitions {
8080
std::unordered_set<const SceneObject *> &modifiedObjsList
8181
);
8282

83-
void DeleteSceneObject(const std::string &name) {
84-
objs.DeleteObj(name);
83+
SceneObjectUPtr DeleteSceneObject(const std::string &name) {
84+
return objs.DeleteObj<SceneObject>(name);
8585
}
8686

8787
void DeleteSceneObjects(const std::vector<std::string> &names) {

include/slg/slg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "luxrays/luxrays.h"
2525
#include "slg/usings.h"
26+
#include "slg/slg.h"
2627

2728
/*!
2829
* \namespace slg

include/slg/textures/texturedefs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ class TextureDefinitions {
7171
return texs.GetNames();
7272
}
7373

74-
void DeleteTexture(const std::string &name) {
75-
texs.DeleteObj(name);
74+
TextureUPtr DeleteTexture(const std::string &name) {
75+
return std::move(texs.DeleteObj<Texture>(name));
7676
}
7777

7878
const std::vector<std::string> GetTextureSortedNames() const;

src/luxrays/core/namedobjectvector.cpp

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -159,59 +159,56 @@ u_int NamedObjectVector::GetSize()const {
159159
//names[i] = GetName(i);
160160
//}
161161

162-
void NamedObjectVector::DeleteObj(const string &name) {
162+
template<>
163+
NamedObjectUPtr NamedObjectVector::DeleteObj(const string &name) {
163164
// We swap remove target and last object, and pop back
165+
if (objs.empty()) throw("Trying to delete an object in an empty container");
166+
167+
// Record index
168+
auto removeObjIndex = GetIndex(name);
169+
auto lastObjIndex = objs.size() - 1;
170+
171+
// Record names
172+
const std::string removeObjName{objs[removeObjIndex]->GetName()};
173+
const std::string lastObjName{objs[lastObjIndex]->GetName()};
174+
175+
if (lastObjIndex != removeObjIndex)
176+
{
177+
178+
std::swap(objs[removeObjIndex], objs[lastObjIndex]);
164179

165-
if (objs.size() > 0)
180+
// redo links
181+
name2index.left.erase(removeObjName);
182+
name2index.left.erase(lastObjName);
183+
name2index.insert(Name2IndexType::value_type(lastObjName, removeObjIndex));
184+
185+
index2obj.left.erase(lastObjIndex);
186+
index2obj.left.erase(removeObjIndex);
187+
index2obj.insert(
188+
Index2ObjType::value_type(
189+
removeObjIndex, std::ref(*objs[removeObjIndex])
190+
)
191+
);
192+
193+
}
194+
else
166195
{
167-
// Record index
168-
auto removeObjIndex = GetIndex(name);
169-
auto lastObjIndex = objs.size() - 1;
170-
171-
// Record names
172-
const string removeObjName{objs[removeObjIndex]->GetName()};
173-
const string lastObjName{objs[lastObjIndex]->GetName()};
174-
175-
if (lastObjIndex != removeObjIndex)
176-
{
177-
178-
std::swap(objs[removeObjIndex], objs[lastObjIndex]);
179-
180-
//TODO
181-
//NamedObject* lastObj = objs[lastIndex];
182-
////int newIndex = index;
183-
//objs[index] = lastObj;
184-
185-
// redo links
186-
name2index.left.erase(removeObjName);
187-
name2index.left.erase(lastObjName);
188-
name2index.insert(Name2IndexType::value_type(lastObjName, removeObjIndex));
189-
190-
index2obj.left.erase(lastObjIndex);
191-
index2obj.left.erase(removeObjIndex);
192-
index2obj.insert(
193-
Index2ObjType::value_type(
194-
removeObjIndex, std::ref(*objs[removeObjIndex])
195-
)
196-
);
197-
198-
}
199-
else
200-
{
201-
// last
202-
name2index.left.erase(removeObjName);
203-
index2obj.left.erase(removeObjIndex);
204-
}
196+
// last
197+
name2index.left.erase(removeObjName);
198+
index2obj.left.erase(removeObjIndex);
205199
}
206200

207201
// remove last
202+
NamedObjectUPtr ret = std::move(objs.back());
208203
objs.pop_back();
204+
return std::move(ret);
209205
}
210206

207+
211208
void NamedObjectVector::DeleteObjs(const std::vector<string> &names) {
212209

213210
for (const string& name : names) {
214-
DeleteObj(name);
211+
DeleteObj<NamedObject>(name);
215212
}
216213
}
217214

src/slg/lights/lightsourcedefs.cpp

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "slg/scene/scene.h"
2525
#include "slg/lights/trianglelight.h"
2626
#include "slg/lights/strategies/logpower.h"
27+
#include "slg/usings.h"
2728

2829
using namespace std;
2930
using namespace luxrays;
@@ -45,18 +46,27 @@ LightSourceDefinitions::LightSourceDefinitions() :
4546
LightSourceDefinitions::~LightSourceDefinitions() {
4647
}
4748

48-
void LightSourceDefinitions::DefineLightSource(LightSourceUPtr&& newLight) {
49+
/// Insert a new light source in the container
50+
///
51+
/// If a light source with the same name already exists in the container,
52+
/// it is extracted and returned.
53+
LightSourceUPtr LightSourceDefinitions::DefineLightSource(LightSourceUPtr&& newLight) {
4954
const string &name = newLight->GetName();
5055

51-
if (IsLightSourceDefined(name)) {
52-
auto& oldLight = GetLightSource(name);
56+
auto e = lightsByName.find(name);
57+
58+
if (e != lightsByName.end()) {
59+
// Light source already exists
60+
auto oldLight = std::move(e->second);
5361

5462
// Update name/LightSource definition
55-
lightsByName.erase(name);
63+
lightsByName.erase(e);
5664
lightsByName[name] = std::move(newLight);
65+
return oldLight;
5766
} else {
5867
// Add the new LightSource
5968
lightsByName[name] = std::move(newLight);
69+
return LightSourceUPtr();
6070
}
6171
}
6272

@@ -120,31 +130,47 @@ vector<string> LightSourceDefinitions::GetLightSourceNames() const {
120130
return names;
121131
}
122132

123-
void LightSourceDefinitions::DeleteLightSource(const string &name) {
133+
LightSourceUPtr LightSourceDefinitions::DeleteLightSource(const string &name) {
124134
auto e = lightsByName.find(name);
125135

126136
if (e == lightsByName.end())
127137
throw runtime_error("Reference to an undefined LightSource in LightSourceDefinitions::DeleteLightSource(): " + name);
128-
else {
129-
lightsByName.erase(name);
130-
}
138+
139+
140+
auto oldLight = std::move(e->second);
141+
lightsByName.erase(e);
142+
return oldLight;
131143
}
132144

133-
void LightSourceDefinitions::DeleteLightSourceStartWith(const string &namePrefix) {
145+
146+
std::vector<LightSourceUPtr> LightSourceDefinitions::DeleteLightSourceStartWith(
147+
const string &namePrefix
148+
) {
149+
std::vector<LightSourceUPtr> oldLights;
150+
134151
// Build the list of lights to delete
135-
vector<string> nameList;
152+
std::vector<string> nameList;
136153
for (auto const &e : lightsByName) {
137154
const string &name = e.first;
138155

139156
if (name.starts_with(namePrefix))
140157
nameList.push_back(name);
141158
}
142159

143-
for (auto const &name : nameList)
144-
DeleteLightSource(name);
160+
// Remove the lights from the container and return the removed lights
161+
for (auto const &name : nameList) {
162+
auto oldLight = DeleteLightSource(name);
163+
oldLights.push_back(std::move(oldLight));
164+
}
165+
return oldLights;
145166
}
146167

147-
void LightSourceDefinitions::DeleteLightSourceByMaterial(MaterialConstRef mat) {
168+
169+
std::vector<LightSourceUPtr> LightSourceDefinitions::DeleteLightSourceByMaterial(
170+
MaterialConstRef mat
171+
) {
172+
std::vector<LightSourceUPtr> oldLights;
173+
148174
// Build the list of lights to delete
149175
std::vector<string> nameList;
150176
for (auto const &e : lightsByName) {
@@ -159,8 +185,12 @@ void LightSourceDefinitions::DeleteLightSourceByMaterial(MaterialConstRef mat) {
159185
}
160186
}
161187

162-
for (auto const &name : nameList)
163-
DeleteLightSource(name);
188+
// Remove the lights from the container and return the removed lights
189+
for (auto const &name : nameList) {
190+
auto oldLight = DeleteLightSource(name);
191+
oldLights.push_back(std::move(oldLight));
192+
}
193+
return oldLights;
164194
}
165195

166196
void LightSourceDefinitions::SetLightStrategy(const luxrays::Properties &props) {

0 commit comments

Comments
 (0)