diff --git a/COMPOSITE_TODO b/COMPOSITE_TODO index ed6e8d7f59..fae75ed68d 100644 --- a/COMPOSITE_TODO +++ b/COMPOSITE_TODO @@ -96,7 +96,7 @@ KDE 4.0 TODO - correct ordering for effects [rivo] would be nice if isn't too strict -- vertex redesign [Seli] +/ vertex redesign [Seli] affects alpha clear hack - support applying opacity only to decoration - not using ARGB visuals @@ -234,7 +234,7 @@ OpenGL TODO % with current nvidia glXCreatePixmap in tfp mode fails with pixmaps 32x32 and smaller -+ vertices list (and possibly more things) should not be part of SceneOpenGL::Window +/ vertices list (and possibly more things) should not be part of SceneOpenGL::Window - otherwise drawWindow() used for thumbnails would use them too - they should be probably part of WindowPaintData diff --git a/effects.cpp b/effects.cpp index 16024e4941..931a2de4ef 100644 --- a/effects.cpp +++ b/effects.cpp @@ -74,11 +74,11 @@ void EffectsHandlerImpl::reconfigure() } // the idea is that effects call this function again which calls the next one -void EffectsHandlerImpl::prePaintScreen( int* mask, QRegion* region, int time ) +void EffectsHandlerImpl::prePaintScreen( ScreenPrePaintData& data, int time ) { if( current_paint_screen < loaded_effects.size()) { - loaded_effects[current_paint_screen++].second->prePaintScreen( mask, region, time ); + loaded_effects[current_paint_screen++].second->prePaintScreen( data, time ); --current_paint_screen; } // no special final code @@ -105,11 +105,11 @@ void EffectsHandlerImpl::postPaintScreen() // no special final code } -void EffectsHandlerImpl::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void EffectsHandlerImpl::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if( current_paint_window < loaded_effects.size()) { - loaded_effects[current_paint_window++].second->prePaintWindow( w, mask, paint, clip, time ); + loaded_effects[current_paint_window++].second->prePaintWindow( w, data, time ); --current_paint_window; } // no special final code @@ -1057,33 +1057,6 @@ EffectWindowList EffectWindowImpl::mainWindows() const return EffectWindowList(); } -QVector& EffectWindowImpl::vertices() - { -#ifdef HAVE_OPENGL - if( SceneOpenGL::Window* w = dynamic_cast< SceneOpenGL::Window* >( sceneWindow())) - return w->vertices(); -#endif - abort(); // TODO - } - -void EffectWindowImpl::requestVertexGrid(int maxquadsize) - { -#ifdef HAVE_OPENGL - if( SceneOpenGL::Window* w = dynamic_cast< SceneOpenGL::Window* >( sceneWindow())) - return w->requestVertexGrid( maxquadsize ); -#endif - abort(); // TODO - } - -void EffectWindowImpl::markVerticesDirty() - { -#ifdef HAVE_OPENGL - if( SceneOpenGL::Window* w = dynamic_cast< SceneOpenGL::Window* >( sceneWindow())) - return w->markVerticesDirty(); -#endif - abort(); // TODO - } - void EffectWindowImpl::setShader(GLShader* shader) { #ifdef HAVE_OPENGL diff --git a/effects.h b/effects.h index 132f5e71cb..5cd64300b2 100644 --- a/effects.h +++ b/effects.h @@ -30,10 +30,10 @@ class EffectsHandlerImpl : public EffectsHandler public: EffectsHandlerImpl(CompositingType type); virtual ~EffectsHandlerImpl(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); virtual void postPaintScreen(); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + 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 ); @@ -189,9 +189,6 @@ class EffectWindowImpl : public EffectWindow virtual EffectWindow* findModal(); virtual EffectWindowList mainWindows() const; - virtual QVector& vertices(); - virtual void requestVertexGrid(int maxquadsize); - virtual void markVerticesDirty(); virtual void setShader(GLShader* shader); const Toplevel* window() const; diff --git a/effects/blur.cpp b/effects/blur.cpp index 1ca7a940bc..bbcf77f612 100644 --- a/effects/blur.cpp +++ b/effects/blur.cpp @@ -132,19 +132,19 @@ bool BlurEffect::supported() } -void BlurEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void BlurEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { mTransparentWindows = 0; mTime += time; - effects->prePaintScreen(mask, region, time); + effects->prePaintScreen(data, time); } -void BlurEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void BlurEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); - if( w->isPaintingEnabled() && ( *mask & PAINT_WINDOW_TRANSLUCENT )) + if( w->isPaintingEnabled() && ( data.mask & PAINT_WINDOW_TRANSLUCENT )) mTransparentWindows++; } diff --git a/effects/blur.h b/effects/blur.h index 422d44f9d2..7be3831a68 100644 --- a/effects/blur.h +++ b/effects/blur.h @@ -33,9 +33,9 @@ class BlurEffect : public Effect BlurEffect(); ~BlurEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); static bool supported(); diff --git a/effects/boxswitch.cpp b/effects/boxswitch.cpp index ce47ec2dc3..c67032483f 100644 --- a/effects/boxswitch.cpp +++ b/effects/boxswitch.cpp @@ -43,12 +43,12 @@ BoxSwitchEffect::~BoxSwitchEffect() { } -void BoxSwitchEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void BoxSwitchEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { - effects->prePaintScreen( mask, region, time ); + effects->prePaintScreen( data, time ); } -void BoxSwitchEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void BoxSwitchEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if( mActivated ) { @@ -56,8 +56,8 @@ void BoxSwitchEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint { if( windows.contains( w ) && w != selected_window ) { - *mask |= PAINT_WINDOW_TRANSLUCENT; - *mask &= ~PAINT_WINDOW_OPAQUE; + data.mask |= PAINT_WINDOW_TRANSLUCENT; + data.mask &= ~PAINT_WINDOW_OPAQUE; } } else @@ -71,7 +71,7 @@ void BoxSwitchEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint } } } - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void BoxSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) diff --git a/effects/boxswitch.h b/effects/boxswitch.h index 921e3743be..add0bcb20c 100644 --- a/effects/boxswitch.h +++ b/effects/boxswitch.h @@ -35,9 +35,9 @@ class BoxSwitchEffect BoxSwitchEffect(); ~BoxSwitchEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); virtual void windowInputMouseEvent( Window w, QEvent* e ); diff --git a/effects/demo_liquid.cpp b/effects/demo_liquid.cpp index 334896ac1c..a1ddf07ffe 100644 --- a/effects/demo_liquid.cpp +++ b/effects/demo_liquid.cpp @@ -95,17 +95,17 @@ bool LiquidEffect::supported() } -void LiquidEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void LiquidEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { mTime += time / 1000.0f; if(mValid) { - *mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; // Start rendering to texture effects->pushRenderTarget(mRenderTarget); } - effects->prePaintScreen(mask, region, time); + effects->prePaintScreen(data, time); } void LiquidEffect::postPaintScreen() diff --git a/effects/demo_liquid.h b/effects/demo_liquid.h index 228698f350..9a078b2e8a 100644 --- a/effects/demo_liquid.h +++ b/effects/demo_liquid.h @@ -30,7 +30,7 @@ class LiquidEffect : public Effect LiquidEffect(); ~LiquidEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void postPaintScreen(); static bool supported(); diff --git a/effects/demo_shakymove.cpp b/effects/demo_shakymove.cpp index 979f9649fc..090bc24cbc 100644 --- a/effects/demo_shakymove.cpp +++ b/effects/demo_shakymove.cpp @@ -23,18 +23,18 @@ ShakyMoveEffect::ShakyMoveEffect() static const int shaky_diff[] = { 0, 1, 2, 3, 2, 1, 0, -1, -2, -3, -2, -1 }; static const int SHAKY_MAX = sizeof( shaky_diff ) / sizeof( shaky_diff[ 0 ] ); -void ShakyMoveEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void ShakyMoveEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( !windows.isEmpty()) - *mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; - effects->prePaintScreen( mask, region, time ); + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + effects->prePaintScreen( data, time ); } -void ShakyMoveEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void ShakyMoveEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if( windows.contains( w )) - *mask |= PAINT_WINDOW_TRANSFORMED; - effects->prePaintWindow( w, mask, paint, clip, time ); + data.mask |= PAINT_WINDOW_TRANSFORMED; + effects->prePaintWindow( w, data, time ); } void ShakyMoveEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) diff --git a/effects/demo_shakymove.h b/effects/demo_shakymove.h index 98889087dd..3093f084ed 100644 --- a/effects/demo_shakymove.h +++ b/effects/demo_shakymove.h @@ -24,8 +24,8 @@ class ShakyMoveEffect Q_OBJECT public: ShakyMoveEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); virtual void windowUserMovedResized( EffectWindow* c, bool first, bool last ); virtual void windowClosed( EffectWindow* c ); diff --git a/effects/demo_shiftworkspaceup.cpp b/effects/demo_shiftworkspaceup.cpp index bba1046d6a..ce2121754e 100644 --- a/effects/demo_shiftworkspaceup.cpp +++ b/effects/demo_shiftworkspaceup.cpp @@ -23,15 +23,15 @@ ShiftWorkspaceUpEffect::ShiftWorkspaceUpEffect() timer.start( 2000 ); } -void ShiftWorkspaceUpEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void ShiftWorkspaceUpEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( up && diff < 1000 ) diff = qBound( 0, diff + time, 1000 ); // KDE3: note this differs from KCLAMP if( !up && diff > 0 ) diff = qBound( 0, diff - time, 1000 ); if( diff != 0 ) - *mask |= PAINT_SCREEN_TRANSFORMED; - effects->prePaintScreen( mask, region, time ); + data.mask |= PAINT_SCREEN_TRANSFORMED; + effects->prePaintScreen( data, time ); } void ShiftWorkspaceUpEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) diff --git a/effects/demo_shiftworkspaceup.h b/effects/demo_shiftworkspaceup.h index 75ad94dd31..1f97f251af 100644 --- a/effects/demo_shiftworkspaceup.h +++ b/effects/demo_shiftworkspaceup.h @@ -24,7 +24,7 @@ class ShiftWorkspaceUpEffect Q_OBJECT public: ShiftWorkspaceUpEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); virtual void postPaintScreen(); private slots: diff --git a/effects/demo_taskbarthumbnail.cpp b/effects/demo_taskbarthumbnail.cpp index 953da8345e..afa8d1012f 100644 --- a/effects/demo_taskbarthumbnail.cpp +++ b/effects/demo_taskbarthumbnail.cpp @@ -24,28 +24,28 @@ TaskbarThumbnailEffect::TaskbarThumbnailEffect() } -void TaskbarThumbnailEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void TaskbarThumbnailEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { // We might need to paint thumbnails if cursor has moved since last // painting or some thumbnails were painted the last time QPoint cpos = cursorPos(); if(cpos != mLastCursorPos || mThumbnails.count() > 0) { - *mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; mThumbnails.clear(); mLastCursorPos = cpos; } - effects->prePaintScreen(mask, region, time); + effects->prePaintScreen(data, time); } -void TaskbarThumbnailEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void TaskbarThumbnailEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { QRect iconGeo = w->iconGeometry(); if(iconGeo.contains( mLastCursorPos )) mThumbnails.append( w ); - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void TaskbarThumbnailEffect::postPaintScreen() diff --git a/effects/demo_taskbarthumbnail.h b/effects/demo_taskbarthumbnail.h index fd9d768864..b6cf68a80c 100644 --- a/effects/demo_taskbarthumbnail.h +++ b/effects/demo_taskbarthumbnail.h @@ -31,8 +31,8 @@ class TaskbarThumbnailEffect public: TaskbarThumbnailEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); virtual void postPaintScreen(); virtual void mouseChanged( const QPoint& pos, const QPoint& old, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers ); diff --git a/effects/demo_wavywindows.cpp b/effects/demo_wavywindows.cpp index a37b344d08..d6813978d3 100644 --- a/effects/demo_wavywindows.cpp +++ b/effects/demo_wavywindows.cpp @@ -25,27 +25,27 @@ WavyWindowsEffect::WavyWindowsEffect() } -void WavyWindowsEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void WavyWindowsEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { // Adjust elapsed time mTimeElapsed += (time / 1000.0f); // We need to mark the screen windows as transformed. Otherwise the whole // screen won't be repainted, resulting in artefacts - *mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; - effects->prePaintScreen(mask, region, time); + effects->prePaintScreen(data, time); } -void WavyWindowsEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void WavyWindowsEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { // This window will be transformed by the effect - *mask |= PAINT_WINDOW_TRANSFORMED; + data.mask |= PAINT_WINDOW_TRANSFORMED; // Check if OpenGL compositing is used // Request the window to be divided into cells which are at most 30x30 // pixels big - w->requestVertexGrid(30); + data.quads = data.quads.makeGrid( 30 ); - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void WavyWindowsEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) @@ -58,15 +58,17 @@ void WavyWindowsEffect::paintWindow( EffectWindow* w, int mask, QRegion region, // We have OpenGL compositing and the window has been subdivided // because of our request (in pre-paint pass) // Transform all the vertices to create wavy effect - QVector< Vertex >& vertices = w->vertices(); - for(int i = 0; i < vertices.count(); i++) - { - vertices[i].pos[0] += sin(mTimeElapsed + vertices[i].texcoord[1] / 60 + 0.5f) * 10; - vertices[i].pos[1] += sin(mTimeElapsed + vertices[i].texcoord[0] / 80) * 10; + for( int i = 0; + i < data.quads.count(); + ++i ) + for( int j = 0; + j < 4; + ++j ) + { + WindowVertex& v = data.quads[ i ][ j ]; + v.move( v.x() + sin(mTimeElapsed + v.textureY() / 60 + 0.5f) * 10, + v.y() + sin(mTimeElapsed + v.textureX() / 80) * 10 ); } - // We have changed the vertices, so they will have to be reset before - // the next paint pass - w->markVerticesDirty(); } // Call the next effect. diff --git a/effects/demo_wavywindows.h b/effects/demo_wavywindows.h index 5efbcbe692..f410535b2b 100644 --- a/effects/demo_wavywindows.h +++ b/effects/demo_wavywindows.h @@ -27,8 +27,8 @@ class WavyWindowsEffect public: WavyWindowsEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); virtual void postPaintScreen(); diff --git a/effects/desktopgrid.cpp b/effects/desktopgrid.cpp index 9f725c6185..6a233a4456 100644 --- a/effects/desktopgrid.cpp +++ b/effects/desktopgrid.cpp @@ -42,7 +42,7 @@ DesktopGridEffect::DesktopGridEffect() slideEnabled = conf.readEntry( "Slide", true ); } -void DesktopGridEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void DesktopGridEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( slide ) { @@ -50,7 +50,7 @@ void DesktopGridEffect::prePaintScreen( int* mask, QRegion* region, int time ) // PAINT_SCREEN_BACKGROUND_FIRST is needed because screen will be actually painted more than once, // so with normal screen painting second screen paint would erase parts of the first paint if( progress != 1 ) - *mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_BACKGROUND_FIRST; + data.mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_BACKGROUND_FIRST; else { slide = false; @@ -66,28 +66,28 @@ void DesktopGridEffect::prePaintScreen( int* mask, QRegion* region, int time ) // PAINT_SCREEN_BACKGROUND_FIRST is needed because screen will be actually painted more than once, // so with normal screen painting second screen paint would erase parts of the first paint if( progress != 0 ) - *mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_BACKGROUND_FIRST; + data.mask |= PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_BACKGROUND_FIRST; if( !activated && progress == 0 ) finish(); int d = posToDesktop( cursorPos()); if( d != hover_desktop ) { - *region |= desktopRect( hover_desktop, true ); + data.paint |= desktopRect( hover_desktop, true ); hover_desktop = d; - *region |= desktopRect( hover_desktop, true ); + data.paint |= desktopRect( hover_desktop, true ); } } - effects->prePaintScreen( mask, region, time ); + effects->prePaintScreen( data, time ); } -void DesktopGridEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void DesktopGridEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if( slide ) { if( w->isOnAllDesktops()) { if( slide_painting_sticky ) - *mask |= PAINT_WINDOW_TRANSFORMED; + data.mask |= PAINT_WINDOW_TRANSFORMED; else w->disablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP ); } @@ -104,12 +104,12 @@ void DesktopGridEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* pai w->disablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP ); if( w == window_move ) { - *mask |= PAINT_WINDOW_TRANSFORMED; + data.mask |= PAINT_WINDOW_TRANSFORMED; if( w->isOnAllDesktops() && painting_desktop != posToDesktop( window_move_pos - window_move_diff )) w->disablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP ); } } - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void DesktopGridEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) diff --git a/effects/desktopgrid.h b/effects/desktopgrid.h index b8bb58bbb1..dc13a1aeaa 100644 --- a/effects/desktopgrid.h +++ b/effects/desktopgrid.h @@ -23,10 +23,10 @@ class DesktopGridEffect Q_OBJECT public: DesktopGridEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); virtual void postPaintScreen(); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); virtual void windowClosed( EffectWindow* w ); virtual void desktopChanged( int old ); diff --git a/effects/dialogparent.cpp b/effects/dialogparent.cpp index 8195eacd76..c683f642bb 100644 --- a/effects/dialogparent.cpp +++ b/effects/dialogparent.cpp @@ -15,7 +15,7 @@ namespace KWin KWIN_EFFECT( dialogparent, DialogParentEffect ) -void DialogParentEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void DialogParentEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { // How long does it take for the effect to get it's full strength (in ms) const float changeTime = 200; @@ -34,7 +34,7 @@ void DialogParentEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* pa } // Call the next effect - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void DialogParentEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) diff --git a/effects/dialogparent.h b/effects/dialogparent.h index 0bf31c110a..979dfafd48 100644 --- a/effects/dialogparent.h +++ b/effects/dialogparent.h @@ -28,7 +28,7 @@ class DialogParentEffect : public Effect { public: - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + 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 ); diff --git a/effects/drunken.cpp b/effects/drunken.cpp index 4bb1c408e2..cb8ef6ebdc 100644 --- a/effects/drunken.cpp +++ b/effects/drunken.cpp @@ -17,24 +17,24 @@ namespace KWin KWIN_EFFECT( drunken, DrunkenEffect ) -void DrunkenEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void DrunkenEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( !windows.isEmpty()) - *mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; - effects->prePaintScreen( mask, region, time ); + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + effects->prePaintScreen( data, time ); } -void DrunkenEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void DrunkenEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if( windows.contains( w )) { windows[ w ] += time / 1000.; if( windows[ w ] < 1 ) - *mask |= PAINT_WINDOW_TRANSFORMED; + data.mask |= PAINT_WINDOW_TRANSFORMED; else windows.remove( w ); } - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void DrunkenEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) diff --git a/effects/drunken.h b/effects/drunken.h index 0650769274..2b665c4536 100644 --- a/effects/drunken.h +++ b/effects/drunken.h @@ -20,8 +20,8 @@ class DrunkenEffect : public Effect { public: - virtual void prePaintScreen( int* mask, QRegion* region, int time ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + 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 windowAdded( EffectWindow* w ); diff --git a/effects/explosioneffect.cpp b/effects/explosioneffect.cpp index bcdd85891e..71580b6ece 100644 --- a/effects/explosioneffect.cpp +++ b/effects/explosioneffect.cpp @@ -100,17 +100,17 @@ bool ExplosionEffect::loadData() return true; } -void ExplosionEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void ExplosionEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( mActiveAnimations > 0 ) // We need to mark the screen as transformed. Otherwise the whole screen // won't be repainted, resulting in artefacts - *mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; - effects->prePaintScreen(mask, region, time); + effects->prePaintScreen(data, time); } -void ExplosionEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void ExplosionEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if( mWindows.contains( w )) { @@ -121,8 +121,8 @@ void ExplosionEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint mWindows[ w ] += time / 700.0; // complete change in 700ms if( mWindows[ w ] < 1 ) { - *mask |= PAINT_WINDOW_TRANSLUCENT | PAINT_WINDOW_TRANSFORMED; - *mask &= ~PAINT_WINDOW_OPAQUE; + data.mask |= PAINT_WINDOW_TRANSLUCENT | PAINT_WINDOW_TRANSFORMED; + data.mask &= ~PAINT_WINDOW_OPAQUE; w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DELETE ); } else @@ -134,7 +134,7 @@ void ExplosionEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint } } - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void ExplosionEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) diff --git a/effects/explosioneffect.h b/effects/explosioneffect.h index 80cc3d4bdf..b2846cd6aa 100644 --- a/effects/explosioneffect.h +++ b/effects/explosioneffect.h @@ -32,8 +32,8 @@ class ExplosionEffect ExplosionEffect(); ~ExplosionEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); virtual void postPaintScreen(); diff --git a/effects/fade.cpp b/effects/fade.cpp index ed421a245c..c65e70d1a6 100644 --- a/effects/fade.cpp +++ b/effects/fade.cpp @@ -25,17 +25,17 @@ FadeEffect::FadeEffect() fadeWindows = conf.readEntry( "FadeWindows", true ); } -void FadeEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void FadeEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( !windows.isEmpty()) { fadeInStep = time / double( fadeInTime ); fadeOutStep = time / double( fadeOutTime ); } - effects->prePaintScreen( mask, region, time ); + effects->prePaintScreen( data, time ); } -void FadeEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void FadeEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if( windows.contains( w )) { @@ -43,8 +43,8 @@ void FadeEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRe windows[ w ].fadeOutStep += fadeOutStep; if( windows[ w ].opacity < 1.0 ) { - *mask &= ~PAINT_WINDOW_OPAQUE; - *mask |= PAINT_WINDOW_TRANSLUCENT; + data.mask &= ~PAINT_WINDOW_OPAQUE; + data.mask |= PAINT_WINDOW_TRANSLUCENT; } if( windows[ w ].deleted ) { @@ -57,7 +57,7 @@ void FadeEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRe w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DELETE ); } } - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); if( windows.contains( w ) && !w->isPaintingEnabled()) { // if the window isn't to be painted, then let's make sure // to track its progress diff --git a/effects/fade.h b/effects/fade.h index d749550973..0b2f20ae9b 100644 --- a/effects/fade.h +++ b/effects/fade.h @@ -21,8 +21,8 @@ class FadeEffect { public: FadeEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); // TODO react also on virtual desktop changes diff --git a/effects/fallapart.cpp b/effects/fallapart.cpp index 46a62e398c..2e1e09e10f 100644 --- a/effects/fallapart.cpp +++ b/effects/fallapart.cpp @@ -18,24 +18,24 @@ namespace KWin KWIN_EFFECT( fallapart, FallApartEffect ) -void FallApartEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void FallApartEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( !windows.isEmpty()) - *mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; - effects->prePaintScreen(mask, region, time); + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + effects->prePaintScreen(data, time); } -void FallApartEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void FallApartEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if( windows.contains( w )) { if( windows[ w ] < 1 ) { windows[ w ] += time / 1000.; - *mask |= PAINT_WINDOW_TRANSFORMED; + data.mask |= PAINT_WINDOW_TRANSFORMED; w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DELETE ); // Request the window to be divided into cells - w->requestVertexGrid( 40 ); + data.quads = data.quads.makeGrid( 40 ); } else { @@ -43,22 +43,20 @@ void FallApartEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint w->unrefWindow(); } } - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void FallApartEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) { if( windows.contains( w )) { - QVector< Vertex >& vertices = w->vertices(); - assert( vertices.count() % 4 == 0 ); - for( int i = 0; - i < vertices.count(); - i += 4 ) + WindowQuadList new_quads; + int cnt = 0; + foreach( WindowQuad quad, data.quads ) { // make fragments move in various directions, based on where // they are (left pieces generally move to the left, etc.) - QPointF p1( vertices[ i ].pos[ 0 ], vertices[ i ].pos[ 1 ] ); + QPointF p1( quad[ 0 ].x(), quad[ 0 ].y()); double xdiff = 0; if( p1.x() < w->width() / 2 ) xdiff = -( w->width() / 2 - p1.x()) / w->width() * 100; @@ -70,38 +68,36 @@ void FallApartEffect::paintWindow( EffectWindow* w, int mask, QRegion region, Wi if( p1.y() > w->height() / 2 ) ydiff = ( p1.y() - w->height() / 2 ) / w->height() * 100; double modif = windows[ w ] * windows[ w ] * 64; - srandom( i ); // change direction randomly but consistently + srandom( cnt ); // change direction randomly but consistently xdiff += ( rand() % 21 - 10 ); ydiff += ( rand() % 21 - 10 ); for( int j = 0; j < 4; ++j ) { - vertices[ i + j ].pos[ 0 ] += xdiff * modif; - vertices[ i + j ].pos[ 1 ] += ydiff * modif; + quad[ j ].move( quad[ j ].x() + xdiff * modif, quad[ j ].y() + ydiff * modif ); } // also make the fragments rotate around their center - QPointF center(( vertices[ i ].pos[ 0 ] + vertices[ i + 1 ].pos[ 0 ] - + vertices[ i + 2 ].pos[ 0 ] + vertices[ i + 3 ].pos[ 0 ] ) / 4, - ( vertices[ i ].pos[ 1 ] + vertices[ i + 1 ].pos[ 1 ] - + vertices[ i + 2 ].pos[ 1 ] + vertices[ i + 3 ].pos[ 1 ] ) / 4 ); + QPointF center(( quad[ 0 ].x() + quad[ 1 ].x() + quad[ 2 ].x() + quad[ 3 ].x()) / 4, + ( quad[ 0 ].y() + quad[ 1 ].y() + quad[ 2 ].y() + quad[ 3 ].y()) / 4 ); double adiff = ( rand() % 720 - 360 ) / 360. * 2 * M_PI; // spin randomly for( int j = 0; j < 4; ++j ) { - double x = vertices[ i + j ].pos[ 0 ] - center.x(); - double y = vertices[ i + j ].pos[ 1 ] - center.y(); + double x = quad[ j ].x() - center.x(); + double y = quad[ j ].y() - center.y(); double angle = atan2( y, x ); angle += windows[ w ] * adiff; double dist = sqrt( x * x + y * y ); x = dist * cos( angle ); y = dist * sin( angle ); - vertices[ i + j ].pos[ 0 ] = center.x() + x; - vertices[ i + j ].pos[ 1 ] = center.y() + y; + quad[ j ].move( center.x() + x, center.y() + y ); } - w->markVerticesDirty(); + new_quads.append( quad ); + ++cnt; } + data.quads = new_quads; } effects->paintWindow( w, mask, region, data ); } diff --git a/effects/fallapart.h b/effects/fallapart.h index 6161690a95..90f399aace 100644 --- a/effects/fallapart.h +++ b/effects/fallapart.h @@ -20,8 +20,8 @@ class FallApartEffect : public Effect { public: - virtual void prePaintScreen( int* mask, QRegion* region, int time ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); virtual void postPaintScreen(); virtual void windowClosed( EffectWindow* c ); diff --git a/effects/flame.cpp b/effects/flame.cpp index e02b5184a1..d875123bd6 100644 --- a/effects/flame.cpp +++ b/effects/flame.cpp @@ -11,30 +11,30 @@ License. See the file "COPYING" for the exact licensing terms. #include "flame.h" #include +#include namespace KWin { KWIN_EFFECT( flame, FlameEffect ) -void FlameEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void FlameEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( !windows.isEmpty()) - *mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; - effects->prePaintScreen(mask, region, time); + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + effects->prePaintScreen(data, time); } -void FlameEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void FlameEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if( windows.contains( w )) { if( windows[ w ] < 1 ) { windows[ w ] += time / 500.; - *mask |= PAINT_WINDOW_TRANSFORMED; + data.mask |= PAINT_WINDOW_TRANSFORMED; w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DELETE ); - // Request the window to be divided into cells - w->requestVertexGrid( qMax( w->height() / 50, 5 )); + data.quads = data.quads.splitAtY( windows[ w ] * w->height()); } else { @@ -42,41 +42,24 @@ void FlameEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QR w->unrefWindow(); } } - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void FlameEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) { if( windows.contains( w )) { - QVector< Vertex >& vertices = w->vertices(); - QVector< Vertex > new_vertices; - double ylimit = windows[ w ] * w->height(); // parts above this are already away - assert( vertices.count() % 4 == 0 ); - for( int i = 0; - i < vertices.count(); - i += 4 ) + WindowQuadList new_quads; + float ylimit = windows[ w ] * w->height(); // parts above this are already away + foreach( WindowQuad quad, data.quads ) { - bool is_in = false; - for( int j = 0; - j < 4; - ++j ) - if( vertices[ i + j ].pos[ 1 ] >= ylimit ) - is_in = true; - if( !is_in ) + if( quad.bottom() <= ylimit ) continue; - for( int j = 0; - j < 4; - ++j ) - { - Vertex vertex = vertices[ i + j ]; - new_vertices.append( vertex ); - } + new_quads.append( quad ); } - if( new_vertices.isEmpty()) + if( new_quads.isEmpty()) return; // nothing to paint - w->vertices() = new_vertices; - w->markVerticesDirty(); + data.quads = new_quads; } effects->paintWindow( w, mask, region, data ); } diff --git a/effects/flame.h b/effects/flame.h index b7b577da5a..ee3ac7da53 100644 --- a/effects/flame.h +++ b/effects/flame.h @@ -20,8 +20,8 @@ class FlameEffect : public Effect { public: - virtual void prePaintScreen( int* mask, QRegion* region, int time ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + 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 windowClosed( EffectWindow* c ); diff --git a/effects/howto.cpp b/effects/howto.cpp index b05cdcc0e1..8976424ab9 100644 --- a/effects/howto.cpp +++ b/effects/howto.cpp @@ -36,7 +36,7 @@ KWIN_EFFECT( howto, HowtoEffect ) // region - the region of the screen that needs to be painted, support for modifying it // is not fully implemented yet, do not use // time - time in milliseconds since the last paint, useful for animations -void HowtoEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void HowtoEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { // Is this window the one that is going to be faded out and in again? if( w == fade_window ) @@ -49,8 +49,8 @@ void HowtoEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QR { // Since the effect will make the window translucent, explicitly change // the flags so that the window will be painted only as translucent. - *mask |= PAINT_WINDOW_TRANSLUCENT; - *mask &= ~PAINT_WINDOW_OPAQUE; + data.mask |= PAINT_WINDOW_TRANSLUCENT; + data.mask &= ~PAINT_WINDOW_OPAQUE; } else { @@ -61,7 +61,7 @@ void HowtoEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QR } // Call the next effect (or the actual window painting code if this is the last effect). // Effects are chained and they all modify something if needed and then call the next one. - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } // The function that handles the actual painting. Some simple modifications are possible diff --git a/effects/howto.h b/effects/howto.h index b7e4499fa4..50b9ea2255 100644 --- a/effects/howto.h +++ b/effects/howto.h @@ -38,7 +38,7 @@ class HowtoEffect // A pre-paint function. It tells the compositing code how the painting will // be affected by this effect. - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); // A paint function. It actually performs the modifications to the painting. virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); diff --git a/effects/magnifier.cpp b/effects/magnifier.cpp index c1547ac7a2..295b475c49 100644 --- a/effects/magnifier.cpp +++ b/effects/magnifier.cpp @@ -42,7 +42,7 @@ MagnifierEffect::MagnifierEffect() magnifier_size = QSize( 200, 200 ); // TODO config option } -void MagnifierEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void MagnifierEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( zoom != target_zoom ) { @@ -52,8 +52,8 @@ void MagnifierEffect::prePaintScreen( int* mask, QRegion* region, int time ) else zoom = qMax( zoom * qMin( 1 - diff, 0.8 ), target_zoom ); } - effects->prePaintScreen( mask, region, time ); - *region |= magnifierArea().adjusted( -FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH ); + effects->prePaintScreen( data, time ); + data.paint |= magnifierArea().adjusted( -FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH ); } void MagnifierEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) diff --git a/effects/magnifier.h b/effects/magnifier.h index 04da5b7796..548bbe7e12 100644 --- a/effects/magnifier.h +++ b/effects/magnifier.h @@ -22,7 +22,7 @@ class MagnifierEffect Q_OBJECT public: MagnifierEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); virtual void postPaintScreen(); virtual void mouseChanged( const QPoint& pos, const QPoint& old, diff --git a/effects/maketransparent.cpp b/effects/maketransparent.cpp index 51748c1e59..869294314f 100644 --- a/effects/maketransparent.cpp +++ b/effects/maketransparent.cpp @@ -15,14 +15,14 @@ namespace KWin KWIN_EFFECT( maketransparent, MakeTransparentEffect ) -void MakeTransparentEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void MakeTransparentEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if(( w->isUserMove() || w->isUserResize()) || w->isDialog()) { - *mask |= PAINT_WINDOW_TRANSLUCENT; - *mask &= ~PAINT_WINDOW_OPAQUE; + data.mask |= PAINT_WINDOW_TRANSLUCENT; + data.mask &= ~PAINT_WINDOW_OPAQUE; } - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void MakeTransparentEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) diff --git a/effects/maketransparent.h b/effects/maketransparent.h index 3d532b99b0..a188655e2b 100644 --- a/effects/maketransparent.h +++ b/effects/maketransparent.h @@ -21,7 +21,7 @@ class MakeTransparentEffect { public: virtual void windowUserMovedResized( EffectWindow* c, bool first, bool last ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); }; diff --git a/effects/minimizeanimation.cpp b/effects/minimizeanimation.cpp index 8b63564f46..d9365597a2 100644 --- a/effects/minimizeanimation.cpp +++ b/effects/minimizeanimation.cpp @@ -22,17 +22,17 @@ MinimizeAnimationEffect::MinimizeAnimationEffect() } -void MinimizeAnimationEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void MinimizeAnimationEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( mActiveAnimations > 0 ) // We need to mark the screen windows as transformed. Otherwise the // whole screen won't be repainted, resulting in artefacts - *mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; - effects->prePaintScreen(mask, region, time); + effects->prePaintScreen(data, time); } -void MinimizeAnimationEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void MinimizeAnimationEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { const float changeTime = 500; if( mAnimationProgress.contains( w )) @@ -55,7 +55,7 @@ void MinimizeAnimationEffect::prePaintWindow( EffectWindow* w, int* mask, QRegio if( mAnimationProgress.contains( w )) { // We'll transform this window - *mask |= PAINT_WINDOW_TRANSFORMED; + data.mask |= PAINT_WINDOW_TRANSFORMED; w->enablePainting( EffectWindow::PAINT_DISABLED_BY_MINIMIZE ); } else @@ -63,7 +63,7 @@ void MinimizeAnimationEffect::prePaintWindow( EffectWindow* w, int* mask, QRegio mActiveAnimations--; } - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void MinimizeAnimationEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) diff --git a/effects/minimizeanimation.h b/effects/minimizeanimation.h index 5aeb4cfc03..4e67e0f8aa 100644 --- a/effects/minimizeanimation.h +++ b/effects/minimizeanimation.h @@ -27,8 +27,8 @@ class MinimizeAnimationEffect public: MinimizeAnimationEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); virtual void postPaintScreen(); diff --git a/effects/presentwindows.cpp b/effects/presentwindows.cpp index a413e2f242..df16a13657 100644 --- a/effects/presentwindows.cpp +++ b/effects/presentwindows.cpp @@ -69,7 +69,7 @@ PresentWindowsEffect::~PresentWindowsEffect() } -void PresentWindowsEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void PresentWindowsEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { // How long does it take for the effect to get it's full strength (in ms) const float changeTime = 300; @@ -89,25 +89,25 @@ void PresentWindowsEffect::prePaintScreen( int* mask, QRegion* region, int time // We need to mark the screen windows as transformed. Otherwise the whole // screen won't be repainted, resulting in artefacts if( mActiveness > 0.0f ) - *mask |= Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + data.mask |= Effect::PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; - effects->prePaintScreen(mask, region, time); + effects->prePaintScreen(data, time); } -void PresentWindowsEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void PresentWindowsEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if( mActiveness > 0.0f ) { if( mWindowData.contains(w) ) { // This window will be transformed by the effect - *mask |= Effect::PAINT_WINDOW_TRANSFORMED; + data.mask |= Effect::PAINT_WINDOW_TRANSFORMED; w->enablePainting( EffectWindow::PAINT_DISABLED_BY_MINIMIZE ); w->enablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP ); // If it's minimized window or on another desktop and effect is not // fully active, then apply some transparency if( mActiveness < 1.0f && (w->isMinimized() || !w->isOnCurrentDesktop() )) - *mask |= Effect::PAINT_WINDOW_TRANSLUCENT; + data.mask |= Effect::PAINT_WINDOW_TRANSLUCENT; // Change window's hover according to cursor pos WindowData& windata = mWindowData[w]; const float hoverchangetime = 200; @@ -119,7 +119,7 @@ void PresentWindowsEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* else if( !w->isDesktop()) w->disablePainting( EffectWindow::PAINT_DISABLED ); } - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void PresentWindowsEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) diff --git a/effects/presentwindows.h b/effects/presentwindows.h index 68784b1545..903a925c57 100644 --- a/effects/presentwindows.h +++ b/effects/presentwindows.h @@ -36,8 +36,8 @@ class PresentWindowsEffect PresentWindowsEffect(); virtual ~PresentWindowsEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); virtual void postPaintScreen(); diff --git a/effects/scalein.cpp b/effects/scalein.cpp index 8535d1ed92..4572ec439f 100644 --- a/effects/scalein.cpp +++ b/effects/scalein.cpp @@ -15,24 +15,24 @@ namespace KWin KWIN_EFFECT( scalein, ScaleInEffect ) -void ScaleInEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void ScaleInEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( !windows.isEmpty()) - *mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; - effects->prePaintScreen( mask, region, time ); + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + effects->prePaintScreen( data, time ); } -void ScaleInEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void ScaleInEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { if( windows.contains( w )) { windows[ w ] += time / 500.; // complete change in 500ms if( windows[ w ] < 1 ) - *mask |= PAINT_WINDOW_TRANSFORMED; + data.mask |= PAINT_WINDOW_TRANSFORMED; else windows.remove( w ); } - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void ScaleInEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) diff --git a/effects/scalein.h b/effects/scalein.h index 524d7f9ce6..a687043973 100644 --- a/effects/scalein.h +++ b/effects/scalein.h @@ -20,8 +20,8 @@ class ScaleInEffect : public Effect { public: - virtual void prePaintScreen( int* mask, QRegion* region, int time ); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); + 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 ); // TODO react also on virtual desktop changes diff --git a/effects/shadow.cpp b/effects/shadow.cpp index f49b44101b..84ce7c78a0 100644 --- a/effects/shadow.cpp +++ b/effects/shadow.cpp @@ -37,11 +37,11 @@ QRect ShadowEffect::shadowRectangle(const QRect& windowRectangle) const return windowRectangle.adjusted( shadowXOffset - shadowFuzzyness - 20, shadowYOffset - shadowFuzzyness - 20, shadowXOffset + shadowFuzzyness + 20, shadowYOffset + shadowFuzzyness + 20); } -void ShadowEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void ShadowEffect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { - *mask |= PAINT_WINDOW_TRANSLUCENT; - *paint |= QRegion( shadowRectangle( ( QRegion( w->geometry()) & *paint ).boundingRect() )); - effects->prePaintWindow( w, mask, paint, clip, time ); + data.mask |= PAINT_WINDOW_TRANSLUCENT; + data.paint |= QRegion( shadowRectangle( ( QRegion( w->geometry()) & data.paint ).boundingRect() )); + effects->prePaintWindow( w, data, time ); } void ShadowEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) diff --git a/effects/shadow.h b/effects/shadow.h index 96ee3e972b..85b0e38216 100644 --- a/effects/shadow.h +++ b/effects/shadow.h @@ -24,7 +24,7 @@ class ShadowEffect { public: ShadowEffect(); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + 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 QRect transformWindowDamage( EffectWindow* w, const QRect& r ); diff --git a/effects/showfps.cpp b/effects/showfps.cpp index 262af3b0b3..44f0788846 100644 --- a/effects/showfps.cpp +++ b/effects/showfps.cpp @@ -57,7 +57,7 @@ ShowFpsEffect::ShowFpsEffect() y = displayHeight() - MAX_TIME - y; } -void ShowFpsEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void ShowFpsEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( time == 0 ) { // TODO optimized away @@ -66,8 +66,8 @@ void ShowFpsEffect::prePaintScreen( int* mask, QRegion* region, int time ) frames[ frames_pos ] = t.minute() * 60000 + t.second() * 1000 + t.msec(); if( ++frames_pos == MAX_FPS ) frames_pos = 0; - effects->prePaintScreen( mask, region, time ); - *region += QRect( x, y, FPS_WIDTH + NUM_PAINTS, MAX_TIME ); + effects->prePaintScreen( data, time ); + data.paint += QRect( x, y, FPS_WIDTH + NUM_PAINTS, MAX_TIME ); } void ShowFpsEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) diff --git a/effects/showfps.h b/effects/showfps.h index f1dc375afd..e85dc98381 100644 --- a/effects/showfps.h +++ b/effects/showfps.h @@ -23,7 +23,7 @@ class ShowFpsEffect { public: ShowFpsEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); virtual void postPaintScreen(); private: diff --git a/effects/test_fbo.cpp b/effects/test_fbo.cpp index d3c40be41e..31ae10156b 100644 --- a/effects/test_fbo.cpp +++ b/effects/test_fbo.cpp @@ -48,16 +48,16 @@ bool TestFBOEffect::supported() } -void TestFBOEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void TestFBOEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if(mValid) { - *mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; // Start rendering to texture effects->pushRenderTarget(mRenderTarget); } - effects->prePaintScreen(mask, region, time); + effects->prePaintScreen(data, time); } void TestFBOEffect::postPaintScreen() diff --git a/effects/test_fbo.h b/effects/test_fbo.h index 523ffda064..9b7eff1c33 100644 --- a/effects/test_fbo.h +++ b/effects/test_fbo.h @@ -31,7 +31,7 @@ class TestFBOEffect : public Effect TestFBOEffect(); ~TestFBOEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void postPaintScreen(); static bool supported(); diff --git a/effects/test_input.cpp b/effects/test_input.cpp index 9bfe38edeb..9eb94ffec0 100644 --- a/effects/test_input.cpp +++ b/effects/test_input.cpp @@ -41,10 +41,10 @@ TestInputEffect::~TestInputEffect() effects->destroyInputWindow( input ); } -void TestInputEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void TestInputEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { - *mask |= PAINT_SCREEN_TRANSFORMED; - effects->prePaintScreen( mask, region, time ); + data.mask |= PAINT_SCREEN_TRANSFORMED; + effects->prePaintScreen( data, time ); } void TestInputEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) diff --git a/effects/test_input.h b/effects/test_input.h index 7f984bbbe7..bfb814f306 100644 --- a/effects/test_input.h +++ b/effects/test_input.h @@ -28,7 +28,7 @@ class TestInputEffect public: TestInputEffect(); virtual ~TestInputEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); virtual void windowInputMouseEvent( Window w, QEvent* e ); private: diff --git a/effects/trackmouse.cpp b/effects/trackmouse.cpp index e5ed016f92..3ea9d50a82 100644 --- a/effects/trackmouse.cpp +++ b/effects/trackmouse.cpp @@ -43,11 +43,11 @@ TrackMouseEffect::~TrackMouseEffect() delete texture; } -void TrackMouseEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void TrackMouseEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( active ) angle = ( angle + time / 10 ) % 360; - effects->prePaintScreen( mask, region, time ); + effects->prePaintScreen( data, time ); } void TrackMouseEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) diff --git a/effects/trackmouse.h b/effects/trackmouse.h index bdd12dc09e..d07bfe8d61 100644 --- a/effects/trackmouse.h +++ b/effects/trackmouse.h @@ -23,7 +23,7 @@ class TrackMouseEffect public: TrackMouseEffect(); virtual ~TrackMouseEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); virtual void postPaintScreen(); virtual void mouseChanged( const QPoint& pos, const QPoint& old, diff --git a/effects/zoom.cpp b/effects/zoom.cpp index 16998a4855..965fe776fe 100644 --- a/effects/zoom.cpp +++ b/effects/zoom.cpp @@ -33,7 +33,7 @@ ZoomEffect::ZoomEffect() a->setGlobalShortcut(KShortcut(Qt::META + Qt::Key_0)); } -void ZoomEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void ZoomEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { if( zoom != target_zoom ) { @@ -44,8 +44,8 @@ void ZoomEffect::prePaintScreen( int* mask, QRegion* region, int time ) zoom = qMax( zoom * qMin( 1 - diff, 0.8 ), target_zoom ); } if( zoom != 1.0 ) - *mask |= PAINT_SCREEN_TRANSFORMED; - effects->prePaintScreen( mask, region, time ); + data.mask |= PAINT_SCREEN_TRANSFORMED; + effects->prePaintScreen( data, time ); } void ZoomEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) diff --git a/effects/zoom.h b/effects/zoom.h index 1d9351ebf1..f198b7391f 100644 --- a/effects/zoom.h +++ b/effects/zoom.h @@ -22,7 +22,7 @@ class ZoomEffect Q_OBJECT public: ZoomEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); virtual void postPaintScreen(); virtual void mouseChanged( const QPoint& pos, const QPoint& old, diff --git a/lib/kwineffects.cpp b/lib/kwineffects.cpp index 03950c2586..8e5aacc628 100644 --- a/lib/kwineffects.cpp +++ b/lib/kwineffects.cpp @@ -125,9 +125,9 @@ void Effect::mouseChanged( const QPoint&, const QPoint&, Qt::MouseButtons, Qt::K { } -void Effect::prePaintScreen( int* mask, QRegion* region, int time ) +void Effect::prePaintScreen( ScreenPrePaintData& data, int time ) { - effects->prePaintScreen( mask, region, time ); + effects->prePaintScreen( data, time ); } void Effect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) @@ -140,9 +140,9 @@ void Effect::postPaintScreen() effects->postPaintScreen(); } -void Effect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) +void Effect::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ) { - effects->prePaintWindow( w, mask, paint, clip, time ); + effects->prePaintWindow( w, data, time ); } void Effect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) @@ -289,5 +289,157 @@ EffectWindowGroup::~EffectWindowGroup() { } +/*************************************************************** + WindowQuad +***************************************************************/ + +WindowQuad WindowQuad::makeSubQuad( float x1, float y1, float x2, float y2 ) const + { + assert( x1 < x2 && y1 < y2 && x1 >= left() && x2 <= right() && y1 >= top() && y2 <= bottom()); + WindowQuad ret( *this ); + ret.verts[ 0 ].px = x1; + ret.verts[ 3 ].px = x1; + ret.verts[ 1 ].px = x2; + ret.verts[ 2 ].px = x2; + ret.verts[ 0 ].py = y1; + ret.verts[ 1 ].py = y1; + ret.verts[ 2 ].py = y2; + ret.verts[ 3 ].py = y2; + float tleft = ( x1 - left()) / ( right() - left()) * ( textureRight() - textureLeft()) + textureLeft(); + float tright = ( x2 - left()) / ( right() - left()) * ( textureRight() - textureLeft()) + textureLeft(); + float ttop = ( y1 - top()) / ( bottom() - top()) * ( textureBottom() - textureTop()) + textureTop(); + float tbottom = ( y2 - top()) / ( bottom() - top()) * ( textureBottom() - textureTop()) + textureTop(); + ret.verts[ 0 ].tx = tleft; + ret.verts[ 3 ].tx = tleft; + ret.verts[ 1 ].tx = tright; + ret.verts[ 2 ].tx = tright; + ret.verts[ 0 ].ty = ttop; + ret.verts[ 1 ].ty = ttop; + ret.verts[ 2 ].ty = tbottom; + ret.verts[ 3 ].ty = tbottom; + return ret; + } + +/*************************************************************** + WindowQuadList +***************************************************************/ + +WindowQuadList WindowQuadList::splitAtX( float x ) const + { + WindowQuadList ret; + foreach( WindowQuad quad, *this ) + { + bool wholeleft = true; + bool wholeright = true; + for( int i = 0; + i < 4; + ++i ) + { + if( quad[ i ].x() < x ) + wholeright = false; + if( quad[ i ].x() >= x ) + wholeleft = false; + } + if( wholeleft || wholeright ) // is whole in one split part + { + ret.append( quad ); + continue; + } + ret.append( quad.makeSubQuad( quad.left(), quad.top(), x, quad.bottom())); + ret.append( quad.makeSubQuad( x, quad.top(), quad.right(), quad.bottom())); + } + return ret; + } + +WindowQuadList WindowQuadList::splitAtY( float y ) const + { + WindowQuadList ret; + foreach( WindowQuad quad, *this ) + { + bool wholetop = true; + bool wholebottom = true; + for( int i = 0; + i < 4; + ++i ) + { + if( quad[ i ].y() < y ) + wholebottom = false; + if( quad[ i ].y() >= y ) + wholetop = false; + } + if( wholetop || wholebottom ) // is whole in one split part + { + ret.append( quad ); + continue; + } + ret.append( quad.makeSubQuad( quad.left(), quad.top(), quad.right(), y )); + ret.append( quad.makeSubQuad( quad.left(), y, quad.right(), quad.bottom())); + } + return ret; + } + +WindowQuadList WindowQuadList::makeGrid( int maxquadsize ) const + { + if( empty()) + return *this; + // find the bounding rectangle + float left = first().left(); + float right = first().right(); + float top = first().top(); + float bottom = first().bottom(); + foreach( WindowQuad quad, *this ) + { + left = qMin( left, quad.left()); + right = qMax( right, quad.right()); + top = qMin( top, quad.top()); + bottom = qMax( bottom, quad.bottom()); + } + WindowQuadList ret; + for( float x = left; + x < right; + x += maxquadsize ) + { + for( float y = top; + y < bottom; + y += maxquadsize ) + { + foreach( WindowQuad quad, *this ) + { + if( QRectF( QPointF( quad.left(), quad.top()), QPointF( quad.right(), quad.bottom())) + .intersects( QRectF( x, y, maxquadsize, maxquadsize ))) + { + ret.append( quad.makeSubQuad( qMax( x, quad.left()), qMax( y, quad.top()), + qMin( quad.right(), x + maxquadsize ), qMin( quad.bottom(), y + maxquadsize ))); + } + } + } + } + return ret; + } + +void WindowQuadList::makeArrays( float** vertices, float** texcoords ) + { + *vertices = new float[ count() * 4 * 2 ]; + *texcoords = new float[ count() * 4 * 2 ]; + float* vpos = *vertices; + float* tpos = *texcoords; + for( int i = 0; + i < count(); + ++i ) + for( int j = 0; + j < 4; + ++j ) + { + *vpos++ = at( i )[ j ].x(); + *vpos++ = at( i )[ j ].y(); + *tpos++ = at( i )[ j ].textureX(); + *tpos++ = at( i )[ j ].textureY(); + } + } + +bool WindowQuadList::smoothNeeded() const + { + return false; // TODO + } } // namespace diff --git a/lib/kwineffects.h b/lib/kwineffects.h index 229d10f98d..188b384a6c 100644 --- a/lib/kwineffects.h +++ b/lib/kwineffects.h @@ -23,7 +23,7 @@ License. See the file "COPYING" for the exact licensing terms. #include #include -#include +#include class KLibrary; class KConfigGroup; @@ -36,9 +36,14 @@ namespace KWin class EffectWindow; class EffectWindowGroup; class Effect; -class Vertex; +class WindowQuad; class GLRenderTarget; class GLShader; +class WindowQuadList; +class WindowPrePaintData; +class WindowPaintData; +class ScreenPrePaintData; +class ScreenPaintData; typedef QPair< QString, Effect* > EffectPair; typedef QPair< Effect*, Window > InputWindowPair; @@ -72,10 +77,10 @@ class KWIN_EXPORT Effect Effect(); virtual ~Effect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ); virtual void postPaintScreen(); - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ); + virtual void prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time ); // paintWindow() can do various transformations virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); virtual void postPaintWindow( EffectWindow* w ); @@ -165,10 +170,10 @@ class KWIN_EXPORT EffectsHandler EffectsHandler(CompositingType type); virtual ~EffectsHandler(); // for use by effects - virtual void prePaintScreen( int* mask, QRegion* region, int time ) = 0; + virtual void prePaintScreen( ScreenPrePaintData& data, int time ) = 0; virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data ) = 0; virtual void postPaintScreen() = 0; - virtual void prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) = 0; + 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 drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ) = 0; @@ -335,14 +340,6 @@ class KWIN_EXPORT EffectWindow virtual EffectWindow* findModal() = 0; virtual EffectWindowList mainWindows() const = 0; - virtual QVector& vertices() = 0; - // Can be called in pre-paint pass. Makes sure that all quads that the - // window consists of are not bigger than maxquadsize x maxquadsize - // (in pixels) in the following paint pass. - virtual void requestVertexGrid(int maxquadsize) = 0; - // Marks vertices of the window as dirty. Call this if you change - // position of the vertices - virtual void markVerticesDirty() = 0; virtual void setShader(GLShader* shader) = 0; }; @@ -355,28 +352,265 @@ class KWIN_EXPORT EffectWindowGroup /** * @short Vertex class - * Vertex has position and texture coordinate which are equal at first, - * however effects can e.g. modify position to move the window or part of it. + * A vertex is one position in a window. WindowQuad consists of four WindowVertex objects + * and represents one part of a window. **/ -class KWIN_EXPORT Vertex -{ +class KWIN_EXPORT WindowVertex + { public: - Vertex() {} - Vertex(float x, float y) - { - pos[0] = texcoord[0] = x; pos[1] = texcoord[1] = y; pos[2] = 0.0f; - } - Vertex(float x, float y, float u, float v) - { - pos[0] = x; pos[1] = y; pos[2] = 0.0f; texcoord[0] = u; texcoord[1] = v; - } - float pos[3]; - float texcoord[2]; -}; + float x() const; + float y() const; + void move( float x, float y ); + void setX( float x ); + void setY( float y ); + float textureX() const; + float textureY() const; + WindowVertex(); + WindowVertex( float x, float y, float tx, float ty ); + private: + friend class WindowQuad; + float px, py; // position + float tx, ty; // texture coords + }; + +/** + * @short Class representing one area of a window. + * WindowQuads consists of four WindowVertex objects and represents one part of a window. + */ +class KWIN_EXPORT WindowQuad + { + public: + WindowQuad(); + WindowQuad makeSubQuad( float x1, float y1, float x2, float y2 ) const; + WindowVertex& operator[]( int index ); + const WindowVertex& operator[]( int index ) const; + // these 8 work only with untransformed quads + float left() const; + float right() const; + float top() const; + float bottom() const; + float textureLeft() const; + float textureRight() const; + float textureTop() const; + float textureBottom() const; + private: + void checkUntransformed() const; + WindowVertex verts[ 4 ]; + }; + +class KWIN_EXPORT WindowQuadList + : public QList< WindowQuad > + { + public: + WindowQuadList splitAtX( float x ) const; + WindowQuadList splitAtY( float y ) const; + WindowQuadList makeGrid( int maxquadsize ) const; + bool smoothNeeded() const; + void makeArrays( float** vertices, float** texcoords ); + }; + +class KWIN_EXPORT WindowPrePaintData + { + public: + int mask; + QRegion paint; + QRegion clip; + WindowQuadList quads; + }; + +class KWIN_EXPORT WindowPaintData + { + public: + WindowPaintData(); + /** + * Window opacity, in range 0 = transparent to 1 = fully opaque + */ + double opacity; + double xScale; + double yScale; + int xTranslate; + int yTranslate; + /** + * Saturation of the window, in range [0; 1] + * 1 means that the window is unchanged, 0 means that it's completely + * unsaturated (greyscale). 0.5 would make the colors less intense, + * but not completely grey + **/ + float saturation; + /** + * Brightness of the window, in range [0; 1] + * 1 means that the window is unchanged, 0 means that it's completely + * black. 0.5 would make it 50% darker than usual + **/ + float brightness; + WindowQuadList quads; + }; + +class KWIN_EXPORT ScreenPaintData + { + public: + ScreenPaintData(); + double xScale; + double yScale; + int xTranslate; + int yTranslate; + }; + +class KWIN_EXPORT ScreenPrePaintData + { + public: + int mask; + QRegion paint; + }; extern KWIN_EXPORT EffectsHandler* effects; +/*************************************************************** + WindowVertex +***************************************************************/ +inline +WindowVertex::WindowVertex() + : px( 0 ), py( 0 ), tx( 0 ), ty( 0 ) + { + } + +inline +WindowVertex::WindowVertex( float _x, float _y, float _tx, float _ty ) + : px( _x ), py( _y ), tx( _tx ), ty( _ty ) + { + } + +inline +float WindowVertex::x() const + { + return px; + } + +inline +float WindowVertex::y() const + { + return py; + } + +inline +void WindowVertex::move( float x, float y ) + { + px = x; + py = y; + } + +inline +void WindowVertex::setX( float x ) + { + px = x; + } + +inline +void WindowVertex::setY( float y ) + { + py = y; + } + +inline +float WindowVertex::textureX() const + { + return tx; + } + +inline +float WindowVertex::textureY() const + { + return ty; + } + +/*************************************************************** + WindowQuad +***************************************************************/ + +inline +WindowQuad::WindowQuad() + { + } + +inline +WindowVertex& WindowQuad::operator[]( int index ) + { + assert( index >= 0 && index < 4 ); + return verts[ index ]; + } + +inline +const WindowVertex& WindowQuad::operator[]( int index ) const + { + assert( index >= 0 && index < 4 ); + return verts[ index ]; + } + +inline +void WindowQuad::checkUntransformed() const + { + assert( verts[ 0 ].py == verts[ 1 ].py && verts[ 2 ].py == verts[ 3 ].py + && verts[ 0 ].px == verts[ 3 ].px && verts[ 1 ].px == verts[ 2 ].px ); + assert( verts[ 0 ].ty == verts[ 1 ].ty && verts[ 2 ].ty == verts[ 3 ].ty + && verts[ 0 ].tx == verts[ 3 ].tx && verts[ 1 ].tx == verts[ 2 ].tx ); + } + +inline +float WindowQuad::left() const + { + checkUntransformed(); + return verts[ 0 ].px; + } + +inline +float WindowQuad::right() const + { + checkUntransformed(); + return verts[ 2 ].px; + } + +inline +float WindowQuad::top() const + { + checkUntransformed(); + return verts[ 0 ].py; + } + +inline +float WindowQuad::bottom() const + { + checkUntransformed(); + return verts[ 2 ].py; + } + +inline +float WindowQuad::textureLeft() const + { + checkUntransformed(); + return verts[ 0 ].tx; + } + +inline +float WindowQuad::textureRight() const + { + checkUntransformed(); + return verts[ 2 ].tx; + } + +inline +float WindowQuad::textureTop() const + { + checkUntransformed(); + return verts[ 0 ].ty; + } + +inline +float WindowQuad::textureBottom() const + { + checkUntransformed(); + return verts[ 2 ].ty; + } } // namespace diff --git a/lib/kwinglobals.h b/lib/kwinglobals.h index 332e675de0..5d54319166 100644 --- a/lib/kwinglobals.h +++ b/lib/kwinglobals.h @@ -13,6 +13,7 @@ License. See the file "COPYING" for the exact licensing terms. #include #include +#include #include @@ -64,43 +65,6 @@ enum ElectricBorder // DesktopListMode lists them in the order created. enum TabBoxMode { TabBoxDesktopMode, TabBoxDesktopListMode, TabBoxWindowsMode }; -class KWIN_EXPORT WindowPaintData - { - public: - WindowPaintData(); - /** - * Window opacity, in range 0 = transparent to 1 = fully opaque - */ - double opacity; - double xScale; - double yScale; - int xTranslate; - int yTranslate; - /** - * Saturation of the window, in range [0; 1] - * 1 means that the window is unchanged, 0 means that it's completely - * unsaturated (greyscale). 0.5 would make the colors less intense, - * but not completely grey - **/ - float saturation; - /** - * Brightness of the window, in range [0; 1] - * 1 means that the window is unchanged, 0 means that it's completely - * black. 0.5 would make it 50% darker than usual - **/ - float brightness; - }; - -class KWIN_EXPORT ScreenPaintData - { - public: - ScreenPaintData(); - double xScale; - double yScale; - int xTranslate; - int yTranslate; - }; - inline KWIN_EXPORT Display* display() { diff --git a/lib/kwinshadereffect.cpp b/lib/kwinshadereffect.cpp index c05f1c7fcb..5f1fa6a6d1 100644 --- a/lib/kwinshadereffect.cpp +++ b/lib/kwinshadereffect.cpp @@ -116,19 +116,19 @@ GLShader* ShaderEffect::shader() const return mShader; } -void ShaderEffect::prePaintScreen( int* mask, QRegion* region, int time ) +void ShaderEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { mTime += time / 1000.0f; #ifdef HAVE_OPENGL if( mValid && mEnabled ) { - *mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; + data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS; // Start rendering to texture effects->pushRenderTarget(mRenderTarget); } #endif - effects->prePaintScreen(mask, region, time); + effects->prePaintScreen(data, time); } void ShaderEffect::postPaintScreen() diff --git a/lib/kwinshadereffect.h b/lib/kwinshadereffect.h index c0284c2dd0..890d6bf1d9 100644 --- a/lib/kwinshadereffect.h +++ b/lib/kwinshadereffect.h @@ -27,7 +27,7 @@ class KWIN_EXPORT ShaderEffect : public Effect ShaderEffect(const QString& shadername); virtual ~ShaderEffect(); - virtual void prePaintScreen( int* mask, QRegion* region, int time ); + virtual void prePaintScreen( ScreenPrePaintData& data, int time ); virtual void postPaintScreen(); static bool supported(); diff --git a/scene.cpp b/scene.cpp index 321fdbea5f..876e686a9c 100644 --- a/scene.cpp +++ b/scene.cpp @@ -94,7 +94,12 @@ void Scene::paintScreen( int* mask, QRegion* region ) updateTimeDiff(); // preparation step static_cast(effects)->startPaint(); - effects->prePaintScreen( mask, region, time_diff ); + ScreenPrePaintData pdata; + pdata.mask = *mask; + pdata.paint = *region; + effects->prePaintScreen( pdata, time_diff ); + *mask = pdata.mask; + *region = pdata.paint; if( *mask & ( PAINT_SCREEN_TRANSFORMED | PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS )) { // Region painting is not possible with transformations, // because screen damage doesn't match transformed positions. @@ -165,19 +170,21 @@ void Scene::paintGenericScreen( int orig_mask, ScreenPaintData ) QList< Phase2Data > phase2; foreach( Window* w, stacking_order ) // bottom to top { - int mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT ); + WindowPrePaintData data; + data.mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT ); w->resetPaintingEnabled(); - QRegion paint = infiniteRegion(); // no clipping, so doesn't really matter - QRegion clip = QRegion(); + data.paint = infiniteRegion(); // no clipping, so doesn't really matter + data.clip = QRegion(); + data.quads = buildQuads( w ); // preparation step - effects->prePaintWindow( effectWindow( w ), &mask, &paint, &clip, time_diff ); + effects->prePaintWindow( effectWindow( w ), data, time_diff ); if( !w->isPaintingEnabled()) continue; - phase2.append( Phase2Data( w, infiniteRegion(), mask )); + phase2.append( Phase2Data( w, infiniteRegion(), data.mask, data.quads )); } foreach( Phase2Data d, phase2 ) - paintWindow( d.window, d.mask, d.region ); + paintWindow( d.window, d.mask, d.region, d.quads ); } // The optimized case without any transformations at all. @@ -199,38 +206,40 @@ void Scene::paintSimpleScreen( int orig_mask, QRegion region ) --i ) { Window* w = stacking_order[ i ]; - int mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT ); + WindowPrePaintData data; + data.mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT ); w->resetPaintingEnabled(); - QRegion paint = region; - QRegion clip = w->isOpaque() ? w->shape().translated( w->x(), w->y()) : QRegion(); + data.paint = region; + data.clip = w->isOpaque() ? w->shape().translated( w->x(), w->y()) : QRegion(); + data.quads = buildQuads( w ); // preparation step - effects->prePaintWindow( effectWindow( w ), &mask, &paint, &clip, time_diff ); + effects->prePaintWindow( effectWindow( w ), data, time_diff ); if( !w->isPaintingEnabled()) continue; - paint -= allclips; // make sure to avoid already clipped areas - if( paint.isEmpty()) // completely clipped + data.paint -= allclips; // make sure to avoid already clipped areas + if( data.paint.isEmpty()) // completely clipped continue; - if( paint != region ) // prepaint added area to draw + if( data.paint != region ) // prepaint added area to draw { - region |= paint; // make sure other windows in that area get painted too - painted_region |= paint; // make sure it makes it to the screen + region |= data.paint; // make sure other windows in that area get painted too + painted_region |= data.paint; // make sure it makes it to the screen } // If the window is transparent, the transparent part will be done // in the 2nd pass. - if( mask & PAINT_WINDOW_TRANSLUCENT ) - phase2translucent.prepend( Phase2Data( w, paint, mask )); - if( mask & PAINT_WINDOW_OPAQUE ) + if( data.mask & PAINT_WINDOW_TRANSLUCENT ) + phase2translucent.prepend( Phase2Data( w, data.paint, data.mask, data.quads )); + if( data.mask & PAINT_WINDOW_OPAQUE ) { - phase2opaque.append( Phase2Data( w, paint, mask )); + phase2opaque.append( Phase2Data( w, data.paint, data.mask, data.quads )); // The window can clip by its opaque parts the windows below. - region -= clip; - allclips |= clip; + region -= data.clip; + allclips |= data.clip; } } // Do the actual painting // First opaque windows, top to bottom foreach( Phase2Data d, phase2opaque ) - paintWindow( d.window, d.mask, d.region ); + paintWindow( d.window, d.mask, d.region, d.quads ); if( !( orig_mask & PAINT_SCREEN_BACKGROUND_FIRST )) paintBackground( region ); // Fill any areas of the root window not covered by windows // Now walk the list bottom to top, drawing translucent windows. @@ -239,17 +248,18 @@ void Scene::paintSimpleScreen( int orig_mask, QRegion region ) QRegion add_paint; foreach( Phase2Data d, phase2translucent ) { - paintWindow( d.window, d.mask, d.region | add_paint ); + paintWindow( d.window, d.mask, d.region | add_paint, d.quads ); // It is necessary to also add paint regions of windows below, because their // pre-paint's might have extended the paint area, so those areas need to be painted too. add_paint |= d.region; } } -void Scene::paintWindow( Window* w, int mask, QRegion region ) +void Scene::paintWindow( Window* w, int mask, QRegion region, WindowQuadList quads ) { WindowPaintData data; data.opacity = w->window()->opacity(); + data.quads = quads; w->prepareForPainting(); effects->paintWindow( effectWindow( w ), mask, region, data ); } @@ -266,6 +276,22 @@ void Scene::finalDrawWindow( EffectWindowImpl* w, int mask, QRegion region, Wind w->sceneWindow()->performPaint( mask, region, data ); } +WindowQuadList Scene::buildQuads( const Window* w ) + { + WindowQuadList ret; + foreach( QRect r, w->shape().rects()) + { + WindowQuad quad; + // TODO asi mam spatne pravy dolni roh - bud tady, nebo v jinych castech + quad[ 0 ] = WindowVertex( r.x(), r.y(), r.x(), r.y()); + quad[ 1 ] = WindowVertex( r.x() + r.width(), r.y(), r.x() + r.width(), r.y()); + quad[ 2 ] = WindowVertex( r.x() + r.width(), r.y() + r.height(), r.x() + r.width(), r.y() + r.height()); + quad[ 3 ] = WindowVertex( r.x(), r.y() + r.height(), r.x(), r.y() + r.height()); + ret.append( quad ); + } + return ret; + } + //**************************************** // Scene::Window //**************************************** diff --git a/scene.h b/scene.h index 3efe7bbc6f..94c7df3ad2 100644 --- a/scene.h +++ b/scene.h @@ -92,9 +92,11 @@ class Scene // called after all effects had their paintWindow() called void finalPaintWindow( EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data ); // shared implementation, starts painting the window - virtual void paintWindow( Window* w, int mask, QRegion region ); + virtual void paintWindow( Window* w, int mask, QRegion region, WindowQuadList quads ); // called after all effects had their drawWindow() called void finalDrawWindow( EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data ); + // creates initial quad list for a window + virtual WindowQuadList buildQuads( const Window* w ); // infinite region, i.e. everything static QRegion infiniteRegion(); // compute time since the last repaint @@ -102,10 +104,12 @@ class Scene // saved data for 2nd pass of optimized screen painting struct Phase2Data { - Phase2Data( Window* w, QRegion r, int m ) : window( w ), region( r ), mask( m ) {} + Phase2Data( Window* w, QRegion r, int m, const WindowQuadList& q ) + : window( w ), region( r ), mask( m ), quads( q ) {} Window* window; QRegion region; int mask; + WindowQuadList quads; }; // windows in their stacking order QVector< Window* > stacking_order; diff --git a/scene_opengl.cpp b/scene_opengl.cpp index b2924eab7e..d85cbfa712 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -709,7 +709,6 @@ void SceneOpenGL::windowGeometryShapeChanged( Toplevel* c ) Window* w = windows[ c ]; w->discardShape(); w->discardTexture(); - w->discardVertices(); } void SceneOpenGL::windowOpacityChanged( Toplevel* ) @@ -1015,96 +1014,17 @@ void SceneOpenGL::Texture::unbind() SceneOpenGL::Window::Window( Toplevel* c ) : Scene::Window( c ) , texture() - , currentXResolution( -1 ) - , currentYResolution( -1 ) - , requestedXResolution( 0 ) - , requestedYResolution( 0 ) - , verticesDirty( false ) { } SceneOpenGL::Window::~Window() { discardTexture(); - discardVertices(); - } - -void SceneOpenGL::Window::requestVertexGrid(int maxquadsize) - { - requestedXResolution = (requestedXResolution <= 0) ? maxquadsize : qMin(maxquadsize, requestedXResolution); - requestedYResolution = (requestedYResolution <= 0) ? maxquadsize : qMin(maxquadsize, requestedYResolution); - } - -void SceneOpenGL::Window::createVertexGrid(int xres, int yres) - { - int oldcount = verticeslist.count(); - verticeslist.clear(); - foreach( QRect r, shape().rects()) - { - // First calculate number of columns/rows that this rect will be - // divided into - int cols = (xres <= 0) ? 1 : (int)ceil( r.width() / (float)xres ); - int rows = (yres <= 0) ? 1 : (int)ceil( r.height() / (float)yres ); - // Now calculate actual size of each cell - int cellw = r.width() / cols; - int cellh = r.height() / rows; - int maxx = r.x() + r.width(); - int maxy = r.y() + r.height(); - for( int x1 = r.x(); x1 < maxx; x1 += cellw ) - { - int x2 = qMin(x1 + cellw, maxx); - for( int y1 = r.y(); y1 < maxy; y1 += cellh ) - { - int y2 = qMin(y1 + cellh, maxy); - // Add this quad to vertices' list - verticeslist.append( Vertex( x1, y1 )); - verticeslist.append( Vertex( x1, y2 )); - verticeslist.append( Vertex( x2, y2 )); - verticeslist.append( Vertex( x2, y1 )); - } - } - } - Client* c = qobject_cast(window()); - kDebug( 1212 ) << k_funcinfo << "'" << (c ? c->caption() : "") << "': Resized vertex grid from " << - oldcount/4 << " quads (minreso: " << currentXResolution << "x" << currentYResolution << - ") to " << verticeslist.count()/4 << " quads (minreso: " << xres << "x" << yres << ")" << endl; - - currentXResolution = xres; - currentYResolution = yres; - verticesDirty = false; - } - -void SceneOpenGL::Window::resetVertices() - { - // This assumes that texcoords of the vertices are unchanged. If they are, - // we need to do this in some other way (or maybe the effects should then - // clean things up themselves) - for(int i = 0; i < verticeslist.count(); i++) - { - verticeslist[i].pos[0] = verticeslist[i].texcoord[0]; - verticeslist[i].pos[1] = verticeslist[i].texcoord[1]; - } - verticesDirty = false; - } - -void SceneOpenGL::Window::prepareVertices() - { - if( requestedXResolution != currentXResolution || requestedYResolution != currentYResolution ) - createVertexGrid( requestedXResolution, requestedYResolution ); - else if( verticesDirty ) - resetVertices(); - - // Reset requests for the next painting - requestedXResolution = 0; - requestedYResolution = 0; - - // Reset shader. If effect wants to use shader, it has to set it in paint pass - shader = 0; } void SceneOpenGL::Window::prepareForPainting() { - prepareVertices(); + shader = NULL; // TODO // We should also bind texture here so that effects could access it in the // paint pass } @@ -1181,13 +1101,6 @@ void SceneOpenGL::Window::discardTexture() texture.discard(); } -void SceneOpenGL::Window::discardVertices() -{ - // Causes list of vertices to be recreated before next rendering pass - currentXResolution = -1; - currentYResolution = -1; -} - // when the window's composite pixmap is discarded, undo binding it to the texture void SceneOpenGL::Window::pixmapDiscarded() { @@ -1240,7 +1153,7 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat // filtering when it actually makes a difference, that is with // minification or changed vertices if( options->smoothScale == 2 - && ( verticesDirty || data.xScale < 1 || data.yScale < 1 )) + && ( data.quads.smoothNeeded() || data.xScale < 1 || data.yScale < 1 )) { texture.setFilter( GL_LINEAR_MIPMAP_LINEAR ); } @@ -1267,12 +1180,15 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat prepareRenderStates( mask, data ); texture.bind(); texture.enableUnnormalizedTexCoords(); - // Render geometry region.translate( toplevel->x(), toplevel->y() ); // Back to screen coords - renderGLGeometry( mask, region, verticeslist.count(), - verticeslist[ 0 ].pos, verticeslist[ 0 ].texcoord, 0, 3, sizeof( Vertex )); - + float* vertices; + float* texcoords; + data.quads.makeArrays( &vertices, &texcoords ); + renderGLGeometry( mask, region, data.quads.count() * 4, + vertices, texcoords, NULL, 2, 0 ); + delete[] vertices; + delete[] texcoords; texture.disableUnnormalizedTexCoords(); glPopMatrix(); diff --git a/scene_opengl.h b/scene_opengl.h index 66db171843..05f82ba8f4 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -123,27 +123,9 @@ class SceneOpenGL::Window virtual void pixmapDiscarded(); bool bindTexture(); void discardTexture(); - void discardVertices(); - - // Returns list of vertices - QVector& vertices() { return verticeslist; } - // Can be called in pre-paint pass. Makes sure that all quads that the - // window consists of are not bigger than maxquadsize x maxquadsize - // (in pixels) in the following paint pass. - void requestVertexGrid(int maxquadsize); - // Marks vertices of the window as dirty. Call this if you change - // position of the vertices - void markVerticesDirty() { verticesDirty = true; } - void setShader( GLShader* s ) { shader = s; } protected: - // Makes sure that vertex grid requests are fulfilled and that vertices - // aren't dirty. Call this before paint pass - void prepareVertices(); - void createVertexGrid(int xres, int yres); - void resetVertices(); // Resets positions of vertices - void prepareRenderStates( int mask, WindowPaintData data ); void prepareShaderRenderStates( int mask, WindowPaintData data ); void restoreRenderStates( int mask, WindowPaintData data ); @@ -151,16 +133,6 @@ class SceneOpenGL::Window private: Texture texture; - - QVector verticeslist; - // Maximum size of the biggest quad that window currently has, in pixels - int currentXResolution; - int currentYResolution; - // Requested maximum size of the biggest quad that window would have - // during the next paint pass, in pixels - int requestedXResolution; - int requestedYResolution; - bool verticesDirty; // vertices have been modified in some way GLShader* shader; // shader to be used for rendering, if any }; diff --git a/scene_xrender.cpp b/scene_xrender.cpp index a5f9a7d4eb..604d65c083 100644 --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -198,31 +198,33 @@ void SceneXrender::paintTransformedScreen( int orig_mask ) --i ) { Window* w = static_cast< Window* >( stacking_order[ i ] ); - int mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT ); + WindowPrePaintData data; + data.mask = orig_mask | ( w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT ); w->resetPaintingEnabled(); - QRegion paint = region; + data.paint = region; // TODO this is wrong, transformedShape() should be used here, but is not known yet - QRegion clip = w->isOpaque() ? region : QRegion(); + data.clip = w->isOpaque() ? region : QRegion(); + data.quads = buildQuads( w ); // preparation step - effects->prePaintWindow( effectWindow( w ), &mask, &paint, &clip, time_diff ); + effects->prePaintWindow( effectWindow( w ), data, time_diff ); if( !w->isPaintingEnabled()) continue; - paint -= allclips; // make sure to avoid already clipped areas - if( paint.isEmpty()) // completely clipped + data.paint -= allclips; // make sure to avoid already clipped areas + if( data.paint.isEmpty()) // completely clipped continue; - if( paint != region ) // prepaint added area to draw + if( data.paint != region ) // prepaint added area to draw { - region |= paint; // make sure other windows in that area get painted too - painted_region |= paint; // make sure it makes it to the screen + region |= data.paint; // make sure other windows in that area get painted too + painted_region |= data.paint; // make sure it makes it to the screen } // If the window is transparent, the transparent part will be done // in the 2nd pass. - if( mask & PAINT_WINDOW_TRANSLUCENT ) - phase2.prepend( Phase2Data( w, paint, mask )); - if( mask & PAINT_WINDOW_OPAQUE ) + if( data.mask & PAINT_WINDOW_TRANSLUCENT ) + phase2.prepend( Phase2Data( w, data.paint, data.mask, data.quads )); + if( data.mask & PAINT_WINDOW_OPAQUE ) { w->setTransformedShape( QRegion()); - paintWindow( w, mask, paint ); + paintWindow( w, data.mask, data.paint, data.quads ); // The window can clip by its opaque parts the windows below. region -= w->transformedShape(); } @@ -236,7 +238,7 @@ void SceneXrender::paintTransformedScreen( int orig_mask ) foreach( Phase2Data d, phase2 ) { Scene::Window* w = d.window; - paintWindow( w, d.mask, d.region | add_paint ); + paintWindow( w, d.mask, d.region | add_paint, d.quads ); // It is necessary to also add paint regions of windows below, because their // pre-paint's might have extended the paint area, so those areas need to be painted too. add_paint |= d.region;