Keeping scene-related data in opengl scene.
svn path=/branches/work/kwin_composite/; revision=590319
This commit is contained in:
parent
efff218441
commit
1c7e7bb2b7
9 changed files with 128 additions and 32 deletions
|
@ -45,12 +45,20 @@ void Workspace::setupCompositing()
|
|||
c->setupCompositing();
|
||||
foreach( Unmanaged* c, unmanaged )
|
||||
c->setupCompositing();
|
||||
foreach( Client* c, clients )
|
||||
scene->windowAdded( c );
|
||||
foreach( Unmanaged* c, unmanaged )
|
||||
scene->windowAdded( c );
|
||||
}
|
||||
|
||||
void Workspace::finishCompositing()
|
||||
{
|
||||
if( scene == NULL )
|
||||
return;
|
||||
foreach( Client* c, clients )
|
||||
scene->windowDeleted( c );
|
||||
foreach( Unmanaged* c, unmanaged )
|
||||
scene->windowDeleted( c );
|
||||
foreach( Client* c, clients )
|
||||
c->finishCompositing();
|
||||
foreach( Unmanaged* c, unmanaged )
|
||||
|
|
|
@ -34,6 +34,10 @@ void Scene::windowOpacityChanged( Toplevel* )
|
|||
{
|
||||
}
|
||||
|
||||
void Scene::windowAdded( Toplevel* )
|
||||
{
|
||||
}
|
||||
|
||||
void Scene::windowDeleted( Toplevel* )
|
||||
{
|
||||
}
|
||||
|
|
1
scene.h
1
scene.h
|
@ -26,6 +26,7 @@ class Scene
|
|||
virtual void paint( XserverRegion damage, ToplevelList windows ) = 0;
|
||||
virtual void windowGeometryShapeChanged( Toplevel* );
|
||||
virtual void windowOpacityChanged( Toplevel* );
|
||||
virtual void windowAdded( Toplevel* );
|
||||
virtual void windowDeleted( Toplevel* );
|
||||
virtual void transformWindowDamage( Toplevel*, XserverRegion ) const;
|
||||
virtual void updateTransformation( Toplevel* );
|
||||
|
|
|
@ -24,6 +24,8 @@ namespace KWinInternal
|
|||
// SceneOpenGL
|
||||
//****************************************
|
||||
|
||||
GLXFBConfig SceneOpenGL::fbcdrawable;
|
||||
|
||||
const int root_attrs[] =
|
||||
{
|
||||
GLX_DOUBLEBUFFER, False,
|
||||
|
@ -81,6 +83,10 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
|
|||
|
||||
SceneOpenGL::~SceneOpenGL()
|
||||
{
|
||||
for( QMap< Toplevel*, Window >::Iterator it = windows.begin();
|
||||
it != windows.end();
|
||||
++it )
|
||||
(*it).free();
|
||||
glXDestroyPixmap( display(), glxroot );
|
||||
XFreeGC( display(), gcroot );
|
||||
XFreePixmap( display(), buffer );
|
||||
|
@ -99,17 +105,12 @@ static void quadDraw( int x, int y, int w, int h )
|
|||
glVertex2i( x, y + h );
|
||||
}
|
||||
|
||||
GLuint txts[ 100 ];
|
||||
int txts_i = 0;
|
||||
GLXDrawable drws[ 100 ];
|
||||
int drws_i;
|
||||
|
||||
void SceneOpenGL::paint( XserverRegion, ToplevelList windows )
|
||||
{
|
||||
grabXServer();
|
||||
glXWaitX();
|
||||
glClearColor( 0, 0, 0, 1 );
|
||||
glClear( GL_COLOR_BUFFER_BIT /* TODO| GL_DEPTH_BUFFER_BIT*/ );
|
||||
txts_i = 0;
|
||||
drws_i = 0;
|
||||
for( ToplevelList::ConstIterator it = windows.begin();
|
||||
it != windows.end();
|
||||
++it )
|
||||
|
@ -117,19 +118,16 @@ void SceneOpenGL::paint( XserverRegion, ToplevelList windows )
|
|||
QRect r = (*it)->geometry().intersect( QRect( 0, 0, displayWidth(), displayHeight()));
|
||||
if( !r.isEmpty())
|
||||
{
|
||||
GLXDrawable gldraw = glXCreatePixmap( display(), fbcdrawable,
|
||||
(*it)->windowPixmap(), NULL );
|
||||
glXMakeContextCurrent( display(), gldraw, gldraw, context );
|
||||
assert( this->windows.contains( *it ));
|
||||
Window& w = this->windows[ *it ];
|
||||
GLXDrawable pixmap = w.glxPixmap();
|
||||
glXMakeContextCurrent( display(), pixmap, pixmap, context );
|
||||
glReadBuffer( GL_FRONT );
|
||||
glDrawBuffer( GL_FRONT );
|
||||
// TODO grabXServer();
|
||||
glXWaitX();
|
||||
GLuint texture;
|
||||
glGenTextures( 1, &texture );
|
||||
Texture texture = w.texture();
|
||||
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
|
||||
glCopyTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
|
||||
0, 0, (*it)->width(), (*it)->height(), 0 );
|
||||
//ungrabXServer();
|
||||
glXMakeContextCurrent( display(), glxroot, glxroot, context );
|
||||
glDrawBuffer( GL_BACK );
|
||||
glPushMatrix();
|
||||
|
@ -143,21 +141,57 @@ void SceneOpenGL::paint( XserverRegion, ToplevelList windows )
|
|||
glDisable( GL_TEXTURE_RECTANGLE_ARB );
|
||||
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 );
|
||||
glXWaitGL();
|
||||
txts[ txts_i++ ] = texture;
|
||||
drws[ drws_i++ ] = gldraw;
|
||||
}
|
||||
}
|
||||
glFlush();
|
||||
XCopyArea( display(), buffer, rootWindow(), gcroot, 0, 0, displayWidth(), displayHeight(), 0, 0 );
|
||||
ungrabXServer();
|
||||
XFlush( display());
|
||||
for( int i = 0;
|
||||
i < txts_i;
|
||||
++i )
|
||||
glDeleteTextures( 1, &txts[ i ] );
|
||||
for( int i = 0;
|
||||
i < drws_i;
|
||||
++i )
|
||||
glXDestroyPixmap( display(), drws[ i ] );
|
||||
}
|
||||
|
||||
void SceneOpenGL::windowAdded( Toplevel* c )
|
||||
{
|
||||
assert( !windows.contains( c ));
|
||||
windows[ c ] = Window( c );
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -26,15 +26,53 @@ class SceneOpenGL
|
|||
SceneOpenGL( Workspace* ws );
|
||||
virtual ~SceneOpenGL();
|
||||
virtual void paint( XserverRegion damage, ToplevelList windows );
|
||||
virtual void windowAdded( Toplevel* );
|
||||
virtual void windowDeleted( Toplevel* );
|
||||
private:
|
||||
typedef GLuint Texture;
|
||||
GC gcroot;
|
||||
Pixmap buffer;
|
||||
GLXFBConfig fbcroot;
|
||||
GLXFBConfig fbcdrawable;
|
||||
static GLXFBConfig fbcdrawable;
|
||||
GLXPixmap glxroot;
|
||||
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
|
||||
|
||||
#endif
|
||||
|
|
|
@ -202,12 +202,17 @@ void SceneXrender::windowOpacityChanged( Toplevel* c )
|
|||
|
||||
void SceneXrender::windowDeleted( Toplevel* c )
|
||||
{
|
||||
if( !window_data.contains( c ))
|
||||
return;
|
||||
assert( window_data.contains( c ));
|
||||
window_data[ c ].free();
|
||||
window_data.remove( c );
|
||||
}
|
||||
|
||||
void SceneXrender::windowAdded( Toplevel* c )
|
||||
{
|
||||
assert( !window_data.contains( c ));
|
||||
resetWindowData( c );
|
||||
}
|
||||
|
||||
// TODO handle xrandr changes
|
||||
|
||||
void SceneXrender::createBuffer()
|
||||
|
|
|
@ -33,6 +33,7 @@ class SceneXrender
|
|||
virtual void paint( XserverRegion damage, ToplevelList windows );
|
||||
virtual void windowGeometryShapeChanged( Toplevel* );
|
||||
virtual void windowOpacityChanged( Toplevel* );
|
||||
virtual void windowAdded( Toplevel* );
|
||||
virtual void windowDeleted( Toplevel* );
|
||||
virtual void transformWindowDamage( Toplevel*, XserverRegion ) const;
|
||||
virtual void updateTransformation( Toplevel* );
|
||||
|
|
|
@ -10,8 +10,6 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
|
||||
#include "toplevel.h"
|
||||
|
||||
#include "scene.h"
|
||||
|
||||
namespace KWinInternal
|
||||
{
|
||||
|
||||
|
@ -30,8 +28,6 @@ Toplevel::~Toplevel()
|
|||
assert( damage_handle == None );
|
||||
assert( damage_region == None );
|
||||
assert( window_pixmap == None );
|
||||
if( scene != NULL )
|
||||
scene->windowDeleted( this );
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -43,6 +43,7 @@ License. See the file "COPYING" for the exact licensing terms.
|
|||
#include "rules.h"
|
||||
#include "kwinadaptor.h"
|
||||
#include "unmanaged.h"
|
||||
#include "scene.h"
|
||||
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/keysym.h>
|
||||
|
@ -486,6 +487,8 @@ Client* Workspace::createClient( Window w, bool is_mapped )
|
|||
return NULL;
|
||||
}
|
||||
addClient( c, Allowed );
|
||||
if( scene )
|
||||
scene->windowAdded( c );
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -498,6 +501,8 @@ Unmanaged* Workspace::createUnmanaged( Window w )
|
|||
return NULL;
|
||||
}
|
||||
addUnmanaged( c, Allowed );
|
||||
if( scene )
|
||||
scene->windowAdded( c );
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -564,6 +569,8 @@ void Workspace::removeClient( Client* c, allowed_t )
|
|||
Notify::raise( Notify::Delete );
|
||||
|
||||
Q_ASSERT( clients.contains( c ) || desktops.contains( c ));
|
||||
if( scene )
|
||||
scene->windowDeleted( c );
|
||||
clients.removeAll( c );
|
||||
desktops.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 )
|
||||
{
|
||||
assert( unmanaged.contains( c ));
|
||||
if( scene )
|
||||
scene->windowDeleted( c );
|
||||
unmanaged.removeAll( c );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue