Get rid of QWidgetBackingStoreTracker

It was added for Symbian almost 10 years ago (d7057e7c1f1a), for a somewhat
dubious use-case. The Symbian code is since long gone (ae30d7141), so the
remaining pieces are just adding complexity to the already intricate workings
of the QtWidgets backingstore/painting logic.

Task-number: QTBUG-8697
Change-Id: I82af610a8ac26719c588ac63f06b4501f59b400d
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
This commit is contained in:
Tor Arne Vestbø 2019-08-14 12:39:27 +02:00
parent e9eddfd856
commit 2e0b0be2ce
5 changed files with 18 additions and 156 deletions

View File

@ -146,91 +146,6 @@ static inline bool qRectIntersects(const QRect &r1, const QRect &r2)
extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp
/*!
\internal
\class QWidgetBackingStoreTracker
\brief Class which allows tracking of which widgets are using a given backing store
QWidgetBackingStoreTracker is a thin wrapper around a QWidgetBackingStore pointer,
which maintains a list of the QWidgets which are currently using the backing
store. This list is modified via the registerWidget and unregisterWidget functions.
*/
QWidgetBackingStoreTracker::QWidgetBackingStoreTracker()
: m_ptr(0)
{
}
QWidgetBackingStoreTracker::~QWidgetBackingStoreTracker()
{
delete m_ptr;
}
/*!
\internal
Destroy the contained QWidgetBackingStore, if not null, and clear the list of
widgets using the backing store, then create a new QWidgetBackingStore, providing
the QWidget.
*/
void QWidgetBackingStoreTracker::create(QWidget *widget)
{
destroy();
m_ptr = new QWidgetBackingStore(widget);
}
/*!
\internal
Destroy the contained QWidgetBackingStore, if not null, and clear the list of
widgets using the backing store.
*/
void QWidgetBackingStoreTracker::destroy()
{
delete m_ptr;
m_ptr = 0;
m_widgets.clear();
}
/*!
\internal
Add the widget to the list of widgets currently using the backing store.
If the widget was already in the list, this function is a no-op.
*/
void QWidgetBackingStoreTracker::registerWidget(QWidget *w)
{
Q_ASSERT(m_ptr);
Q_ASSERT(w->internalWinId());
Q_ASSERT(qt_widget_private(w)->maybeBackingStore() == m_ptr);
m_widgets.insert(w);
}
/*!
\internal
Remove the widget from the list of widgets currently using the backing store.
If the widget was in the list, and removing it causes the list to be empty,
the backing store is deleted.
If the widget was not in the list, this function is a no-op.
*/
void QWidgetBackingStoreTracker::unregisterWidget(QWidget *w)
{
if (m_widgets.remove(w) && m_widgets.isEmpty()) {
delete m_ptr;
m_ptr = 0;
}
}
/*!
\internal
Recursively remove widget and all of its descendents.
*/
void QWidgetBackingStoreTracker::unregisterWidgetSubtree(QWidget *widget)
{
unregisterWidget(widget);
foreach (QObject *child, widget->children())
if (QWidget *childWidget = qobject_cast<QWidget *>(child))
unregisterWidgetSubtree(childWidget);
}
QWidgetPrivate::QWidgetPrivate(int version)
: QObjectPrivate(version)
, extra(0)
@ -1364,10 +1279,8 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
d->create();
// a real toplevel window needs a backing store
if (isWindow() && windowType() != Qt::Desktop) {
d->topData()->backingStoreTracker.destroy();
d->topData()->backingStoreTracker.create(this);
}
if (isWindow() && windowType() != Qt::Desktop)
d->topData()->widgetBackingStore.reset(new QWidgetBackingStore(this));
d->setModal_sys();
@ -1891,7 +1804,7 @@ void QWidgetPrivate::deleteTLSysExtra()
//the qplatformbackingstore may hold a reference to the window, so the backingstore
//needs to be deleted first.
extra->topextra->backingStoreTracker.destroy();
extra->topextra->widgetBackingStore.reset(nullptr);
deleteBackingStore(this);
#ifndef QT_NO_OPENGL
extra->topextra->widgetTextures.clear();
@ -10755,16 +10668,8 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
if (newParent && isAncestorOf(focusWidget()))
focusWidget()->clearFocus();
QTLWExtra *oldTopExtra = window()->d_func()->maybeTopData();
QWidgetBackingStoreTracker *oldBsTracker = oldTopExtra ? &oldTopExtra->backingStoreTracker : 0;
d->setParent_sys(parent, f);
QTLWExtra *topExtra = window()->d_func()->maybeTopData();
QWidgetBackingStoreTracker *bsTracker = topExtra ? &topExtra->backingStoreTracker : 0;
if (oldBsTracker && oldBsTracker != bsTracker)
oldBsTracker->unregisterWidgetSubtree(this);
if (desktopWidget)
parent = 0;
@ -11134,7 +11039,7 @@ void QWidgetPrivate::repaint(T r)
QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
tlwExtra->backingStoreTracker->markDirty(r, q, QWidgetBackingStore::UpdateNow);
tlwExtra->widgetBackingStore->markDirty(r, q, QWidgetBackingStore::UpdateNow);
}
/*!
@ -11209,7 +11114,7 @@ void QWidgetPrivate::update(T r)
QTLWExtra *tlwExtra = q->window()->d_func()->maybeTopData();
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
tlwExtra->backingStoreTracker->markDirty(clipped, q);
tlwExtra->widgetBackingStore->markDirty(clipped, q);
}
/*!

View File

@ -116,56 +116,12 @@ protected:
QRegion m_region;
};
class Q_AUTOTEST_EXPORT QWidgetBackingStoreTracker
{
public:
QWidgetBackingStoreTracker();
~QWidgetBackingStoreTracker();
void create(QWidget *tlw);
void destroy();
void registerWidget(QWidget *w);
void unregisterWidget(QWidget *w);
void unregisterWidgetSubtree(QWidget *w);
inline QWidgetBackingStore* data()
{
return m_ptr;
}
inline QWidgetBackingStore* operator->()
{
return m_ptr;
}
inline QWidgetBackingStore& operator*()
{
return *m_ptr;
}
inline operator bool() const
{
return (nullptr != m_ptr);
}
private:
Q_DISABLE_COPY_MOVE(QWidgetBackingStoreTracker)
private:
QWidgetBackingStore* m_ptr;
QSet<QWidget *> m_widgets;
};
struct QTLWExtra {
// *************************** Cross-platform variables *****************************
// Regular pointers (keep them together to avoid gaps on 64 bits architectures).
std::unique_ptr<QIcon> icon; // widget icon
QWidgetBackingStoreTracker backingStoreTracker;
std::unique_ptr<QWidgetBackingStore> widgetBackingStore;
QBackingStore *backingStore;
QPainter *sharedPainter;
QWidgetWindow *window;
@ -1028,7 +984,7 @@ inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const
{
Q_Q(const QWidget);
QTLWExtra *x = q->window()->d_func()->maybeTopData();
return x ? x->backingStoreTracker.data() : nullptr;
return x ? x->widgetBackingStore.get() : nullptr;
}
QT_END_NAMESPACE

View File

@ -300,7 +300,7 @@ void QWidgetBackingStore::unflushPaint(QWidget *widget, const QRegion &rgn)
if (!tlwExtra)
return;
qt_flush(widget, rgn, tlwExtra->backingStoreTracker->store, tlw, 0, tlw->d_func()->maybeBackingStore());
qt_flush(widget, rgn, tlwExtra->widgetBackingStore->store, tlw, 0, tlw->d_func()->maybeBackingStore());
}
#endif // QT_NO_PAINT_DEBUG
@ -800,7 +800,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
invalidateBackingStore((newRect & clipR).translated(-data.crect.topLeft()));
} else {
QWidgetBackingStore *wbs = x->backingStoreTracker.data();
QWidgetBackingStore *wbs = x->widgetBackingStore.get();
QRegion childExpose(newRect & clipR);
QRegion overlappedExpose;
@ -864,7 +864,7 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
if (x->inTopLevelResize)
return;
QWidgetBackingStore *wbs = x->backingStoreTracker.data();
QWidgetBackingStore *wbs = x->widgetBackingStore.get();
if (!wbs)
return;
@ -1528,10 +1528,10 @@ void QWidgetPrivate::invalidateBackingStore(const T &r)
if (masked.isEmpty())
return;
tlwExtra->backingStoreTracker->markDirty(masked, q,
tlwExtra->widgetBackingStore->markDirty(masked, q,
QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid);
} else {
tlwExtra->backingStoreTracker->markDirty(clipped, q,
tlwExtra->widgetBackingStore->markDirty(clipped, q,
QWidgetBackingStore::UpdateLater, QWidgetBackingStore::BufferInvalid);
}
}

View File

@ -770,7 +770,7 @@ void QWidgetWindow::repaintWindow()
QTLWExtra *tlwExtra = m_widget->window()->d_func()->maybeTopData();
if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
tlwExtra->backingStoreTracker->markDirty(m_widget->rect(), m_widget,
tlwExtra->widgetBackingStore->markDirty(m_widget->rect(), m_widget,
QWidgetBackingStore::UpdateNow, QWidgetBackingStore::BufferInvalid);
}

View File

@ -46,6 +46,7 @@
#include <qstylefactory.h>
#include <qdesktopwidget.h>
#include <private/qwidget_p.h>
#include <private/qwidgetbackingstore_p.h>
#include <private/qapplication_p.h>
#include <private/qhighdpiscaling_p.h>
#include <qcalendarwidget.h>
@ -9564,7 +9565,7 @@ void tst_QWidget::destroyBackingStore()
QTRY_VERIFY(w.numPaintEvents > 0);
w.reset();
w.update();
qt_widget_private(&w)->topData()->backingStoreTracker.create(&w);
qt_widget_private(&w)->topData()->widgetBackingStore.reset(new QWidgetBackingStore(&w));
w.update();
QApplication::processEvents();
@ -9584,7 +9585,7 @@ QWidgetBackingStore* backingStore(QWidget &widget)
QWidgetBackingStore *backingStore = nullptr;
#ifdef QT_BUILD_INTERNAL
if (QTLWExtra *topExtra = qt_widget_private(&widget)->maybeTopData())
backingStore = topExtra->backingStoreTracker.data();
backingStore = topExtra->widgetBackingStore.get();
#endif
return backingStore;
}
@ -9784,12 +9785,12 @@ class scrollWidgetWBS : public QWidget
public:
void deleteBackingStore()
{
static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStoreTracker.destroy();
static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->widgetBackingStore.reset(nullptr);
}
void enableBackingStore()
{
if (!static_cast<QWidgetPrivate*>(d_ptr.data())->maybeBackingStore()) {
static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->backingStoreTracker.create(this);
static_cast<QWidgetPrivate*>(d_ptr.data())->topData()->widgetBackingStore.reset(new QWidgetBackingStore(this));
static_cast<QWidgetPrivate*>(d_ptr.data())->invalidateBackingStore(this->rect());
repaint();
}