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:
parent
f78d838fc7
commit
b7ee35bba1
7 changed files with 64 additions and 46 deletions
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -14,7 +14,6 @@ install( FILES
|
|||
# Data files
|
||||
install( FILES
|
||||
invert/data/invert.frag
|
||||
invert/data/invert.vert
|
||||
DESTINATION ${DATA_INSTALL_DIR}/kwin )
|
||||
|
||||
#######################################
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
void main()
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = ftransform();
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue