summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Endrodi <ext-adam.endrodi@nokia.com>2010-11-04 09:57:41 +0200
committerAdam Endrodi <ext-adam.endrodi@nokia.com>2010-11-04 09:57:41 +0200
commit2d4f449502a391b9279f21c262141c007275815b (patch)
tree97c2597f85385a1c17670fc6e87435ee2b98aea7
parent968406726621da2d399a7d02c552080a9a1e3ed5 (diff)
allow for a limited number of updates on transitioning windowspastdamages
Repair transitioning windows not more than ten times per second. Only implemented in the EGL variant. * src/mcompositewindow.h * src/mtexturepixmapitem.h: Add an optional Time parameter to MCompositeWindow::updateWindowPixmap() denoting the time when the damage notification was sent by the server. * src/mtexturepixmapitem.h: * src/mtexturepixmapitem_p.cpp: Add MTexturePixmapPrivate::pastDamages to remember them for the timeframe if necessary. * src/mtexturepixmapitem_egl.cpp (MTexturePixmapItem::updateWindowPixmap::updateWindowPixmap): If we receive a damage during a transition check if we can afford a repair an do it if all's positive. * src/mtexturepixmapitem_glx.cpp (MTexturePixmapItem::updateWindowPixmap::updateWindowPixmap) Just added the new parameter, but left unused.
-rw-r--r--src/mcompositemanager.cpp2
-rw-r--r--src/mcompositewindow.h3
-rw-r--r--src/mtexturepixmapitem.h3
-rw-r--r--src/mtexturepixmapitem_egl.cpp33
-rw-r--r--src/mtexturepixmapitem_glx.cpp3
-rw-r--r--src/mtexturepixmapitem_p.cpp3
-rw-r--r--src/mtexturepixmapitem_p.h5
7 files changed, 45 insertions, 7 deletions
diff --git a/src/mcompositemanager.cpp b/src/mcompositemanager.cpp
index 9b81c54..82a2b9c 100644
--- a/src/mcompositemanager.cpp
+++ b/src/mcompositemanager.cpp
@@ -910,7 +910,7 @@ void MCompositeManagerPrivate::damageEvent(XDamageNotifyEvent *e)
MCompositeWindow *item = COMPOSITE_WINDOW(e->drawable);
if (item && rects) {
- item->updateWindowPixmap(rects, num);
+ item->updateWindowPixmap(rects, num, e->timestamp);
if (item->waitingForDamage())
item->damageReceived(false);
}
diff --git a/src/mcompositewindow.h b/src/mcompositewindow.h
index 5d53b88..b82dfc6 100644
--- a/src/mcompositewindow.h
+++ b/src/mcompositewindow.h
@@ -239,7 +239,8 @@ public:
* Ensures that the corresponding texture reflects the contents of the
* associated pixmap and schedules a redraw of this item.
*/
- virtual void updateWindowPixmap(XRectangle *rects = 0, int num = 0) = 0;
+ virtual void updateWindowPixmap(XRectangle *rects = 0, int num = 0,
+ Time when = 0) = 0;
/*!
* Recreates the pixmap id and saves the offscreen buffer that represents
diff --git a/src/mtexturepixmapitem.h b/src/mtexturepixmapitem.h
index 1a25b29..15ee6b2 100644
--- a/src/mtexturepixmapitem.h
+++ b/src/mtexturepixmapitem.h
@@ -61,7 +61,8 @@ public:
* Ensures that the corresponding texture reflects the contents of the
* associated pixmap and schedules a redraw of this item.
*/
- void updateWindowPixmap(XRectangle *rects = 0, int num = 0);
+ void updateWindowPixmap(XRectangle *rects = 0, int num = 0,
+ Time when = 0);
/*!
* Recreates the pixmap id and saves the offscreen buffer that represents
diff --git a/src/mtexturepixmapitem_egl.cpp b/src/mtexturepixmapitem_egl.cpp
index c5487e7..b60a28b 100644
--- a/src/mtexturepixmapitem_egl.cpp
+++ b/src/mtexturepixmapitem_egl.cpp
@@ -251,9 +251,38 @@ void MTexturePixmapItem::cleanup()
XFreePixmap(QX11Info::display(), d->windowp);
}
-void MTexturePixmapItem::updateWindowPixmap(XRectangle *rects, int num)
+void MTexturePixmapItem::updateWindowPixmap(XRectangle *rects, int num,
+ Time when)
{
- if (hasTransitioningWindow() || d->direct_fb_render || !windowVisible()
+ // When a window is in transitioning limit the number of updates
+ // to @limit/@expiry miliseconds.
+ const unsigned expiry = 1000;
+ const int limit = 10;
+
+ if (hasTransitioningWindow()) {
+ // Limit the number of damages we're willing to process if we're
+ // in the middle of a transition, so the competition for the GL
+ // resources will be less tight.
+ if (d->pastDamages) {
+ // Forget about pastDamages we received long ago.
+ while (d->pastDamages->size() > 0
+ && d->pastDamages->first() + expiry < when)
+ d->pastDamages->removeFirst();
+ if (d->pastDamages->size() >= limit)
+ // Too many damages in the given timeframe, throttle.
+ return;
+ } else
+ d->pastDamages = new QList<Time>;
+ // Can afford this damage, but recoed when we received it,
+ // so to know when to forget about them.
+ d->pastDamages->append(when);
+ } else if (d->pastDamages) {
+ // The window is not transitioning, forget about all pastDamages.
+ delete d->pastDamages;
+ d->pastDamages = NULL;
+ }
+
+ if (d->direct_fb_render || !windowVisible()
|| propertyCache()->isInputOnly())
return;
diff --git a/src/mtexturepixmapitem_glx.cpp b/src/mtexturepixmapitem_glx.cpp
index 0129a31..c2551a5 100644
--- a/src/mtexturepixmapitem_glx.cpp
+++ b/src/mtexturepixmapitem_glx.cpp
@@ -273,7 +273,8 @@ void MTexturePixmapItem::cleanup()
XFreePixmap(QX11Info::display(), d->windowp);
}
-void MTexturePixmapItem::updateWindowPixmap(XRectangle *rects, int num)
+void MTexturePixmapItem::updateWindowPixmap(XRectangle *rects, int num,
+ Time when)
{
Q_UNUSED(rects);
Q_UNUSED(num);
diff --git a/src/mtexturepixmapitem_p.cpp b/src/mtexturepixmapitem_p.cpp
index e8a1e98..33a9da4 100644
--- a/src/mtexturepixmapitem_p.cpp
+++ b/src/mtexturepixmapitem_p.cpp
@@ -412,7 +412,8 @@ MTexturePixmapPrivate::MTexturePixmapPrivate(Qt::HANDLE window,
direct_fb_render(false),
angle(0),
item(p),
- prev_effect(0)
+ prev_effect(0),
+ pastDamages(0)
{
XCompositeRedirectWindow(QX11Info::display(), window,
CompositeRedirectManual);
diff --git a/src/mtexturepixmapitem_p.h b/src/mtexturepixmapitem_p.h
index c351b00..cd4c086 100644
--- a/src/mtexturepixmapitem_p.h
+++ b/src/mtexturepixmapitem_p.h
@@ -89,6 +89,11 @@ public:
QPointer<MCompositeWindowShaderEffect> current_effect;
const MCompositeWindowShaderEffect *prev_effect;
+ // Contains a limited number of server times we received damage
+ // notifications for this window. Only used by the EGL variant
+ // to throttle repairs if the window is transitioning.
+ QList<Time> *pastDamages;
+
#ifdef GLES2_VERSION
static EglResourceManager *eglresource;
#endif