Make sure that both the render target and the shader are valid

before using them.

svn path=/trunk/KDE/kdebase/workspace/; revision=1102465
This commit is contained in:
Fredrik Höglund 2010-03-12 15:56:19 +00:00
parent 7e68fc7c44
commit c82351488e
3 changed files with 27 additions and 7 deletions

View file

@ -162,12 +162,13 @@ void BlurEffect::drawWindow(EffectWindow *w, int mask, QRegion region, WindowPai
bool translated = data.xTranslate || data.yTranslate; bool translated = data.xTranslate || data.yTranslate;
bool transformed = scaled || translated; bool transformed = scaled || translated;
bool hasAlpha = w->hasAlpha() || (w->hasDecoration() && effects->decorationsHaveAlpha()); bool hasAlpha = w->hasAlpha() || (w->hasDecoration() && effects->decorationsHaveAlpha());
bool valid = target->valid() && shader->isValid();
QRegion shape; QRegion shape;
if (!effects->activeFullScreenEffect() && hasAlpha && !w->isDesktop() && !transformed) if (!effects->activeFullScreenEffect() && hasAlpha && !w->isDesktop() && !transformed)
shape = blurRegion(w).translated(w->geometry().topLeft()) & screen; shape = blurRegion(w).translated(w->geometry().topLeft()) & screen;
if (!shape.isEmpty() && region.intersects(shape.boundingRect())) if (valid && !shape.isEmpty() && region.intersects(shape.boundingRect()))
{ {
const QRect r = expand(shape.boundingRect()) & screen; const QRect r = expand(shape.boundingRect()) & screen;
const QPoint offset = -shape.boundingRect().topLeft() + const QPoint offset = -shape.boundingRect().topLeft() +

View file

@ -29,7 +29,7 @@ using namespace KWin;
BlurShader::BlurShader() BlurShader::BlurShader()
: mRadius(12) : mRadius(0), mValid(false)
{ {
} }
@ -52,6 +52,7 @@ void BlurShader::setRadius(int radius)
if (mRadius != r) { if (mRadius != r) {
mRadius = r; mRadius = r;
reset(); reset();
init();
} }
} }
@ -117,10 +118,15 @@ void GLSLBlurShader::reset()
glDeleteProgram(program); glDeleteProgram(program);
program = 0; program = 0;
} }
setIsValid(false);
} }
void GLSLBlurShader::setPixelDistance(float val) void GLSLBlurShader::setPixelDistance(float val)
{ {
if (!isValid())
return;
float pixelSize[2] = { 0.0, 0.0 }; float pixelSize[2] = { 0.0, 0.0 };
if (direction() == Qt::Horizontal) if (direction() == Qt::Horizontal)
@ -133,14 +139,17 @@ void GLSLBlurShader::setPixelDistance(float val)
void GLSLBlurShader::setOpacity(float val) void GLSLBlurShader::setOpacity(float val)
{ {
if (!isValid())
return;
const float opacity[4] = { val, val, val, val }; const float opacity[4] = { val, val, val, val };
glUniform4fv(uOpacity, 1, opacity); glUniform4fv(uOpacity, 1, opacity);
} }
void GLSLBlurShader::bind() void GLSLBlurShader::bind()
{ {
if (!program) if (!isValid())
init(); return;
glUseProgram(program); glUseProgram(program);
glUniform1i(uTexUnit, 0); glUniform1i(uTexUnit, 0);
@ -284,6 +293,8 @@ void GLSLBlurShader::init()
uPixelSize = glGetUniformLocation(program, "pixelSize"); uPixelSize = glGetUniformLocation(program, "pixelSize");
uOpacity = glGetUniformLocation(program, "opacity"); uOpacity = glGetUniformLocation(program, "opacity");
} }
setIsValid(program != 0);
} }
@ -308,6 +319,8 @@ void ARBBlurShader::reset()
glDeleteProgramsARB(1, &program); glDeleteProgramsARB(1, &program);
program = 0; program = 0;
} }
setIsValid(false);
} }
void ARBBlurShader::setPixelDistance(float val) void ARBBlurShader::setPixelDistance(float val)
@ -331,8 +344,8 @@ void ARBBlurShader::setOpacity(float val)
void ARBBlurShader::bind() void ARBBlurShader::bind()
{ {
if (!program) if (!isValid())
init(); return;
glEnable(GL_FRAGMENT_PROGRAM_ARB); glEnable(GL_FRAGMENT_PROGRAM_ARB);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program);
@ -413,7 +426,9 @@ void ARBBlurShader::init()
if (glGetError()) { if (glGetError()) {
const char *error = (const char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB); const char *error = (const char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB);
kError() << "Failed to compile fragment program:" << error; kError() << "Failed to compile fragment program:" << error;
} setIsValid(false);
} else
setIsValid(true);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
} }

View file

@ -33,6 +33,8 @@ public:
static BlurShader *create(); static BlurShader *create();
bool isValid() const { return mValid; }
// Sets the radius in pixels // Sets the radius in pixels
void setRadius(int radius); void setRadius(int radius);
int radius() const { return mRadius; } int radius() const { return mRadius; }
@ -53,6 +55,7 @@ public:
protected: protected:
float gaussian(float x, float sigma) const; float gaussian(float x, float sigma) const;
QVector<float> gaussianKernel() const; QVector<float> gaussianKernel() const;
void setIsValid(bool value) { mValid = value; }
virtual void init() = 0; virtual void init() = 0;
virtual void reset() = 0; virtual void reset() = 0;
virtual int maxKernelSize() const = 0; virtual int maxKernelSize() const = 0;
@ -60,6 +63,7 @@ protected:
private: private:
int mRadius; int mRadius;
Qt::Orientation mDirection; Qt::Orientation mDirection;
bool mValid;
}; };