diff options
author | Gareth Stockwell <ext-gareth.stockwell@nokia.com> | 2010-05-11 15:50:00 (GMT) |
---|---|---|
committer | Gareth Stockwell <ext-gareth.stockwell@nokia.com> | 2010-06-02 13:40:47 (GMT) |
commit | d7057e7c1f1a4769c6e9b0e1c54446d5104c1484 (patch) | |
tree | 5278dbf2b152a39939d41b628df49e66ae5a8d8b /src/gui/kernel/qwidget.cpp | |
parent | 3a72235d7cf2aa953cb32654545c480fd2d08866 (diff) | |
download | Qt-d7057e7c1f1a4769c6e9b0e1c54446d5104c1484.zip Qt-d7057e7c1f1a4769c6e9b0e1c54446d5104c1484.tar.gz Qt-d7057e7c1f1a4769c6e9b0e1c54446d5104c1484.tar.bz2 |
Added reference counting to QWidgetBackingStore
On Symbian, the top-level widget's backing store must be destroyed when
it is no longer required, in order to conserve memory. The criteria
for destroying the backing store is when neither the TLW nor any of
its native descendents (which share the backing store) are visible.
In order to implement this requirement, a count must be kept of the
number of native widgets which are using the TLW's backing store.
This patch provides the mechanism for maintaining this count, and for
destroying the backing store when the count is decremented to zero.
No calls to either the increment nor decrement functions are made,
however, by this code included in this patch; this code will be added
to only the Symbian backend by a subsequent patch.
Task-number: QTBUG-8697
Reviewed-by: Bjørn Erik Nilsen
Reviewed-by: Jason Barron
Diffstat (limited to 'src/gui/kernel/qwidget.cpp')
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 57 |
1 files changed, 49 insertions, 8 deletions
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index e180001..a9ea9ac 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -161,6 +161,51 @@ static inline bool hasBackingStoreSupport() extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp + +QRefCountedWidgetBackingStore::QRefCountedWidgetBackingStore() + : m_ptr(0) + , m_count(0) +{ + +} + +QRefCountedWidgetBackingStore::~QRefCountedWidgetBackingStore() +{ + delete m_ptr; +} + +void QRefCountedWidgetBackingStore::create(QWidget *widget) +{ + destroy(); + m_ptr = new QWidgetBackingStore(widget); + m_count = 0; +} + +void QRefCountedWidgetBackingStore::destroy() +{ + delete m_ptr; + m_ptr = 0; + m_count = 0; +} + +void QRefCountedWidgetBackingStore::ref() +{ + Q_ASSERT(m_ptr); + ++m_count; +} + +void QRefCountedWidgetBackingStore::deref() +{ + if (m_count) { + Q_ASSERT(m_ptr); + if (0 == --m_count) { + delete m_ptr; + m_ptr = 0; + } + } +} + + QWidgetPrivate::QWidgetPrivate(int version) : QObjectPrivate(version) , extra(0) @@ -1324,11 +1369,9 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) // a real toplevel window needs a backing store if (isWindow() && windowType() != Qt::Desktop) { - delete d->topData()->backingStore; - // QWidgetBackingStore will check this variable, hence it must be 0 - d->topData()->backingStore = 0; + d->topData()->backingStore.destroy(); if (hasBackingStoreSupport()) - d->topData()->backingStore = new QWidgetBackingStore(this); + d->topData()->backingStore.create(this); } d->setModal_sys(); @@ -1451,8 +1494,7 @@ QWidget::~QWidget() // the backing store will delete its window surface, which may or may // not have a reference to this widget that will be used later to // notify the window it no longer has a surface. - delete d->extra->topextra->backingStore; - d->extra->topextra->backingStore = 0; + d->extra->topextra->backingStore.destroy(); } #endif if (QWidgetBackingStore *bs = d->maybeBackingStore()) { @@ -1540,7 +1582,6 @@ void QWidgetPrivate::createTLExtra() QTLWExtra* x = extra->topextra = new QTLWExtra; x->icon = 0; x->iconPixmap = 0; - x->backingStore = 0; x->windowSurface = 0; x->sharedPainter = 0; x->incw = x->inch = 0; @@ -1619,7 +1660,7 @@ void QWidgetPrivate::deleteExtra() #endif if (extra->topextra) { deleteTLSysExtra(); - delete extra->topextra->backingStore; + extra->topextra->backingStore.destroy(); delete extra->topextra->icon; delete extra->topextra->iconPixmap; #if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) |