[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: KDE/kdegames/kwin4/src
From: Martin Heni <martin () heni-online ! de>
Date: 2007-10-31 18:56:13
Message-ID: 1193856973.970212.1515.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 731449 by heni:
Another try to handle the performance issues of the reflections
- Split reflection calculation into several steps
- Slow down Qt graphics update on slow computers
M +112 -53 kwin4view.cpp
M +24 -4 kwin4view.h
M +1 -1 pixmapsprite.h
M +2 -1 thememanager.cpp
M +2 -3 thememanager.h
--- trunk/KDE/kdegames/kwin4/src/kwin4view.cpp #731448:731449
@@ -25,7 +25,6 @@
#include <math.h>
// Qt includes
-#include <QTimer>
#include <QColor>
#include <QEvent>
#include <QTime>
@@ -46,7 +45,9 @@
// How many time measurements for average
#define MEASUREMENT_LIST_SIZE 50
// How many warnings until reflections are switched off
-#define WARNING_MAX_COUNT 10
+#define WARNING_MAX_COUNT 5
+// How many milliseconds rounding error
+#define MEASUREMENT_ROUNDING_ERROR 5
// Constructor for the view
@@ -55,11 +56,15 @@
ReflectionGraphicsScene* scene,
ThemeManager* theme,
QWidget* parent)
- : QGraphicsView(scene, parent)
+ : Themeable("theview", theme), QGraphicsView(scene, parent)
{
// Store attributes
- mScene = scene;
- mTheme = theme;
+ mScene = scene;
+ mTheme = theme;
+ mDefaultUpdateTime = updateTime;
+ mSlowDownFactor = 1.0;
+ mSlowCnt = 0;
+ mReflectPhase = 0;
// We do not need scrolling so switch it off
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@@ -81,9 +86,9 @@
scene->setBackgroundBrush(QColor(0,0,128));
- QTimer* timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(updateAndAdvance()));
- timer->start(updateTime);
+ mTimer = new QTimer(this);
+ connect(mTimer, SIGNAL(timeout()), this, SLOT(updateAndAdvance()));
+ mTimer->start(mDefaultUpdateTime);
// Game status
mIsRunning = false;
@@ -116,7 +121,6 @@
mReflectionSprite->hide();
// Debug
- mDisplayUpdateTime = updateTime;
mFrameSprite = new QGraphicsTextItem(0, scene);
mFrameSprite->setPos(QPointF(0.0, 0.0));
mFrameSprite->setZValue(1000.0);
@@ -145,47 +149,118 @@
if (mReflectionSprite) delete mReflectionSprite;
}
+// Main themeable function. Called for any theme change.
+void KWin4View::changeTheme()
+{
+ if (global_debug > 0) kDebug() << "CHANGE THEME IN VIEW ... resetting slow \
counter"; + mDrawTimes.clear();
+ mSlowDownFactor = 1.0;
+ mSlowCnt = 0;
+ mTimer->setInterval(int(mDefaultUpdateTime*mSlowDownFactor));
+}
+
// Advance and update canvas/scene
void KWin4View::updateAndAdvance()
{
+ // Time measurement (maybe remove static at some point)
+ static bool first = true;
+ static QTime time;
+ int elapsed = time.elapsed();
+ if (first) {elapsed = 0;first=false;}
+ time.restart();
+
+ // Time display
+ mDrawTimes.append(elapsed);
+ if (mDrawTimes.size() > MEASUREMENT_LIST_SIZE) mDrawTimes.removeFirst();
+ double avg = 0.0;
+ for (int i=0; i<mDrawTimes.size(); i++) avg += mDrawTimes[i];
+ avg /= mDrawTimes.size();
+
+ // Set debug sprite
+ if (global_debug > 0)
+ {
+ mFrameSprite->setPlainText(QString("CurrentUpdate: %1 ms AverageUpdate%2 ms \
DefaultUpdate: %3*%4 ms"). + \
arg(elapsed).arg(int(avg)).arg(mDefaultUpdateTime).arg(mSlowDownFactor)); + }
+
+
+ // Dynamic update of the graphics advance and update speed
+ if (mDrawTimes.size() == MEASUREMENT_LIST_SIZE &&
+ avg > mDefaultUpdateTime*mSlowDownFactor+MEASUREMENT_ROUNDING_ERROR)
+ {
+ mSlowCnt++;
+ kDebug() << "Warning " << mSlowCnt << " avg=" << avg;
+ mDrawTimes.clear();
+ if (mSlowCnt > WARNING_MAX_COUNT)
+ {
+ mSlowDownFactor = \
double(MEASUREMENT_ROUNDING_ERROR+avg)/double(mDefaultUpdateTime); + mSlowCnt = \
0; + mTimer->setInterval(int(mDefaultUpdateTime*mSlowDownFactor));
+
+ kDebug() << "SLOW COMPUTER WARNING: Decreasing graphics update speed "
+ << mDefaultUpdateTime*mSlowDownFactor<<"ms. Maybe switch off \
reflections."; + }
+ }
+
+
+ // Scene advance
scene()->advance();
// QGV takes care of updating dirty rects, no need to call update or the whole \
scene is dirtied and repainted // scene()->update();
+
+ // ====================================================================================
// Reflections need to be done in the view otherwise the update's go wrong
if (mReflectionRect.width() >0 && mReflectionRect.height() > 0)
{
- QImage image(mReflectionRect.width(), mReflectionRect.height(), \
QImage::Format_ARGB32);
- image.fill(Qt::transparent);
- QPainter imagePainter(&image);
- // imagePainter.fillRect(image.rect(),QBrush(Qt::red));
+ // Draw reflection in steps to save processing power
+ if (mReflectPhase == 0)
+ {
+ mReflectImage = QImage(mReflectionRect.width(), mReflectionRect.height(), \
QImage::Format_ARGB32); + mReflectImage.fill(Qt::transparent);
+ QPainter imagePainter(&mReflectImage);
+ // imagePainter.fillRect(image.rect(),QBrush(Qt::red));
- //Turn on all optimizations
- imagePainter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing \
| QPainter::SmoothPixmapTransform, false);
- imagePainter.setClipping(true);
- imagePainter.setWorldMatrix(QMatrix(1.0,0.0,0.0,-1.0,0.0,image.height()));
- QRect source = QRect(mReflectionRect.x(),mReflectionRect.y()-image.height(), \
image.width(), image.height()); + //Turn on all optimizations
+ imagePainter.setRenderHints(QPainter::Antialiasing |
+ QPainter::TextAntialiasing |
+ QPainter::SmoothPixmapTransform, false);
+ imagePainter.setClipping(true);
+ imagePainter.setWorldMatrix(QMatrix(1.0,0.0,0.0,-1.0,0.0,mReflectImage.height()));
+ QRect source = \
QRect(mReflectionRect.x(),mReflectionRect.y()-mReflectImage.height(), + \
mReflectImage.width(), mReflectImage.height());
- bool vis = mReflectionSprite->isVisible();
- mReflectionSprite->hide();
- dynamic_cast<ReflectionGraphicsScene*>(scene())->setBackground(false);
- scene()->render(&imagePainter, image.rect(), source, Qt::IgnoreAspectRatio);
- dynamic_cast<ReflectionGraphicsScene*>(scene())->setBackground(true);
- if (vis) mReflectionSprite->show();
-
- // Semi transparent
- imagePainter.setTransform(QTransform());
- imagePainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
- imagePainter.drawImage(0,0,mGradientImage);
-
- // Set to sprite
- QPixmap pm = QPixmap::fromImage(image);
- mReflectionSprite->setPixmap(pm);
- mReflectionSprite->update();
+ bool vis = mReflectionSprite->isVisible();
+ mReflectionSprite->hide();
+ dynamic_cast<ReflectionGraphicsScene*>(scene())->setBackground(false);
+ scene()->render(&imagePainter, mReflectImage.rect(), source, \
Qt::IgnoreAspectRatio); + \
dynamic_cast<ReflectionGraphicsScene*>(scene())->setBackground(true); + if (vis) \
mReflectionSprite->show(); + mReflectPhase = 1;
+ }
+ // Draw reflection in steps to save processing power
+ else if (mReflectPhase == 1)
+ {
+ // Semi transparent
+ QPainter imagePainter(&mReflectImage);
+ imagePainter.setTransform(QTransform());
+ imagePainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ imagePainter.drawImage(0,0,mGradientImage);
+ mReflectPhase = 2;
+ }
+ // Draw reflection in steps to save processing power
+ else if (mReflectPhase == 2)
+ {
+ // Set to sprite
+ QPixmap pm = QPixmap::fromImage(mReflectImage);
+ mReflectionSprite->setPixmap(pm);
+ mReflectionSprite->update();
+ mReflectPhase = 0;
+ }
}
+ // ====================================================================================
-
}
@@ -219,27 +294,11 @@
}
}
-// QGV drawItems function
+
+// QGV drawItems function (for debug time measurements)
void KWin4View::drawItems(QPainter* painter, int numItems, QGraphicsItem* items[], \
const QStyleOptionGraphicsItem options[]) {
- static bool first = true;
- static QTime time;
- int elapsed = time.elapsed();
- if (first) {elapsed = 0;first=false;}
- time.restart();
QGraphicsView::drawItems(painter, numItems, items, options);
-
- // Time display
- mDrawTimes.append(elapsed);
- if (mDrawTimes.size() > MEASUREMENT_LIST_SIZE) mDrawTimes.removeFirst();
- double avg = 0.0;
- for (int i=0; i<mDrawTimes.size(); i++) avg += mDrawTimes[i];
- avg /= mDrawTimes.size();
-
-
- if (global_debug > 0)
- mFrameSprite->setPlainText(QString("Draw: %1 ms Average %2 ms Update: %3 \
ms").arg(elapsed).arg(int(avg)).arg(mDisplayUpdateTime));
-
}
--- trunk/KDE/kdegames/kwin4/src/kwin4view.h #731448:731449
@@ -34,7 +34,9 @@
#include <QLinearGradient>
#include <QImage>
#include <QPixmap>
+#include <QTimer>
+
// KDE includes
#include <kgameio.h>
@@ -51,7 +53,7 @@
/**
* The view object which shows the graphics for the game.
*/
-class KWin4View : public QGraphicsView
+class KWin4View : public QGraphicsView, public virtual Themeable
{
Q_OBJECT
@@ -73,6 +75,12 @@
*/
~KWin4View();
+ /** Main theme manager function. Called when any theme change like
+ * a new theme or a theme size change occurs. This object needs to
+ * resiez and redraw then.
+ */
+ virtual void changeTheme();
+
/** Initial setup of the game view.
*/
void initGame(Score *scoreData);
@@ -186,8 +194,9 @@
// The theme manager
ThemeManager* mTheme;
- // Theme Queue
+ // Theme queue
QList<int> mThemeQueue;
+ // Theme offset queque
QList<QPoint> mThemeOffset;
// The scene to plot to
@@ -213,13 +222,24 @@
QGraphicsPixmapItem* mReflectionSprite;
// Refection size
QRect mReflectionRect;
+ // Paint image of reflection
+ QImage mReflectImage;
+ // Phase of reflection drawing
+ int mReflectPhase;
// Debug frame rate sprite
QGraphicsTextItem* mFrameSprite;
- // Time between updates
- int mDisplayUpdateTime;
// Average update times
QList<int> mDrawTimes;
+
+ // Update and advance timer
+ QTimer* mTimer;
+ // Default update time [ms]
+ int mDefaultUpdateTime;
+ // Update slow down factor
+ double mSlowDownFactor;
+ // Slow incident counter
+ int mSlowCnt;
};
#endif // KWIN4_KWIN4VIEW_H
--- trunk/KDE/kdegames/kwin4/src/pixmapsprite.h #731448:731449
@@ -179,7 +179,7 @@
/** Offset status.
*/
- bool mOffsetStatus;
+ bool mOffsetStatus;
};
#endif
--- trunk/KDE/kdegames/kwin4/src/thememanager.cpp #731448:731449
@@ -130,7 +130,8 @@
// Rescale the theme. Call all registed objects so that they can refresh.
void ThemeManager::rescale(int scale, QPoint offset)
{
- if (global_debug > 0) kDebug() << "THEMEMANAGER::Rescaling theme to " << scale;
+ if (global_debug > 0)
+ kDebug() << "THEMEMANAGER::Rescaling theme to " << scale<<" offset to " << \
offset;
mThemeFileChanged = false;
--- trunk/KDE/kdegames/kwin4/src/thememanager.h #731448:731449
@@ -184,12 +184,11 @@
void updateTheme(const QString &themefile);
/** Change the scale of the theme and update all registered
- * theme objects. If the scale did not change no action is
- * performed!
+ * theme objects.
* @param scale The new scale (maximum extension)
* @param offset The new offset of the theme (left upper corner)
*/
- void rescale(int scale, QPoint offset);
+ void rescale(int scale, QPoint offset);
/** Retrieve the theme's apsect ratio. This is stored as
* 'aspect-ratio' key in the 'general' group of the theme.
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic