From efff218441c39f23dd4c7ff2f1c0c296b10ad63f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Fri, 29 Sep 2006 16:49:34 +0000 Subject: [PATCH] A very crude OpenGL-based compositing code. svn path=/branches/work/kwin_composite/; revision=590265 --- CMakeLists.txt | 67 +++++++++++++++++-- composite.cpp | 4 +- scene_opengl.cpp | 163 +++++++++++++++++++++++++++++++++++++++++++++++ scene_opengl.h | 40 ++++++++++++ 4 files changed, 269 insertions(+), 5 deletions(-) create mode 100644 scene_opengl.cpp create mode 100644 scene_opengl.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 775efa3207..c07e1cee15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/composite.cpp b/composite.cpp index 77e529170e..6f1a2d378f 100644 --- a/composite.cpp +++ b/composite.cpp @@ -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 ) diff --git a/scene_opengl.cpp b/scene_opengl.cpp new file mode 100644 index 0000000000..2636c89a9e --- /dev/null +++ b/scene_opengl.cpp @@ -0,0 +1,163 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2006 Lubos Lunak + +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 diff --git a/scene_opengl.h b/scene_opengl.h new file mode 100644 index 0000000000..ad00287558 --- /dev/null +++ b/scene_opengl.h @@ -0,0 +1,40 @@ +/***************************************************************** + KWin - the KDE window manager + This file is part of the KDE project. + +Copyright (C) 2006 Lubos Lunak + +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 +#include + +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