Warning, /graphics/krita/3rdparty/ext_qt/0110-Pass-proper-dirty-rect-in-paint-event-to-QOpenGLWidg.patch is written in an unsupported language. File is not indexed.
0001 From f31141eb0636b94ebe90ae60a6c0b07a771769cd Mon Sep 17 00:00:00 2001 0002 From: Dmitry Kazakov <dimula73@gmail.com> 0003 Date: Thu, 3 Sep 2020 15:19:59 +0300 0004 Subject: [PATCH 27/47] Pass proper dirty rect in paint event to QOpenGLWidget 0005 with partial updates 0006 0007 When QOpenGLWidget has partial updates enabled, there is no reason to 0008 render entire scene on every frame. Instead, the widget may rerender 0009 only a portion of it. All the data has been cached by Qt in the internal 0010 framebuffer object. This limiting is necessary when rendering a complex 0011 scene on 4k display. See https://bugs.kde.org/show_bug.cgi?id=413504 0012 0013 The patch adds a special flag into QWidgetPrivate to notify 0014 QWidgetBackingStore that this widget needs proper tracking of 0015 the dirty region. 0016 0017 Theoretically, flushing of the textures could also be limited to 0018 the dirty region, but it is a different task. 0019 --- 0020 src/widgets/kernel/qopenglwidget.cpp | 1 + 0021 src/widgets/kernel/qwidget.cpp | 1 + 0022 src/widgets/kernel/qwidget_p.h | 1 + 0023 src/widgets/kernel/qwidgetbackingstore.cpp | 34 +++++++++++++++++----- 0024 4 files changed, 29 insertions(+), 8 deletions(-) 0025 0026 diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp 0027 index 36eae9f9db..7a0f4f2440 100644 0028 --- a/src/widgets/kernel/qopenglwidget.cpp 0029 +++ b/src/widgets/kernel/qopenglwidget.cpp 0030 @@ -1036,6 +1036,7 @@ void QOpenGLWidget::setUpdateBehavior(UpdateBehavior updateBehavior) 0031 { 0032 Q_D(QOpenGLWidget); 0033 d->updateBehavior = updateBehavior; 0034 + d->renderToTextureWithPartialUpdates = updateBehavior == PartialUpdate; 0035 } 0036 0037 /*! 0038 diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp 0039 index 85fa2ffe39..79be7a1f88 100644 0040 --- a/src/widgets/kernel/qwidget.cpp 0041 +++ b/src/widgets/kernel/qwidget.cpp 0042 @@ -271,6 +271,7 @@ QWidgetPrivate::QWidgetPrivate(int version) 0043 , usesDoubleBufferedGLContext(0) 0044 , mustHaveWindowHandle(0) 0045 , renderToTexture(0) 0046 + , renderToTextureWithPartialUpdates(0) 0047 , textureChildSeen(0) 0048 #ifndef QT_NO_IM 0049 , inheritsInputMethodHints(0) 0050 diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h 0051 index e541cb70e4..8c3bd88ddf 100644 0052 --- a/src/widgets/kernel/qwidget_p.h 0053 +++ b/src/widgets/kernel/qwidget_p.h 0054 @@ -772,6 +772,7 @@ public: 0055 uint usesDoubleBufferedGLContext : 1; 0056 uint mustHaveWindowHandle : 1; 0057 uint renderToTexture : 1; 0058 + uint renderToTextureWithPartialUpdates : 1; 0059 uint textureChildSeen : 1; 0060 #ifndef QT_NO_IM 0061 uint inheritsInputMethodHints : 1; 0062 diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp 0063 index d5b613a4e5..8b29a4edeb 100644 0064 --- a/src/widgets/kernel/qwidgetbackingstore.cpp 0065 +++ b/src/widgets/kernel/qwidgetbackingstore.cpp 0066 @@ -557,8 +557,14 @@ void QWidgetBackingStore::markDirty(const QRegion &rgn, QWidget *widget, 0067 const QPoint offset = widget->mapTo(tlw, QPoint()); 0068 0069 if (QWidgetPrivate::get(widget)->renderToTexture) { 0070 - if (!widget->d_func()->inDirtyList) 0071 + if (!widget->d_func()->inDirtyList) { 0072 addDirtyRenderToTextureWidget(widget); 0073 + if (QWidgetPrivate::get(widget)->renderToTextureWithPartialUpdates) 0074 + widget->d_func()->dirty = rgn; 0075 + } else if (QWidgetPrivate::get(widget)->renderToTextureWithPartialUpdates) { 0076 + widget->d_func()->dirty += rgn; 0077 + } 0078 + 0079 if (!updateRequestSent || updateTime == UpdateNow) 0080 sendUpdateRequest(tlw, updateTime); 0081 return; 0082 @@ -646,16 +652,24 @@ void QWidgetBackingStore::markDirty(const QRect &rect, QWidget *widget, 0083 return; 0084 } 0085 0086 + const QRect widgetRect = widget->d_func()->effectiveRectFor(rect); 0087 + 0088 if (QWidgetPrivate::get(widget)->renderToTexture) { 0089 - if (!widget->d_func()->inDirtyList) 0090 + if (!widget->d_func()->inDirtyList) { 0091 addDirtyRenderToTextureWidget(widget); 0092 + if (QWidgetPrivate::get(widget)->renderToTextureWithPartialUpdates) 0093 + widget->d_func()->dirty = widgetRect; 0094 + } else if (QWidgetPrivate::get(widget)->renderToTextureWithPartialUpdates && 0095 + !qt_region_strictContains(widget->d_func()->dirty, widgetRect)) { 0096 + 0097 + widget->d_func()->dirty += widgetRect; 0098 + } 0099 + 0100 if (!updateRequestSent || updateTime == UpdateNow) 0101 sendUpdateRequest(tlw, updateTime); 0102 return; 0103 } 0104 0105 - 0106 - const QRect widgetRect = widget->d_func()->effectiveRectFor(rect); 0107 QRect translatedRect = widgetRect; 0108 if (widget != tlw) 0109 translatedRect.translate(widget->mapTo(tlw, QPoint())); 0110 @@ -1321,18 +1335,22 @@ void QWidgetBackingStore::doSync() 0111 // prevent triggering unnecessary backingstore painting when only the 0112 // OpenGL content changes. Check if we have such widgets in the special 0113 // dirty list. 0114 - QVarLengthArray<QWidget *, 16> paintPending; 0115 + QVarLengthArray<QPair<QWidget *, QRegion>, 16> paintPending; 0116 const int numPaintPending = dirtyRenderToTextureWidgets.count(); 0117 paintPending.reserve(numPaintPending); 0118 for (int i = 0; i < numPaintPending; ++i) { 0119 QWidget *w = dirtyRenderToTextureWidgets.at(i); 0120 - paintPending << w; 0121 + paintPending << qMakePair(w, w->d_func()->dirty); 0122 resetWidget(w); 0123 } 0124 dirtyRenderToTextureWidgets.clear(); 0125 for (int i = 0; i < numPaintPending; ++i) { 0126 - QWidget *w = paintPending[i]; 0127 - w->d_func()->sendPaintEvent(w->rect()); 0128 + QWidget *w = paintPending[i].first; 0129 + const QRegion dirtyRegion = paintPending[i].second.isEmpty() ? QRegion(w->rect()) : paintPending[i].second; 0130 + 0131 + w->d_func()->sendPaintEvent(dirtyRegion); 0132 + 0133 + 0134 if (w != tlw) { 0135 QWidget *npw = w->nativeParentWidget(); 0136 if (hasPlatformWindow(w) || (npw && npw != tlw)) { 0137 -- 0138 2.20.1.windows.1 0139