Skip to content

BUG: Fix OpenGL errors/segfault when entering volume rendering module

Created by: msmolens

The following workflow triggered OpenGL errors (when using the VTK OpenGL backend) followed by a segfault (when using the VTK OpenGL2 backend):

  1. Set 3D-only layout, restart app
  2. Load volume
  3. Enter the volume rendering module

For the OpenGL2 backend, the top of the stack trace is similar to the following:

vtkOpenGL-7.1.dll!vtkShaderProgram::IsUniformUsed(const char * cname) Line 847  C++
vtkOpenGL-7.1.dll!vtkOpenGLPolyDataMapper2D::SetMapperShaderParameters(vtkOpenGLHelper & cellBO, vtkViewport * viewport, vtkActor2D * actor) Line 409   C++
vtkOpenGL-7.1.dll!vtkOpenGLPolyDataMapper2D::UpdateShaders(vtkOpenGLHelper & cellBO, vtkViewport * viewport, vtkActor2D * actor) Line 325   C++
vtkOpenGL-7.1.dll!vtkOpenGLPolyDataMapper2D::RenderOverlay(vtkViewport * viewport, vtkActor2D * actor) Line 874 C++
vtkRendering-7.1.dll!vtkActor2D::RenderOverlay(vtkViewport * viewport) Line 125 C++
vtkRendering-7.1.dll!vtkRenderer::PickGeometry() Line 1810  C++
vtkOpenGL-7.1.dll!vtkOpenGLRenderer::DevicePickRender() Line 602    C++
vtkRendering-7.1.dll!vtkRenderer::PickRender(vtkPropCollection * props) Line 1735   C++
vtkRendering-7.1.dll!vtkRenderer::PickProp(double selectionX1, double selectionY1, double selectionX2, double selectionY2) Line 1559    C++
vtkRendering-7.1.dll!vtkRenderer::PickProp(double selectionX, double selectionY) Line 432   C++
vtkRendering-7.1.dll!vtkViewport::PickPropFrom(double selectionX, double selectionY, vtkPropCollection * pickfrom) Line 721 C++
vtkRendering-7.1.dll!vtkPropPicker::PickProp(double selectionX, double selectionY, vtkRenderer * renderer) Line 87  C++
vtkRendering-7.1.dll!vtkPropPicker::PickProp(double selectionX, double selectionY, vtkRenderer * renderer, vtkPropCollection * pickfrom) Line 63    C++
vtkRendering-7.1.dll!vtkPropPicker::Pick(double selectionX, double selectionY, double __formal, vtkRenderer * renderer) Line 49 C++
vtkSlicerAnnotationsModuleVTKWidgets.dll!vtkAnnotationROIRepresentation2D::ComputeInteractionState(int X, int Y, int __formal) Line 644 C++
vtkInteraction-7.1.dll!vtkAbstractWidget::SetEnabled(int enabling) Line 155 C++
vtkRendering-7.1.dll!vtkInteractorObserver::On() Line 73    C++
vtkSlicerAnnotationsModuleMRMLDisplayableManager.dll!vtkMRMLAnnotationROIDisplayableManager::CreateWidget(vtkMRMLAnnotationNode * node) Line 192    C++
vtkSlicerAnnotationsModuleMRMLDisplayableManager.dll!vtkMRMLAnnotationDisplayableManager::AddAnnotation(vtkMRMLAnnotationNode * annotationNode) Line 2166   C++
vtkSlicerAnnotationsModuleMRMLDisplayableManager.dll!vtkMRMLAnnotationDisplayableManager::OnMRMLSceneNodeAdded(vtkMRMLNode * node) Line 464 C++
MRMLLogic.dll!vtkMRMLAbstractLogic::ProcessMRMLSceneEvents(vtkObject * caller, unsigned long event, void * callData) Line 476   C++
MRMLLogic.dll!vtkMRMLAbstractLogic::MRMLSceneCallback(vtkObject * caller, unsigned long eid, void * clientData, void * callData) Line 173   C++
vtkCommon-7.1.dll!vtkCallbackCommand::Execute(vtkObject * caller, unsigned long event, void * callData) Line 43 C++
MRMLCore.dll!vtkEventBroker::InvokeObservation(vtkObservation * observation, unsigned long eid, void * callData) Line 842   C++
MRMLCore.dll!vtkEventBroker::ProcessEvent(vtkObservation * observation, vtkObject * caller, unsigned long eid, void * callData) Line 687    C++
MRMLCore.dll!vtkEventBroker::Callback(vtkObject * caller, unsigned long eid, void * clientData, void * callData) Line 914   C++
vtkCommon-7.1.dll!vtkCallbackCommand::Execute(vtkObject * caller, unsigned long event, void * callData) Line 43 C++
vtkCommon-7.1.dll!vtkSubjectHelper::InvokeEvent(unsigned long event, void * callData, vtkObject * self) Line 619    C++
vtkCommon-7.1.dll!vtkObject::InvokeEvent(unsigned long event, void * callData) Line 785 C++
MRMLCore.dll!vtkMRMLScene::AddNode(vtkMRMLNode * n) Line 1241   C++
vtkSlicerAnnotationsModuleMRML.dll!vtkMRMLAnnotationNode::Initialize(vtkMRMLScene * mrmlScene) Line 668 C++
vtkSlicerAnnotationsModuleMRML.dll!vtkMRMLAnnotationControlPointsNode::Initialize(vtkMRMLScene * mrmlScene) Line 702    C++
vtkSlicerAnnotationsModuleMRML.dll!vtkMRMLAnnotationLinesNode::Initialize(vtkMRMLScene * mrmlScene) Line 570    C++
vtkSlicerAnnotationsModuleMRML.dll!vtkMRMLAnnotationROINode::Initialize(vtkMRMLScene * mrmlScene) Line 47   C++
vtkSlicerVolumeRenderingModuleLogic.dll!vtkSlicerVolumeRenderingLogic::UpdateDisplayNodeFromVolumeNode(vtkMRMLVolumeRenderingDisplayNode * displayNode, vtkMRMLVolumeNode * volumeNode, vtkMRMLVolumePropertyNode * * propNode, vtkMRMLAnnotationROINode * * roiNode) Line 939  C++
qSlicerVolumeRenderingModuleWidgets.dll!qSlicerVolumeRenderingModuleWidgetPrivate::createVolumeRenderingDisplayNode(vtkMRMLVolumeNode * volumeNode) Line 249    C++
qSlicerVolumeRenderingModuleWidgets.dll!qSlicerVolumeRenderingModuleWidget::onCurrentMRMLVolumeNodeChanged(vtkMRMLNode * node) Line 346 C++
...

The errors/segfault occur when hardware picking is performed before the render window has created an OpenGL context. Usually render windows create a context on their first render, but that doesn't happen in this case because the slice views aren't visible; see [1].

This commit fixes the problem by forcing an initial render when creating a slice view. This ensures that the render window has a context, which in turn prevents the OpenGL errors/segfault in the above workflow, and possibly others.

[1] https://github.com/commontk/CTK/blob/bacd360/Libs/Visualization/VTK/Widgets/ctkVTKAbstractView.cpp#L229-L233.

Merge request reports