Commit b5efa06f authored by Ken Martin's avatar Ken Martin

reduce segfaults on shader compile failure

When a shader program fails to compile often the
application would crash because code assumed that the
program was created. The shader compilation error messages
often were hard to obtain as the segault kills the output
window.

This topic catches many places where the program was assumed
to exists and makes them not crash. It was developed by
modifying the shader cache to always fail when building a
shader and then running the VTK tests to see if anything
crashed. Lots did. With this topic at least

ctest -R OpenGL2
ctest -R RenderingCore
ctest -R Chart

all work without segaulting even when the shader fails
to compile. This makes catching the shader compilation
error messages lots easier and of course less chance of
an application segfaulting as opposed to gracefully
reporting an error.
parent 71147f74
......@@ -800,9 +800,17 @@ void vtkOpenGLContextDevice2D::DrawPoly(float *f, int n, unsigned char *colors,
{
this->ReadyLinesBOProgram();
cbo = this->LinesBO;
cbo->Program->SetUniform4uc("vertexColor",
this->Pen->GetColor());
if (cbo->Program)
{
cbo->Program->SetUniform4uc("vertexColor",
this->Pen->GetColor());
}
}
if (!cbo->Program)
{
return;
}
cbo->Program->SetUniformi("stipple",this->LinePattern);
this->SetMatrices(cbo->Program);
......@@ -939,9 +947,18 @@ void vtkOpenGLContextDevice2D::DrawLines(float *f, int n, unsigned char *colors,
{
this->ReadyLinesBOProgram();
cbo = this->LinesBO;
if (!cbo->Program)
{
return;
}
cbo->Program->SetUniform4uc("vertexColor",
this->Pen->GetColor());
}
if (!cbo->Program)
{
return;
}
cbo->Program->SetUniformi("stipple",this->LinePattern);
this->SetMatrices(cbo->Program);
......@@ -1057,11 +1074,19 @@ void vtkOpenGLContextDevice2D::DrawPoints(float *f, int n, unsigned char *c,
{
this->ReadyVCBOProgram();
cbo = this->VCBO;
if (!cbo->Program)
{
return;
}
}
else
{
this->ReadyVBOProgram();
cbo = this->VBO;
if (!cbo->Program)
{
return;
}
cbo->Program->SetUniform4uc("vertexColor",
this->Pen->GetColor());
}
......@@ -1103,11 +1128,19 @@ void vtkOpenGLContextDevice2D::DrawPointSprites(vtkImageData *sprite,
{
this->ReadySCBOProgram();
cbo = this->SCBO;
if (!cbo->Program)
{
return;
}
}
else
{
this->ReadySBOProgram();
cbo = this->SBO;
if (!cbo->Program)
{
return;
}
cbo->Program->SetUniform4uc("vertexColor",
this->Pen->GetColor());
}
......@@ -1234,6 +1267,10 @@ void vtkOpenGLContextDevice2D::CoreDrawTriangles(std::vector<float> &tverts,
{
this->ReadyVTBOProgram();
cbo = this->VTBO;
if (!cbo->Program)
{
return;
}
this->SetTexture(this->Brush->GetTexture(),
this->Brush->GetTextureProperties());
this->Storage->Texture->Render(this->Renderer);
......@@ -1258,6 +1295,11 @@ void vtkOpenGLContextDevice2D::CoreDrawTriangles(std::vector<float> &tverts,
cbo = this->VBO;
}
if (!cbo->Program)
{
return;
}
cbo->Program->SetUniform4uc("vertexColor",
this->Brush->GetColor());
......@@ -1735,6 +1777,10 @@ void vtkOpenGLContextDevice2D::DrawString(float *point,
vtkOpenGLHelper *cbo = 0;
this->ReadyVTBOProgram();
cbo = this->VTBO;
if (!cbo->Program)
{
return;
}
int tunit = vtkOpenGLTexture::SafeDownCast(texture)->GetTextureUnit();
cbo->Program->SetUniformi("texture1", tunit);
......@@ -1939,6 +1985,10 @@ void vtkOpenGLContextDevice2D::DrawImage(float p[2], float scale,
vtkOpenGLHelper *cbo = 0;
this->ReadyVTBOProgram();
cbo = this->VTBO;
if (!cbo->Program)
{
return;
}
int tunit = vtkOpenGLTexture::SafeDownCast(
this->Storage->Texture)->GetTextureUnit();
cbo->Program->SetUniformi("texture1", tunit);
......@@ -2053,6 +2103,10 @@ void vtkOpenGLContextDevice2D::DrawImage(const vtkRectf& pos,
vtkOpenGLHelper *cbo = 0;
this->ReadyVTBOProgram();
cbo = this->VTBO;
if (!cbo->Program)
{
return;
}
cbo->Program->SetUniformi("texture1", tunit);
this->BuildVBO(cbo, points, 6, NULL, 0, texCoord);
......
......@@ -396,11 +396,19 @@ void vtkOpenGLContextDevice3D::DrawPoly(const float *verts, int n,
{
this->ReadyVCBOProgram();
cbo = this->VCBO;
if (!cbo->Program)
{
return;
}
}
else
{
this->ReadyVBOProgram();
cbo = this->VBO;
if (!cbo->Program)
{
return;
}
if (this->HaveWideLines())
{
vtkWarningMacro(<< "a line width has been requested that is larger than your system supports");
......@@ -457,11 +465,19 @@ void vtkOpenGLContextDevice3D::DrawLines(const float *verts, int n,
{
this->ReadyVCBOProgram();
cbo = this->VCBO;
if (!cbo->Program)
{
return;
}
}
else
{
this->ReadyVBOProgram();
cbo = this->VBO;
if (!cbo->Program)
{
return;
}
cbo->Program->SetUniform4uc("vertexColor",
this->Pen->GetColor());
}
......@@ -497,11 +513,19 @@ void vtkOpenGLContextDevice3D::DrawPoints(const float *verts, int n,
{
this->ReadyVCBOProgram();
cbo = this->VCBO;
if (!cbo->Program)
{
return;
}
}
else
{
this->ReadyVBOProgram();
cbo = this->VBO;
if (!cbo->Program)
{
return;
}
cbo->Program->SetUniform4uc("vertexColor",
this->Pen->GetColor());
}
......@@ -535,11 +559,19 @@ void vtkOpenGLContextDevice3D::DrawTriangleMesh(const float *mesh, int n,
{
this->ReadyVCBOProgram();
cbo = this->VCBO;
if (!cbo->Program)
{
return;
}
}
else
{
this->ReadyVBOProgram();
cbo = this->VBO;
if (!cbo->Program)
{
return;
}
cbo->Program->SetUniform4uc("vertexColor",
this->Pen->GetColor());
}
......
......@@ -308,6 +308,10 @@ void vtkCompositeMapperHelper2::DrawIBO(
// First we do the triangles, update the shader, set uniforms, etc.
this->UpdateShaders(CellBO, ren, actor);
vtkShaderProgram *prog = CellBO.Program;
if (!prog)
{
return;
}
this->PrimIDUsed = prog->IsUniformUsed("PrimitiveIDOffset");
this->OverideColorUsed = prog->IsUniformUsed("OverridesColor");
CellBO.IBO->Bind();
......
......@@ -177,6 +177,11 @@ void vtkDepthOfFieldPass::Render(const vtkRenderState *s)
renWin->GetShaderCache()->ReadyShaderProgram(this->BlurProgram->Program);
}
if (!this->BlurProgram->Program)
{
return;
}
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
......
......@@ -260,25 +260,28 @@ void vtkDepthPeelingPass::BlendFinalPeel(vtkOpenGLRenderWindow *renWin)
this->FinalBlendProgram->Program);
}
this->FinalBlendProgram->Program->SetUniformi(
"translucentRGBATexture", this->TranslucentRGBATexture->GetTextureUnit());
if (this->FinalBlendProgram->Program)
{
this->FinalBlendProgram->Program->SetUniformi(
"translucentRGBATexture", this->TranslucentRGBATexture->GetTextureUnit());
this->OpaqueRGBATexture->Activate();
this->FinalBlendProgram->Program->SetUniformi(
"opaqueRGBATexture", this->OpaqueRGBATexture->GetTextureUnit());
this->OpaqueRGBATexture->Activate();
this->FinalBlendProgram->Program->SetUniformi(
"opaqueRGBATexture", this->OpaqueRGBATexture->GetTextureUnit());
this->OpaqueZTexture->Activate();
this->FinalBlendProgram->Program->SetUniformi(
"opaqueZTexture", this->OpaqueZTexture->GetTextureUnit());
this->OpaqueZTexture->Activate();
this->FinalBlendProgram->Program->SetUniformi(
"opaqueZTexture", this->OpaqueZTexture->GetTextureUnit());
// blend in OpaqueRGBA
glEnable(GL_DEPTH_TEST);
glDepthFunc( GL_ALWAYS );
this->OpaqueRGBATexture->CopyToFrameBuffer(0, 0,
this->ViewportWidth-1, this->ViewportHeight-1,
0, 0, this->ViewportWidth, this->ViewportHeight,
this->FinalBlendProgram->Program,
this->FinalBlendProgram->VAO);
// blend in OpaqueRGBA
glEnable(GL_DEPTH_TEST);
glDepthFunc( GL_ALWAYS );
this->OpaqueRGBATexture->CopyToFrameBuffer(0, 0,
this->ViewportWidth-1, this->ViewportHeight-1,
0, 0, this->ViewportWidth, this->ViewportHeight,
this->FinalBlendProgram->Program,
this->FinalBlendProgram->VAO);
}
glDepthFunc( GL_LEQUAL );
}
......
......@@ -658,6 +658,11 @@ void vtkDualDepthPeelingPass::CopyOpaqueDepthBuffer()
renWin->GetShaderCache()->ReadyShaderProgram(this->CopyDepthProgram);
}
if (!this->CopyDepthProgram)
{
return;
}
if (!this->CopyDepthVAO)
{
this->CopyDepthVBO = vtkOpenGLBufferObject::New();
......@@ -838,6 +843,11 @@ void vtkDualDepthPeelingPass::BlendBackBuffer()
renWin->GetShaderCache()->ReadyShaderProgram(this->BackBlendProgram);
}
if (!this->BackBlendProgram)
{
return;
}
if (!this->BackBlendVAO)
{
this->BackBlendVBO = vtkOpenGLBufferObject::New();
......@@ -1042,6 +1052,11 @@ void vtkDualDepthPeelingPass::BlendFinalImage()
renWin->GetShaderCache()->ReadyShaderProgram(this->BlendProgram);
}
if (!this->BlendProgram)
{
return;
}
if (!this->BlendVAO)
{
this->BlendVBO = vtkOpenGLBufferObject::New();
......
......@@ -714,6 +714,13 @@ void vtkEDLShading::Render(const vtkRenderState *s)
//
this->EDLInitializeShaders(renWin);
if (this->EDLShadeProgram.Program == 0 ||
this->EDLComposeProgram.Program == 0 ||
this->BilateralProgram.Program == 0)
{
return;
}
//////////////////////////////////////////////////////
//
// 4. DELEGATE RENDER IN PROJECTION FBO
......
......@@ -225,7 +225,7 @@ void vtkGaussianBlurPass::Render(const vtkRenderState *s)
renWin->GetShaderCache()->ReadyShaderProgram(this->BlurProgram->Program);
}
if(this->BlurProgram->Program->GetCompiled() != true)
if(!this->BlurProgram->Program || this->BlurProgram->Program->GetCompiled() != true)
{
vtkErrorMacro("Couldn't build the shader program. At this point , it can be an error in a shader or a driver bug.");
......
......@@ -311,6 +311,11 @@ void vtkOpenGLFXAAFilter::ApplyFilter()
renWin->GetShaderCache()->ReadyShaderProgram(this->Program);
}
if (!this->Program)
{
return;
}
if (!this->VAO)
{
this->VBO = vtkOpenGLBufferObject::New();
......
......@@ -429,6 +429,11 @@ void vtkOpenGLGlyph3DHelper::GlyphRender(
// handle the middle
vtkShaderProgram *program = this->Primitives[PrimitiveTris].Program;
if (!program)
{
return;
}
// Apply the extra transform
program->SetUniformMatrix4x4("GCMCMatrix", &(matrices[inPtId*16]));
......@@ -522,6 +527,10 @@ void vtkOpenGLGlyph3DHelper::GlyphRenderInstances(
this->UsingInstancing = true;
this->RenderPieceStart(ren,actor);
this->UpdateShaders(this->Primitives[PrimitiveTris], ren, actor);
if (!this->Primitives[PrimitiveTris].Program)
{
return;
}
// do the superclass and then reset a couple values
if (this->Primitives[PrimitiveTris].IBO->IndexCount && // we have points and one of
......
......@@ -88,22 +88,6 @@ void vtkOpenGLLabeledContourMapper::ReleaseGraphicsResources(vtkWindow *win)
bool vtkOpenGLLabeledContourMapper::ApplyStencil(vtkRenderer *ren,
vtkActor *act)
{
// Save some state:
GLboolean colorMask[4];
glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
GLboolean depthMask;
glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
// Enable rendering into the stencil buffer:
glEnable(GL_STENCIL_TEST);
glStencilMask(0xFF);
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
// Draw stencil quads into stencil buffer:
// compile and bind it if needed
vtkOpenGLRenderWindow *renWin =
......@@ -130,6 +114,27 @@ bool vtkOpenGLLabeledContourMapper::ApplyStencil(vtkRenderer *ren,
renWin->GetShaderCache()->ReadyShaderProgram(this->StencilBO->Program);
}
if (!this->StencilBO->Program)
{
return false;
}
// Save some state:
GLboolean colorMask[4];
glGetBooleanv(GL_COLOR_WRITEMASK, colorMask);
GLboolean depthMask;
glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask);
// Enable rendering into the stencil buffer:
glEnable(GL_STENCIL_TEST);
glStencilMask(0xFF);
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
vtkOpenGLCamera *cam = (vtkOpenGLCamera *)(ren->GetActiveCamera());
vtkMatrix4x4 *wcdc;
vtkMatrix4x4 *wcvc;
......
......@@ -1799,13 +1799,16 @@ void vtkOpenGLPolyDataMapper::UpdateShaders(
renWin->GetShaderCache()->ReadyShaderProgram(cellBO.Program);
}
this->SetMapperShaderParameters(cellBO, ren, actor);
this->SetPropertyShaderParameters(cellBO, ren, actor);
this->SetCameraShaderParameters(cellBO, ren, actor);
this->SetLightingShaderParameters(cellBO, ren, actor);
if (cellBO.Program)
{
this->SetMapperShaderParameters(cellBO, ren, actor);
this->SetPropertyShaderParameters(cellBO, ren, actor);
this->SetCameraShaderParameters(cellBO, ren, actor);
this->SetLightingShaderParameters(cellBO, ren, actor);
// allow the program to set what it wants
this->InvokeEvent(vtkCommand::UpdateShaderEvent,&cellBO);
// allow the program to set what it wants
this->InvokeEvent(vtkCommand::UpdateShaderEvent,&cellBO);
}
vtkOpenGLCheckErrorMacro("failed after UpdateShader");
}
......
......@@ -339,9 +339,12 @@ void vtkOpenGLPolyDataMapper2D::UpdateShaders(vtkOpenGLHelper &cellBO,
renWin->GetShaderCache()->ReadyShaderProgram(cellBO.Program);
}
this->SetMapperShaderParameters(cellBO, viewport, actor);
this->SetPropertyShaderParameters(cellBO, viewport, actor);
this->SetCameraShaderParameters(cellBO, viewport, actor);
if (cellBO.Program)
{
this->SetMapperShaderParameters(cellBO, viewport, actor);
this->SetPropertyShaderParameters(cellBO, viewport, actor);
this->SetCameraShaderParameters(cellBO, viewport, actor);
}
}
......
......@@ -1881,6 +1881,10 @@ int vtkOpenGLRenderWindow::SetZbufferData( int x1, int y1,
"void main(void) {\n"
" gl_FragDepth = texture2D(source,tcoordVC).r; }\n",
"");
if (!program)
{
return VTK_ERROR;
}
vtkOpenGLVertexArrayObject *VAO = vtkOpenGLVertexArrayObject::New();
// bind and activate this texture
......
......@@ -174,6 +174,11 @@ void vtkPointFillPass::Render(const vtkRenderState *s)
renWin->GetShaderCache()->ReadyShaderProgram(this->BlurProgram->Program);
}
if (!this->BlurProgram->Program)
{
return;
}
glDisable(GL_BLEND);
// glDisable(GL_DEPTH_TEST);
......
......@@ -208,7 +208,7 @@ void vtkSSAAPass::Render(const vtkRenderState *s)
renWin->GetShaderCache()->ReadyShaderProgram(this->SSAAProgram->Program);
}
if(this->SSAAProgram->Program->GetCompiled() != true)
if(!this->SSAAProgram->Program)
{
vtkErrorMacro("Couldn't build the shader program. At this point , it can be an error in a shader or a driver bug.");
......
......@@ -276,7 +276,7 @@ void vtkSobelGradientMagnitudePass::Render(const vtkRenderState *s)
glFinish();
#endif
if(this->Program1->Program->GetCompiled() != true)
if (!this->Program1->Program || this->Program1->Program->GetCompiled() != true)
{
vtkErrorMacro("Couldn't build the shader program. At this point , it can be an error in a shader or a driver bug.");
......@@ -408,7 +408,7 @@ void vtkSobelGradientMagnitudePass::Render(const vtkRenderState *s)
glFinish();
#endif
if(this->Program2->Program->GetCompiled() != true)
if(!this->Program2->Program || this->Program2->Program->GetCompiled() != true)
{
vtkErrorMacro("Couldn't build the shader program. At this point , it can be an error in a shader or a driver bug.");
return;
......
......@@ -2069,13 +2069,16 @@ void vtkTextureObject::CopyToFrameBuffer(float *tcoords, float *verts,
this->ShaderProgram->Program);
}
// bind and activate this texture
this->Activate();
int sourceId = this->GetTextureUnit();
this->ShaderProgram->Program->SetUniformi("source",sourceId);
vtkOpenGLRenderUtilities::RenderQuad(verts, tcoords, this->ShaderProgram->Program,
this->ShaderProgram->VAO);
this->Deactivate();
if (this->ShaderProgram->Program)
{
// bind and activate this texture
this->Activate();
int sourceId = this->GetTextureUnit();
this->ShaderProgram->Program->SetUniformi("source",sourceId);
vtkOpenGLRenderUtilities::RenderQuad(verts, tcoords, this->ShaderProgram->Program,
this->ShaderProgram->VAO);
this->Deactivate();
}
}
else
{
......
......@@ -3051,6 +3051,12 @@ void vtkOpenGLGPUVolumeRayCastMapper::DoGPURender(vtkRenderer* ren,
int noOfComponents,
int independentComponents)
{
// if the shader didn't compile return
if (!prog)
{
return;
}
// Cell spacing is required to be computed globally (full volume extents)
// given that gradients are computed globally (not per block).
float fvalue3[3]; /* temporary value container */
......
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