Commit fd6ac300 authored by Carson Brownlee's avatar Carson Brownlee
Browse files

debugging memory leaks in ospray

parent 3b0ea9aa
......@@ -70,7 +70,7 @@ namespace RTW
public:
RTWError Init() override
{
const bool throwError = false;
const bool throwError = true;
static bool once = false;
RTWError ret = RTW_NO_ERROR;
if (!once) {
......@@ -113,18 +113,18 @@ namespace RTW
return false;
}
RTWData NewCopyData1D(size_t numElements, RTWDataType dataType, const void *source) override
{
OSPData data = ospNewData1D(static_cast<OSPDataType>(dataType), numElements);
ospCommit(data);
OSPData shared = ospNewSharedData1D(source, static_cast<OSPDataType>(dataType), numElements);
ospCommit(shared);
ospCopyData1D(shared, data, 0);
ospCommit(data);
ospRelease(shared);
return reinterpret_cast<RTWData>(data);
}
RTWData NewData(size_t numElements, RTWDataType dataType) override
{
return reinterpret_cast<RTWData>(ospNewData(static_cast<OSPDataType>(dataType), numElements));
......
......@@ -441,13 +441,13 @@ OSPGeometricModel RenderAsTriangles(OSPData vertices, std::vector<unsigned int>&
int numPointColors, osp::vec4f* PointColors, int numPointValueTextureCoords,
float* pointValueTextureCoords, RTW::Backend* backend)
{
std::cout << "ospPDMN::RenderAsTriangles begin\n";
if (backend == nullptr)
return OSPGeometry();
OSPGeometry ospMesh = ospNewGeometry("mesh");
OSPGeometricModel ospGeoModel = ospNewGeometricModel(ospMesh);
ospRelease(ospMesh);
ospSetObject(ospMesh, "vertex.position", vertices);
ospRelease(vertices);
size_t numTriangles = indexArray.size() / 3;
std::vector<osp::vec3ui> triangles(numTriangles);
......@@ -465,16 +465,16 @@ OSPGeometricModel RenderAsTriangles(OSPData vertices, std::vector<unsigned int>&
OSPData _normals = nullptr;
if (numNormals)
{
_normals = ospNewCopyData1D(numNormals, OSP_VEC3F, normals.data());
ospSetObject(ospMesh, "vertex.normal", _normals);
ospRelease(_normals);
// _normals = ospNewCopyData1D(numNormals, OSP_VEC3F, normals.data());
// ospSetObject(ospMesh, "vertex.normal", _normals);
// ospRelease(_normals);
}
// send the texture map and texture coordinates over
bool _hastm = false;
OSPData tcs = nullptr;
std::vector<osp::vec2f> tc;
if (numTextureCoordinates || numPointValueTextureCoords)
if (0) // numTextureCoordinates || numPointValueTextureCoords)
{
_hastm = true;
......@@ -516,7 +516,7 @@ OSPGeometricModel RenderAsTriangles(OSPData vertices, std::vector<unsigned int>&
int* ids = nullptr;
if (!useCustomMaterial)
{
if (vNormalTextureMap && _hastm)
if (0) // vNormalTextureMap && _hastm)
{
OSPTexture t2d = vtkOSPRayMaterialHelpers::VTKToOSPTexture(backend, vNormalTextureMap);
if (interpolationType == VTK_PBR)
......@@ -535,7 +535,7 @@ OSPGeometricModel RenderAsTriangles(OSPData vertices, std::vector<unsigned int>&
ospCommit(actorMaterial);
}
if (interpolationType == VTK_PBR && vMaterialTextureMap && _hastm)
if (0) // interpolationType == VTK_PBR && vMaterialTextureMap && _hastm)
{
vtkNew<vtkImageExtractComponents> extractRoughness;
extractRoughness->SetInputData(vMaterialTextureMap);
......@@ -565,8 +565,9 @@ OSPGeometricModel RenderAsTriangles(OSPData vertices, std::vector<unsigned int>&
ospCommit(actorMaterial);
}
if (vColorTextureMap && _hastm)
if (0) // vColorTextureMap && _hastm)
{
std::cout << "has vcolortexturmap\n";
// Note: this will only have an affect on OBJMaterials
OSPTexture t2d = vtkOSPRayMaterialHelpers::VTKToOSPTexture(backend, vColorTextureMap);
if (interpolationType == VTK_PBR)
......@@ -584,6 +585,7 @@ OSPGeometricModel RenderAsTriangles(OSPData vertices, std::vector<unsigned int>&
}
ospRelease(t2d);
ospCommit(actorMaterial);
std::cout << "vcolortexturmap end\n";
}
else if (numCellMaterials)
{
......@@ -599,17 +601,24 @@ OSPGeometricModel RenderAsTriangles(OSPData vertices, std::vector<unsigned int>&
}
else if (numPointColors)
{
_PointColors = ospNewCopyData1D(numPointColors, OSP_VEC4F, &PointColors[0]);
ospSetObject(ospMesh, "vertex.color", _PointColors);
ospRelease(_PointColors);
std::cout << "numpointcolors\n";
// _PointColors = ospNewCopyData1D(numPointColors, OSP_VEC4F, &PointColors[0]);
// ospSetObject(ospMesh, "vertex.color", _PointColors);
// ospRelease(_PointColors);
std::cout << "numpointcolors end\n";
}
}
ospSetObject(ospGeoModel, "material", actorMaterial);
std::cout << "setting material\n";
ospSetObjectAsData(ospGeoModel, "material", OSP_MATERIAL, actorMaterial);
std::cout << "commit mesh\n";
ospCommit(ospMesh);
std::cout << "commit geomodel\n";
ospCommit(ospGeoModel);
std::cout << "commit geomodel done\n";
std::cout << "ospPDMN::RenderAsTriangles done\n";
return ospGeoModel;
}
......@@ -726,6 +735,7 @@ vtkOSPRayPolyDataMapperNode::vtkOSPRayPolyDataMapperNode()
this->UseGeometryCache = true;
this->GeometryCache = new vtkOSPRayCache<vtkOSPRayCacheItemGeometricModels>;
this->InstanceCache = new vtkOSPRayCache<vtkOSPRayCacheItemObject>;
std::cout << "vtkOSPDMN new (" << this << ")\n";
}
//----------------------------------------------------------------------------
......@@ -733,6 +743,7 @@ vtkOSPRayPolyDataMapperNode::~vtkOSPRayPolyDataMapperNode()
{
delete this->GeometryCache;
delete this->InstanceCache;
std::cout << "vtkOSPDMN delete (" << this << ")\n";
}
//----------------------------------------------------------------------------
......@@ -780,7 +791,9 @@ void vtkOSPRayPolyDataMapperNode::ORenderPoly(void* renderer, vtkOSPRayActorNode
vertices[i] = osp::vec3f{ static_cast<float>(_vertices[i * 3 + 0]),
static_cast<float>(_vertices[i * 3 + 1]), static_cast<float>(_vertices[i * 3 + 2]) };
}
std::cout << "creating position data\n";
OSPData position = ospNewCopyData1D(numPositions, OSP_VEC3F, &vertices[0]);
std::cout << "done creating position data\n";
ospCommit(position);
_vertices.clear();
......@@ -820,7 +833,6 @@ void vtkOSPRayPolyDataMapperNode::ORenderPoly(void* renderer, vtkOSPRayActorNode
orn->GetRendererType(vtkRenderer::SafeDownCast(orn->GetRenderable()));
bool pt_avail =
rendererType == std::string("pathtracer") || rendererType == std::string("optix pathtracer");
//}
OSPMaterial oMaterial = vtkosp::MakeActorMaterial(orn, oRenderer, property, ambientColor,
diffuseColor, specularf, opacity, pt_avail, useCustomMaterial, mats, materialName);
ospCommit(oMaterial);
......@@ -926,6 +938,7 @@ void vtkOSPRayPolyDataMapperNode::ORenderPoly(void* renderer, vtkOSPRayActorNode
}
else if (cellFlag == 1)
{
std::cout << "cellMaterial\n";
// color or material on cell
vtkScalarsToColors* s2c = mapper->GetLookupTable();
std::vector<OSPMaterial> cellColors;
......@@ -1183,8 +1196,11 @@ void vtkOSPRayPolyDataMapperNode::ORenderPoly(void* renderer, vtkOSPRayActorNode
}
}
}
ospRelease(position);
ospRelease(cellMaterials);
std::cout << "ospPDMN::ORenderPoly freeing data\n";
if (position)
ospRelease(position);
if (cellMaterials)
ospRelease(cellMaterials);
for (auto it : mats)
{
......@@ -1305,6 +1321,7 @@ void vtkOSPRayPolyDataMapperNode::PopulateCache()
//----------------------------------------------------------------------------
void vtkOSPRayPolyDataMapperNode::RenderGeometricModels()
{
std::cout << "ospPDMN::RenderGeometric Models begin\n";
vtkOSPRayRendererNode* orn =
static_cast<vtkOSPRayRendererNode*>(this->GetFirstAncestorOfType("vtkOSPRayRendererNode"));
double tstep = vtkOSPRayRendererNode::GetViewTime(orn->GetRenderer());
......@@ -1334,31 +1351,47 @@ void vtkOSPRayPolyDataMapperNode::RenderGeometricModels()
}
for (auto g : this->GeometricModels)
{
// std::cout << "vtkpdm: adding geometric model to scene\n";
// orn->GeometricModels.emplace_back(g);
OSPGroup group = ospNewGroup();
OSPInstance instance = ospNewInstance(group);
OSPInstance instance = ospNewInstance(group); // valgrind reports instance is lost
ospCommit(instance);
ospRelease(group);
OSPData data = ospNewCopyData1D(1, OSP_GEOMETRIC_MODEL, &g);
ospRelease(&(*g));
ospCommit(data);
ospSetObject(group, "geometry", data);
std::cout << "vtkOPDMN: commit group\n";
ospCommit(group);
std::cout << "vtkOPDMN: done commit group\n";
ospRelease(data);
// ospRelease(instance);
orn->Instances.emplace_back(instance);
this->Instances.emplace_back(instance);
ospRelease(data);
ospRelease(group);
}
// this->GeometricModels.clear();
std::cout << "vtkOPDMN(" << this
<< ")::RenderGeometry added num instances: " << this->Instances.size() << std::endl;
std::cout << "ospPDMN::RenderGeometric Models end\n";
}
//----------------------------------------------------------------------------
void vtkOSPRayPolyDataMapperNode::ClearGeometricModels()
{
std::cout << "vtkOPDMN(" << this << ")::ClearGeometricModels\n";
vtkOSPRayRendererNode* orn =
static_cast<vtkOSPRayRendererNode*>(this->GetFirstAncestorOfType("vtkOSPRayRendererNode"));
RTW::Backend* backend = orn->GetBackend();
for (auto g : this->GeometricModels)
{
// ospRelease(g);
}
std::cout << "num instances: " << this->Instances.size() << std::endl;
for (auto i : this->Instances)
{
// std::cout << "vtkOPDMN::ClearGeometricModels: releasing instance\n";
// ospRelease(i);
}
this->GeometricModels.clear();
this->Instances.clear();
}
......@@ -448,6 +448,7 @@ vtkOSPRayRendererNode::vtkOSPRayRendererNode()
//----------------------------------------------------------------------------
vtkOSPRayRendererNode::~vtkOSPRayRendererNode()
{
std::cout << "vtkORN::delete\n";
if (this->Internal->Backend != nullptr)
{
RTW::Backend* backend = this->Internal->Backend;
......@@ -1014,7 +1015,16 @@ void vtkOSPRayRendererNode::Traverse(int operation)
it->GoToNextItem();
}
RTW::Backend* backend = this->Internal->Backend;
if (backend == nullptr)
return;
// lights
// TODO: Carson: free lights
for (auto light : this->Lights)
{
ospRelease(&(*light));
}
this->Lights.clear();
it->InitTraversal();
bool hasAmbient = false;
......@@ -1032,10 +1042,6 @@ void vtkOSPRayRendererNode::Traverse(int operation)
it->GoToNextItem();
}
RTW::Backend* backend = this->Internal->Backend;
if (backend == nullptr)
return;
if (!hasAmbient && (this->GetAmbientSamples(static_cast<vtkRenderer*>(this->Renderable)) > 0))
{
// hardcode an ambient light for AO since OSP 1.2 stopped doing so.
......@@ -1081,7 +1087,9 @@ void vtkOSPRayRendererNode::Traverse(int operation)
{
for (auto i : this->Instances)
{
ospRelease(i);
std::cout << "vtkORN: removing instance " << &(*i) << std::endl;
ospRelease(&(*i));
// ospRelease(&(*i)); // TODO: DEBUG: instance is not freeing unless calling this twice...?
}
this->Instances.clear();
this->NumActors = numAct;
......@@ -1104,15 +1112,20 @@ void vtkOSPRayRendererNode::Traverse(int operation)
this->RenderTime = recent;
// if (this->OWorld)
// ospRelease(this->OWorld);
if (!this->OWorld)
;
{
this->OWorld = ospNewWorld();
ospCommit(this->OWorld);
}
// if (this->OWorld)
// {
// ospRelease(this->OWorld);
// }
// std::cout << "creating new world " << this->OWorld << ", vtkORN: " << this << "\n";
// this->OWorld = ospNewWorld();
// ospCommit(this->OWorld);
// ospCommit(this->OWorld);
// ospSetObject(oRenderer,"model", oWorld);
// ospCommit(oRenderer);
for (auto i : this->Instances)
{
std::cout << "vtkORN: found new instance " << &(*i) << std::endl;
}
}
else
{
......@@ -1241,21 +1254,80 @@ void vtkOSPRayRendererNode::Render(bool prepass)
}
else
{
std::cout << "vtkORN: render pass" << std::endl;
// if (this->OWorld)
// ospRelease(this->OWorld);
// this->OWorld = ospNewWorld();
// ospCommit(this->OWorld);
std::cout << "creating new world " << this->OWorld << ", vtkORN: " << this << "\n";
this->OWorld = ospNewWorld();
ospCommit(this->OWorld);
OSPWorld oWorld = this->OWorld;
// put the model into a group (collection of models)
if (this->Instances.size() && this->Lights.size())
if (this->Instances.size())
{
auto data = ospNewSharedData1D(this->Lights.data(), OSP_LIGHT, this->Lights.size());
ospCommit(data);
ospSetObject(oWorld, "light", data);
ospRelease(data);
if (this->Lights.size())
{
auto data = ospNewSharedData1D(this->Lights.data(), OSP_LIGHT, this->Lights.size());
ospCommit(data);
ospSetObject(oWorld, "light", data);
ospRelease(data);
}
std::cout << "vtkORN: create instanceData" << std::endl;
// auto instanceData = ospNewSharedData1D(this->Instances.data(), OSP_INSTANCE,
// this->Instances.size());
auto instanceData =
ospNewCopyData1D(this->Instances.size(), OSP_INSTANCE, this->Instances.data());
ospCommit(instanceData);
// ospSetParam(oWorld, "instance", OSP_DATA, &instanceData);
ospSetObject(oWorld, "instance", instanceData);
std::cout << "vtkORN: create instanceData done" << std::endl;
ospRelease(instanceData);
// ospRelease(instanceData);
// if (this->OInstanceData)
// ospRelease(this->OInstanceData);
this->OInstanceData = instanceData;
}
else // commenting else makes the mem leak dissapear. baffling. something in oworld commit
// likely cause
{
// ospray crashes with empty scene, create dummy instance
static OSPData dummyInstanceData = nullptr;
if (!dummyInstanceData)
{
std::cout << "vtkORN: creating dummy group\n";
OSPGroup group = ospNewGroup();
std::cout << "vtkORN: creating dummy instance\n";
auto instance = ospNewInstance(group);
ospCommit(group);
ospCommit(instance);
std::cout << "vtkORN: setting dummy instance\n";
dummyInstanceData = ospNewCopyData1D(1, OSP_INSTANCE, &instance);
ospCommit(dummyInstanceData);
// auto instanceData = ospNewCopyData1D(1, OSP_INSTANCE, &instance);
ospSetObject(oWorld, "instance", dummyInstanceData);
// this->OInstanceData = dummyInstanceData;
// ospRelease(dummyInstanceData);
// ospRelease(instance);
// ospRelease(group);
std::cout << "vtkORN: done creating dummies\n";
}
else
{
if (this->OInstanceData)
{
// ospRelease(this->OInstanceData);
// ospRelease(this->OInstanceData); //TODO: Carson: ospray seems to need 2 defrecs to
// free.
}
ospSetObject(oWorld, "instance", dummyInstanceData);
// this->OInstanceData = dummyInstanceData;
}
}
auto instanceData =
ospNewSharedData1D(this->Instances.data(), OSP_INSTANCE, this->Instances.size());
ospSetParam(oWorld, "instance", OSP_DATA, &instanceData);
ospRelease(instanceData);
std::cout << "vtkORN: world commit\n";
ospCommit(oWorld);
std::cout << "vtkORN: world committed\n";
OSPRenderer oRenderer = this->ORenderer;
ospCommit(oRenderer);
......@@ -1266,7 +1338,8 @@ void vtkOSPRayRendererNode::Render(bool prepass)
this->ImageX = this->Size[0];
this->ImageY = this->Size[1];
const size_t size = this->ImageX * this->ImageY;
ospRelease(this->OFrameBuffer);
if (this->OFrameBuffer)
ospRelease(this->OFrameBuffer);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wextra"
this->OFrameBuffer = ospNewFrameBuffer(isize,
......@@ -1505,6 +1578,22 @@ void vtkOSPRayRendererNode::Render(bool prepass)
#pragma GCC diagnostic ignored "-Wextra"
ospRenderFrame(this->OFrameBuffer, oRenderer, this->OCamera, this->OWorld);
#pragma GCC diagnostic pop
if (this->OInstanceData)
{
ospRelease(this->OInstanceData);
this->OInstanceData = nullptr;
}
ospRelease(this->OWorld);
this->OWorld = nullptr;
// ospRelease(this->OWorld);
// for(auto i : this->Instances)
// {
// std::cout << "vtkORN: release instance3 " << &(*i) << std::endl;
// ospRelease(i);
// std::cout << "vtkORN: release instance3 done " << &(*i) << std::endl;
// }
// this->Instances.clear();
// Check if backend can do direct OpenGL display using textures
bool useOpenGLInterop = backend->IsSupported(RTW_OPENGL_INTEROP);
......
......@@ -365,6 +365,7 @@ protected:
OSPFrameBuffer OFrameBuffer{ nullptr };
OSPData OLightArray{ nullptr };
OSPCamera OCamera{ nullptr };
OSPData OInstanceData{ nullptr };
int ImageX, ImageY;
std::vector<OSPLight> Lights;
int NumActors;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment