Move functionality to the base Scene class.
svn path=/branches/work/kwin_composite/; revision=596186
This commit is contained in:
parent
caed149f40
commit
ddab4e0d2c
9 changed files with 152 additions and 205 deletions
14
effects.h
14
effects.h
|
@ -133,6 +133,20 @@ class ShiftWorkspaceUp
|
|||
};
|
||||
#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
|
||||
class Scene::WrapperEffect
|
||||
: public Effect
|
||||
{
|
||||
public:
|
||||
virtual ~WrapperEffect();
|
||||
virtual void prePaintScreen( int* mask, QRegion* region );
|
||||
virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data );
|
||||
virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region );
|
||||
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
|
||||
};
|
||||
|
||||
|
||||
inline
|
||||
WindowPaintData::WindowPaintData()
|
||||
: opacity( 1.0 )
|
||||
|
|
98
scene.cpp
98
scene.cpp
|
@ -13,9 +13,19 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
|
||||
#include <X11/extensions/shape.h>
|
||||
|
||||
#include "effects.h"
|
||||
|
||||
namespace KWinInternal
|
||||
{
|
||||
|
||||
//****************************************
|
||||
// Scene::WrapperEffect
|
||||
//****************************************
|
||||
|
||||
Scene::WrapperEffect::~WrapperEffect()
|
||||
{
|
||||
}
|
||||
|
||||
//****************************************
|
||||
// Scene
|
||||
//****************************************
|
||||
|
@ -30,7 +40,91 @@ Scene::Scene( Workspace* ws )
|
|||
Scene::~Scene()
|
||||
{
|
||||
}
|
||||
|
||||
void Scene::WrapperEffect::prePaintScreen( int*, QRegion* )
|
||||
{
|
||||
// nothing, no changes
|
||||
}
|
||||
|
||||
// the function that'll be eventually called by paintScreen() above
|
||||
void Scene::WrapperEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
||||
{
|
||||
if( mask & PAINT_SCREEN_REGION )
|
||||
scene->paintSimpleScreen( region );
|
||||
else
|
||||
scene->paintGenericScreen();
|
||||
}
|
||||
|
||||
// the generic painting code that should eventually handle even
|
||||
// transformations
|
||||
void Scene::paintGenericScreen()
|
||||
{
|
||||
paintBackground( infiniteRegion());
|
||||
foreach( Window* w, stacking_order ) // bottom to top
|
||||
{
|
||||
if( !w->isVisible())
|
||||
continue;
|
||||
paintWindow( w, PAINT_WINDOW_OPAQUE | PAINT_WINDOW_TRANSLUCENT, infiniteRegion());
|
||||
}
|
||||
}
|
||||
|
||||
// the optimized case without any transformations at all
|
||||
void Scene::paintSimpleScreen( QRegion region )
|
||||
{
|
||||
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
|
||||
i >= 0;
|
||||
--i )
|
||||
{
|
||||
Window* w = stacking_order[ i ];
|
||||
if( !w->isVisible())
|
||||
continue;
|
||||
if( region.isEmpty()) // completely clipped
|
||||
continue;
|
||||
if( !w->isOpaque())
|
||||
{
|
||||
phase2.prepend( Phase2Data( w, region ));
|
||||
continue;
|
||||
}
|
||||
paintWindow( w, PAINT_WINDOW_OPAQUE, region );
|
||||
// window is opaque, clip windows below
|
||||
region -= w->shape().translated( w->x(), w->y());
|
||||
}
|
||||
// Fill any areas of the root window not covered by windows
|
||||
paintBackground( region );
|
||||
// Now walk the list bottom to top, drawing translucent windows.
|
||||
// That we draw bottom to top is important now since we're drawing translucent objects
|
||||
// and also are clipping only by opaque windows.
|
||||
foreach( Phase2Data d, phase2 )
|
||||
{
|
||||
Window* w = d.window;
|
||||
paintWindow( w, PAINT_WINDOW_TRANSLUCENT, d.region );
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::WrapperEffect::prePaintWindow( Scene::Window* , int*, QRegion* )
|
||||
{
|
||||
// nothing, no changes
|
||||
}
|
||||
|
||||
void Scene::paintWindow( Window* w, int mask, QRegion region )
|
||||
{
|
||||
WindowPaintData data;
|
||||
// data.opacity = w->opacity();
|
||||
WrapperEffect wrapper;
|
||||
effects->paintWindow( w, mask, region, data, &wrapper );
|
||||
}
|
||||
|
||||
// the function that'll be eventually called by paintWindow() above
|
||||
void Scene::WrapperEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
|
||||
{
|
||||
w->performPaint( region, mask );
|
||||
}
|
||||
|
||||
void Scene::windowGeometryShapeChanged( Toplevel* )
|
||||
{
|
||||
}
|
||||
|
@ -61,6 +155,10 @@ Scene::Window::~Window()
|
|||
{
|
||||
}
|
||||
|
||||
void Scene::Window::free()
|
||||
{
|
||||
}
|
||||
|
||||
void Scene::Window::discardShape()
|
||||
{
|
||||
shape_valid = false;
|
||||
|
|
15
scene.h
15
scene.h
|
@ -11,8 +11,8 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#ifndef KWIN_SCENE_H
|
||||
#define KWIN_SCENE_H
|
||||
|
||||
#include "utils.h"
|
||||
#include "toplevel.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace KWinInternal
|
||||
{
|
||||
|
@ -48,15 +48,20 @@ class Scene
|
|||
PAINT_SCREEN_REGION = 1 << 0,
|
||||
PAINT_SCREEN_ALL = 1 << 1
|
||||
};
|
||||
virtual void paintGenericScreen();
|
||||
virtual void paintSimpleScreen( QRegion region );
|
||||
virtual void paintBackground( QRegion region ) = 0;
|
||||
virtual void paintWindow( Window* w, int mask, QRegion region );
|
||||
static QRegion infiniteRegion();
|
||||
template< typename T >
|
||||
struct Phase2Data
|
||||
{
|
||||
Phase2Data( T* w, QRegion r ) : window( w ), region( r ) {}
|
||||
T* window;
|
||||
Phase2Data( Window* w, QRegion r ) : window( w ), region( r ) {}
|
||||
Window* window;
|
||||
QRegion region;
|
||||
};
|
||||
QVector< Window* > stacking_order;
|
||||
Workspace* wspace;
|
||||
class WrapperEffect;
|
||||
};
|
||||
|
||||
class Scene::Window
|
||||
|
@ -64,6 +69,8 @@ class Scene::Window
|
|||
public:
|
||||
Window( Toplevel* c );
|
||||
virtual ~Window();
|
||||
virtual void free(); // is often copied by value, use manually instead of dtor
|
||||
virtual void performPaint( QRegion region, int mask ) = 0;
|
||||
int x() const;
|
||||
int y() const;
|
||||
int width() const;
|
||||
|
|
|
@ -56,4 +56,9 @@ void SceneBasic::paint( QRegion, ToplevelList windows )
|
|||
XFlush( display());
|
||||
}
|
||||
|
||||
void SceneBasic::paintBackground( QRegion )
|
||||
{
|
||||
// empty, not using inherited functionality
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -23,6 +23,8 @@ class SceneBasic
|
|||
SceneBasic( Workspace* ws );
|
||||
virtual ~SceneBasic();
|
||||
virtual void paint( QRegion damage, ToplevelList windows );
|
||||
protected:
|
||||
virtual void paintBackground( QRegion region );
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -10,8 +10,6 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
Based on glcompmgr code by Felix Bellaby.
|
||||
******************************************************************/
|
||||
|
||||
|
||||
|
||||
#include "scene_opengl.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
@ -263,6 +261,11 @@ bool SceneOpenGL::findConfig( const int* attrs, GLXFBConfig& config, VisualID vi
|
|||
|
||||
void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
|
||||
{
|
||||
foreach( Toplevel* c, toplevels )
|
||||
{
|
||||
assert( windows.contains( c ));
|
||||
stacking_order.append( &windows[ c ] );
|
||||
}
|
||||
grabXServer();
|
||||
glXWaitX();
|
||||
glPushMatrix();
|
||||
|
@ -270,11 +273,6 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
|
|||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
glScalef( 1, -1, 1 );
|
||||
glTranslatef( 0, -displayHeight(), 0 );
|
||||
foreach( Toplevel* c, toplevels )
|
||||
{
|
||||
assert( windows.contains( c ));
|
||||
stacking_order.append( &windows[ c ] );
|
||||
}
|
||||
int mask = ( damage == QRegion( 0, 0, displayWidth(), displayHeight()))
|
||||
? PAINT_SCREEN_ALL : PAINT_SCREEN_REGION;
|
||||
WrapperEffect wrapper;
|
||||
|
@ -283,6 +281,7 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
|
|||
// TODO call also prePaintWindow() for all windows
|
||||
ScreenPaintData data;
|
||||
effects->paintScreen( mask, damage, data, &wrapper );
|
||||
stacking_order.clear();
|
||||
glPopMatrix();
|
||||
// TODO only partial repaint for mask & PAINT_SCREEN_REGION
|
||||
if( root_db )
|
||||
|
@ -296,85 +295,14 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
|
|||
}
|
||||
ungrabXServer();
|
||||
checkGLError( "PostPaint" );
|
||||
stacking_order.clear();
|
||||
}
|
||||
|
||||
void SceneOpenGL::WrapperEffect::prePaintScreen( int*, QRegion* )
|
||||
{
|
||||
// nothing, no changes
|
||||
}
|
||||
|
||||
// the function that'll be eventually called by wrapper.peformPaintScreen() above
|
||||
void SceneOpenGL::WrapperEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
||||
{
|
||||
if( mask & PAINT_SCREEN_REGION )
|
||||
static_cast< SceneOpenGL* >( scene )->paintSimpleScreen( region );
|
||||
else
|
||||
static_cast< SceneOpenGL* >( scene )->paintGenericScreen();
|
||||
}
|
||||
|
||||
// the generic painting code that should eventually handle even
|
||||
// transformations
|
||||
void SceneOpenGL::paintGenericScreen()
|
||||
{
|
||||
paintBackground( infiniteRegion());
|
||||
foreach( Window* w, stacking_order ) // bottom to top
|
||||
{
|
||||
if( !w->isVisible())
|
||||
continue;
|
||||
paintWindow( w, PAINT_WINDOW_OPAQUE | PAINT_WINDOW_TRANSLUCENT, infiniteRegion());
|
||||
}
|
||||
}
|
||||
|
||||
// the optimized case without any transformations at all
|
||||
void SceneOpenGL::paintSimpleScreen( QRegion region )
|
||||
{
|
||||
QList< Phase2Data > phase2;
|
||||
// TODO repaint only damaged areas (means also don't do glXSwapBuffers and similar)
|
||||
region = QRegion( 0, 0, displayWidth(), displayHeight());
|
||||
for( int i = stacking_order.count() - 1; // top to bottom
|
||||
i >= 0;
|
||||
--i )
|
||||
{
|
||||
Window* w = stacking_order[ i ];
|
||||
if( !w->isVisible())
|
||||
continue;
|
||||
if( region.isEmpty()) // completely clipped
|
||||
continue;
|
||||
if( !w->isOpaque())
|
||||
{
|
||||
phase2.prepend( Phase2Data( w, region ));
|
||||
continue;
|
||||
}
|
||||
paintWindow( w, PAINT_WINDOW_OPAQUE, region );
|
||||
// window is opaque, clip windows below
|
||||
region -= w->shape().translated( w->x(), w->y());
|
||||
}
|
||||
paintBackground( region );
|
||||
foreach( Phase2Data d, phase2 )
|
||||
{
|
||||
Window* w = d.window;
|
||||
paintWindow( w, PAINT_WINDOW_TRANSLUCENT, d.region );
|
||||
}
|
||||
}
|
||||
|
||||
void SceneOpenGL::WrapperEffect::prePaintWindow( Scene::Window* , int*, QRegion* )
|
||||
{
|
||||
// nothing, no changes
|
||||
}
|
||||
|
||||
void SceneOpenGL::paintWindow( Window* w, int mask, QRegion region )
|
||||
{
|
||||
WindowPaintData data;
|
||||
// data.opacity = w->opacity();
|
||||
WrapperEffect wrapper;
|
||||
effects->paintWindow( w, mask, region, data, &wrapper );
|
||||
}
|
||||
|
||||
// the function that'll be eventually called by paintWindow() above
|
||||
void SceneOpenGL::WrapperEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
|
||||
{
|
||||
static_cast< Window* >( w )->performPaint( region, mask );
|
||||
Scene::paintSimpleScreen( region );
|
||||
}
|
||||
|
||||
void SceneOpenGL::paintBackground( QRegion )
|
||||
|
|
|
@ -12,7 +12,6 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#define KWIN_SCENE_OPENGL_H
|
||||
|
||||
#include "scene.h"
|
||||
#include "effects.h"
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
|
@ -31,14 +30,12 @@ class SceneOpenGL
|
|||
virtual void windowOpacityChanged( Toplevel* );
|
||||
virtual void windowAdded( Toplevel* );
|
||||
virtual void windowDeleted( Toplevel* );
|
||||
protected:
|
||||
virtual void paintSimpleScreen( QRegion region );
|
||||
virtual void paintBackground( QRegion region );
|
||||
private:
|
||||
void initBuffer();
|
||||
bool findConfig( const int* attrs, GLXFBConfig& config, VisualID visual = None );
|
||||
void paintGenericScreen();
|
||||
void paintSimpleScreen( QRegion region );
|
||||
void paintBackground( QRegion region );
|
||||
class Window;
|
||||
void paintWindow( Window* w, int mask, QRegion region );
|
||||
typedef GLuint Texture;
|
||||
GC gcroot;
|
||||
Drawable buffer;
|
||||
|
@ -48,10 +45,8 @@ class SceneOpenGL
|
|||
static GLXDrawable glxroot;
|
||||
static GLXContext context;
|
||||
static bool tfp_mode;
|
||||
class Window;
|
||||
QMap< Toplevel*, Window > windows;
|
||||
QVector< Window* > stacking_order;
|
||||
typedef Scene::Phase2Data< Window > Phase2Data;
|
||||
class WrapperEffect;
|
||||
};
|
||||
|
||||
class SceneOpenGL::Window
|
||||
|
@ -59,8 +54,8 @@ class SceneOpenGL::Window
|
|||
{
|
||||
public:
|
||||
Window( Toplevel* c );
|
||||
void free(); // is often copied by value, use manually instead of dtor
|
||||
void performPaint( QRegion region, int mask );
|
||||
virtual void free();
|
||||
virtual void performPaint( QRegion region, int mask );
|
||||
void bindTexture();
|
||||
void discardTexture();
|
||||
Window() {} // QMap sucks even in Qt4
|
||||
|
@ -71,17 +66,6 @@ class SceneOpenGL::Window
|
|||
GLXPixmap bound_glxpixmap; // only for tfp_mode
|
||||
};
|
||||
|
||||
// a special effect that is last in the order that'll actually call the painting functions
|
||||
class SceneOpenGL::WrapperEffect
|
||||
: public Effect
|
||||
{
|
||||
public:
|
||||
virtual void prePaintScreen( int* mask, QRegion* region );
|
||||
virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data );
|
||||
virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region );
|
||||
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
|
|
@ -88,8 +88,10 @@ void SceneXrender::paint( QRegion damage, ToplevelList toplevels )
|
|||
WrapperEffect wrapper;
|
||||
// preparation step
|
||||
effects->prePaintScreen( &mask, &damage, &wrapper );
|
||||
// TODO call also prePaintWindow() for all windows
|
||||
ScreenPaintData data;
|
||||
effects->paintScreen( mask, damage, data, &wrapper );
|
||||
stacking_order.clear();
|
||||
if( mask & PAINT_SCREEN_REGION )
|
||||
{
|
||||
// Use the damage region as the clip region for the root window
|
||||
|
@ -107,82 +109,6 @@ void SceneXrender::paint( QRegion damage, ToplevelList toplevels )
|
|||
XRenderComposite( display(), PictOpSrc, buffer, None, front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight());
|
||||
XFlush( display());
|
||||
}
|
||||
stacking_order.clear();
|
||||
}
|
||||
|
||||
void SceneXrender::WrapperEffect::prePaintScreen( int*, QRegion* )
|
||||
{
|
||||
// nothing, no changes
|
||||
}
|
||||
|
||||
void SceneXrender::WrapperEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
||||
{
|
||||
if( mask & PAINT_SCREEN_REGION )
|
||||
static_cast< SceneXrender* >( scene )->paintSimpleScreen( region );
|
||||
else
|
||||
static_cast< SceneXrender* >( scene )->paintGenericScreen();
|
||||
}
|
||||
|
||||
void SceneXrender::paintGenericScreen()
|
||||
{
|
||||
paintBackground( infiniteRegion());
|
||||
foreach( Window* w, stacking_order ) // bottom to top
|
||||
{
|
||||
if( !w->isVisible())
|
||||
continue;
|
||||
paintWindow( w, PAINT_WINDOW_OPAQUE | PAINT_WINDOW_TRANSLUCENT, infiniteRegion());
|
||||
}
|
||||
}
|
||||
|
||||
void SceneXrender::paintSimpleScreen( QRegion region )
|
||||
{
|
||||
QList< Phase2Data > phase2;
|
||||
// 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;
|
||||
i >= 0;
|
||||
--i )
|
||||
{
|
||||
Window* w = stacking_order[ i ];
|
||||
if( !w->isVisible())
|
||||
continue;
|
||||
if( !w->isOpaque())
|
||||
{
|
||||
phase2.prepend( Phase2Data( w, region ));
|
||||
continue;
|
||||
}
|
||||
paintWindow( w, PAINT_WINDOW_OPAQUE, region );
|
||||
// window is opaque, clip windows below
|
||||
region -= w->shape().translated( w->x(), w->y());
|
||||
}
|
||||
// Fill any areas of the root window not covered by windows
|
||||
paintBackground( region );
|
||||
// Now walk the list bottom to top, drawing translucent windows.
|
||||
// That we draw bottom to top is important now since we're drawing translucent objects
|
||||
// and also are clipping only by opaque windows.
|
||||
foreach( Phase2Data d, phase2 )
|
||||
{
|
||||
Window* w = d.window;
|
||||
paintWindow( w, PAINT_WINDOW_TRANSLUCENT, d.region );
|
||||
}
|
||||
}
|
||||
|
||||
void SceneXrender::WrapperEffect::prePaintWindow( Scene::Window* , int*, QRegion* )
|
||||
{
|
||||
// nothing, no changes
|
||||
}
|
||||
|
||||
void SceneXrender::paintWindow( Window* w, int mask, QRegion region )
|
||||
{
|
||||
WindowPaintData data;
|
||||
// data.opacity = w->opacity();
|
||||
WrapperEffect wrapper;
|
||||
effects->paintWindow( w, mask, region, data, &wrapper );
|
||||
}
|
||||
|
||||
void SceneXrender::WrapperEffect::paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data )
|
||||
{
|
||||
static_cast< Window* >( w )->performPaint( region, mask );
|
||||
}
|
||||
|
||||
void SceneXrender::paintBackground( QRegion region )
|
||||
|
|
|
@ -13,12 +13,11 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include "scene.h"
|
||||
|
||||
#ifdef HAVE_XRENDER
|
||||
#include <X11/extensions/Xrender.h>
|
||||
|
||||
#include "scene.h"
|
||||
#include "effects.h"
|
||||
|
||||
namespace KWinInternal
|
||||
{
|
||||
|
||||
|
@ -35,21 +34,16 @@ class SceneXrender
|
|||
virtual void windowOpacityChanged( Toplevel* );
|
||||
virtual void windowAdded( Toplevel* );
|
||||
virtual void windowDeleted( Toplevel* );
|
||||
protected:
|
||||
virtual void paintBackground( QRegion region );
|
||||
private:
|
||||
void createBuffer();
|
||||
void paintGenericScreen();
|
||||
void paintSimpleScreen( QRegion region );
|
||||
void paintBackground( QRegion region );
|
||||
class Window;
|
||||
void paintWindow( Window* w, int mask, QRegion region );
|
||||
static XserverRegion toXserverRegion( QRegion region );
|
||||
XRenderPictFormat* format;
|
||||
Picture front;
|
||||
static Picture buffer;
|
||||
class Window;
|
||||
QMap< Toplevel*, Window > windows;
|
||||
QVector< Window* > stacking_order;
|
||||
typedef Scene::Phase2Data< Window > Phase2Data;
|
||||
class WrapperEffect;
|
||||
};
|
||||
|
||||
class SceneXrender::Window
|
||||
|
@ -57,8 +51,8 @@ class SceneXrender::Window
|
|||
{
|
||||
public:
|
||||
Window( Toplevel* c );
|
||||
void free(); // is often copied by value, use manually instead of dtor
|
||||
void performPaint( QRegion region, int mask );
|
||||
virtual void free();
|
||||
virtual void performPaint( QRegion region, int mask );
|
||||
void discardPicture();
|
||||
void discardAlpha();
|
||||
Window() {} // QMap sucks even in Qt4
|
||||
|
@ -71,17 +65,6 @@ class SceneXrender::Window
|
|||
double alpha_cached_opacity;
|
||||
};
|
||||
|
||||
// a special effect that is last in the order that'll actually call the painting functions
|
||||
class SceneXrender::WrapperEffect
|
||||
: public Effect
|
||||
{
|
||||
public:
|
||||
virtual void prePaintScreen( int* mask, QRegion* region );
|
||||
virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data );
|
||||
virtual void prePaintWindow( Scene::Window* w, int* mask, QRegion* region );
|
||||
virtual void paintWindow( Scene::Window* w, int mask, QRegion region, WindowPaintData& data );
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue