1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-16 10:08:36 +03:00

0023345: Crash when destroying OpenGl_Element

OpenGl_PrimitiveArray::Release() - avoid possible NULL-pointer dereference
OpenGl_GraphicDriver::RemoveView() - release GL resources within removing last view
Fixed OCC280 test command - do not remove old view until new one is initialized
This commit is contained in:
kgv 2012-10-12 16:56:23 +04:00
parent eeaaaefb6f
commit dd8a4ce929
5 changed files with 71 additions and 11 deletions

View File

@ -409,17 +409,30 @@ Standard_Boolean OpenGl_Workspace::BufferDump (OpenGl_FrameBuffer* theFB
return Standard_True; return Standard_True;
} }
void OpenGl_GraphicDriver::RemoveView (const Graphic3d_CView& ACView) void OpenGl_GraphicDriver::RemoveView (const Graphic3d_CView& theCView)
{ {
if (myMapOfView.IsBound (ACView.ViewId)) Handle(OpenGl_Context) aShareCtx = GetSharedContext();
myMapOfView.UnBind (ACView.ViewId); if (myMapOfView.IsBound (theCView.ViewId))
myMapOfView.UnBind (theCView.ViewId);
if (myMapOfWS.IsBound (ACView.WsId)) if (myMapOfWS.IsBound (theCView.WsId))
myMapOfWS.UnBind (ACView.WsId); myMapOfWS.UnBind (theCView.WsId);
OpenGl_CView *aCView = (OpenGl_CView *)ACView.ptrView; if (myMapOfWS.IsEmpty() && !myMapOfStructure.IsEmpty())
{
// The last view removed but some objects still present.
// Release GL resources now without object destruction.
for (NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator aStructIt (myMapOfStructure);
aStructIt.More (); aStructIt.Next())
{
OpenGl_Structure* aStruct = aStructIt.ChangeValue();
aStruct->ReleaseGlResources (aShareCtx);
}
}
OpenGl_CView *aCView = (OpenGl_CView *)theCView.ptrView;
delete aCView; delete aCView;
((Graphic3d_CView *)&ACView)->ptrView = NULL; ((Graphic3d_CView *)&theCView)->ptrView = NULL;
} }
void OpenGl_GraphicDriver::SetLight (const Graphic3d_CView& ACView) void OpenGl_GraphicDriver::SetLight (const Graphic3d_CView& ACView)

View File

@ -17,7 +17,6 @@
// purpose or non-infringement. Please see the License for the specific terms // purpose or non-infringement. Please see the License for the specific terms
// and conditions governing the rights and limitations under the License. // and conditions governing the rights and limitations under the License.
#include <OpenGl_IndexBuffer.hxx> #include <OpenGl_IndexBuffer.hxx>
#include <OpenGl_Context.hxx> #include <OpenGl_Context.hxx>
@ -1551,8 +1550,11 @@ void OpenGl_PrimitiveArray::Release (const Handle(OpenGl_Context)& theContext)
for (Standard_Integer anIter = 0; anIter < VBOMaxType; ++anIter) for (Standard_Integer anIter = 0; anIter < VBOMaxType; ++anIter)
{ {
if (!myVbos[anIter].IsNull()) if (!myVbos[anIter].IsNull())
{
if (!theContext.IsNull())
{ {
theContext->DelayedRelease (myVbos[anIter]); theContext->DelayedRelease (myVbos[anIter]);
}
myVbos[anIter].Nullify(); myVbos[anIter].Nullify();
} }
} }

View File

@ -447,6 +447,42 @@ void OpenGl_Structure::Release (const Handle(OpenGl_Context)& theGlCtx)
ClearHighlightColor (theGlCtx); ClearHighlightColor (theGlCtx);
} }
// =======================================================================
// function : ReleaseGlResources
// purpose :
// =======================================================================
void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx)
{
for (OpenGl_ListOfGroup::Iterator anIter (myGroups); anIter.More(); anIter.Next())
{
OpenGl_Group* aGroup = const_cast<OpenGl_Group*& > (anIter.ChangeValue());
if (aGroup != NULL)
{
aGroup->Release (theGlCtx);
}
}
if (myAspectLine != NULL)
{
myAspectLine->Release (theGlCtx);
}
if (myAspectFace != NULL)
{
myAspectFace->Release (theGlCtx);
}
if (myAspectMarker != NULL)
{
myAspectMarker->Release (theGlCtx);
}
if (myAspectText != NULL)
{
myAspectText->Release (theGlCtx);
}
if (myHighlightBox != NULL)
{
myHighlightBox->Release (theGlCtx);
}
}
//======================================================================= //=======================================================================
//function : SetZLayer //function : SetZLayer
//purpose : //purpose :

View File

@ -84,6 +84,14 @@ public:
virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const; virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const;
virtual void Release (const Handle(OpenGl_Context)& theGlCtx); virtual void Release (const Handle(OpenGl_Context)& theGlCtx);
//! This method releases GL resources without actual elements destruction.
//! As result structure could be correctly destroyed layter without GL context
//! (after last window was closed for example).
//!
//! Notice however that reusage of this structure after calling this method is incorrect
//! and will lead to broken visualization due to loosed data.
void ReleaseGlResources (const Handle(OpenGl_Context)& theGlCtx);
protected: protected:
virtual ~OpenGl_Structure(); virtual ~OpenGl_Structure();

View File

@ -581,8 +581,6 @@ static Standard_Integer OCC280 (Draw_Interpretor& di, Standard_Integer argc, con
Handle(Aspect_Window) asp = anOldView->Window(); Handle(Aspect_Window) asp = anOldView->Window();
aViewer->SetViewOff (anOldView); aViewer->SetViewOff (anOldView);
anOldView->Remove();
anOldView.Nullify();
Handle(V3d_View) aNewView = aViewer->CreateView(); Handle(V3d_View) aNewView = aViewer->CreateView();
ViewerTest::CurrentView (aNewView); ViewerTest::CurrentView (aNewView);
@ -590,6 +588,9 @@ static Standard_Integer OCC280 (Draw_Interpretor& di, Standard_Integer argc, con
aNewView->SetWindow (asp); aNewView->SetWindow (asp);
if (!asp->IsMapped()) asp->Map(); if (!asp->IsMapped()) asp->Map();
anOldView->Remove();
anOldView.Nullify();
aNewView->Update(); aNewView->Update();
// replace view in event manager // replace view in event manager