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:
Martin Gräßlin 2010-07-24 16:29:16 +00:00
parent df8b8beaf4
commit 89c0ea0c8d
7 changed files with 103 additions and 6 deletions

View file

@ -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 );
}

View file

@ -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

View file

@ -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 );

View file

@ -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:

View file

@ -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 );

View file

@ -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.
*/

View file

@ -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();
}