From 779597a64835291c1c4b0528cc1fcbe595b4cda6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Sat, 21 Oct 2006 18:07:00 +0000 Subject: [PATCH] Basic screen transformation. svn path=/branches/work/kwin_composite/; revision=597815 --- effects.cpp | 28 ++++++++++++++-------------- effects.h | 5 +++-- scene.cpp | 20 ++++++++++---------- scene.h | 16 +++++++--------- scene_opengl.cpp | 20 +++++++++++++++++--- scene_opengl.h | 3 ++- scene_xrender.cpp | 42 +++++++++++++++++++++++++++++++++--------- scene_xrender.h | 2 ++ 8 files changed, 88 insertions(+), 48 deletions(-) diff --git a/effects.cpp b/effects.cpp index 2bfe877c00..c4701133c0 100644 --- a/effects.cpp +++ b/effects.cpp @@ -151,6 +151,7 @@ void GrowMove::windowUserMovedResized( Toplevel* c, bool first, bool last ) c->workspace()->addDamage( c->geometry()); } } +#endif ShiftWorkspaceUp::ShiftWorkspaceUp( Workspace* ws ) : up( false ) @@ -160,13 +161,18 @@ ShiftWorkspaceUp::ShiftWorkspaceUp( Workspace* ws ) timer.start( 2000 ); } -void ShiftWorkspaceUp::transformWorkspace( Matrix& matrix, EffectData& ) +void ShiftWorkspaceUp::prePaintScreen( int* mask, QRegion* region ) { - if( !up ) - return; - Matrix m; - m.m[ 1 ][ 3 ] = -10; - matrix *= m; + if( up ) + *mask |= Scene::PAINT_SCREEN_TRANSFORMED; + effects->nextPrePaintScreen( mask, region ); + } + +void ShiftWorkspaceUp::paintScreen( int mask, QRegion region, ScreenPaintData& data ) + { + if( up ) + data.yTranslate -= 10; + effects->nextPaintScreen( mask, region, data ); } void ShiftWorkspaceUp::tick() @@ -175,12 +181,6 @@ void ShiftWorkspaceUp::tick() wspace->addDamage( 0, 0, displayWidth(), displayHeight()); } -static MakeHalfTransparent* mht; -static ShakyMove* sm; -static GrowMove* gm; -static ShiftWorkspaceUp* swu; -#endif - //**************************************** // EffectsHandler //**************************************** @@ -194,9 +194,9 @@ EffectsHandler::EffectsHandler( Workspace* ws ) // effects.append( new MakeHalfTransparent ); // effects.append( new ShakyMove ); // effects.append( new GrowMove ); -// effects.append( new ShiftWorkspaceUp( ws )); + effects.append( new ShiftWorkspaceUp( ws )); } - + EffectsHandler::~EffectsHandler() { foreach( Effect* e, effects ) diff --git a/effects.h b/effects.h index b9bc6b056c..efc32c6304 100644 --- a/effects.h +++ b/effects.h @@ -116,6 +116,7 @@ class GrowMove virtual void windowUserMovedResized( Toplevel* c, bool first, bool last ); virtual void transformWindow( Toplevel* c, Matrix& m, EffectData& data ); }; +#endif class ShiftWorkspaceUp : public QObject, public Effect @@ -123,7 +124,8 @@ class ShiftWorkspaceUp Q_OBJECT public: ShiftWorkspaceUp( Workspace* ws ); - virtual void transformWorkspace( Matrix& m, EffectData& data ); + virtual void prePaintScreen( int* mask, QRegion* region ); + virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); private slots: void tick(); private: @@ -131,7 +133,6 @@ class ShiftWorkspaceUp bool up; Workspace* wspace; }; -#endif // a special effect that is last in the order that'll actually call the painting functions // TODO this should actually be in scene.h diff --git a/scene.cpp b/scene.cpp index c9ed1c96ea..bc76ab2bf1 100644 --- a/scene.cpp +++ b/scene.cpp @@ -50,30 +50,30 @@ void Scene::WrapperEffect::prePaintScreen( int*, QRegion* ) void Scene::WrapperEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) { if( mask & PAINT_SCREEN_REGION ) - scene->paintSimpleScreen( region ); + scene->paintSimpleScreen( mask, region ); else - scene->paintGenericScreen(); + scene->paintGenericScreen( mask, data ); } - + // the generic painting code that should eventually handle even // transformations -void Scene::paintGenericScreen() +void Scene::paintGenericScreen( int mask, ScreenPaintData ) { paintBackground( infiniteRegion()); foreach( Window* w, stacking_order ) // bottom to top { if( !w->isVisible()) continue; - paintWindow( w, PAINT_WINDOW_OPAQUE | PAINT_WINDOW_TRANSLUCENT, infiniteRegion()); + paintWindow( w, mask | PAINT_WINDOW_OPAQUE | PAINT_WINDOW_TRANSLUCENT, infiniteRegion()); } } // the optimized case without any transformations at all -void Scene::paintSimpleScreen( QRegion region ) +void Scene::paintSimpleScreen( int mask, QRegion region ) { + assert(( mask & ( PAINT_WINDOW_TRANSFORMED | PAINT_SCREEN_TRANSFORMED + | PAINT_WINDOW_TRANSLUCENT | PAINT_WINDOW_OPAQUE )) == 0 ); QList< Phase2Data > phase2; - // TODO repaint only damaged areas (means also don't do glXSwapBuffers and similar) - region = QRegion( 0, 0, displayWidth(), displayHeight()); // Draw each opaque window top to bottom, subtracting the bounding rect of // each window from the clip region after it's been drawn. for( int i = stacking_order.count() - 1; // top to bottom @@ -90,7 +90,7 @@ void Scene::paintSimpleScreen( QRegion region ) phase2.prepend( Phase2Data( w, region )); continue; } - paintWindow( w, PAINT_WINDOW_OPAQUE, region ); + paintWindow( w, mask | PAINT_WINDOW_OPAQUE, region ); // window is opaque, clip windows below region -= w->shape().translated( w->x(), w->y()); } @@ -102,7 +102,7 @@ void Scene::paintSimpleScreen( QRegion region ) foreach( Phase2Data d, phase2 ) { Window* w = d.window; - paintWindow( w, PAINT_WINDOW_TRANSLUCENT, d.region ); + paintWindow( w, mask | PAINT_WINDOW_TRANSLUCENT, d.region ); } } diff --git a/scene.h b/scene.h index c1d5f8df47..14dfdbb6b8 100644 --- a/scene.h +++ b/scene.h @@ -37,19 +37,17 @@ class Scene virtual void windowAdded( Toplevel* ); // a window has been destroyed virtual void windowDeleted( Toplevel* ); - protected: enum { PAINT_WINDOW_OPAQUE = 1 << 0, - PAINT_WINDOW_TRANSLUCENT = 1 << 1 + PAINT_WINDOW_TRANSLUCENT = 1 << 1, + PAINT_WINDOW_TRANSFORMED = 1 << 2, + PAINT_SCREEN_REGION = 1 << 3, + PAINT_SCREEN_TRANSFORMED = 1 << 4 }; - enum - { - PAINT_SCREEN_REGION = 1 << 0, - PAINT_SCREEN_ALL = 1 << 1 - }; - virtual void paintGenericScreen(); - virtual void paintSimpleScreen( QRegion region ); + protected: + virtual void paintGenericScreen( int mask, ScreenPaintData data ); + virtual void paintSimpleScreen( int mask, QRegion region ); virtual void paintBackground( QRegion region ) = 0; virtual void paintWindow( Window* w, int mask, QRegion region ); static QRegion infiniteRegion(); diff --git a/scene_opengl.cpp b/scene_opengl.cpp index c1cf55d3be..5a1114af07 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -278,10 +278,12 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels ) glScalef( 1, -1, 1 ); glTranslatef( 0, -displayHeight(), 0 ); int mask = ( damage == QRegion( 0, 0, displayWidth(), displayHeight())) - ? PAINT_SCREEN_ALL : PAINT_SCREEN_REGION; + ? 0 : PAINT_SCREEN_REGION; WrapperEffect wrapper; // preparation step effects->prePaintScreen( &mask, &damage, &wrapper ); + if( mask & ( PAINT_SCREEN_TRANSFORMED | PAINT_WINDOW_TRANSFORMED )) + mask &= ~PAINT_SCREEN_REGION; // TODO call also prePaintWindow() for all windows ScreenPaintData data; effects->paintScreen( mask, damage, data, &wrapper ); @@ -301,12 +303,24 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels ) checkGLError( "PostPaint" ); } +void SceneOpenGL::paintGenericScreen( int mask, ScreenPaintData data ) + { + if( mask & PAINT_SCREEN_TRANSFORMED ) + { + glPushMatrix(); + glTranslatef( data.xTranslate, data.yTranslate, 0 ); + } + Scene::paintGenericScreen( mask, data ); + if( mask & PAINT_SCREEN_TRANSFORMED ) + glPopMatrix(); + } + // the optimized case without any transformations at all -void SceneOpenGL::paintSimpleScreen( QRegion region ) +void SceneOpenGL::paintSimpleScreen( int mask, QRegion region ) { // TODO repaint only damaged areas (means also don't do glXSwapBuffers and similar) region = QRegion( 0, 0, displayWidth(), displayHeight()); - Scene::paintSimpleScreen( region ); + Scene::paintSimpleScreen( mask, region ); } void SceneOpenGL::paintBackground( QRegion ) diff --git a/scene_opengl.h b/scene_opengl.h index 9a300d4c65..973713d166 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -31,7 +31,8 @@ class SceneOpenGL virtual void windowAdded( Toplevel* ); virtual void windowDeleted( Toplevel* ); protected: - virtual void paintSimpleScreen( QRegion region ); + virtual void paintGenericScreen( int mask, ScreenPaintData data ); + virtual void paintSimpleScreen( int mask, QRegion region ); virtual void paintBackground( QRegion region ); private: void initBuffer(); diff --git a/scene_xrender.cpp b/scene_xrender.cpp index b346791ab1..d09c700a95 100644 --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -50,6 +50,7 @@ kdbgstream& operator<<( kdbgstream& stream, RegionDebug r ) #endif Picture SceneXrender::buffer; +ScreenPaintData SceneXrender::screen_paint; SceneXrender::SceneXrender( Workspace* ws ) : Scene( ws ) @@ -84,10 +85,12 @@ void SceneXrender::paint( QRegion damage, ToplevelList toplevels ) stacking_order.append( &windows[ c ] ); } int mask = ( damage == QRegion( 0, 0, displayWidth(), displayHeight())) - ? PAINT_SCREEN_ALL : PAINT_SCREEN_REGION; + ? 0 : PAINT_SCREEN_REGION; WrapperEffect wrapper; // preparation step effects->prePaintScreen( &mask, &damage, &wrapper ); + if( mask & ( PAINT_SCREEN_TRANSFORMED | PAINT_WINDOW_TRANSFORMED )) + mask &= ~PAINT_SCREEN_REGION; // TODO call also prePaintWindow() for all windows ScreenPaintData data; effects->paintScreen( mask, damage, data, &wrapper ); @@ -101,6 +104,7 @@ void SceneXrender::paint( QRegion damage, ToplevelList toplevels ) // copy composed buffer to the root window XFixesSetPictureClipRegion( display(), buffer, 0, 0, None ); XRenderComposite( display(), PictOpSrc, buffer, None, front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight()); + XFixesSetPictureClipRegion( display(), front, 0, 0, None ); XFlush( display()); } else @@ -111,13 +115,23 @@ void SceneXrender::paint( QRegion damage, ToplevelList toplevels ) } } +void SceneXrender::paintGenericScreen( int mask, ScreenPaintData data ) + { + screen_paint = data; // save, transformations will be done when painting windows + Scene::paintGenericScreen( mask, data ); + } + void SceneXrender::paintBackground( QRegion region ) { - XserverRegion background_region = toXserverRegion( region ); - XFixesSetPictureClipRegion( display(), buffer, 0, 0, background_region ); - XFixesDestroyRegion( display(), background_region ); + if( region != infiniteRegion()) + { + XserverRegion background_region = toXserverRegion( region ); + XFixesSetPictureClipRegion( display(), buffer, 0, 0, background_region ); + XFixesDestroyRegion( display(), background_region ); + } XRenderColor col = { 0xffff, 0xffff, 0xffff, 0xffff }; XRenderFillRectangle( display(), PictOpSrc, buffer, &col, 0, 0, displayWidth(), displayHeight()); + XFixesSetPictureClipRegion( display(), buffer, 0, 0, None ); } void SceneXrender::windowGeometryShapeChanged( Toplevel* c ) @@ -307,22 +321,32 @@ void SceneXrender::Window::performPaint( QRegion region, int mask ) if( isOpaque()) return; } - XserverRegion clip_region = toXserverRegion( region ); - XFixesSetPictureClipRegion( display(), buffer, 0, 0, clip_region ); - XFixesDestroyRegion( display(), clip_region ); + if( region != infiniteRegion()) + { + XserverRegion clip_region = toXserverRegion( region ); + XFixesSetPictureClipRegion( display(), buffer, 0, 0, clip_region ); + XFixesDestroyRegion( display(), clip_region ); + } Picture pic = picture(); if( pic == None ) // The render format can be null for GL and/or Xv visuals return; + int x = toplevel->x(); + int y = toplevel->y(); + if( mask & PAINT_SCREEN_TRANSFORMED ) + { + x += screen_paint.xTranslate; + y += screen_paint.yTranslate; + } if( isOpaque()) { XRenderComposite( display(), PictOpSrc, pic, None, buffer, 0, 0, 0, 0, - toplevel->x(), toplevel->y(), toplevel->width(), toplevel->height()); + x, y, toplevel->width(), toplevel->height()); } else { Picture alpha = alphaMask(); XRenderComposite( display(), PictOpOver, pic, alpha, buffer, 0, 0, 0, 0, - toplevel->x(), toplevel->y(), toplevel->width(), toplevel->height()); + x, y, toplevel->width(), toplevel->height()); } XFixesSetPictureClipRegion( display(), buffer, 0, 0, None ); } diff --git a/scene_xrender.h b/scene_xrender.h index be1ed873a7..224e4ef93c 100644 --- a/scene_xrender.h +++ b/scene_xrender.h @@ -36,12 +36,14 @@ class SceneXrender virtual void windowDeleted( Toplevel* ); protected: virtual void paintBackground( QRegion region ); + virtual void paintGenericScreen( int mask, ScreenPaintData data ); private: void createBuffer(); static XserverRegion toXserverRegion( QRegion region ); XRenderPictFormat* format; Picture front; static Picture buffer; + static ScreenPaintData screen_paint; class Window; QMap< Toplevel*, Window > windows; };