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):
- Set 3D-only layout, restart app
- Load volume
- 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.