diff --git a/CMakeLists.txt b/CMakeLists.txt index 85db33cf59..8abd5b3021 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,9 @@ target_link_libraries(kdeinit_kwin ${KDE4_KDEUI_LIBS} kdecorations ${X11_LIBRAR target_link_libraries(kdeinit_kwin -lGL) # -ldl used by OpenGL code target_link_libraries(kdeinit_kwin -ldl) +if (X11_Xrandr_FOUND) + target_link_libraries(kdeinit_kwin ${X11_Xrandr_LIB}) +endif (X11_Xrandr_FOUND) if (X11_Xcomposite_FOUND) target_link_libraries(kdeinit_kwin ${X11_Xcomposite_LIB}) endif (X11_Xcomposite_FOUND) diff --git a/COMPOSITE_TODO b/COMPOSITE_TODO index 2b550fde53..db333ecdeb 100644 --- a/COMPOSITE_TODO +++ b/COMPOSITE_TODO @@ -16,6 +16,7 @@ TODO - in other words, these should be the best if you want to get started with the code / = work in progress ? = should it be done? +% = should be probably done later, during cleanups and preparations for being stable General TODO @@ -40,7 +41,7 @@ General TODO - maybe posted paint events need to be processed immediatelly, or maybe the compositing code should not update the window until the decoration is finished painting -* handle XRandr changes +/ handle XRandr changes - output buffers and similar probably need recreating when the screen size changes ! compile even without OpenGL or XRender @@ -51,17 +52,18 @@ General TODO ? Expose events for overlay window - is it necessary to track it, like with root window? +% paint throttling + - there's 5ms grace period per repaint to avoid overloading the system with just compositing + and not letting the system do anything else - check and evaluate + OpenGL TODO ================================= + Check/make it work with other gfx cards - I've tested only with nvidia with the 9625 beta drivers and 8776 stable drivers so far + - ATI - some (especially R200 chips) seem to work - I have absolutely no idea about other gfx cards, needs to be tested - - ati -! - does kwin_composite work there at all? -! - does glcompmgr work there at all? (even with the various switches in the source) -+ - make kwin_composite work there if it doesn't - intel ! - does kwin_composite work there at all? ! - does glcompmgr work there at all? (even with the various switches in the source) @@ -80,9 +82,8 @@ OpenGL TODO ? - is there a good reason to support Xgl? With the 9625 nvidia drivers it seems to work fine without them and there's AIGLX -? AIGLX support - - no idea about this at all -+ - find out if it works ++ AIGLX support + - kind of works, needs more work ! improved GLXFBConfig support - it seems a different config for each depth would be needed @@ -96,10 +97,6 @@ OpenGL TODO one for the root window (or for the window used in the XComposite overlay) and the best one for every depth of drawables -/ sync to vblank - - currently the compositing code is run with 20ms timer, i.e. constant 50fps - - the GLX_SGI_video_sync extension should be used - + GL_ARB_texture_rectangle vs GL_ARB_texture_non_power_of_two - code currently uses GL_ARB_texture_rectangle (GL_TEXTURE_RECTANGLE_ARB), using normal textures when GL_ARB_texture_non_power_of_two is available should(?) be diff --git a/composite.cpp b/composite.cpp index 3516ff6bc9..d3948ec8c6 100644 --- a/composite.cpp +++ b/composite.cpp @@ -80,7 +80,34 @@ void Workspace::setupCompositing() kDebug( 1212 ) << "No compositing" << endl; return; } - compositeTimer.start( 20 ); + int rate = 0; + if( options->refreshRate > 0 ) + { // use manually configured refresh rate + rate = options->refreshRate; + } +#ifdef HAVE_XRANDR + else + { // autoconfigure refresh rate based on XRandR info + if( Extensions::randrAvailable() ) + { + XRRScreenConfiguration *config; + + config = XRRGetScreenInfo( display(), rootWindow() ); + rate = XRRConfigCurrentRate( config ); + XRRFreeScreenConfigInfo( config ); + } + } +#endif + // 0Hz or less is invalid, so we fallback to a default rate + if( rate <= 0 ) + rate = 50; + // QTimer gives us 1msec (1000Hz) at best, so we ignore anything higher; + // however, since compositing is limited to no more than once per 5msec, + // 200Hz to 1000Hz are effectively identical + else if( rate > 1000 ) + rate = 1000; + kDebug( 1212 ) << "Refresh rate " << rate << "Hz" << endl; + compositeTimer.start( 1000 / rate ); lastCompositePaint.start(); XCompositeRedirectSubwindows( display(), rootWindow(), CompositeRedirectManual ); if( dynamic_cast< SceneOpenGL* >( scene )) diff --git a/options.cpp b/options.cpp index f0d202ed13..70a619b0ec 100644 --- a/options.cpp +++ b/options.cpp @@ -194,6 +194,7 @@ unsigned long Options::updateSettings() removeShadowsOnResize = config->readEntry("RemoveShadowsOnResize", QVariant(true)).toBool(); onlyDecoTranslucent = config->readEntry("OnlyDecoTranslucent", QVariant(false)).toBool(); + refreshRate = config->readEntry( "RefreshRate", 0 ); QString glmode = config->readEntry("GLMode", "TFP" ).upper(); if( glmode == "TFP" ) glMode = GLTFP; diff --git a/options.h b/options.h index 24893f8579..621fb7aba9 100644 --- a/options.h +++ b/options.h @@ -300,6 +300,7 @@ class Options : public KDecorationOptions uint dockShadowSize; bool onlyDecoTranslucent; + uint refreshRate; enum GLMode { GLTFP, GLSHM, GLFallback }; GLMode glMode; bool glAlwaysRebind; diff --git a/utils.cpp b/utils.cpp index 78244bf1c7..6df86c80ae 100644 --- a/utils.cpp +++ b/utils.cpp @@ -45,6 +45,8 @@ namespace KWinInternal bool Extensions::has_shape = false; int Extensions::shape_event_base = 0; +bool Extensions::has_randr = false; +int Extensions::randr_event_base = 0; bool Extensions::has_damage = false; int Extensions::damage_event_base = 0; bool Extensions::has_composite = false; @@ -55,6 +57,17 @@ void Extensions::init() { int dummy; has_shape = XShapeQueryExtension( display(), &shape_event_base, &dummy); +#ifdef HAVE_XRANDR + has_randr = XRRQueryExtension( display(), &randr_event_base, &dummy ); + if( has_randr ) + { + int major, minor; + XRRQueryVersion( display(), &major, &minor ); + has_randr = ( major > 1 || ( major == 1 && minor >= 1 ) ); + } +#else + has_randr = false; +#endif #ifdef HAVE_XDAMAGE has_damage = XDamageQueryExtension( display(), &damage_event_base, &dummy ); #else @@ -99,6 +112,15 @@ bool Extensions::hasShape( Window w ) return boundingShaped != 0; } +int Extensions::randrNotifyEvent() + { +#ifdef HAVE_XRANDR + return randr_event_base + RRScreenChangeNotify; +#else + return 0; +#endif + } + int Extensions::damageNotifyEvent() { #ifdef HAVE_XDAMAGE diff --git a/utils.h b/utils.h index 5f09639a33..233b207075 100644 --- a/utils.h +++ b/utils.h @@ -17,6 +17,10 @@ License. See the file "COPYING" for the exact licensing terms. #include +#ifdef HAVE_XRANDR +#include +#endif + #ifdef HAVE_XCOMPOSITE #include #if XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR >= 3 @@ -151,6 +155,8 @@ class Extensions static void init(); static bool shapeAvailable() { return has_shape; } static int shapeNotifyEvent(); + static bool randrAvailable() { return has_randr; } + static int randrNotifyEvent(); static bool damageAvailable() { return has_damage; } static int damageNotifyEvent(); static bool compositeAvailable() { return has_composite; } @@ -160,6 +166,8 @@ class Extensions private: static bool has_shape; static int shape_event_base; + static bool has_randr; + static int randr_event_base; static bool has_damage; static int damage_event_base; static bool has_composite;