diff options
-rw-r--r-- | src/mcompositemanager.cpp | 2 | ||||
-rw-r--r-- | src/mcompositewindow.h | 3 | ||||
-rw-r--r-- | src/mtexturepixmapitem.h | 3 | ||||
-rw-r--r-- | src/mtexturepixmapitem_egl.cpp | 33 | ||||
-rw-r--r-- | src/mtexturepixmapitem_glx.cpp | 3 | ||||
-rw-r--r-- | src/mtexturepixmapitem_p.cpp | 3 | ||||
-rw-r--r-- | src/mtexturepixmapitem_p.h | 5 |
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 |