Bind ARBBlurShader to OpenGL1

The logic has already ensured that the ARBBlurShader can only be used
when using the OpenGL1 compositor, the OpenGL 2 compositor needs to use
the GLSLBlurShader.

This change moves the complete ARBBlurShader into a KWIN_HAVE_OPENGL_1
ifdef section.

As a side-effect the ::create method can now return a NULL pointer which
makes more sense then returning an ARBBlurShader in case that the
GLSLShader is not supported.

REVIEW: 106738
This commit is contained in:
Martin Gräßlin 2012-10-05 11:46:13 +02:00
parent cf5de22586
commit 99db844912
3 changed files with 26 additions and 29 deletions

View file

@ -55,7 +55,7 @@ BlurEffect::BlurEffect()
// ### Hackish way to announce support.
// Should be included in _NET_SUPPORTED instead.
if (shader->isValid() && target->valid()) {
if (shader && shader->isValid() && target->valid()) {
XChangeProperty(display(), rootWindow(), net_wm_blur_region, net_wm_blur_region,
32, PropModeReplace, 0, 0);
} else {
@ -89,13 +89,14 @@ void BlurEffect::reconfigure(ReconfigureFlags flags)
BlurConfig::self()->readConfig();
int radius = qBound(2, BlurConfig::blurRadius(), 14);
shader->setRadius(radius);
if (shader)
shader->setRadius(radius);
m_shouldCache = BlurConfig::cacheTexture();
windows.clear();
if (!shader->isValid())
if (!shader || !shader->isValid())
XDeleteProperty(display(), rootWindow(), net_wm_blur_region);
}
@ -164,8 +165,12 @@ bool BlurEffect::enabledByDefault()
bool BlurEffect::supported()
{
bool supported = GLRenderTarget::supported() && GLTexture::NPOTTextureSupported() &&
(GLSLBlurShader::supported() || ARBBlurShader::supported());
bool supported = GLRenderTarget::supported() && GLTexture::NPOTTextureSupported() && GLSLBlurShader::supported();
#ifdef KWIN_HAVE_OPENGL_1
if (effects->compositingType() == OpenGL1Compositing) {
supported = GLRenderTarget::supported() && GLTexture::NPOTTextureSupported() && ARBBlurShader::supported();
}
#endif
if (supported) {
int maxTexSize;
@ -262,6 +267,9 @@ void BlurEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int t
if (!w->isPaintingEnabled()) {
return;
}
if (!shader || !shader->isValid()) {
return;
}
// to blur an area partially we have to shrink the opaque area of a window
QRegion newClip;
@ -356,7 +364,7 @@ void BlurEffect::prePaintWindow(EffectWindow* w, WindowPrePaintData& data, int t
bool BlurEffect::shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data) const
{
if (!target->valid() || !shader->isValid())
if (!target->valid() || !shader || !shader->isValid())
return false;
if (effects->activeFullScreenEffect() && !w->data(WindowForceBlurRole).toBool())
@ -409,7 +417,7 @@ void BlurEffect::drawWindow(EffectWindow *w, int mask, QRegion region, WindowPai
void BlurEffect::paintEffectFrame(EffectFrame *frame, QRegion region, double opacity, double frameOpacity)
{
const QRect screen(0, 0, displayWidth(), displayHeight());
bool valid = target->valid() && shader->isValid();
bool valid = target->valid() && shader && shader->isValid();
QRegion shape = frame->geometry().adjusted(-5, -5, 5, 5) & screen;
if (valid && !shape.isEmpty() && region.intersects(shape.boundingRect()) && frame->style() != EffectFrameNone) {
doBlur(shape, screen, opacity * frameOpacity);
@ -675,6 +683,9 @@ void BlurEffect::doCachedBlur(EffectWindow *w, const QRegion& region, const floa
int BlurEffect::blurRadius() const
{
if (!shader) {
return 0;
}
return shader->radius();
}

View file

@ -47,7 +47,11 @@ BlurShader *BlurShader::create()
if (GLSLBlurShader::supported())
return new GLSLBlurShader();
#ifdef KWIN_HAVE_OPENGL_1
return new ARBBlurShader();
#else
return NULL;
#endif
}
void BlurShader::setRadius(int radius)
@ -299,7 +303,7 @@ void GLSLBlurShader::init()
// ----------------------------------------------------------------------------
#ifdef KWIN_HAVE_OPENGL_1
ARBBlurShader::ARBBlurShader()
: BlurShader(), program(0)
{
@ -312,21 +316,16 @@ ARBBlurShader::~ARBBlurShader()
void ARBBlurShader::reset()
{
#ifdef KWIN_HAVE_OPENGL_1
if (program) {
glDeleteProgramsARB(1, &program);
program = 0;
}
setIsValid(false);
#endif
}
bool ARBBlurShader::supported()
{
#ifdef KWIN_HAVE_OPENGLES
return false;
#else
if (!hasGLExtension("GL_ARB_fragment_program"))
return false;
@ -359,14 +358,10 @@ bool ARBBlurShader::supported()
return false;
return true;
#endif
}
void ARBBlurShader::setPixelDistance(float val)
{
#ifdef KWIN_HAVE_OPENGLES
Q_UNUSED(val)
#else
float firstStep = val * 1.5;
float nextStep = val * 2.0;
@ -377,37 +372,29 @@ void ARBBlurShader::setPixelDistance(float val)
glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, 0, firstStep, 0, 0);
glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 0, nextStep, 0, 0);
}
#endif
}
void ARBBlurShader::bind()
{
#ifdef KWIN_HAVE_OPENGL_1
if (!isValid())
return;
glEnable(GL_FRAGMENT_PROGRAM_ARB);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program);
#endif
}
void ARBBlurShader::unbind()
{
#ifdef KWIN_HAVE_OPENGL_1
int boundObject;
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_BINDING_ARB, &boundObject);
if (boundObject == (int)program) {
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
glDisable(GL_FRAGMENT_PROGRAM_ARB);
}
#endif
}
int ARBBlurShader::maxKernelSize() const
{
#ifdef KWIN_HAVE_OPENGLES
return 0;
#else
int value;
int result;
@ -418,12 +405,10 @@ int ARBBlurShader::maxKernelSize() const
result = qMin(result, value / 3); // We need 3 instructions / sample
return result;
#endif
}
void ARBBlurShader::init()
{
#ifdef KWIN_HAVE_OPENGL_1
QVector<float> kernel = gaussianKernel();
const int size = kernel.size();
const int center = size / 2;
@ -480,6 +465,6 @@ void ARBBlurShader::init()
setIsValid(true);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0);
#endif
}
#endif

View file

@ -108,7 +108,7 @@ private:
// ----------------------------------------------------------------------------
#ifdef KWIN_HAVE_OPENGL_1
class ARBBlurShader : public BlurShader
{
public:
@ -131,6 +131,7 @@ protected:
private:
GLuint program;
};
#endif
} // namespace KWin