Sanity check the shader limitations to protect against implementations

returning bogus values.

FIXED-IN: 4.5
BUG: 241449

svn path=/trunk/KDE/kdebase/workspace/; revision=1137677
This commit is contained in:
Fredrik Höglund 2010-06-14 00:18:04 +00:00
parent abdd055665
commit 253647ec1e
3 changed files with 70 additions and 3 deletions

View file

@ -116,8 +116,7 @@ void BlurEffect::propertyNotify(EffectWindow *w, long atom)
bool BlurEffect::supported()
{
return GLRenderTarget::supported() && GLTexture::NPOTTextureSupported() &&
((GLShader::vertexShaderSupported() && GLShader::fragmentShaderSupported()) ||
hasGLExtension("GL_ARB_fragment_program"));
(GLSLBlurShader::supported() || ARBBlurShader::supported());
}
QRect BlurEffect::expand(const QRect &rect) const

View file

@ -39,7 +39,7 @@ BlurShader::~BlurShader()
BlurShader *BlurShader::create()
{
if (GLShader::vertexShaderSupported() && GLShader::fragmentShaderSupported())
if (GLSLBlurShader::supported())
return new GLSLBlurShader();
return new ARBBlurShader();
@ -122,6 +122,34 @@ void GLSLBlurShader::reset()
setIsValid(false);
}
bool GLSLBlurShader::supported()
{
if (!GLShader::fragmentShaderSupported() || !GLShader::vertexShaderSupported())
return false;
(void) glGetError(); // Clear the error state
// These are the minimum values the implementation is required to support
int value = 0;
glGetIntegerv(GL_MAX_VARYING_FLOATS, &value);
if (value < 32)
return false;
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &value);
if (value < 64)
return false;
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &value);
if (value < 512)
return false;
if (glGetError() != GL_NO_ERROR)
return false;
return true;
}
void GLSLBlurShader::setPixelDistance(float val)
{
if (!isValid())
@ -312,6 +340,42 @@ void ARBBlurShader::reset()
setIsValid(false);
}
bool ARBBlurShader::supported()
{
if (!hasGLExtension("GL_ARB_fragment_program"))
return false;
(void) glGetError(); // Clear the error state
// These are the minimum values the implementation is required to support
int value = 0;
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_PARAMETERS_ARB, &value);
if (value < 24)
return false;
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &value);
if (value < 16)
return false;
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &value);
if (value < 72)
return false;
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, &value);
if (value < 24)
return false;
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB, &value);
if (value < 4)
return false;
if (glGetError() != GL_NO_ERROR)
return false;
return true;
}
void ARBBlurShader::setPixelDistance(float val)
{
float firstStep = val * 1.5;

View file

@ -78,6 +78,8 @@ public:
void bind();
void unbind();
static bool supported();
protected:
void init();
void reset();
@ -108,6 +110,8 @@ public:
void bind();
void unbind();
static bool supported();
protected:
void init();
void reset();