summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;