diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-02-02 07:21:22 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-02-02 07:21:22 (GMT) |
commit | 0d3159120674ae8fd8f941d104cf03120305b4dc (patch) | |
tree | 52d3b1aca7b18a10295a55fa76050adef77d7ff3 /src | |
parent | 57d33781bd8e02904a85de7fc54f8f4e8bd299e6 (diff) | |
parent | 9258959f4f81b9c3efa4418aa344a5be5f9d12ab (diff) | |
download | Qt-0d3159120674ae8fd8f941d104cf03120305b4dc.zip Qt-0d3159120674ae8fd8f941d104cf03120305b4dc.tar.gz Qt-0d3159120674ae8fd8f941d104cf03120305b4dc.tar.bz2 |
Merge branch '4.6' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.6-integration
* '4.6' of scm.dev.nokia.troll.no:qt/oslo-staging-2:
Fix QTBUG_7714_fullUpdateDiscardingOpacityUpdate2 autotest in qws-linux
Assert failure when setting a widget focus proxy as its successor in tab order
Fixed garbled 3D Qt logo in the overpainting example.
fix crash in Phonon::DS9 backend
Don't crash when running Qt on KDE with Oxygen style.
Fixes missing update when setting opacity on an item that had opacity 0.0
Avoids missing opacity updates by not propagating the ignoreOpacity flag
Cleanup in graphicsitem autotest
Adds convenience functions QGraphicsItemPrivate::isOpacityNull
Fixed a crash when QPixmaps are destroyed after the ~QApplication.
Fix GL texture leaks when pixmaps are deleted
Doc fix. No need to put something deprecated if it's not.
Warn if the plugin seems to not exist instead of simply passing.
Diffstat (limited to 'src')
-rw-r--r-- | src/3rdparty/phonon/ds9/videowidget.cpp | 3 | ||||
-rw-r--r-- | src/gui/dialogs/qfiledialog.cpp | 3 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 5 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 10 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 7 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicssceneindex.cpp | 4 | ||||
-rw-r--r-- | src/gui/image/qimagepixmapcleanuphooks.cpp | 20 | ||||
-rw-r--r-- | src/gui/image/qimagepixmapcleanuphooks_p.h | 23 | ||||
-rw-r--r-- | src/gui/image/qpixmap.cpp | 12 | ||||
-rw-r--r-- | src/gui/image/qpixmap_x11.cpp | 14 | ||||
-rw-r--r-- | src/gui/image/qpixmapdata.cpp | 11 | ||||
-rw-r--r-- | src/gui/image/qpixmapdata_p.h | 8 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 2 | ||||
-rw-r--r-- | src/gui/painting/qpainter.cpp | 4 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 3 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 32 | ||||
-rw-r--r-- | src/opengl/qgl_p.h | 9 | ||||
-rw-r--r-- | src/opengl/qglpixmapfilter.cpp | 22 |
18 files changed, 114 insertions, 78 deletions
diff --git a/src/3rdparty/phonon/ds9/videowidget.cpp b/src/3rdparty/phonon/ds9/videowidget.cpp index 091be16..95423c6 100644 --- a/src/3rdparty/phonon/ds9/videowidget.cpp +++ b/src/3rdparty/phonon/ds9/videowidget.cpp @@ -218,6 +218,9 @@ namespace Phonon if (toNative && m_noNativeRendererSupported) return current; //no switch here + if (!mediaObject()) + return current; + //firt we delete the renderer //initialization of the widgets for(int i = 0; i < FILTER_COUNT; ++i) { diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index 21650bb..089e04a 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -229,11 +229,10 @@ Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook \value ReadOnly Indicates that the model is readonly. \value HideNameFilterDetails Indicates if the is hidden or not. - This value is obsolete and does nothing since Qt 4.5: \value DontUseSheet In previous versions of Qt, the static functions would create a sheet by default if the static function - was given a parent. This is no longer supported in Qt 4.5, The + was given a parent. This is no longer supported and does nothing in Qt 4.5, The static functions will always be an application modal dialog. If you want to use sheets, use QFileDialog::open() instead. diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index ed36f87..b4e19d1 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2569,6 +2569,7 @@ void QGraphicsItem::setOpacity(qreal opacity) if (newOpacity == d_ptr->opacity) return; + bool wasFullyTransparent = d_ptr->isOpacityNull(); d_ptr->opacity = newOpacity; // Notify change. @@ -2584,7 +2585,9 @@ void QGraphicsItem::setOpacity(qreal opacity) d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false, - /*ignoreOpacity=*/true); + /*ignoreOpacity=*/d_ptr->isOpacityNull()); + if (wasFullyTransparent) + d_ptr->paintedViewBoundingRectsNeedRepaint = 1; } if (d_ptr->isObject) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 5ad6cd5..b3ca3b5 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -358,14 +358,20 @@ public: return o; } + inline bool isOpacityNull() const + { return (opacity < qreal(0.001)); } + + static inline bool isOpacityNull(qreal opacity) + { return (opacity < qreal(0.001)); } + inline bool isFullyTransparent() const { - if (opacity < 0.001) + if (isOpacityNull()) return true; if (!parent) return false; - return calcEffectiveOpacity() < 0.001; + return isOpacityNull(calcEffectiveOpacity()); } inline qreal effectiveOpacity() const { diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 54d47fa..842d368 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4630,7 +4630,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * return; // Item has neither contents nor children!(?) const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); - const bool itemIsFullyTransparent = (opacity < 0.0001); + const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity); if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) return; @@ -4750,7 +4750,7 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q qreal opacity, const QTransform *effectTransform, bool wasDirtyParentSceneTransform, bool drawItem) { - const bool itemIsFullyTransparent = (opacity < 0.0001); + const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity); const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); const bool itemHasChildren = !item->d_ptr->children.isEmpty(); @@ -4980,7 +4980,8 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool } const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); - const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity && opacity < 0.0001; + const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity + && QGraphicsItemPrivate::isOpacityNull(opacity); if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) { resetDirtyItem(item, /*recursive=*/itemHasChildren); return; diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index 043c4eb..707c71f 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -279,7 +279,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe return; const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); - const bool itemIsFullyTransparent = (opacity < 0.0001); + const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity); const bool itemHasChildren = !item->d_ptr->children.isEmpty(); if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) return; @@ -554,7 +554,7 @@ QList<QGraphicsItem *> QGraphicsSceneIndex::estimateTopLevelItems(const QRectF & /*! \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(Qt::SortOrder order = Qt::DescendingOrder) const - + This pure virtual function all items in the index and sort them using \a order. */ diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp index 61d538f..ace4bb6 100644 --- a/src/gui/image/qimagepixmapcleanuphooks.cpp +++ b/src/gui/image/qimagepixmapcleanuphooks.cpp @@ -62,12 +62,12 @@ QImagePixmapCleanupHooks *QImagePixmapCleanupHooks::instance() return qt_image_and_pixmap_cleanup_hooks(); } -void QImagePixmapCleanupHooks::addPixmapModificationHook(_qt_pixmap_cleanup_hook_pm hook) +void QImagePixmapCleanupHooks::addPixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd hook) { pixmapModificationHooks.append(hook); } -void QImagePixmapCleanupHooks::addPixmapDestructionHook(_qt_pixmap_cleanup_hook_pm hook) +void QImagePixmapCleanupHooks::addPixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd hook) { pixmapDestructionHooks.append(hook); } @@ -78,12 +78,12 @@ void QImagePixmapCleanupHooks::addImageHook(_qt_image_cleanup_hook_64 hook) imageHooks.append(hook); } -void QImagePixmapCleanupHooks::removePixmapModificationHook(_qt_pixmap_cleanup_hook_pm hook) +void QImagePixmapCleanupHooks::removePixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd hook) { pixmapModificationHooks.removeAll(hook); } -void QImagePixmapCleanupHooks::removePixmapDestructionHook(_qt_pixmap_cleanup_hook_pm hook) +void QImagePixmapCleanupHooks::removePixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd hook) { pixmapDestructionHooks.removeAll(hook); } @@ -93,24 +93,24 @@ void QImagePixmapCleanupHooks::removeImageHook(_qt_image_cleanup_hook_64 hook) imageHooks.removeAll(hook); } -void QImagePixmapCleanupHooks::executePixmapModificationHooks(QPixmap* pm) +void QImagePixmapCleanupHooks::executePixmapDataModificationHooks(QPixmapData* pmd) { QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks(); for (int i = 0; i < h->pixmapModificationHooks.count(); ++i) - h->pixmapModificationHooks[i](pm); + h->pixmapModificationHooks[i](pmd); if (qt_pixmap_cleanup_hook_64) - qt_pixmap_cleanup_hook_64(pm->cacheKey()); + qt_pixmap_cleanup_hook_64(pmd->cacheKey()); } -void QImagePixmapCleanupHooks::executePixmapDestructionHooks(QPixmap* pm) +void QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(QPixmapData* pmd) { QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks(); for (int i = 0; i < h->pixmapDestructionHooks.count(); ++i) - h->pixmapDestructionHooks[i](pm); + h->pixmapDestructionHooks[i](pmd); if (qt_pixmap_cleanup_hook_64) - qt_pixmap_cleanup_hook_64(pm->cacheKey()); + qt_pixmap_cleanup_hook_64(pmd->cacheKey()); } void QImagePixmapCleanupHooks::executeImageHooks(qint64 key) diff --git a/src/gui/image/qimagepixmapcleanuphooks_p.h b/src/gui/image/qimagepixmapcleanuphooks_p.h index 7176044..88dd3a6 100644 --- a/src/gui/image/qimagepixmapcleanuphooks_p.h +++ b/src/gui/image/qimagepixmapcleanuphooks_p.h @@ -58,7 +58,8 @@ QT_BEGIN_NAMESPACE typedef void (*_qt_image_cleanup_hook_64)(qint64); -typedef void (*_qt_pixmap_cleanup_hook_pm)(QPixmap*); +typedef void (*_qt_pixmap_cleanup_hook_pmd)(QPixmapData*); + class QImagePixmapCleanupHooks; @@ -71,27 +72,27 @@ public: static void enableCleanupHooks(const QPixmap &pixmap); static void enableCleanupHooks(QPixmapData *pixmapData); - // Gets called when a pixmap is about to be modified: - void addPixmapModificationHook(_qt_pixmap_cleanup_hook_pm); + // Gets called when a pixmap data is about to be modified: + void addPixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd); - // Gets called when a pixmap is about to be destroyed: - void addPixmapDestructionHook(_qt_pixmap_cleanup_hook_pm); + // Gets called when a pixmap data is about to be destroyed: + void addPixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd); // Gets called when an image is about to be modified or destroyed: void addImageHook(_qt_image_cleanup_hook_64); - void removePixmapModificationHook(_qt_pixmap_cleanup_hook_pm); - void removePixmapDestructionHook(_qt_pixmap_cleanup_hook_pm); + void removePixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd); + void removePixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd); void removeImageHook(_qt_image_cleanup_hook_64); - static void executePixmapModificationHooks(QPixmap*); - static void executePixmapDestructionHooks(QPixmap*); + static void executePixmapDataModificationHooks(QPixmapData*); + static void executePixmapDataDestructionHooks(QPixmapData*); static void executeImageHooks(qint64 key); private: QList<_qt_image_cleanup_hook_64> imageHooks; - QList<_qt_pixmap_cleanup_hook_pm> pixmapModificationHooks; - QList<_qt_pixmap_cleanup_hook_pm> pixmapDestructionHooks; + QList<_qt_pixmap_cleanup_hook_pmd> pixmapModificationHooks; + QList<_qt_pixmap_cleanup_hook_pmd> pixmapDestructionHooks; }; QT_END_NAMESPACE diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index f823fdc..d1e5c40 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -320,8 +320,6 @@ QPixmap::QPixmap(const char * const xpm[]) QPixmap::~QPixmap() { Q_ASSERT(!data || data->ref >= 1); // Catch if ref-counting changes again - if (data && data->is_cached && data->ref == 1) // ref will be decrememnted after destructor returns - QImagePixmapCleanupHooks::executePixmapDestructionHooks(this); } /*! @@ -1025,12 +1023,8 @@ qint64 QPixmap::cacheKey() const if (isNull()) return 0; - int classKey = data->classId(); - if (classKey >= 1024) - classKey = -(classKey >> 10); - return ((((qint64) classKey) << 56) - | (((qint64) data->serialNumber()) << 32) - | ((qint64) (data->detach_no))); + Q_ASSERT(data); + return data->cacheKey(); } static void sendResizeEvents(QWidget *target) @@ -1943,7 +1937,7 @@ void QPixmap::detach() } if (data->is_cached && data->ref == 1) - QImagePixmapCleanupHooks::executePixmapModificationHooks(this); + QImagePixmapCleanupHooks::executePixmapDataModificationHooks(data.data()); #if defined(Q_WS_MAC) QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0; diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index 0e66e09..e1e8a0d 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -68,6 +68,7 @@ #include "qx11info_x11.h" #include <private/qdrawhelper_p.h> #include <private/qimage_p.h> +#include <private/qimagepixmapcleanuphooks_p.h> #include <stdlib.h> @@ -1228,6 +1229,12 @@ void QX11PixmapData::fill(const QColor &fillColor) QX11PixmapData::~QX11PixmapData() { + // Cleanup hooks have to be called before the handles are freed + if (is_cached) { + QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(this); + is_cached = false; + } + release(); } @@ -1236,8 +1243,13 @@ void QX11PixmapData::release() delete pengine; pengine = 0; - if (!X11) + if (!X11) { +#ifndef QT_NO_DEBUG + qWarning("~QX11PixmapData(): QPixmap objects must be destroyed before the QApplication" + " object, otherwise the native pixmap object will be leaked."); +#endif return; + } if (x11_mask) { #ifndef QT_NO_XRENDER diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp index 65032da..ea4fe6b 100644 --- a/src/gui/image/qpixmapdata.cpp +++ b/src/gui/image/qpixmapdata.cpp @@ -45,6 +45,7 @@ #include <QtGui/qimagereader.h> #include <private/qgraphicssystem_p.h> #include <private/qapplication_p.h> +#include <private/qimagepixmapcleanuphooks_p.h> QT_BEGIN_NAMESPACE @@ -80,6 +81,16 @@ QPixmapData::QPixmapData(PixelType pixelType, int objectId) QPixmapData::~QPixmapData() { + // Sometimes the pixmap cleanup hooks will be called from derrived classes, which will + // then set is_cached to false. For example, on X11 QtOpenGL needs to delete the GLXPixmap + // or EGL Pixmap Surface for a given pixmap _before_ the native X11 pixmap is deleted, + // otherwise some drivers will leak the GL surface. In this case, QX11PixmapData will + // call the cleanup hooks itself before deleting the native pixmap and set is_cached to + // false. + if (is_cached) { + QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(this); + is_cached = false; + } } QPixmapData *QPixmapData::createCompatiblePixmapData() const diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h index 1125515..827fa18 100644 --- a/src/gui/image/qpixmapdata_p.h +++ b/src/gui/image/qpixmapdata_p.h @@ -117,6 +117,14 @@ public: inline int colorCount() const { return metric(QPaintDevice::PdmNumColors); } inline int depth() const { return d; } inline bool isNull() const { return is_null; } + inline qint64 cacheKey() const { + int classKey = id; + if (classKey >= 1024) + classKey = -(classKey >> 10); + return ((((qint64) classKey) << 56) + | (((qint64) ser_no) << 32) + | ((qint64) detach_no)); + } #if defined(Q_OS_SYMBIAN) virtual void* toNativeType(NativeType type); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index ffad38b..4054d2a 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -6414,6 +6414,8 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second) first = fp; } + if (fp == second) + return; if (QWidget *sp = second->focusProxy()) second = sp; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index cde6a2d..bf12c6b 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7509,7 +7509,7 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) return widgetPrivate->redirected(offset); } - if (*globalRedirectionAtomic() == 0) + if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0) return 0; QMutexLocker locker(globalRedirectionsMutex()); @@ -7529,7 +7529,7 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) void qt_painter_removePaintDevice(QPaintDevice *dev) { - if (*globalRedirectionAtomic() == 0) + if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0) return; QMutex *mutex = 0; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index b282676..35e95be 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -558,6 +558,9 @@ void QGL2PaintEngineExPrivate::resetGLState() glStencilMask(0xff); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_ALWAYS, 0, 0xff); + glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); + glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); + glDisableVertexAttribArray(QT_OPACITY_ATTR); } void QGL2PaintEngineEx::endNativePainting() diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 2a60708..dd977cb 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1590,10 +1590,8 @@ QGLTextureCache::QGLTextureCache() Q_ASSERT(qt_gl_texture_cache == 0); qt_gl_texture_cache = this; - QImagePixmapCleanupHooks::instance()->addPixmapModificationHook(cleanupTextures); -#ifdef Q_WS_X11 - QImagePixmapCleanupHooks::instance()->addPixmapDestructionHook(cleanupPixmapSurfaces); -#endif + QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTextures); + QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction); QImagePixmapCleanupHooks::instance()->addImageHook(imageCleanupHook); } @@ -1601,10 +1599,8 @@ QGLTextureCache::~QGLTextureCache() { qt_gl_texture_cache = 0; - QImagePixmapCleanupHooks::instance()->removePixmapModificationHook(cleanupTextures); -#ifdef Q_WS_X11 - QImagePixmapCleanupHooks::instance()->removePixmapDestructionHook(cleanupPixmapSurfaces); -#endif + QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTextures); + QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction); QImagePixmapCleanupHooks::instance()->removeImageHook(imageCleanupHook); } @@ -1672,30 +1668,30 @@ void QGLTextureCache::imageCleanupHook(qint64 cacheKey) } -void QGLTextureCache::cleanupTextures(QPixmap* pixmap) +void QGLTextureCache::cleanupTextures(QPixmapData* pmd) { // ### remove when the GL texture cache becomes thread-safe if (qApp->thread() == QThread::currentThread()) { - const qint64 cacheKey = pixmap->cacheKey(); + const qint64 cacheKey = pmd->cacheKey(); QGLTexture *texture = instance()->getTexture(cacheKey); if (texture && texture->options & QGLContext::MemoryManagedBindOption) instance()->remove(cacheKey); } } -#if defined(Q_WS_X11) -void QGLTextureCache::cleanupPixmapSurfaces(QPixmap* pixmap) +void QGLTextureCache::cleanupBeforePixmapDestruction(QPixmapData* pmd) { // Remove any bound textures first: - cleanupTextures(pixmap); + cleanupTextures(pmd); + Q_ASSERT(instance()->getTexture(pmd->cacheKey()) == 0); - QPixmapData *pd = pixmap->data_ptr().data(); - if (pd->classId() == QPixmapData::X11Class) { - Q_ASSERT(pd->ref == 1); // Make sure reference counting isn't broken - QGLContextPrivate::destroyGlSurfaceForPixmap(pd); +#if defined(Q_WS_X11) + if (pmd->classId() == QPixmapData::X11Class) { + Q_ASSERT(pmd->ref == 0); // Make sure reference counting isn't broken + QGLContextPrivate::destroyGlSurfaceForPixmap(pmd); } -} #endif +} void QGLTextureCache::deleteIfEmpty() { diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 0104f07..713b067 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -522,7 +522,7 @@ public: QSize bindCompressedTexturePVR(const char *buf, int len); }; -class QGLTextureCache { +class Q_AUTOTEST_EXPORT QGLTextureCache { public: QGLTextureCache(); ~QGLTextureCache(); @@ -539,11 +539,8 @@ public: static QGLTextureCache *instance(); static void deleteIfEmpty(); static void imageCleanupHook(qint64 cacheKey); - static void cleanupTextures(QPixmap* pixmap); -#ifdef Q_WS_X11 - // X11 needs to catch pixmap data destruction to delete EGL/GLX pixmap surfaces - static void cleanupPixmapSurfaces(QPixmap* pixmap); -#endif + static void cleanupTextures(QPixmapData* pixmap); + static void cleanupBeforePixmapDestruction(QPixmapData* pixmap); private: QCache<qint64, QGLTexture> m_cache; diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index 11011ee..37bb7c0 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -319,14 +319,14 @@ public: ~QGLBlurTextureCache(); QGLBlurTextureInfo *takeBlurTextureInfo(const QPixmap &pixmap); - bool hasBlurTextureInfo(const QPixmap &pixmap) const; + bool hasBlurTextureInfo(quint64 cacheKey) const; void insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info); - void clearBlurTextureInfo(const QPixmap &pixmap); + void clearBlurTextureInfo(quint64 cacheKey); void timerEvent(QTimerEvent *event); private: - static void pixmapDestroyed(QPixmap *pixmap); + static void pixmapDestroyed(QPixmapData *pixmap); QCache<quint64, QGLBlurTextureInfo > cache; @@ -379,21 +379,21 @@ QGLBlurTextureInfo *QGLBlurTextureCache::takeBlurTextureInfo(const QPixmap &pixm return cache.take(pixmap.cacheKey()); } -void QGLBlurTextureCache::clearBlurTextureInfo(const QPixmap &pixmap) +void QGLBlurTextureCache::clearBlurTextureInfo(quint64 cacheKey) { - cache.remove(pixmap.cacheKey()); + cache.remove(cacheKey); } -bool QGLBlurTextureCache::hasBlurTextureInfo(const QPixmap &pixmap) const +bool QGLBlurTextureCache::hasBlurTextureInfo(quint64 cacheKey) const { - return cache.contains(pixmap.cacheKey()); + return cache.contains(cacheKey); } void QGLBlurTextureCache::insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info) { static bool hookAdded = false; if (!hookAdded) { - QImagePixmapCleanupHooks::instance()->addPixmapDestructionHook(pixmapDestroyed); + QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(pixmapDestroyed); hookAdded = true; } @@ -406,11 +406,11 @@ void QGLBlurTextureCache::insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTe timerId = startTimer(8000); } -void QGLBlurTextureCache::pixmapDestroyed(QPixmap *pixmap) +void QGLBlurTextureCache::pixmapDestroyed(QPixmapData *pmd) { foreach (QGLBlurTextureCache *cache, blurTextureCaches) { - if (cache->hasBlurTextureInfo(*pixmap)) - cache->clearBlurTextureInfo(*pixmap); + if (cache->hasBlurTextureInfo(pmd->cacheKey())) + cache->clearBlurTextureInfo(pmd->cacheKey()); } } |