A very crude OpenGL-based compositing code.

svn path=/branches/work/kwin_composite/; revision=590265
This commit is contained in:
Luboš Luňák 2006-09-29 16:49:34 +00:00
parent 93d4b9ff9f
commit efff218441
4 changed files with 269 additions and 5 deletions

View file

@ -15,7 +15,7 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/lib ${CMAKE_CURRENT_SOURCE_DIR}
########### next target ###############
set(kwin_KDEINIT_SRCS
kwinadaptor.cpp
kwinadaptor.cpp
workspace.cpp
client.cpp
placement.cpp
@ -38,7 +38,15 @@ set(kwin_KDEINIT_SRCS
activation.cpp
useractions.cpp
geometry.cpp
rules.cpp )
rules.cpp
composite.cpp
toplevel.cpp
unmanaged.cpp
scene.cpp
scene_basic.cpp
scene_xrender.cpp
scene_opengl.cpp
effects.cpp )
kde4_automoc(${kwin_KDEINIT_SRCS})
@ -46,17 +54,68 @@ kde4_automoc(${kwin_KDEINIT_SRCS})
kde4_add_kdeinit_executable( kwin ${kwin_KDEINIT_SRCS})
target_link_libraries(kdeinit_kwin ${KDE4_KDEUI_LIBS} kdecorations ${X11_LIBRARIES} ${QT_QT3SUPPORT_LIBRARY} )
target_link_libraries(kdeinit_kwin -lGL)
if (X11_Xcomposite_FOUND)
target_link_libraries(kdeinit_kwin ${X11_Xcomposite_LIB})
endif (X11_Xcomposite_FOUND)
if (X11_Xdamage_FOUND)
target_link_libraries(kdeinit_kwin ${X11_Xdamage_LIB})
endif (X11_Xdamage_FOUND)
if (X11_Xrender_FOUND)
target_link_libraries(kdeinit_kwin ${X11_Xrender_LIB})
endif (X11_Xrender_FOUND)
if (X11_Xfixes_FOUND)
target_link_libraries(kdeinit_kwin ${X11_Xfixes_LIB})
endif (X11_Xfixes_FOUND)
install(TARGETS kdeinit_kwin DESTINATION ${LIB_INSTALL_DIR} )
target_link_libraries( kwin kdeinit_kwin )
install(TARGETS kwin DESTINATION ${BIN_INSTALL_DIR})
install(TARGETS kwin DESTINATION bin)
########### install files ###############
install( FILES kwin.kcfg DESTINATION ${KCFG_INSTALL_DIR} )
install( FILES eventsrc DESTINATION ${DATA_INSTALL_DIR}/kwin )
kde4_install_icons( ${ICON_INSTALL_DIR} )
kde4_install_icons( ${ICON_INSTALL_DIR} crystalsvg )
#original Makefile.am contents follow:
#INCLUDES = -I$(srcdir)/lib $(all_includes)
#
#SUBDIRS = lib . killer kcmkwin pics clients oldheaders data
#
#bin_PROGRAMS =
#lib_LTLIBRARIES =
#kdeinit_LTLIBRARIES = kwin.la
#
#kwin_la_SOURCES = workspace.cpp client.cpp placement.cpp atoms.cpp \
# utils.cpp layers.cpp main.cpp popupinfo.cpp tabbox.cpp \
# options.cpp plugins.cpp events.cpp KWinInterface.skel \
# killwindow.cpp geometrytip.cpp sm.cpp group.cpp bridge.cpp \
# manage.cpp notifications.cpp activation.cpp useractions.cpp \
# geometry.cpp rules.cpp
#
#kwin_la_LIBADD = $(LIB_KDEUI) lib/libkdecorations.la
#kwin_la_LDFLAGS = $(all_libraries) -module -avoid-version
#
#include_HEADERS = KWinInterface.h
#
#KDE_ICON = kwin
#
#METASOURCES = AUTO
#
#messages: rc.cpp
# $(XGETTEXT) *.h *.cpp killer/*.cpp lib/*.cpp -o $(podir)/kwin.pot
#
#kwin_datadir = $(kde_datadir)/kwin
#
#kwin_data_DATA= eventsrc
#
#kde_kcfg_DATA = kwin.kcfg
#
#include ../../admin/Doxyfile.am

View file

