• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KWin

compositingprefs.cpp

Go to the documentation of this file.
00001 /********************************************************************
00002  KWin - the KDE window manager
00003  This file is part of the KDE project.
00004 
00005 Copyright (C) 2007 Rivo Laks <rivolaks@hot.ee>
00006 
00007 This program is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 This program is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 *********************************************************************/
00020 
00021 #include "compositingprefs.h"
00022 
00023 #include "kwinglobals.h"
00024 
00025 #include <kdebug.h>
00026 #include <kxerrorhandler.h>
00027 #include <klocale.h>
00028 #include <kdeversion.h>
00029 
00030 
00031 namespace KWin
00032 {
00033 
00034 CompositingPrefs::CompositingPrefs()
00035     : mXgl( false )
00036     , mEnableCompositing( false )
00037     , mEnableVSync( true )
00038     , mEnableDirectRendering( true )
00039     , mStrictBinding( true )
00040     {
00041     }
00042 
00043 CompositingPrefs::~CompositingPrefs()
00044     {
00045     }
00046 
00047 bool CompositingPrefs::enableCompositing() const
00048     {
00049     return false; // disabled by default, for the time being, until support becomes better
00050     return mEnableCompositing;
00051     }
00052 
00053 bool CompositingPrefs::compositingPossible()
00054     {
00055 #ifdef KWIN_HAVE_COMPOSITING
00056     Extensions::init();
00057     if( !Extensions::compositeAvailable())
00058         {
00059         kDebug( 1212 ) << "No composite extension available";
00060         return false;
00061         }
00062     if( !Extensions::damageAvailable())
00063         {
00064         kDebug( 1212 ) << "No damage extension available";
00065         return false;
00066         }
00067 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
00068     if( Extensions::glxAvailable())
00069         return true;
00070 #endif
00071 #ifdef KWIN_HAVE_XRENDER_COMPOSITING
00072     if( Extensions::renderAvailable() && Extensions::fixesAvailable())
00073         return true;
00074 #endif
00075     kDebug( 1212 ) << "No OpenGL or XRender/XFixes support";
00076     return false;
00077 #else
00078     return false;
00079 #endif
00080     }
00081 
00082 QString CompositingPrefs::compositingNotPossibleReason()
00083     {
00084 #ifdef KWIN_HAVE_COMPOSITING
00085     Extensions::init();
00086     if( !Extensions::compositeAvailable() || !Extensions::damageAvailable())
00087         {
00088         return i18n("Required X extensions (XComposite and XDamage) are not available.");
00089         }
00090 #if defined( KWIN_HAVE_OPENGL_COMPOSITING ) && !defined( KWIN_HAVE_XRENDER_COMPOSITING )
00091     if( !Extensions::glxAvailable())
00092         return i18n( "GLX/OpenGL are not available and only OpenGL support is compiled." );
00093 #elif !defined( KWIN_HAVE_OPENGL_COMPOSITING ) && defined( KWIN_HAVE_XRENDER_COMPOSITING )
00094     if( !( Extensions::renderAvailable() && Extensions::fixesAvailable()))
00095         return i18n( "XRender/XFixes extensions are not available and only XRender support"
00096             " is compiled." );
00097 #else
00098     if( !( Extensions::glxAvailable()
00099             || ( Extensions::renderAvailable() && Extensions::fixesAvailable())))
00100         {
00101         return i18n( "GLX/OpenGL and XRender/XFixes are not available." );
00102         }
00103 #endif
00104     return QString();
00105 #else
00106     return i18n("Compositing was disabled at compile time.\n"
00107             "It is likely Xorg development headers were not installed.");
00108 #endif
00109     }
00110 
00111 void CompositingPrefs::detect()
00112     {
00113     if( !compositingPossible())
00114         {
00115         return;
00116         }
00117 
00118 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
00119     if( !Extensions::glxAvailable())
00120         {
00121         kDebug( 1212 ) << "No GLX available";
00122         return;
00123         }
00124     int glxmajor, glxminor;
00125     glXQueryVersion( display(), &glxmajor, &glxminor );
00126     kDebug( 1212 ) << "glx version is " << glxmajor << "." << glxminor;
00127     bool hasglx13 = ( glxmajor > 1 || ( glxmajor == 1 && glxminor >= 3 ));
00128 
00129     // remember and later restore active context
00130     GLXContext oldcontext = glXGetCurrentContext();
00131     GLXDrawable olddrawable = glXGetCurrentDrawable();
00132     GLXDrawable oldreaddrawable = None;
00133     if( hasglx13 )
00134         oldreaddrawable = glXGetCurrentReadDrawable();
00135 
00136     if( initGLXContext() )
00137         {
00138         detectDriverAndVersion();
00139         applyDriverSpecificOptions();
00140         }
00141     if( hasglx13 )
00142         glXMakeContextCurrent( display(), olddrawable, oldreaddrawable, oldcontext );
00143     else
00144         glXMakeCurrent( display(), olddrawable, oldcontext );
00145     deleteGLXContext();
00146 #endif
00147     }
00148 
00149 bool CompositingPrefs::initGLXContext()
00150 {
00151 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
00152     mGLContext = NULL;
00153     KXErrorHandler handler;
00154     // Most of this code has been taken from glxinfo.c
00155     QVector<int> attribs;
00156     attribs << GLX_RGBA;
00157     attribs << GLX_RED_SIZE << 1;
00158     attribs << GLX_GREEN_SIZE << 1;
00159     attribs << GLX_BLUE_SIZE << 1;
00160     attribs << None;
00161 
00162     XVisualInfo* visinfo = glXChooseVisual( display(), DefaultScreen( display()), attribs.data() );
00163     if( !visinfo )
00164         {
00165         attribs.last() = GLX_DOUBLEBUFFER;
00166         attribs << None;
00167         visinfo = glXChooseVisual( display(), DefaultScreen( display()), attribs.data() );
00168         if (!visinfo)
00169             {
00170             kDebug( 1212 ) << "Error: couldn't find RGB GLX visual";
00171             return false;
00172             }
00173         }
00174 
00175     mGLContext = glXCreateContext( display(), visinfo, NULL, True );
00176     if ( !mGLContext )
00177     {
00178         kDebug( 1212 ) << "glXCreateContext failed";
00179         XDestroyWindow( display(), mGLWindow );
00180         return false;
00181     }
00182 
00183     XSetWindowAttributes attr;
00184     attr.background_pixel = 0;
00185     attr.border_pixel = 0;
00186     attr.colormap = XCreateColormap( display(), rootWindow(), visinfo->visual, AllocNone );
00187     attr.event_mask = StructureNotifyMask | ExposureMask;
00188     unsigned long mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
00189     int width = 100, height = 100;
00190     mGLWindow = XCreateWindow( display(), rootWindow(), 0, 0, width, height,
00191                        0, visinfo->depth, InputOutput,
00192                        visinfo->visual, mask, &attr );
00193 
00194     return glXMakeCurrent( display(), mGLWindow, mGLContext ) && !handler.error( true );
00195 #else
00196    return false;
00197 #endif
00198 }
00199 
00200 void CompositingPrefs::deleteGLXContext()
00201 {
00202 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
00203     if( mGLContext == NULL )
00204         return;
00205     glXDestroyContext( display(), mGLContext );
00206     XDestroyWindow( display(), mGLWindow );
00207 #endif
00208 }
00209 
00210 void CompositingPrefs::detectDriverAndVersion()
00211     {
00212 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
00213     mGLVendor = QString((const char*)glGetString( GL_VENDOR ));
00214     mGLRenderer = QString((const char*)glGetString( GL_RENDERER ));
00215     mGLVersion = QString((const char*)glGetString( GL_VERSION ));
00216     mXgl = detectXgl();
00217     kDebug( 1212 ) << "GL vendor is" << mGLVendor;
00218     kDebug( 1212 ) << "GL renderer is" << mGLRenderer;
00219     kDebug( 1212 ) << "GL version is" << mGLVersion;
00220     kDebug( 1212 ) << "XGL:" << ( mXgl ? "yes" : "no" );
00221 
00222     if( mGLRenderer.contains( "Intel" ))
00223         {
00224         mDriver = "intel";
00225         QStringList words = mGLRenderer.split(" ");
00226         mVersion = Version( words[ words.count() - 2 ] );
00227         }
00228     else if( mGLVendor.contains( "NVIDIA" ))
00229         {
00230         mDriver = "nvidia";
00231         QStringList words = mGLVersion.split(" ");
00232         mVersion = Version( words[ words.count() - 1 ] );
00233         }
00234     else
00235         {
00236         mDriver = "unknown";
00237         }
00238 
00239     kDebug( 1212 ) << "Detected driver" << mDriver << ", version" << mVersion.join(".");
00240 #endif
00241     }
00242 
00243 void CompositingPrefs::applyDriverSpecificOptions()
00244     {
00245     if( mXgl )
00246         {
00247         kDebug( 1212 ) << "xgl, enabling";
00248         mEnableCompositing = true;
00249         mStrictBinding = false;
00250         }
00251     else if( mDriver == "intel" )
00252         {
00253         kDebug( 1212 ) << "intel driver, disabling vsync, enabling direct";
00254         mEnableVSync = false;
00255         mEnableDirectRendering = true;
00256         // Enable compositing by default only on 900-series cards
00257         if( mVersion >= Version( "20061017" ) && mGLRenderer.contains( "Intel(R) 9" ))
00258             {
00259             kDebug( 1212 ) << "intel >= 20061017 and 900-series card, enabling compositing";
00260             mEnableCompositing = true;
00261             }
00262         }
00263     else if( mDriver == "nvidia" )
00264         {
00265         mStrictBinding = false;
00266         if( mVersion <= Version( "100.14.23" ))
00267             {
00268             kDebug( 1212 ) << "nvidia <= 100.14.23, disabling vsync";
00269             mEnableVSync = false;
00270             }
00271         if( mVersion >= Version( "96.39" ))
00272             {
00273             kDebug( 1212 ) << "nvidia >= 96.39, enabling compositing";
00274             mEnableCompositing = true;
00275             }
00276         }
00277     }
00278 
00279 
00280 bool CompositingPrefs::detectXgl()
00281     { // Xgl apparently uses only this specific X version
00282     return VendorRelease(display()) == 70000001;
00283     }
00284 
00285 CompositingPrefs::Version::Version( const QString& str ) :
00286         QStringList()
00287     {
00288     QRegExp numrx( "(\\d+)|(\\D+)" );
00289     int pos = 0;
00290     while(( pos = numrx.indexIn( str, pos )) != -1 )
00291         {
00292         pos += numrx.matchedLength();
00293 
00294         QString part = numrx.cap();
00295         if( part == "." )
00296             continue;
00297 
00298         append( part );
00299         }
00300     }
00301 
00302 int CompositingPrefs::Version::compare( const Version& v ) const
00303     {
00304     for( int i = 0; i < qMin( count(), v.count() ); i++ )
00305         {
00306         if( at( i )[ 0 ].isDigit() )
00307             {
00308             // This part of version string is numeric - compare numbers
00309             int num = at( i ).toInt();
00310             int vnum = v.at( i ).toInt();
00311             if( num > vnum )
00312                 return 1;
00313             else if( num < vnum )
00314                 return -1;
00315             }
00316         else
00317             {
00318             // This part is string
00319             if( at( i ) > v.at( i ))
00320                 return 1;
00321             else if( at( i ) < v.at( i ))
00322                 return -1;
00323             }
00324         }
00325 
00326     if( count() > v.count() )
00327         return 1;
00328     else if( count() < v.count() )
00329         return -1;
00330     else
00331         return 0;
00332     }
00333 
00334 } // namespace
00335 

KWin

Skip menu "KWin"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libplasma
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal