Detect screen refresh rate for finding out optimal compositing
redraw speed. Patch by Philip Falkner. svn path=/branches/work/kwin_composite/; revision=607253
This commit is contained in:
parent
8bbf28ed9c
commit
38f4f76b31
7 changed files with 72 additions and 13 deletions
|
@ -71,6 +71,9 @@ target_link_libraries(kdeinit_kwin ${KDE4_KDEUI_LIBS} kdecorations ${X11_LIBRAR
|
||||||
target_link_libraries(kdeinit_kwin -lGL)
|
target_link_libraries(kdeinit_kwin -lGL)
|
||||||
# -ldl used by OpenGL code
|
# -ldl used by OpenGL code
|
||||||
target_link_libraries(kdeinit_kwin -ldl)
|
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)
|
if (X11_Xcomposite_FOUND)
|
||||||
target_link_libraries(kdeinit_kwin ${X11_Xcomposite_LIB})
|
target_link_libraries(kdeinit_kwin ${X11_Xcomposite_LIB})
|
||||||
endif (X11_Xcomposite_FOUND)
|
endif (X11_Xcomposite_FOUND)
|
||||||
|
|
|
@ -16,6 +16,7 @@ TODO
|
||||||
- in other words, these should be the best if you want to get started with the code
|
- in other words, these should be the best if you want to get started with the code
|
||||||
/ = work in progress
|
/ = work in progress
|
||||||
? = should it be done?
|
? = should it be done?
|
||||||
|
% = should be probably done later, during cleanups and preparations for being stable
|
||||||
|
|
||||||
|
|
||||||
General TODO
|
General TODO
|
||||||
|
@ -40,7 +41,7 @@ General TODO
|
||||||
- maybe posted paint events need to be processed immediatelly, or maybe the compositing
|
- 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
|
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
|
- output buffers and similar probably need recreating when the screen size changes
|
||||||
|
|
||||||
! compile even without OpenGL or XRender
|
! 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?
|
? 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
|
OpenGL TODO
|
||||||
=================================
|
=================================
|
||||||
|
|
||||||
+ Check/make it work with other gfx cards
|
+ 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
|
- 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
|
- 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
|
- intel
|
||||||
! - does kwin_composite work there at all?
|
! - does kwin_composite work there at all?
|
||||||
! - does glcompmgr work there at all? (even with the various switches in the source)
|
! - 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
|
? - is there a good reason to support Xgl? With the 9625 nvidia drivers
|
||||||
it seems to work fine without them and there's AIGLX
|
it seems to work fine without them and there's AIGLX
|
||||||
|
|
||||||
? AIGLX support
|
+ AIGLX support
|
||||||
- no idea about this at all
|
- kind of works, needs more work
|
||||||
+ - find out if it works
|
|
||||||
|
|
||||||
! improved GLXFBConfig support
|
! improved GLXFBConfig support
|
||||||
- it seems a different config for each depth would be needed
|
- 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)
|
one for the root window (or for the window used in the XComposite overlay)
|
||||||
and the best one for every depth of drawables
|
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
|
+ GL_ARB_texture_rectangle vs GL_ARB_texture_non_power_of_two
|
||||||
- code currently uses GL_ARB_texture_rectangle (GL_TEXTURE_RECTANGLE_ARB), using
|
- 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
|
normal textures when GL_ARB_texture_non_power_of_two is available should(?) be
|
||||||
|
|
|
@ -80,7 +80,34 @@ void Workspace::setupCompositing()
|
||||||
kDebug( 1212 ) << "No compositing" << endl;
|
kDebug( 1212 ) << "No compositing" << endl;
|
||||||
return;
|
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();
|
lastCompositePaint.start();
|
||||||
XCompositeRedirectSubwindows( display(), rootWindow(), CompositeRedirectManual );
|
XCompositeRedirectSubwindows( display(), rootWindow(), CompositeRedirectManual );
|
||||||
if( dynamic_cast< SceneOpenGL* >( scene ))
|
if( dynamic_cast< SceneOpenGL* >( scene ))
|
||||||
|
|
|
@ -194,6 +194,7 @@ unsigned long Options::updateSettings()
|
||||||
removeShadowsOnResize = config->readEntry("RemoveShadowsOnResize", QVariant(true)).toBool();
|
removeShadowsOnResize = config->readEntry("RemoveShadowsOnResize", QVariant(true)).toBool();
|
||||||
onlyDecoTranslucent = config->readEntry("OnlyDecoTranslucent", QVariant(false)).toBool();
|
onlyDecoTranslucent = config->readEntry("OnlyDecoTranslucent", QVariant(false)).toBool();
|
||||||
|
|
||||||
|
refreshRate = config->readEntry( "RefreshRate", 0 );
|
||||||
QString glmode = config->readEntry("GLMode", "TFP" ).upper();
|
QString glmode = config->readEntry("GLMode", "TFP" ).upper();
|
||||||
if( glmode == "TFP" )
|
if( glmode == "TFP" )
|
||||||
glMode = GLTFP;
|
glMode = GLTFP;
|
||||||
|
|
|
@ -300,6 +300,7 @@ class Options : public KDecorationOptions
|
||||||
uint dockShadowSize;
|
uint dockShadowSize;
|
||||||
bool onlyDecoTranslucent;
|
bool onlyDecoTranslucent;
|
||||||
|
|
||||||
|
uint refreshRate;
|
||||||
enum GLMode { GLTFP, GLSHM, GLFallback };
|
enum GLMode { GLTFP, GLSHM, GLFallback };
|
||||||
GLMode glMode;
|
GLMode glMode;
|
||||||
bool glAlwaysRebind;
|
bool glAlwaysRebind;
|
||||||
|
|
22
utils.cpp
22
utils.cpp
|
@ -45,6 +45,8 @@ namespace KWinInternal
|
||||||
|
|
||||||
bool Extensions::has_shape = false;
|
bool Extensions::has_shape = false;
|
||||||
int Extensions::shape_event_base = 0;
|
int Extensions::shape_event_base = 0;
|
||||||
|
bool Extensions::has_randr = false;
|
||||||
|
int Extensions::randr_event_base = 0;
|
||||||
bool Extensions::has_damage = false;
|
bool Extensions::has_damage = false;
|
||||||
int Extensions::damage_event_base = 0;
|
int Extensions::damage_event_base = 0;
|
||||||
bool Extensions::has_composite = false;
|
bool Extensions::has_composite = false;
|
||||||
|
@ -55,6 +57,17 @@ void Extensions::init()
|
||||||
{
|
{
|
||||||
int dummy;
|
int dummy;
|
||||||
has_shape = XShapeQueryExtension( display(), &shape_event_base, &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
|
#ifdef HAVE_XDAMAGE
|
||||||
has_damage = XDamageQueryExtension( display(), &damage_event_base, &dummy );
|
has_damage = XDamageQueryExtension( display(), &damage_event_base, &dummy );
|
||||||
#else
|
#else
|
||||||
|
@ -99,6 +112,15 @@ bool Extensions::hasShape( Window w )
|
||||||
return boundingShaped != 0;
|
return boundingShaped != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Extensions::randrNotifyEvent()
|
||||||
|
{
|
||||||
|
#ifdef HAVE_XRANDR
|
||||||
|
return randr_event_base + RRScreenChangeNotify;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int Extensions::damageNotifyEvent()
|
int Extensions::damageNotifyEvent()
|
||||||
{
|
{
|
||||||
#ifdef HAVE_XDAMAGE
|
#ifdef HAVE_XDAMAGE
|
||||||
|
|
8
utils.h
8
utils.h
|
@ -17,6 +17,10 @@ License. See the file "COPYING" for the exact licensing terms.
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_XRANDR
|
||||||
|
#include <X11/extensions/Xrandr.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_XCOMPOSITE
|
#ifdef HAVE_XCOMPOSITE
|
||||||
#include <X11/extensions/Xcomposite.h>
|
#include <X11/extensions/Xcomposite.h>
|
||||||
#if XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR >= 3
|
#if XCOMPOSITE_MAJOR > 0 || XCOMPOSITE_MINOR >= 3
|
||||||
|
@ -151,6 +155,8 @@ class Extensions
|
||||||
static void init();
|
static void init();
|
||||||
static bool shapeAvailable() { return has_shape; }
|
static bool shapeAvailable() { return has_shape; }
|
||||||
static int shapeNotifyEvent();
|
static int shapeNotifyEvent();
|
||||||
|
static bool randrAvailable() { return has_randr; }
|
||||||
|
static int randrNotifyEvent();
|
||||||
static bool damageAvailable() { return has_damage; }
|
static bool damageAvailable() { return has_damage; }
|
||||||
static int damageNotifyEvent();
|
static int damageNotifyEvent();
|
||||||
static bool compositeAvailable() { return has_composite; }
|
static bool compositeAvailable() { return has_composite; }
|
||||||
|
@ -160,6 +166,8 @@ class Extensions
|
||||||
private:
|
private:
|
||||||
static bool has_shape;
|
static bool has_shape;
|
||||||
static int shape_event_base;
|
static int shape_event_base;
|
||||||
|
static bool has_randr;
|
||||||
|
static int randr_event_base;
|
||||||
static bool has_damage;
|
static bool has_damage;
|
||||||
static int damage_event_base;
|
static int damage_event_base;
|
||||||
static bool has_composite;
|
static bool has_composite;
|
||||||
|
|
Loading…
Reference in a new issue