Invert effect ported to GLES.

It uses a generic vertex shader and because of that it needs to
mark all windows which are inverted as transformed.
There is currently a conflict with Lanczos (or thumbnails) and with
the desktop in cube effect.
This commit is contained in:
Martin Gräßlin 2011-01-06 20:00:03 +01:00
parent f78d838fc7
commit b7ee35bba1
7 changed files with 64 additions and 46 deletions

View file

@ -93,6 +93,7 @@ if( KWIN_HAVE_OPENGL_COMPOSITING )
include( cube/CMakeLists.txt )
include( flipswitch/CMakeLists.txt )
include( glide/CMakeLists.txt )
include( invert/CMakeLists.txt )
include( lookingglass/CMakeLists.txt )
include( magnifier/CMakeLists.txt )
include( mousemark/CMakeLists.txt )
@ -106,7 +107,6 @@ endif( KWIN_HAVE_OPENGL_COMPOSITING )
if( KWIN_HAVE_OPENGL_COMPOSITING AND NOT KWIN_HAVE_OPENGLES_COMPOSITING )
include( blur/CMakeLists.txt )
include( explosion/CMakeLists.txt )
include( invert/CMakeLists.txt )
include( sharpen/CMakeLists.txt )
include( snow/CMakeLists.txt )
endif( KWIN_HAVE_OPENGL_COMPOSITING AND NOT KWIN_HAVE_OPENGLES_COMPOSITING )

View file

@ -44,6 +44,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "cube/cubeslide_config.h"
#include "flipswitch/flipswitch_config.h"
#include "glide/glide_config.h"
#include "invert/invert_config.h"
#include "lookingglass/lookingglass_config.h"
#include "magnifier/magnifier_config.h"
#include "mousemark/mousemark_config.h"
@ -51,7 +52,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "wobblywindows/wobblywindows_config.h"
#ifndef KWIN_HAVE_OPENGLES
#include "blur/blur_config.h"
#include "invert/invert_config.h"
#include "sharpen/sharpen_config.h"
#include "snow/snow_config.h"
#endif
@ -86,6 +86,7 @@ KWIN_EFFECT_CONFIG_MULTIPLE( builtins,
KWIN_EFFECT_CONFIG_SINGLE( cubeslide, CubeSlideEffectConfig )
KWIN_EFFECT_CONFIG_SINGLE( flipswitch, FlipSwitchEffectConfig )
KWIN_EFFECT_CONFIG_SINGLE( glide, GlideEffectConfig )
KWIN_EFFECT_CONFIG_SINGLE( invert, InvertEffectConfig )
KWIN_EFFECT_CONFIG_SINGLE( lookingglass, LookingGlassEffectConfig )
KWIN_EFFECT_CONFIG_SINGLE( magnifier, MagnifierEffectConfig )
KWIN_EFFECT_CONFIG_SINGLE( mousemark, MouseMarkEffectConfig )
@ -93,7 +94,6 @@ KWIN_EFFECT_CONFIG_MULTIPLE( builtins,
KWIN_EFFECT_CONFIG_SINGLE( wobblywindows, WobblyWindowsEffectConfig )
#ifndef KWIN_HAVE_OPENGLES
KWIN_EFFECT_CONFIG_SINGLE( blur, BlurEffectConfig )
KWIN_EFFECT_CONFIG_SINGLE( invert, InvertEffectConfig )
KWIN_EFFECT_CONFIG_SINGLE( sharpen, SharpenEffectConfig )
KWIN_EFFECT_CONFIG_SINGLE( snow, SnowEffectConfig )
#endif

View file

@ -14,7 +14,6 @@ install( FILES
# Data files
install( FILES
invert/data/invert.frag
invert/data/invert.vert
DESTINATION ${DATA_INSTALL_DIR}/kwin )
#######################################

View file

@ -1,9 +1,12 @@
uniform sampler2D winTexture;
uniform sampler2D sample;
uniform float textureWidth;
uniform float textureHeight;
uniform float opacity;
uniform float brightness;
uniform float saturation;
uniform int u_forceAlpha;
varying vec2 varyingTexCoords;
// Converts pixel coordinates to texture coordinates
vec2 pix2tex( vec2 pix )
@ -13,15 +16,19 @@ vec2 pix2tex( vec2 pix )
void main()
{
vec4 tex = texture2D( winTexture, pix2tex( gl_TexCoord[0].st ));
tex = vec4(( vec3( 1.0 ) - tex.rgb / vec3( tex.a )) * vec3( tex.a * opacity ), tex.a * opacity );
vec4 tex = texture2D( sample, pix2tex( varyingTexCoords ));
if( saturation != 1.0 )
{
vec3 desaturated = tex.rgb * vec3( 0.30, 0.59, 0.11 );
desaturated = vec3( dot( desaturated, tex.rgb ));
tex.rgb = tex.rgb * vec3( saturation ) + desaturated * vec3( 1.0 - saturation );
}
tex.rgb = tex.rgb * vec3( brightness );
tex.rgb = tex.rgb * opacity * vec3( brightness );
tex.rgb = vec3(1.0) - tex.rgb;
tex.a = tex.a * opacity;
if (u_forceAlpha > 0) {
tex.a = 1.0;
}
gl_FragColor = tex;
}

View file

@ -1,6 +0,0 @@
void main()
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

View file

@ -29,11 +29,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <kwinshadereffect.h>
#include <KStandardDirs>
#include <QMatrix4x4>
namespace KWin
{
KWIN_EFFECT( invert, InvertEffect )
KWIN_EFFECT_SUPPORTED( invert, ShaderEffect::supported() )
KWIN_EFFECT_SUPPORTED( invert, InvertEffect::supported() )
InvertEffect::InvertEffect()
: m_inited( false ),
@ -59,34 +61,48 @@ InvertEffect::~InvertEffect()
delete m_shader;
}
bool InvertEffect::supported()
{
return GLRenderTarget::supported() &&
GLShader::fragmentShaderSupported() &&
(effects->compositingType() == OpenGLCompositing);
}
bool InvertEffect::loadData()
{
m_inited = true;
QString fragmentshader = KGlobal::dirs()->findResource("data", "kwin/invert.frag");
QString vertexshader = KGlobal::dirs()->findResource("data", "kwin/invert.vert");
if(fragmentshader.isEmpty() || vertexshader.isEmpty())
{
kError(1212) << "Couldn't locate shader files" << endl;
if (!ShaderManager::instance()->isValid()) {
return false;
}
}
m_shader = new GLShader(vertexshader, fragmentshader);
const QString fragmentshader = KGlobal::dirs()->findResource("data", "kwin/invert.frag");
m_shader = ShaderManager::instance()->loadFragmentShader(ShaderManager::GenericShader, fragmentshader);
if( !m_shader->isValid() )
{
kError(1212) << "The shader failed to load!" << endl;
return false;
}
else
{
m_shader->bind();
m_shader->setUniform("winTexture", 0);
m_shader->unbind();
}
return true;
}
void InvertEffect::prePaintScreen(ScreenPrePaintData &data, int time)
{
if (m_valid && (m_allWindows || !m_windows.isEmpty())) {
data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_WITHOUT_FULL_REPAINTS;
}
effects->prePaintScreen(data, time);
}
void InvertEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time)
{
if (m_valid && ( m_allWindows != m_windows.contains( w ))) {
data.mask |= PAINT_WINDOW_TRANSFORMED;
}
effects->prePaintWindow(w, data, time);
}
void InvertEffect::drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
// Load if we haven't already
@ -94,28 +110,22 @@ void InvertEffect::drawWindow( EffectWindow* w, int mask, QRegion region, Window
m_valid = loadData();
bool useShader = m_valid && ( m_allWindows != m_windows.contains( w ));
if( useShader )
{
m_shader->bind();
int texw = w->width();
int texh = w->height();
if( !GLTexture::NPOTTextureSupported() )
{
kWarning( 1212 ) << "NPOT textures not supported, wasting some memory" ;
texw = nearestPowerOfTwo(texw);
texh = nearestPowerOfTwo(texh);
}
m_shader->setTextureWidth( (float)texw );
m_shader->setTextureHeight( (float)texh );
if (useShader) {
ShaderManager *shaderManager = ShaderManager::instance();
GLShader *genericShader = shaderManager->pushShader(ShaderManager::GenericShader);
QMatrix4x4 screenTransformation = genericShader->getUniformMatrix4x4("screenTransformation");
shaderManager->popShader();
shaderManager->pushShader(m_shader);
m_shader->setUniform("screenTransformation", screenTransformation);
data.shader = m_shader;
}
}
effects->drawWindow( w, mask, region, data );
if( useShader )
m_shader->unbind();
if (useShader) {
ShaderManager::instance()->popShader();
}
}
void InvertEffect::paintEffectFrame( KWin::EffectFrame* frame, QRegion region, double opacity, double frameOpacity )
@ -123,7 +133,11 @@ void InvertEffect::paintEffectFrame( KWin::EffectFrame* frame, QRegion region, d
if( m_valid && m_allWindows )
{
frame->setShader( m_shader );
ShaderManager::instance()->pushShader(m_shader);
m_shader->setUniform("screenTransformation", QMatrix4x4());
m_shader->setUniform("windowTransformation", QMatrix4x4());
effects->paintEffectFrame( frame, region, opacity, frameOpacity );
ShaderManager::instance()->popShader();
}
else
{

View file

@ -41,9 +41,13 @@ class InvertEffect
~InvertEffect();
virtual void drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
virtual void prePaintScreen(ScreenPrePaintData &data, int time);
virtual void prePaintWindow(EffectWindow *w, WindowPrePaintData &data, int time);
virtual void paintEffectFrame( KWin::EffectFrame* frame, QRegion region, double opacity, double frameOpacity );
virtual void windowClosed( EffectWindow* w );
static bool supported();
public slots:
void toggle();
void toggleWindow();