diff --git a/lanczos-fragment.glsl b/lanczos-fragment.glsl index 1aabdb8bc8..fda7e8db58 100644 --- a/lanczos-fragment.glsl +++ b/lanczos-fragment.glsl @@ -2,12 +2,14 @@ uniform sampler2D texUnit; uniform vec2 offsets[25]; uniform vec4 kernel[25]; +varying vec2 varyingTexCoords; + void main(void) { - vec4 sum = texture2D(texUnit, gl_TexCoord[0].st) * kernel[0]; + vec4 sum = texture2D(texUnit, varyingTexCoords.st) * kernel[0]; for (int i = 1; i < 25; i++) { - sum += texture2D(texUnit, gl_TexCoord[0].st - offsets[i]) * kernel[i]; - sum += texture2D(texUnit, gl_TexCoord[0].st + offsets[i]) * kernel[i]; + sum += texture2D(texUnit, varyingTexCoords.st - offsets[i]) * kernel[i]; + sum += texture2D(texUnit, varyingTexCoords.st + offsets[i]) * kernel[i]; } gl_FragColor = sum; } diff --git a/lanczos-vertex.glsl b/lanczos-vertex.glsl deleted file mode 100644 index f04c034d3e..0000000000 --- a/lanczos-vertex.glsl +++ /dev/null @@ -1,6 +0,0 @@ -void main(void) -{ - gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; -} - diff --git a/lanczosfilter.cpp b/lanczosfilter.cpp index 9f03fed9da..f0501a7d09 100644 --- a/lanczosfilter.cpp +++ b/lanczosfilter.cpp @@ -38,11 +38,9 @@ namespace KWin LanczosFilter::LanczosFilter( QObject* parent ) : QObject( parent ) #ifdef KWIN_HAVE_OPENGL_COMPOSITING -#ifndef KWIN_HAVE_OPENGLES , m_offscreenTex( 0 ) , m_offscreenTarget( 0 ) , m_shader( 0 ) -#endif #endif , m_inited( false) { @@ -51,10 +49,8 @@ LanczosFilter::LanczosFilter( QObject* parent ) LanczosFilter::~LanczosFilter() { #ifdef KWIN_HAVE_OPENGL_COMPOSITING -#ifndef KWIN_HAVE_OPENGLES delete m_offscreenTarget; delete m_offscreenTex; -#endif #endif } @@ -64,7 +60,6 @@ void LanczosFilter::init() return; m_inited = true; #ifdef KWIN_HAVE_OPENGL_COMPOSITING -#ifndef KWIN_HAVE_OPENGLES KSharedConfigPtr config = KSharedConfig::openConfig( "kwinrc" ); @@ -85,7 +80,6 @@ void LanczosFilter::init() delete m_shader; m_shader = 0; } -#endif #endif } @@ -132,7 +126,6 @@ static float lanczos( float x, float a ) } #ifdef KWIN_HAVE_OPENGL_COMPOSITING -#ifndef KWIN_HAVE_OPENGLES void LanczosShader::createKernel( float delta, int *size ) { const float a = 2.0; @@ -173,13 +166,11 @@ void LanczosShader::createOffsets( int count, float width, Qt::Orientation direc } } #endif -#endif void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data ) { #ifdef KWIN_HAVE_OPENGL_COMPOSITING -#ifndef KWIN_HAVE_OPENGLES - if( effects->compositingType() == KWin::OpenGLCompositing && data.opacity == 1.0 && + if( effects->compositingType() == KWin::OpenGLCompositing && KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects ) { if (!m_inited) @@ -225,9 +216,23 @@ void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region, if( cachedTexture->width() == tw && cachedTexture->height() == th ) { cachedTexture->bind(); - prepareRenderStates( cachedTexture, data.opacity, data.brightness, data.saturation ); - cachedTexture->render( textureRect, textureRect ); - restoreRenderStates( cachedTexture, data.opacity, data.brightness, data.saturation ); + if (ShaderManager::instance()->isValid()) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::SimpleShader); + shader->setUniform("offset", QVector2D(0, 0)); + shader->setUniform("opacity", (float)data.opacity); + shader->setUniform("brightness", (float)data.brightness); + shader->setUniform("saturation", (float)data.saturation); + shader->setUniform("u_forceAlpha", 0); + cachedTexture->render(textureRect, textureRect); + ShaderManager::instance()->popShader(); + glDisable(GL_BLEND); + } else { + prepareRenderStates( cachedTexture, data.opacity, data.brightness, data.saturation ); + cachedTexture->render( textureRect, textureRect ); + restoreRenderStates( cachedTexture, data.opacity, data.brightness, data.saturation ); + } cachedTexture->unbind(); m_timer.start( 5000, this ); return; @@ -254,6 +259,7 @@ void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region, updateOffscreenSurfaces(); effects->pushRenderTarget( m_offscreenTarget ); + glClearColor(0.0, 0.0, 0.0, 0.0); glClear( GL_COLOR_BUFFER_BIT ); w->sceneWindow()->performPaint( mask, infiniteRegion(), thumbData ); @@ -276,13 +282,21 @@ void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region, // Draw the window back into the FBO, this time scaled horizontally glClear( GL_COLOR_BUFFER_BIT ); + QVector verts; + QVector texCoords; + verts.reserve(12); + texCoords.reserve(12); - glBegin( GL_QUADS ); - glTexCoord2f( 0, 0 ); glVertex2i( 0, 0 ); // Top left - glTexCoord2f( 1, 0 ); glVertex2i( tw, 0 ); // Top right - glTexCoord2f( 1, 1 ); glVertex2i( tw, sh ); // Bottom right - glTexCoord2f( 0, 1 ); glVertex2i( 0, sh ); // Bottom left - glEnd(); + texCoords << 1.0 << 0.0; verts << tw << 0.0; // Top right + texCoords << 0.0 << 0.0; verts << 0.0 << 0.0; // Top left + texCoords << 0.0 << 1.0; verts << 0.0 << sh; // Bottom left + texCoords << 0.0 << 1.0; verts << 0.0 << sh; // Bottom left + texCoords << 1.0 << 1.0; verts << tw << sh; // Bottom right + texCoords << 1.0 << 0.0; verts << tw << 0.0; // Top right + GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); + vbo->reset(); + vbo->setData(6, 2, verts.constData(), texCoords.constData()); + vbo->render(GL_TRIANGLES); // At this point we don't need the scratch texture anymore tex.unbind(); @@ -306,12 +320,16 @@ void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region, // coordinates on the screen, while scaling it vertically and blending it. glClear( GL_COLOR_BUFFER_BIT ); - glBegin( GL_QUADS ); - glTexCoord2f( 0, 0 ); glVertex2i( 0, 0 ); // Top left - glTexCoord2f( 1, 0 ); glVertex2i( tw, 0 ); // Top right - glTexCoord2f( 1, 1 ); glVertex2i( tw, th ); // Bottom right - glTexCoord2f( 0, 1 ); glVertex2i( 0, th ); // Bottom left - glEnd(); + verts.clear(); + + verts << tw << 0.0; // Top right + verts << 0.0 << 0.0; // Top left + verts << 0.0 << th; // Bottom left + verts << 0.0 << th; // Bottom left + verts << tw << th; // Bottom right + verts << tw << 0.0; // Top right + vbo->setData(6, 2, verts.constData(), texCoords.constData()); + vbo->render(GL_TRIANGLES); tex2.unbind(); tex2.discard(); @@ -325,9 +343,23 @@ void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region, cache->bind(); glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - th, tw, th ); effects->popRenderTarget(); - prepareRenderStates( cache, data.opacity, data.brightness, data.saturation ); - cache->render( textureRect, textureRect ); - restoreRenderStates( cache, data.opacity, data.brightness, data.saturation ); + if (ShaderManager::instance()->isValid()) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::SimpleShader); + shader->setUniform("offset", QVector2D(0, 0)); + shader->setUniform("opacity", (float)data.opacity); + shader->setUniform("brightness", (float)data.brightness); + shader->setUniform("saturation", (float)data.saturation); + shader->setUniform("u_forceAlpha", 0); + cache->render(textureRect, textureRect); + ShaderManager::instance()->popShader(); + glDisable(GL_BLEND); + } else { + prepareRenderStates( cache, data.opacity, data.brightness, data.saturation ); + cache->render( textureRect, textureRect ); + restoreRenderStates( cache, data.opacity, data.brightness, data.saturation ); + } cache->unbind(); w->setData( LanczosCacheRole, QVariant::fromValue( static_cast( cache ))); @@ -336,7 +368,6 @@ void LanczosFilter::performPaint( EffectWindowImpl* w, int mask, QRegion region, return; } } // if ( effects->compositingType() == KWin::OpenGLCompositing ) -#endif #endif w->sceneWindow()->performPaint( mask, region, data ); } // End of function @@ -520,7 +551,6 @@ void LanczosFilter::restoreRenderStates( GLTexture* tex, double opacity, double * LanczosShader ************************************************/ #ifdef KWIN_HAVE_OPENGL_COMPOSITING -#ifndef KWIN_HAVE_OPENGLES LanczosShader::LanczosShader( QObject* parent ) : QObject( parent ) , m_shader( 0 ) @@ -531,28 +561,33 @@ LanczosShader::LanczosShader( QObject* parent ) LanczosShader::~LanczosShader() { delete m_shader; +#ifndef KWIN_HAVE_OPENGLES if( m_arbProgram ) { glDeleteProgramsARB(1, &m_arbProgram); m_arbProgram = 0; } +#endif } void LanczosShader::bind() { if( m_shader ) - m_shader->bind(); + ShaderManager::instance()->pushShader(m_shader); +#ifndef KWIN_HAVE_OPENGLES else { glEnable(GL_FRAGMENT_PROGRAM_ARB); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_arbProgram); } +#endif } void LanczosShader::unbind() { if( m_shader ) - m_shader->unbind(); + ShaderManager::instance()->popShader(); +#ifndef KWIN_HAVE_OPENGLES else { int boundObject; @@ -563,6 +598,7 @@ void LanczosShader::unbind() glDisable(GL_FRAGMENT_PROGRAM_ARB); } } +#endif } void LanczosShader::setUniforms() @@ -573,6 +609,7 @@ void LanczosShader::setUniforms() glUniform2fv( m_uOffsets, 25, (const GLfloat*)m_offsets ); glUniform4fv( m_uKernel, 25, (const GLfloat*)m_kernel ); } +#ifndef KWIN_HAVE_OPENGLES else { for( int i=0; i<25; ++i ) @@ -584,6 +621,7 @@ void LanczosShader::setUniforms() glProgramLocalParameter4fARB( GL_FRAGMENT_PROGRAM_ARB, i+25, m_kernel[i].x(), m_kernel[i].y(), m_kernel[i].z(), m_kernel[i].w() ); } } +#endif } bool LanczosShader::init() @@ -592,7 +630,7 @@ bool LanczosShader::init() GLShader::vertexShaderSupported() && GLRenderTarget::supported() ) { - m_shader = new GLShader(":/resources/lanczos-vertex.glsl", ":/resources/lanczos-fragment.glsl"); + m_shader = ShaderManager::instance()->loadFragmentShader(ShaderManager::SimpleShader, ":/resources/lanczos-fragment.glsl"); if (m_shader->isValid()) { m_shader->bind(); @@ -610,6 +648,10 @@ bool LanczosShader::init() } } +#ifdef KWIN_HAVE_OPENGLES + // no ARB shader in GLES + return false; +#else // try to create an ARB Shader if( !hasGLExtension("GL_ARB_fragment_program") ) return false; @@ -652,8 +694,8 @@ bool LanczosShader::init() glDisable(GL_FRAGMENT_PROGRAM_ARB); kDebug( 1212 ) << "ARB Shader compiled, id: " << m_arbProgram; return true; - } #endif + } #endif } // namespace diff --git a/lanczosfilter.h b/lanczosfilter.h index 08c36da1d8..b383918405 100644 --- a/lanczosfilter.h +++ b/lanczosfilter.h @@ -39,10 +39,8 @@ class GLTexture; class GLRenderTarget; class GLShader; #ifdef KWIN_HAVE_OPENGL_COMPOSITING -#ifndef KWIN_HAVE_OPENGLES class LanczosShader; #endif -#endif class LanczosFilter : public QObject @@ -64,16 +62,13 @@ class LanczosFilter GLTexture *m_offscreenTex; GLRenderTarget *m_offscreenTarget; #ifdef KWIN_HAVE_OPENGL_COMPOSITING -#ifndef KWIN_HAVE_OPENGLES LanczosShader *m_shader; -#endif #endif QBasicTimer m_timer; bool m_inited; }; #ifdef KWIN_HAVE_OPENGL_COMPOSITING -#ifndef KWIN_HAVE_OPENGLES class LanczosShader : public QObject { @@ -100,7 +95,6 @@ class LanczosShader uint m_arbProgram; // TODO: GLuint }; #endif -#endif } // namespace diff --git a/resources.qrc b/resources.qrc index b4e1fb62a8..03a5c1c844 100644 --- a/resources.qrc +++ b/resources.qrc @@ -1,6 +1,5 @@ - lanczos-vertex.glsl lanczos-fragment.glsl scene-vertex.glsl scene-fragment.glsl