Change timers to QElapsedTimers

Instead of calculating the elapsed time from epoch clock, using
a QElapsedTimer as well as reusing the timer object instead of
creating a new one in the scene each frame.

REVIEW: 102473
This commit is contained in:
Martin Gräßlin 2011-08-29 06:47:07 +02:00
parent e930a50f8a
commit 6e15c0c208
7 changed files with 20 additions and 18 deletions

View file

@ -168,7 +168,7 @@ void Workspace::setupCompositing()
} else } else
vBlankInterval = 1 << 10; // no sync - DO NOT set "0", would cause div-by-zero segfaults. vBlankInterval = 1 << 10; // no sync - DO NOT set "0", would cause div-by-zero segfaults.
vBlankPadding = 3; // vblank rounding errors... :-( vBlankPadding = 3; // vblank rounding errors... :-(
nextPaintReference = QDateTime::currentMSecsSinceEpoch(); nextPaintReference.restart();
checkCompositeTimer(); checkCompositeTimer();
XCompositeRedirectSubwindows(display(), rootWindow(), CompositeRedirectManual); XCompositeRedirectSubwindows(display(), rootWindow(), CompositeRedirectManual);
new EffectsHandlerImpl(scene->compositingType()); // sets also the 'effects' pointer new EffectsHandlerImpl(scene->compositingType()); // sets also the 'effects' pointer
@ -393,10 +393,10 @@ void Workspace::performCompositing()
if (scene->waitSyncAvailable()) { if (scene->waitSyncAvailable()) {
// vsync: paint the scene, than rebase the timer and use the duration for next timeout estimation // vsync: paint the scene, than rebase the timer and use the duration for next timeout estimation
scene->paint(repaints, windows); scene->paint(repaints, windows);
nextPaintReference = QDateTime::currentMSecsSinceEpoch(); nextPaintReference.restart();
} else { } else {
// no vsyc -> inversion: reset the timer, then paint the scene, this way we can provide a constant framerate // no vsyc -> inversion: reset the timer, then paint the scene, this way we can provide a constant framerate
nextPaintReference = QDateTime::currentMSecsSinceEpoch(); nextPaintReference.restart();
scene->paint(repaints, windows); scene->paint(repaints, windows);
} }
// reset the roundin error corrective... :-( // reset the roundin error corrective... :-(
@ -436,7 +436,7 @@ void Workspace::setCompositeTimer()
return; return;
// interval - "time since last paint completion" - "time we need to paint" // interval - "time since last paint completion" - "time we need to paint"
uint passed = (QDateTime::currentMSecsSinceEpoch() - nextPaintReference) << 10; uint passed = nextPaintReference.elapsed() << 10;
uint delay = fpsInterval; uint delay = fpsInterval;
if (scene->waitSyncAvailable()) { if (scene->waitSyncAvailable()) {
if (passed > fpsInterval) { if (passed > fpsInterval) {

View file

@ -164,7 +164,7 @@ void Scene::paintScreen(int* mask, QRegion* region)
// Compute time since the last painting pass. // Compute time since the last painting pass.
void Scene::updateTimeDiff() void Scene::updateTimeDiff()
{ {
if (last_time.isNull()) { if (!last_time.isValid()) {
// Painting has been idle (optimized out) for some time, // Painting has been idle (optimized out) for some time,
// which means time_diff would be huge and would break animations. // which means time_diff would be huge and would break animations.
// Simply set it to one (zero would mean no change at all and could // Simply set it to one (zero would mean no change at all and could
@ -174,14 +174,14 @@ void Scene::updateTimeDiff()
time_diff = last_time.elapsed(); time_diff = last_time.elapsed();
if (time_diff < 0) // check time rollback if (time_diff < 0) // check time rollback
time_diff = 1; time_diff = 1;
last_time.start();; last_time.restart();;
} }
// Painting pass is optimized away. // Painting pass is optimized away.
void Scene::idle() void Scene::idle()
{ {
// Don't break time since last paint for the next pass. // Don't break time since last paint for the next pass.
last_time = QTime(); last_time.invalidate();;
} }
// the function that'll be eventually called by paintScreen() above // the function that'll be eventually called by paintScreen() above

View file

@ -21,8 +21,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef KWIN_SCENE_H #ifndef KWIN_SCENE_H
#define KWIN_SCENE_H #define KWIN_SCENE_H
#include <QDateTime>
#include "toplevel.h" #include "toplevel.h"
#include "utils.h" #include "utils.h"
#include "kwineffects.h" #include "kwineffects.h"
@ -151,11 +149,12 @@ protected:
// time since last repaint // time since last repaint
int time_diff; int time_diff;
uint lastRenderTime; uint lastRenderTime;
QTime last_time; QElapsedTimer last_time;
Workspace* wspace; Workspace* wspace;
bool has_waitSync; bool has_waitSync;
LanczosFilter* lanczos_filter; LanczosFilter* lanczos_filter;
OverlayWindow* m_overlayWindow; OverlayWindow* m_overlayWindow;
QElapsedTimer m_renderTimer;
}; };
// The base class for windows representations in composite backends // The base class for windows representations in composite backends

View file

@ -167,7 +167,7 @@ bool SceneOpenGL::initDrawableConfigs()
// the entry function for painting // the entry function for painting
void SceneOpenGL::paint(QRegion damage, ToplevelList toplevels) void SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
{ {
QTime t = QTime::currentTime(); m_renderTimer.restart();
foreach (Toplevel * c, toplevels) { foreach (Toplevel * c, toplevels) {
assert(windows.contains(c)); assert(windows.contains(c));
stacking_order.append(windows[ c ]); stacking_order.append(windows[ c ]);
@ -179,7 +179,8 @@ void SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
ungrabXServer(); // ungrab before flushBuffer(), it may wait for vsync ungrabXServer(); // ungrab before flushBuffer(), it may wait for vsync
if (m_overlayWindow->window()) // show the window only after the first pass, since if (m_overlayWindow->window()) // show the window only after the first pass, since
m_overlayWindow->show(); // that pass may take long m_overlayWindow->show(); // that pass may take long
lastRenderTime = t.elapsed(); lastRenderTime = m_renderTimer.elapsed();
m_renderTimer.invalidate();
flushBuffer(mask, damage); flushBuffer(mask, damage);
// do cleanup // do cleanup
stacking_order.clear(); stacking_order.clear();

View file

@ -437,7 +437,7 @@ bool SceneOpenGL::initDrawableConfigs()
// the entry function for painting // the entry function for painting
void SceneOpenGL::paint(QRegion damage, ToplevelList toplevels) void SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
{ {
QTime t = QTime::currentTime(); m_renderTimer.restart();
foreach (Toplevel * c, toplevels) { foreach (Toplevel * c, toplevels) {
assert(windows.contains(c)); assert(windows.contains(c));
stacking_order.append(windows[ c ]); stacking_order.append(windows[ c ]);
@ -457,7 +457,8 @@ void SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
ungrabXServer(); // ungrab before flushBuffer(), it may wait for vsync ungrabXServer(); // ungrab before flushBuffer(), it may wait for vsync
if (m_overlayWindow->window()) // show the window only after the first pass, since if (m_overlayWindow->window()) // show the window only after the first pass, since
m_overlayWindow->show(); // that pass may take long m_overlayWindow->show(); // that pass may take long
lastRenderTime = t.elapsed(); lastRenderTime = m_renderTimer.elapsed();
m_renderTimer.invalidate();
flushBuffer(mask, damage); flushBuffer(mask, damage);
// do cleanup // do cleanup
stacking_order.clear(); stacking_order.clear();

View file

@ -161,7 +161,7 @@ void SceneXrender::createBuffer()
// the entry point for painting // the entry point for painting
void SceneXrender::paint(QRegion damage, ToplevelList toplevels) void SceneXrender::paint(QRegion damage, ToplevelList toplevels)
{ {
QTime t = QTime::currentTime(); m_renderTimer.restart();
foreach (Toplevel * c, toplevels) { foreach (Toplevel * c, toplevels) {
assert(windows.contains(c)); assert(windows.contains(c));
stacking_order.append(windows[ c ]); stacking_order.append(windows[ c ]);
@ -170,7 +170,8 @@ void SceneXrender::paint(QRegion damage, ToplevelList toplevels)
paintScreen(&mask, &damage); paintScreen(&mask, &damage);
if (m_overlayWindow->window()) // show the window only after the first pass, since if (m_overlayWindow->window()) // show the window only after the first pass, since
m_overlayWindow->show(); // that pass may take long m_overlayWindow->show(); // that pass may take long
lastRenderTime = t.elapsed(); lastRenderTime = m_renderTimer.elapsed();
m_renderTimer.invalidate();
flushBuffer(mask, damage); flushBuffer(mask, damage);
// do cleanup // do cleanup
stacking_order.clear(); stacking_order.clear();

View file

@ -29,7 +29,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QCursor> #include <QCursor>
#include <netwm.h> #include <netwm.h>
#include <kxmessages.h> #include <kxmessages.h>
#include <QDateTime> #include <QElapsedTimer>
#include <kmanagerselection.h> #include <kmanagerselection.h>
#include "kactivitycontroller.h" #include "kactivitycontroller.h"
@ -888,7 +888,7 @@ private:
KSelectionOwner* cm_selection; KSelectionOwner* cm_selection;
bool compositingSuspended, compositingBlocked; bool compositingSuspended, compositingBlocked;
QBasicTimer compositeTimer; QBasicTimer compositeTimer;
qint64 nextPaintReference; QElapsedTimer nextPaintReference;
QTimer mousePollingTimer; QTimer mousePollingTimer;
uint vBlankInterval, vBlankPadding, fpsInterval, estimatedRenderTime; uint vBlankInterval, vBlankPadding, fpsInterval, estimatedRenderTime;
int xrrRefreshRate; // used only for compositing int xrrRefreshRate; // used only for compositing