summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGareth Stockwell <ext-gareth.stockwell@nokia.com>2010-08-10 15:34:19 (GMT)
committerGareth Stockwell <ext-gareth.stockwell@nokia.com>2010-08-18 09:13:51 (GMT)
commitcb8d2dcc70846ccd9384a8b94b2a80821c0eb285 (patch)
treec73cc9799567e86486d22f6985624e6981f477b9 /src
parentb5360eb223d5377beb62008fcc1da48f432dc8dd (diff)
downloadQt-cb8d2dcc70846ccd9384a8b94b2a80821c0eb285.zip
Qt-cb8d2dcc70846ccd9384a8b94b2a80821c0eb285.tar.gz
Qt-cb8d2dcc70846ccd9384a8b94b2a80821c0eb285.tar.bz2
Replaced backing store reference count with list of visible widgets
Previously, the following sequence: 1. Widget is hidden 2. Widget partially revealed 3. Widget fully revealed resulted in the reference count of the backing store owned by the widget's window() being incremented twice. This patch replaces the simple reference count with a QSet which stores pointers to the native widgets which are descendents of the backing store owner, and which are currently visible. The sequence above therefore results in just a single insertion at step (2), with step (3) having no effect on the backing store. The QRefCountedWidgetBackingStore class has been renamed QWidgetBackingStoreTracker to better reflect its purpose. Task-number: QTBUG-12800 Task-number: QTBUG-12817 Reviewed-by: Jason Barron
Diffstat (limited to 'src')
-rw-r--r--src/gui/kernel/qapplication_s60.cpp11
-rw-r--r--src/gui/kernel/qwidget.cpp61
-rw-r--r--src/gui/kernel/qwidget_p.h17
3 files changed, 58 insertions, 31 deletions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 559bb6a..df93bc5 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -1926,27 +1926,24 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent
QWidget *const window = w->window();
if (!window->d_func()->maybeTopData())
break;
- QRefCountedWidgetBackingStore &backingStore = window->d_func()->maybeTopData()->backingStore;
+ QWidgetBackingStoreTracker &backingStore = window->d_func()->maybeTopData()->backingStore;
if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) {
#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
S60->wsSession().SendEffectCommand(ETfxCmdDeallocateLayer);
#endif
- // Decrement backing store reference count
- backingStore.deref();
+ backingStore.unregisterWidget(w);
// In order to ensure that any resources used by the window surface
// are immediately freed, we flush the WSERV command buffer.
S60->wsSession().Flush();
} else if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible) {
if (backingStore.data()) {
- // Increment backing store reference count
- backingStore.ref();
+ backingStore.registerWidget(w);
} else {
#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
S60->wsSession().SendEffectCommand(ETfxCmdRestoreLayer);
#endif
- // Create backing store with an initial reference count of 1
backingStore.create(window);
- backingStore.ref();
+ backingStore.registerWidget(w);
w->d_func()->invalidateBuffer(w->rect());
w->repaint();
}
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index aaa29a1..dad4848 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -162,47 +162,76 @@ static inline bool hasBackingStoreSupport()
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
-QRefCountedWidgetBackingStore::QRefCountedWidgetBackingStore()
+ 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)
- , m_count(0)
{
}
-QRefCountedWidgetBackingStore::~QRefCountedWidgetBackingStore()
+QWidgetBackingStoreTracker::~QWidgetBackingStoreTracker()
{
delete m_ptr;
}
-void QRefCountedWidgetBackingStore::create(QWidget *widget)
+/*!
+ \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);
- m_count = 0;
}
-void QRefCountedWidgetBackingStore::destroy()
+/*!
+ \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_count = 0;
+ m_widgets.clear();
}
-void QRefCountedWidgetBackingStore::ref()
+/*!
+ \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);
- ++m_count;
+ Q_ASSERT(w->internalWinId());
+ Q_ASSERT(qt_widget_private(w)->maybeBackingStore() == m_ptr);
+ m_widgets.insert(w);
}
-void QRefCountedWidgetBackingStore::deref()
+/*!
+ \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_count) {
- Q_ASSERT(m_ptr);
- if (0 == --m_count) {
- delete m_ptr;
- m_ptr = 0;
- }
+ if (m_widgets.remove(w) && m_widgets.isEmpty()) {
+ delete m_ptr;
+ m_ptr = 0;
}
}
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 587d7fb..4a79dc7 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -110,17 +110,18 @@ class QWidgetItemV2;
class QStyle;
-class Q_AUTOTEST_EXPORT QRefCountedWidgetBackingStore
+class Q_AUTOTEST_EXPORT QWidgetBackingStoreTracker
{
+
public:
- QRefCountedWidgetBackingStore();
- ~QRefCountedWidgetBackingStore();
+ QWidgetBackingStoreTracker();
+ ~QWidgetBackingStoreTracker();
void create(QWidget *tlw);
void destroy();
- void ref();
- void deref();
+ void registerWidget(QWidget *w);
+ void unregisterWidget(QWidget *w);
inline QWidgetBackingStore* data()
{
@@ -143,11 +144,11 @@ public:
}
private:
- Q_DISABLE_COPY(QRefCountedWidgetBackingStore)
+ Q_DISABLE_COPY(QWidgetBackingStoreTracker)
private:
QWidgetBackingStore* m_ptr;
- int m_count;
+ QSet<QWidget *> m_widgets;
};
struct QTLWExtra {
@@ -156,7 +157,7 @@ struct QTLWExtra {
// Regular pointers (keep them together to avoid gaps on 64 bits architectures).
QIcon *icon; // widget icon
QPixmap *iconPixmap;
- QRefCountedWidgetBackingStore backingStore;
+ QWidgetBackingStoreTracker backingStore;
QWindowSurface *windowSurface;
QPainter *sharedPainter;