QtWidgets: Improve native and top-level OpenGL widget performance

Since 7c6625b105 native OpenGL widgets
are able to render, but performance is very low.  It also slows down
rendering for top-level OpenGL widgets.

Render-to-texture widgets prevent triggering unnecessary backingstore
painting when only the OpenGL content changes.
This patch makes possible to use that feature for native and top-level
widgets by calling "markDirtyOnScreen()" function only when necessary.

This patch also prevents native and top-level OpenGL widgets from
flickering during resizing.

Task-number: QTBUG-50381
Task-number: QTBUG-49620
Change-Id: I0c16ea644fb869a00772fd74e1709611e627bff3
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
This commit is contained in:
Błażej Szczygieł 2016-01-11 15:25:12 +01:00
parent a87dfdb196
commit 465e93aa95

View File

@ -1079,7 +1079,8 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg
// Nothing to repaint.
if (!isDirty() && store->size().isValid()) {
qt_flush(exposedWidget, exposedRegion, store, tlw, tlwOffset, widgetTexturesFor(tlw, tlw), this);
QPlatformTextureList *tl = widgetTexturesFor(tlw, exposedWidget);
qt_flush(exposedWidget, tl ? QRegion() : exposedRegion, store, tlw, tlwOffset, tl, this);
return;
}
@ -1250,9 +1251,17 @@ void QWidgetBackingStore::doSync()
for (int i = 0; i < paintPending.count(); ++i) {
QWidget *w = paintPending[i];
w->d_func()->sendPaintEvent(w->rect());
QWidget *npw = w->nativeParentWidget();
if (w->internalWinId() || (npw && npw != tlw))
markDirtyOnScreen(w->rect(), w, w->mapTo(tlw, QPoint()));
if (w != tlw) {
QWidget *npw = w->nativeParentWidget();
if (w->internalWinId() || (npw && npw != tlw)) {
if (!w->internalWinId())
w = npw;
QWidgetPrivate *wPrivate = w->d_func();
if (!wPrivate->needsFlush)
wPrivate->needsFlush = new QRegion;
appendDirtyOnScreenWidget(w);
}
}
}
// We might have newly exposed areas on the screen if this function was
@ -1277,13 +1286,8 @@ void QWidgetBackingStore::doSync()
}
}
}
for (int i = 0; i < dirtyRenderToTextureWidgets.count(); ++i) {
QWidget *w = dirtyRenderToTextureWidgets.at(i);
resetWidget(w);
QWidget *npw = w->nativeParentWidget();
if (w->internalWinId() || (npw && npw != tlw))
markDirtyOnScreen(w->rect(), w, w->mapTo(tlw, QPoint()));
}
for (int i = 0; i < dirtyRenderToTextureWidgets.count(); ++i)
resetWidget(dirtyRenderToTextureWidgets.at(i));
dirtyRenderToTextureWidgets.clear();
#endif