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