@ -16,6 +16,7 @@ License. See the file "COPYING" for the exact licensing terms.
#include "scene.h"
#include "scene_basic.h"
#include "scene_xrender.h"
#include "scene_opengl.h"
namespace KWinInternal
{
@ -36,7 +37,8 @@ void Workspace::setupCompositing()
compositeTimer.start( 20 );
XCompositeRedirectSubwindows( display(), rootWindow(), CompositeRedirectManual );
// scene = new SceneBasic( this );
scene = new SceneXrender( this );
// scene = new SceneXrender( this );
scene = new SceneOpenGL( this );
effects = new EffectsHandler( this );
addDamage( 0, 0, displayWidth(), displayHeight());
foreach( Client* c, clients )

163
scene_opengl.cpp Normal file
View file

@ -0,0 +1,163 @@
/*****************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
You can Freely distribute this program under the GNU General Public
License. See the file "COPYING" for the exact licensing terms.
Based on glcompmgr code by Felix Bellaby.
******************************************************************/
#include "scene_opengl.h"
#include "utils.h"
#include "client.h"
namespace KWinInternal
{
//****************************************
// SceneOpenGL
//****************************************
const int root_attrs[] =
{
GLX_DOUBLEBUFFER, False,
GLX_DEPTH_SIZE, 16,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 1,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT | GLX_WINDOW_BIT,
None
};
const int drawable_attrs[] =
{
GLX_DOUBLEBUFFER, False,
GLX_DEPTH_SIZE, 0,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_ALPHA_SIZE, 1,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT | GLX_WINDOW_BIT,
None
};
SceneOpenGL::SceneOpenGL( Workspace* ws )
: Scene( ws )
{
// TODO add checks where needed
int dummy;
if( !glXQueryExtension( display(), &dummy, &dummy ))
return;
XGCValues gcattr;
gcattr.subwindow_mode = IncludeInferiors;
gcroot = XCreateGC( display(), rootWindow(), GCSubwindowMode, &gcattr );
buffer = XCreatePixmap( display(), rootWindow(), displayWidth(), displayHeight(),
QX11Info::appDepth());
GLXFBConfig* fbconfigs = glXChooseFBConfig( display(), DefaultScreen( display()),
root_attrs, &dummy );
fbcroot = fbconfigs[ 0 ];
XFree( fbconfigs );
fbconfigs = glXChooseFBConfig( display(), DefaultScreen( display()),
drawable_attrs, &dummy );
fbcdrawable = fbconfigs[ 0 ];
XFree( fbconfigs );
glxroot = glXCreatePixmap( display(), fbcroot, buffer, NULL );
context = glXCreateNewContext( display(), fbcroot, GLX_RGBA_TYPE, NULL, GL_FALSE );
glXMakeContextCurrent( display(), glxroot, glxroot, context );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, displayWidth(), 0, displayHeight(), 0, 65535 );
// TODO glEnable( GL_DEPTH_TEST );
}
SceneOpenGL::~SceneOpenGL()
{
glXDestroyPixmap( display(), glxroot );
XFreeGC( display(), gcroot );
XFreePixmap( display(), buffer );
glXDestroyContext( display(), context );
}
static void quadDraw( int x, int y, int w, int h )
{
glTexCoord2i( x, y );
glVertex2i( x, y );
glTexCoord2i( x + w, y );
glVertex2i( x + w, y );
glTexCoord2i( x + w, y + h );
glVertex2i( x + w, y + h );
glTexCoord2i( 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 )
{
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 )
{
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 );
glReadBuffer( GL_FRONT );
glDrawBuffer( GL_FRONT );
// TODO grabXServer();
glXWaitX();
GLuint texture;
glGenTextures( 1, &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();
// TODO Y axis in opengl grows up apparently
glTranslatef( (*it)->x(), displayHeight() - (*it)->height() - (*it)->y(), 0 );
glEnable( GL_TEXTURE_RECTANGLE_ARB );
glBegin( GL_QUADS );
quadDraw( 0, 0, (*it)->width(), (*it)->height());
glEnd();
glPopMatrix();
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 );
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 ] );
}
} // namespace

40
scene_opengl.h Normal file
View file

@ -0,0 +1,40 @@
/*****************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2006 Lubos Lunak <l.lunak@kde.org>
You can Freely distribute this program under the GNU General Public
License. See the file "COPYING" for the exact licensing terms.
******************************************************************/
#ifndef KWIN_SCENE_OPENGL_H
#define KWIN_SCENE_OPENGL_H
#include "scene.h"
#include <GL/gl.h>
#include <GL/glx.h>
namespace KWinInternal
{
class SceneOpenGL
: public Scene
{
public:
SceneOpenGL( Workspace* ws );
virtual ~SceneOpenGL();
virtual void paint( XserverRegion damage, ToplevelList windows );
private:
GC gcroot;
Pixmap buffer;
GLXFBConfig fbcroot;
GLXFBConfig fbcdrawable;
GLXPixmap glxroot;
GLXContext context;
};
} // namespace
#endif