Pass EffectFrame through all effects, so that they can do something with the frame.
E.g. set a shader to invert it. CCBUG: 241389 svn path=/trunk/KDE/kdebase/workspace/; revision=1154071
This commit is contained in:
parent
df8b8beaf4
commit
89c0ea0c8d
7 changed files with 103 additions and 6 deletions
22
effects.cpp
22
effects.cpp
|
@ -99,6 +99,7 @@ EffectsHandlerImpl::EffectsHandlerImpl(CompositingType type)
|
|||
, fullscreen_effect( 0 )
|
||||
, next_window_quad_type( EFFECT_QUAD_TYPE_START )
|
||||
, mouse_poll_ref_count( 0 )
|
||||
, current_paint_effectframe( 0 )
|
||||
{
|
||||
reconfigure();
|
||||
}
|
||||
|
@ -203,6 +204,20 @@ void EffectsHandlerImpl::paintWindow( EffectWindow* w, int mask, QRegion region,
|
|||
scene->finalPaintWindow( static_cast<EffectWindowImpl*>( w ), mask, region, data );
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::paintEffectFrame( EffectFrame* frame, QRegion region, double opacity, double frameOpacity )
|
||||
{
|
||||
if( current_paint_effectframe < loaded_effects.size())
|
||||
{
|
||||
loaded_effects[current_paint_effectframe++].second->paintEffectFrame( frame, region, opacity, frameOpacity );
|
||||
--current_paint_effectframe;
|
||||
}
|
||||
else
|
||||
{
|
||||
const EffectFrameImpl* frameImpl = static_cast<const EffectFrameImpl*>( frame );
|
||||
frameImpl->finalRender( region, opacity, frameOpacity );
|
||||
}
|
||||
}
|
||||
|
||||
void EffectsHandlerImpl::postPaintWindow( EffectWindow* w )
|
||||
{
|
||||
if( current_paint_window < loaded_effects.size())
|
||||
|
@ -1647,6 +1662,7 @@ EffectFrameImpl::EffectFrameImpl( EffectFrameStyle style, bool staticSize, QPoin
|
|||
, m_static( staticSize )
|
||||
, m_point( position )
|
||||
, m_alignment( alignment )
|
||||
, m_shader( NULL )
|
||||
{
|
||||
if( m_style == Styled )
|
||||
{
|
||||
|
@ -1775,10 +1791,14 @@ void EffectFrameImpl::render( QRegion region, double opacity, double frameOpacit
|
|||
{
|
||||
return; // Nothing to display
|
||||
}
|
||||
m_shader = NULL;
|
||||
effects->paintEffectFrame( this, region, opacity, frameOpacity );
|
||||
}
|
||||
|
||||
void EffectFrameImpl::finalRender( QRegion region, double opacity, double frameOpacity ) const
|
||||
{
|
||||
region = infiniteRegion(); // TODO: Old region doesn't seem to work with OpenGL
|
||||
|
||||
// TODO: pass through all effects
|
||||
m_sceneFrame->render( region, opacity, frameOpacity );
|
||||
}
|
||||
|
||||
|
|
12
effects.h
12
effects.h
|
@ -46,6 +46,7 @@ class EffectsHandlerImpl : public EffectsHandler
|
|||
virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time );
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void postPaintWindow( EffectWindow* w );
|
||||
virtual void paintEffectFrame( EffectFrame* frame, QRegion region, double opacity, double frameOpacity );
|
||||
|
||||
bool providesResizeEffect();
|
||||
|
||||
|
@ -198,6 +199,7 @@ class EffectsHandlerImpl : public EffectsHandler
|
|||
QHash< long, int > registered_atoms;
|
||||
int next_window_quad_type;
|
||||
int mouse_poll_ref_count;
|
||||
int current_paint_effectframe;
|
||||
};
|
||||
|
||||
class EffectWindowImpl : public EffectWindow
|
||||
|
@ -345,6 +347,15 @@ class EffectFrameImpl
|
|||
{
|
||||
return m_static;
|
||||
};
|
||||
void finalRender( QRegion region, double opacity, double frameOpacity ) const;
|
||||
virtual void setShader( GLShader* shader )
|
||||
{
|
||||
m_shader = shader;
|
||||
}
|
||||
virtual GLShader* shader() const
|
||||
{
|
||||
return m_shader;
|
||||
}
|
||||
|
||||
private Q_SLOTS:
|
||||
void plasmaThemeChanged();
|
||||
|
@ -370,6 +381,7 @@ class EffectFrameImpl
|
|||
QSize m_iconSize;
|
||||
|
||||
Scene::EffectFrame* m_sceneFrame;
|
||||
GLShader* m_shader;
|
||||
};
|
||||
|
||||
inline
|
||||
|
|
|
@ -118,6 +118,19 @@ void InvertEffect::drawWindow( EffectWindow* w, int mask, QRegion region, Window
|
|||
m_shader->unbind();
|
||||
}
|
||||
|
||||
void InvertEffect::paintEffectFrame( KWin::EffectFrame* frame, QRegion region, double opacity, double frameOpacity )
|
||||
{
|
||||
if( m_valid && m_allWindows )
|
||||
{
|
||||
frame->setShader( m_shader );
|
||||
effects->paintEffectFrame( frame, region, opacity, frameOpacity );
|
||||
}
|
||||
else
|
||||
{
|
||||
effects->paintEffectFrame( frame, region, opacity, frameOpacity );
|
||||
}
|
||||
}
|
||||
|
||||
void InvertEffect::windowClosed( EffectWindow* w )
|
||||
{
|
||||
m_windows.removeOne( w );
|
||||
|
|
|
@ -41,6 +41,7 @@ class InvertEffect
|
|||
~InvertEffect();
|
||||
|
||||
virtual void drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||
virtual void paintEffectFrame( KWin::EffectFrame* frame, QRegion region, double opacity, double frameOpacity );
|
||||
virtual void windowClosed( EffectWindow* w );
|
||||
|
||||
public slots:
|
||||
|
|
|
@ -247,6 +247,11 @@ void Effect::postPaintWindow( EffectWindow* w )
|
|||
effects->postPaintWindow( w );
|
||||
}
|
||||
|
||||
void Effect::paintEffectFrame( KWin::EffectFrame* frame, QRegion region, double opacity, double frameOpacity )
|
||||
{
|
||||
effects->paintEffectFrame( frame, region, opacity, frameOpacity );
|
||||
}
|
||||
|
||||
void Effect::drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
|
||||
{
|
||||
effects->drawWindow( w, mask, region, data );
|
||||
|
|
|
@ -170,7 +170,7 @@ X-KDE-Library=kwin4_effect_cooleffect
|
|||
|
||||
#define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor ))
|
||||
#define KWIN_EFFECT_API_VERSION_MAJOR 0
|
||||
#define KWIN_EFFECT_API_VERSION_MINOR 153
|
||||
#define KWIN_EFFECT_API_VERSION_MINOR 154
|
||||
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
|
||||
KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
|
||||
|
||||
|
@ -392,6 +392,18 @@ class KWIN_EXPORT Effect
|
|||
**/
|
||||
virtual void postPaintWindow( EffectWindow* w );
|
||||
|
||||
/**
|
||||
* This method is called directly before painting an @ref EffectFrame.
|
||||
* You can implement this method if you need to bind a shader or perform
|
||||
* other operations before the frame is rendered.
|
||||
* @param frame The EffectFrame which will be rendered
|
||||
* @param region Region to restrict painting to
|
||||
* @param opacity Opacity of text/icon
|
||||
* @param frameOpacity Opacity of background
|
||||
* @since 4.6
|
||||
**/
|
||||
virtual void paintEffectFrame( EffectFrame* frame, QRegion region, double opacity, double frameOpacity );
|
||||
|
||||
/**
|
||||
* Called on Transparent resizes.
|
||||
* return true if your effect substitutes the XOR rubberband
|
||||
|
@ -573,6 +585,7 @@ class KWIN_EXPORT EffectsHandler
|
|||
virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) = 0;
|
||||
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) = 0;
|
||||
virtual void postPaintWindow( EffectWindow* w ) = 0;
|
||||
virtual void paintEffectFrame( EffectFrame* frame, QRegion region, double opacity, double frameOpacity ) = 0;
|
||||
virtual void drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) = 0;
|
||||
virtual void buildQuads( EffectWindow* w, WindowQuadList& quadList ) = 0;
|
||||
virtual QRect transformWindowDamage( EffectWindow* w, const QRect& r );
|
||||
|
@ -1724,6 +1737,15 @@ class KWIN_EXPORT EffectFrame
|
|||
virtual void setIconSize( const QSize& size ) = 0;
|
||||
virtual const QSize& iconSize() const = 0;
|
||||
|
||||
/**
|
||||
* @param shader The GLShader for rendering.
|
||||
**/
|
||||
virtual void setShader( GLShader* shader ) = 0;
|
||||
/**
|
||||
* @returns The GLShader used for rendering or null if none.
|
||||
**/
|
||||
virtual GLShader* shader() const = 0;
|
||||
|
||||
/**
|
||||
* The foreground text color as specified by the default Plasma theme.
|
||||
*/
|
||||
|
|
|
@ -1968,10 +1968,22 @@ void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double fr
|
|||
|
||||
region = infiniteRegion(); // TODO: Old region doesn't seem to work with OpenGL
|
||||
|
||||
GLShader* shader = m_effectFrame->shader();
|
||||
if( shader )
|
||||
{
|
||||
shader->bind();
|
||||
shader->setUniform("saturation", 1.0f);
|
||||
shader->setUniform("brightness", 1.0f);
|
||||
|
||||
shader->setUniform("textureWidth", 1.0f);
|
||||
shader->setUniform("textureHeight", 1.0f);
|
||||
}
|
||||
|
||||
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
if( !shader )
|
||||
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
|
@ -2082,7 +2094,10 @@ void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double fr
|
|||
m_unstyledVBO->setData( verts.count() / 2, 2, verts.data(), texCoords.data() );
|
||||
}
|
||||
|
||||
glColor4f( 0.0, 0.0, 0.0, opacity * frameOpacity );
|
||||
if( shader )
|
||||
shader->setUniform( "opacity", (float)(opacity * frameOpacity) );
|
||||
else
|
||||
glColor4f( 0.0, 0.0, 0.0, opacity * frameOpacity );
|
||||
|
||||
m_unstyledTexture->bind();
|
||||
m_unstyledVBO->render( region, GL_TRIANGLES );
|
||||
|
@ -2093,7 +2108,10 @@ void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double fr
|
|||
if( !m_texture ) // Lazy creation
|
||||
updateTexture();
|
||||
|
||||
glColor4f( 1.0, 1.0, 1.0, opacity * frameOpacity );
|
||||
if( shader )
|
||||
shader->setUniform( "opacity", (float)(opacity * frameOpacity) );
|
||||
else
|
||||
glColor4f( 1.0, 1.0, 1.0, opacity * frameOpacity );
|
||||
|
||||
m_texture->bind();
|
||||
qreal left, top, right, bottom;
|
||||
|
@ -2102,7 +2120,10 @@ void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double fr
|
|||
m_texture->unbind();
|
||||
}
|
||||
|
||||
glColor4f( 1.0, 1.0, 1.0, opacity );
|
||||
if( shader )
|
||||
shader->setUniform( "opacity", (float)opacity );
|
||||
else
|
||||
glColor4f( 1.0, 1.0, 1.0, opacity );
|
||||
|
||||
// Render icon
|
||||
if( !m_effectFrame->icon().isNull() && !m_effectFrame->iconSize().isEmpty() )
|
||||
|
@ -2131,6 +2152,9 @@ void SceneOpenGL::EffectFrame::render( QRegion region, double opacity, double fr
|
|||
m_textTexture->unbind();
|
||||
}
|
||||
|
||||
if( shader )
|
||||
shader->unbind();
|
||||
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue