Keeping scene-related data in opengl scene.

svn path=/branches/work/kwin_composite/; revision=590319
This commit is contained in:
Luboš Luňák 2006-09-29 19:05:36 +00:00
parent efff218441
commit 1c7e7bb2b7
9 changed files with 128 additions and 32 deletions

View file

@ -45,12 +45,20 @@ void Workspace::setupCompositing()
c->setupCompositing(); c->setupCompositing();
foreach( Unmanaged* c, unmanaged ) foreach( Unmanaged* c, unmanaged )
c->setupCompositing(); c->setupCompositing();
foreach( Client* c, clients )
scene->windowAdded( c );
foreach( Unmanaged* c, unmanaged )
scene->windowAdded( c );
} }
void Workspace::finishCompositing() void Workspace::finishCompositing()
{ {
if( scene == NULL ) if( scene == NULL )
return; return;
foreach( Client* c, clients )
scene->windowDeleted( c );
foreach( Unmanaged* c, unmanaged )
scene->windowDeleted( c );
foreach( Client* c, clients ) foreach( Client* c, clients )
c->finishCompositing(); c->finishCompositing();
foreach( Unmanaged* c, unmanaged ) foreach( Unmanaged* c, unmanaged )

View file

@ -34,6 +34,10 @@ void Scene::windowOpacityChanged( Toplevel* )
{ {
} }
void Scene::windowAdded( Toplevel* )
{
}
void Scene::windowDeleted( Toplevel* ) void Scene::windowDeleted( Toplevel* )
{ {
} }

View file

@ -26,6 +26,7 @@ class Scene
virtual void paint( XserverRegion damage, ToplevelList windows ) = 0; virtual void paint( XserverRegion damage, ToplevelList windows ) = 0;
virtual void windowGeometryShapeChanged( Toplevel* ); virtual void windowGeometryShapeChanged( Toplevel* );
virtual void windowOpacityChanged( Toplevel* ); virtual void windowOpacityChanged( Toplevel* );
virtual void windowAdded( Toplevel* );
virtual void windowDeleted( Toplevel* ); virtual void windowDeleted( Toplevel* );
virtual void transformWindowDamage( Toplevel*, XserverRegion ) const; virtual void transformWindowDamage( Toplevel*, XserverRegion ) const;
virtual void updateTransformation( Toplevel* ); virtual void updateTransformation( Toplevel* );

View file

@ -24,6 +24,8 @@ namespace KWinInternal
// SceneOpenGL // SceneOpenGL
//**************************************** //****************************************
GLXFBConfig SceneOpenGL::fbcdrawable;
const int root_attrs[] = const int root_attrs[] =
{ {
GLX_DOUBLEBUFFER, False, GLX_DOUBLEBUFFER, False,
@ -81,6 +83,10 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
SceneOpenGL::~SceneOpenGL() SceneOpenGL::~SceneOpenGL()
{ {
for( QMap< Toplevel*, Window >::Iterator it = windows.begin();
it != windows.end();
++it )
(*it).free();
glXDestroyPixmap( display(), glxroot ); glXDestroyPixmap( display(), glxroot );
XFreeGC( display(), gcroot ); XFreeGC( display(), gcroot );
XFreePixmap( display(), buffer ); XFreePixmap( display(), buffer );
@ -99,17 +105,12 @@ static void quadDraw( int x, int y, int w, int h )
glVertex2i( x, y + h ); glVertex2i( x, y + h );
} }
GLuint txts[ 100 ];
int txts_i = 0;
GLXDrawable drws[ 100 ];
int drws_i;
void SceneOpenGL::paint( XserverRegion, ToplevelList windows ) void SceneOpenGL::paint( XserverRegion, ToplevelList windows )
{ {
grabXServer();
glXWaitX();
glClearColor( 0, 0, 0, 1 ); glClearColor( 0, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT /* TODO| GL_DEPTH_BUFFER_BIT*/ ); glClear( GL_COLOR_BUFFER_BIT /* TODO| GL_DEPTH_BUFFER_BIT*/ );
txts_i = 0;
drws_i = 0;
for( ToplevelList::ConstIterator it = windows.begin(); for( ToplevelList::ConstIterator it = windows.begin();
it != windows.end(); it != windows.end();
++it ) ++it )
@ -117,19 +118,16 @@ void SceneOpenGL::paint( XserverRegion, ToplevelList windows )
QRect r = (*it)->geometry().intersect( QRect( 0, 0, displayWidth(), displayHeight())); QRect r = (*it)->geometry().intersect( QRect( 0, 0, displayWidth(), displayHeight()));
if( !r.isEmpty()) if( !r.isEmpty())
{ {
GLXDrawable gldraw = glXCreatePixmap( display(), fbcdrawable, assert( this->windows.contains( *it ));
(*it)->windowPixmap(), NULL ); Window& w = this->windows[ *it ];
glXMakeContextCurrent( display(), gldraw, gldraw, context ); GLXDrawable pixmap = w.glxPixmap();
glXMakeContextCurrent( display(), pixmap, pixmap, context );
glReadBuffer( GL_FRONT ); glReadBuffer( GL_FRONT );
glDrawBuffer( GL_FRONT ); glDrawBuffer( GL_FRONT );
// TODO grabXServer(); Texture texture = w.texture();
glXWaitX();
GLuint texture;
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
glCopyTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, glCopyTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
0, 0, (*it)->width(), (*it)->height(), 0 ); 0, 0, (*it)->width(), (*it)->height(), 0 );
//ungrabXServer();
glXMakeContextCurrent( display(), glxroot, glxroot, context ); glXMakeContextCurrent( display(), glxroot, glxroot, context );
glDrawBuffer( GL_BACK ); glDrawBuffer( GL_BACK );
glPushMatrix(); glPushMatrix();
@ -143,21 +141,57 @@ void SceneOpenGL::paint( XserverRegion, ToplevelList windows )
glDisable( GL_TEXTURE_RECTANGLE_ARB ); glDisable( GL_TEXTURE_RECTANGLE_ARB );
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 ); glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 );
glXWaitGL(); glXWaitGL();
txts[ txts_i++ ] = texture;
drws[ drws_i++ ] = gldraw;
} }
} }
glFlush(); glFlush();
XCopyArea( display(), buffer, rootWindow(), gcroot, 0, 0, displayWidth(), displayHeight(), 0, 0 ); XCopyArea( display(), buffer, rootWindow(), gcroot, 0, 0, displayWidth(), displayHeight(), 0, 0 );
ungrabXServer();
XFlush( display()); XFlush( display());
for( int i = 0; }
i < txts_i;
++i ) void SceneOpenGL::windowAdded( Toplevel* c )
glDeleteTextures( 1, &txts[ i ] ); {
for( int i = 0; assert( !windows.contains( c ));
i < drws_i; windows[ c ] = Window( c );
++i ) }
glXDestroyPixmap( display(), drws[ i ] );
void SceneOpenGL::windowDeleted( Toplevel* c )
{
assert( windows.contains( c ));
windows[ c ].free();
windows.remove( c );
}
SceneOpenGL::Window::Window( Toplevel* c )
: toplevel( c )
, glxpixmap( None )
, gltexture( None )
{
}
SceneOpenGL::Window::~Window()
{
}
void SceneOpenGL::Window::free()
{
discardPixmap();
discardTexture();
}
GLXPixmap SceneOpenGL::Window::glxPixmap() const
{
if( glxpixmap == None )
glxpixmap = glXCreatePixmap( display(), fbcdrawable,
toplevel->windowPixmap(), NULL );
return glxpixmap;
}
SceneOpenGL::Texture SceneOpenGL::Window::texture() const
{
if( gltexture == None )
glGenTextures( 1, &gltexture );
return gltexture;
} }
} // namespace } // namespace

View file

@ -26,15 +26,53 @@ class SceneOpenGL
SceneOpenGL( Workspace* ws ); SceneOpenGL( Workspace* ws );
virtual ~SceneOpenGL(); virtual ~SceneOpenGL();
virtual void paint( XserverRegion damage, ToplevelList windows ); virtual void paint( XserverRegion damage, ToplevelList windows );
virtual void windowAdded( Toplevel* );
virtual void windowDeleted( Toplevel* );
private: private:
typedef GLuint Texture;
GC gcroot; GC gcroot;
Pixmap buffer; Pixmap buffer;
GLXFBConfig fbcroot; GLXFBConfig fbcroot;
GLXFBConfig fbcdrawable; static GLXFBConfig fbcdrawable;
GLXPixmap glxroot; GLXPixmap glxroot;
GLXContext context; GLXContext context;
class Window;
QMap< Toplevel*, Window > windows;
}; };
class SceneOpenGL::Window
{
public:
Window( Toplevel* c );
~Window();
void free(); // is often copied by value, use manually instead of dtor
GLXPixmap glxPixmap() const;
Texture texture() const;
Window() {} // QMap sucks even in Qt4
private:
void discardPixmap();
void discardTexture();
Toplevel* toplevel;
mutable GLXPixmap glxpixmap;
mutable Texture gltexture;
};
inline
void SceneOpenGL::Window::discardPixmap()
{
if( glxpixmap != None )
glXDestroyPixmap( display(), glxpixmap );
glxpixmap = None;
}
inline
void SceneOpenGL::Window::discardTexture()
{
if( gltexture != None )
glDeleteTextures( 1, &gltexture );
gltexture = None;
}
} // namespace } // namespace
#endif #endif

View file

@ -202,12 +202,17 @@ void SceneXrender::windowOpacityChanged( Toplevel* c )
void SceneXrender::windowDeleted( Toplevel* c ) void SceneXrender::windowDeleted( Toplevel* c )
{ {
if( !window_data.contains( c )) assert( window_data.contains( c ));
return;
window_data[ c ].free(); window_data[ c ].free();
window_data.remove( c ); window_data.remove( c );
} }
void SceneXrender::windowAdded( Toplevel* c )
{
assert( !window_data.contains( c ));
resetWindowData( c );
}
// TODO handle xrandr changes // TODO handle xrandr changes
void SceneXrender::createBuffer() void SceneXrender::createBuffer()

View file

@ -33,6 +33,7 @@ class SceneXrender
virtual void paint( XserverRegion damage, ToplevelList windows ); virtual void paint( XserverRegion damage, ToplevelList windows );
virtual void windowGeometryShapeChanged( Toplevel* ); virtual void windowGeometryShapeChanged( Toplevel* );
virtual void windowOpacityChanged( Toplevel* ); virtual void windowOpacityChanged( Toplevel* );
virtual void windowAdded( Toplevel* );
virtual void windowDeleted( Toplevel* ); virtual void windowDeleted( Toplevel* );
virtual void transformWindowDamage( Toplevel*, XserverRegion ) const; virtual void transformWindowDamage( Toplevel*, XserverRegion ) const;
virtual void updateTransformation( Toplevel* ); virtual void updateTransformation( Toplevel* );

View file

@ -10,8 +10,6 @@ License. See the file "COPYING" for the exact licensing terms.
#include "toplevel.h" #include "toplevel.h"
#include "scene.h"
namespace KWinInternal namespace KWinInternal
{ {
@ -30,8 +28,6 @@ Toplevel::~Toplevel()
assert( damage_handle == None ); assert( damage_handle == None );
assert( damage_region == None ); assert( damage_region == None );
assert( window_pixmap == None ); assert( window_pixmap == None );
if( scene != NULL )
scene->windowDeleted( this );
} }
#ifndef NDEBUG #ifndef NDEBUG

View file

@ -43,6 +43,7 @@ License. See the file "COPYING" for the exact licensing terms.
#include "rules.h" #include "rules.h"
#include "kwinadaptor.h" #include "kwinadaptor.h"
#include "unmanaged.h" #include "unmanaged.h"
#include "scene.h"
#include <X11/extensions/shape.h> #include <X11/extensions/shape.h>
#include <X11/keysym.h> #include <X11/keysym.h>
@ -486,6 +487,8 @@ Client* Workspace::createClient( Window w, bool is_mapped )
return NULL; return NULL;
} }
addClient( c, Allowed ); addClient( c, Allowed );
if( scene )
scene->windowAdded( c );
return c; return c;
} }
@ -498,6 +501,8 @@ Unmanaged* Workspace::createUnmanaged( Window w )
return NULL; return NULL;
} }
addUnmanaged( c, Allowed ); addUnmanaged( c, Allowed );
if( scene )
scene->windowAdded( c );
return c; return c;
} }
@ -564,6 +569,8 @@ void Workspace::removeClient( Client* c, allowed_t )
Notify::raise( Notify::Delete ); Notify::raise( Notify::Delete );
Q_ASSERT( clients.contains( c ) || desktops.contains( c )); Q_ASSERT( clients.contains( c ) || desktops.contains( c ));
if( scene )
scene->windowDeleted( c );
clients.removeAll( c ); clients.removeAll( c );
desktops.removeAll( c ); desktops.removeAll( c );
unconstrained_stacking_order.removeAll( c ); unconstrained_stacking_order.removeAll( c );
@ -602,6 +609,8 @@ void Workspace::removeClient( Client* c, allowed_t )
void Workspace::removeUnmanaged( Unmanaged* c, allowed_t ) void Workspace::removeUnmanaged( Unmanaged* c, allowed_t )
{ {
assert( unmanaged.contains( c )); assert( unmanaged.contains( c ));
if( scene )
scene->windowDeleted( c );
unmanaged.removeAll( c ); unmanaged.removeAll( c );
} }