diff options
Diffstat (limited to 'src/widgets/kernel/qwidgetbackingstore.cpp')
-rw-r--r-- | src/widgets/kernel/qwidgetbackingstore.cpp | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index d5c8691459..63419ea093 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -448,6 +448,26 @@ void QWidgetBackingStore::sendUpdateRequest(QWidget *widget, UpdateTime updateTi if (!widget) return; +#ifndef QT_NO_OPENGL + // Having every repaint() leading to a sync/flush is bad as it causes + // compositing and waiting for vsync each and every time. Change to + // UpdateLater, except for approx. once per frame to prevent starvation in + // case the control does not get back to the event loop. + QWidget *w = widget->window(); + if (updateTime == UpdateNow && w && w->windowHandle() && QWindowPrivate::get(w->windowHandle())->compositing) { + int refresh = 60; + QScreen *ws = w->windowHandle()->screen(); + if (ws) + refresh = ws->refreshRate(); + QWindowPrivate *wd = QWindowPrivate::get(w->windowHandle()); + if (wd->lastComposeTime.isValid()) { + const qint64 elapsed = wd->lastComposeTime.elapsed(); + if (elapsed <= qint64(1000.0f / refresh)) + updateTime = UpdateLater; + } + } +#endif + switch (updateTime) { case UpdateLater: updateRequestSent = true; @@ -621,7 +641,11 @@ void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, const QRect widgetRect = widget->d_func()->effectiveRectFor(rect); - const QRect translatedRect(widgetRect.translated(widget->mapTo(tlw, QPoint()))); + QRect translatedRect = widgetRect; + if (widget != tlw) + translatedRect.translate(widget->mapTo(tlw, QPoint())); + // Graphics effects may exceed window size, clamp. + translatedRect = translatedRect.intersected(QRect(QPoint(), tlw->size())); if (qt_region_strictContains(dirty, translatedRect)) { if (updateTime == UpdateNow) sendUpdateRequest(tlw, updateTime); |