diff options
-rw-r--r-- | doc/src/examples/waitconditions.qdoc | 2 | ||||
-rw-r--r-- | mkspecs/common/qws.conf | 4 | ||||
-rw-r--r-- | src/corelib/kernel/qabstractitemmodel.cpp | 92 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 24 | ||||
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 17 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 51 | ||||
-rw-r--r-- | src/opengl/qgl_p.h | 36 |
7 files changed, 148 insertions, 78 deletions
diff --git a/doc/src/examples/waitconditions.qdoc b/doc/src/examples/waitconditions.qdoc index 1d3ff84..d4f680e 100644 --- a/doc/src/examples/waitconditions.qdoc +++ b/doc/src/examples/waitconditions.qdoc @@ -92,7 +92,7 @@ Together, the wait conditions, the mutex, and the \c numUsedBytes counter ensure that the producer is never more than \c BufferSize bytes ahead of the consumer, and that the consumer never reads - data that the consumer hasn't generated yet. + data that the producer hasn't generated yet. \section1 Producer Class diff --git a/mkspecs/common/qws.conf b/mkspecs/common/qws.conf index 96341a7..225f0ff 100644 --- a/mkspecs/common/qws.conf +++ b/mkspecs/common/qws.conf @@ -14,6 +14,10 @@ QMAKE_INCDIR_X11 = QMAKE_LIBDIR_X11 = QMAKE_INCDIR_OPENGL = QMAKE_LIBDIR_OPENGL = +QMAKE_INCDIR_OPENGL_ES1 = +QMAKE_LIBDIR_OPENGL_ES1 = +QMAKE_INCDIR_OPENGL_ES2 = +QMAKE_LIBDIR_OPENGL_ES2 = QMAKE_LIBS_X11 = QMAKE_LIBS_X11SM = QMAKE_LIBS_OPENGL = diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index 24c26b6..b0e2f48 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -2508,29 +2508,35 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star When reimplementing a subclass, this method simplifies moving entities in your model. This method is responsible for moving persistent indexes in the model, which you would otherwise be - required to do yourself. - - Using beginMoveRows and endMoveRows is an alternative to emitting - layoutAboutToBeChanged and layoutChanged directly along with - changePersistentIndexes. layoutAboutToBeChanged is emitted by - this method for compatibility reasons. + required to do yourself. Using beginMoveRows and endMoveRows + is an alternative to emitting layoutAboutToBeChanged and + layoutChanged directly along with changePersistentIndexes. + layoutAboutToBeChanged is emitted by this method for compatibility + reasons. The \a sourceParent index corresponds to the parent from which the - rows are moved; \a sourceFirst and \a sourceLast are the row - numbers of the rows to be moved. The \a destinationParent index - corresponds to the parent into which the rows are moved. The \a + rows are moved; \a sourceFirst and \a sourceLast are the first and last + row numbers of the rows to be moved. The \a destinationParent index + corresponds to the parent into which those rows are moved. The \a destinationChild is the row to which the rows will be moved. That is, the index at row \a sourceFirst in \a sourceParent will become - row \a destinationChild in \a destinationParent. Its siblings will - be moved correspondingly. - - Note that \a sourceParent and \a destinationParent may be the - same, in which case you must ensure that the \a destinationChild is - not within the range of \a sourceFirst and \a sourceLast. You - must also ensure that you do not attempt to move a row to one of - its own children or ancestors. This method returns false if either - condition is true, in which case you should abort your move - operation. + row \a destinationChild in \a destinationParent, followed by all other + rows up to \a sourceLast. + + However, when moving rows down in the same parent (\a sourceParent + and \a destinationParent are equal), the rows will be placed before the + \a destinationChild index. That is, if you wish to move rows 0 and 1 so + they will become rows 1 and 2, \a destinationChild should be 3. In this + case, the new index for the source row \c i (which is between + \a sourceFirst and \a sourceLast) is equal to + \c {(destinationChild-sourceLast-1+i)}. + + Note that if \a sourceParent and \a destinationParent are the same, + you must ensure that the \a destinationChild is not within the range + of \a sourceFirst and \a sourceLast + 1. You must also ensure that you + do not attempt to move a row to one of its own children or ancestors. + This method returns false if either condition is true, in which case you + should abort your move operation. \table 80% \row @@ -2761,29 +2767,35 @@ void QAbstractItemModel::endRemoveColumns() When reimplementing a subclass, this method simplifies moving entities in your model. This method is responsible for moving persistent indexes in the model, which you would otherwise be - required to do yourself. - - Using beginMoveColumns and endMoveColumns is an alternative to - emitting layoutAboutToBeChanged and layoutChanged directly along - with changePersistentIndexes. layoutAboutToBeChanged is emitted - by this method for compatibility reasons. + required to do yourself. Using beginMoveRows and endMoveRows + is an alternative to emitting layoutAboutToBeChanged and + layoutChanged directly along with changePersistentIndexes. + layoutAboutToBeChanged is emitted by this method for compatibility + reasons. The \a sourceParent index corresponds to the parent from which the - columns are moved; \a sourceFirst and \a sourceLast are the column - numbers of the columns to be moved. The \a destinationParent index - corresponds to the parent into which the columns are moved. The \a - destinationChild is the column to which the columns will be - moved. That is, the index at column \a sourceFirst in \a - sourceParent will become column \a destinationChild in \a - destinationParent. Its siblings will be moved correspondingly. - - Note that \a sourceParent and \a destinationParent may be the - same, in which case you must ensure that the \a destinationChild - is not within the range of \a sourceFirst and \a sourceLast. You - must also ensure that you do not attempt to move a row to one of - its own chilren or ancestors. This method returns false if either - condition is true, in which case you should abort your move - operation. + columns are moved; \a sourceFirst and \a sourceLast are the first and last + column numbers of the columns to be moved. The \a destinationParent index + corresponds to the parent into which those columns are moved. The \a + destinationChild is the column to which the columns will be moved. That + is, the index at column \a sourceFirst in \a sourceParent will become + column \a destinationChild in \a destinationParent, followed by all other + columns up to \a sourceLast. + + However, when moving columns down in the same parent (\a sourceParent + and \a destinationParent are equal), the columnss will be placed before the + \a destinationChild index. That is, if you wish to move columns 0 and 1 so + they will become columns 1 and 2, \a destinationChild should be 3. In this + case, the new index for the source column \c i (which is between + \a sourceFirst and \a sourceLast) is equal to + \c {(destinationChild-sourceLast-1+i)}. + + Note that if \a sourceParent and \a destinationParent are the same, + you must ensure that the \a destinationChild is not within the range + of \a sourceFirst and \a sourceLast + 1. You must also ensure that you + do not attempt to move a column to one of its own children or ancestors. + This method returns false if either condition is true, in which case you + should abort your move operation. \sa endMoveColumns() diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 36d21a6..9d7354a 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -5687,32 +5687,28 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect) return; } + // Find pixmap in cache, then remove to avoid deep copy when modifying.s QPixmap cachedPixmap; if (!QPixmapCache::find(cache->key, &cachedPixmap)) { update(rect); return; } + QPixmapCache::remove(cache->key); + + QRect scrollRect = (rect.isNull() ? boundingRect() : rect).toAlignedRect(); + if (!scrollRect.intersects(cache->boundingRect)) + return; // Nothing to scroll. QRegion exposed; - const bool scrollEntirePixmap = rect.isNull(); - if (scrollEntirePixmap) { - // Scroll entire pixmap. - cachedPixmap.scroll(dx, dy, cachedPixmap.rect(), &exposed); - } else { - if (!rect.intersects(cache->boundingRect)) - return; // Nothing to scroll. - // Scroll sub-rect of pixmap. The rect is in item coordinates - // so we have to translate it to pixmap coordinates. - QRect scrollRect = rect.toAlignedRect(); - cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed); - } + cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed); - QPixmapCache::replace(cache->key, cachedPixmap); + // Reinsert into cache. + cache->key = QPixmapCache::insert(cachedPixmap); // Translate the existing expose. for (int i = 0; i < cache->exposed.size(); ++i) { QRectF &e = cache->exposed[i]; - if (!scrollEntirePixmap && !e.intersects(rect)) + if (!rect.isNull() && !e.intersects(rect)) continue; e.translate(dx, dy); } diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index a2c058a..09a3bfe 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -780,6 +780,9 @@ void QApplicationPrivate::construct( qt_is_gui_used = (qt_appType != QApplication::Tty); process_cmdline(); + // the environment variable has the lowest precedence of runtime graphicssystem switches + if (graphics_system_name.isEmpty()) + graphics_system_name = QString::fromLocal8Bit(qgetenv("QT_GRAPHICSSYSTEM")); // Must be called before initialize() qt_init(this, qt_appType #ifdef Q_WS_X11 @@ -1560,10 +1563,18 @@ QStyle* QApplication::setStyle(const QString& style) on-screen widgets and QPixmaps. The available systems are \c{"native"}, \c{"raster"} and \c{"opengl"}. - This function call overrides both the application commandline - \c{-graphicssystem} switch and the configure \c{-graphicssystem} switch. + There are several ways to set the graphics backend, in order of decreasing + precedence: + \list + \o the application commandline \c{-graphicssystem} switch + \o QApplication::setGraphicsSystem() + \o the QT_GRAPHICSSYSTEM environment variable + \o the Qt configure \c{-graphicssystem} switch + \endlist + If the highest precedence switch sets an invalid name, the error will be + ignored and the default backend will be used. - \warning This function must be called before the QApplication constructor + \warning This function is only effective before the QApplication constructor is called. \note The \c{"opengl"} option is currently experimental. diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 922a96c..c8502c2 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -91,6 +91,7 @@ #include "qcolormap.h" #include "qfile.h" #include "qlibrary.h" +#include <qmutex.h> QT_BEGIN_NAMESPACE @@ -1515,10 +1516,33 @@ bool operator!=(const QGLFormat& a, const QGLFormat& b) return !(a == b); } +struct QGLContextGroupList { + void append(QGLContextGroup *group) { + QMutexLocker locker(&m_mutex); + m_list.append(group); + } + + void remove(QGLContextGroup *group) { + QMutexLocker locker(&m_mutex); + m_list.removeOne(group); + } + + QList<QGLContextGroup *> m_list; + QMutex m_mutex; +}; + +Q_GLOBAL_STATIC(QGLContextGroupList, qt_context_groups) + /***************************************************************************** QGLContext implementation *****************************************************************************/ +QGLContextGroup::QGLContextGroup(const QGLContext *context) + : m_context(context), m_guards(0), m_refs(1) +{ + qt_context_groups()->append(this); +} + QGLContextGroup::~QGLContextGroup() { // Clear any remaining QGLSharedResourceGuard objects on the group. @@ -1528,6 +1552,7 @@ QGLContextGroup::~QGLContextGroup() guard->m_id = 0; guard = guard->m_next; } + qt_context_groups()->remove(this); } void QGLContextGroup::addGuard(QGLSharedResourceGuard *guard) @@ -1736,7 +1761,7 @@ void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, i QWriteLocker locker(&m_lock); if (m_cache.totalCost() + cost > m_cache.maxCost()) { // the cache is full - make an attempt to remove something - const QList<qint64> keys = m_cache.keys(); + const QList<QGLTextureCacheKey> keys = m_cache.keys(); int i = 0; while (i < m_cache.count() && (m_cache.totalCost() + cost > m_cache.maxCost())) { @@ -1746,13 +1771,26 @@ void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, i ++i; } } - m_cache.insert(key, texture, cost); + const QGLTextureCacheKey cacheKey = {key, QGLContextPrivate::contextGroup(ctx)}; + m_cache.insert(cacheKey, texture, cost); +} + +void QGLTextureCache::remove(qint64 key) +{ + QWriteLocker locker(&m_lock); + QMutexLocker groupLocker(&qt_context_groups()->m_mutex); + QList<QGLContextGroup *>::const_iterator it = qt_context_groups()->m_list.constBegin(); + while (it != qt_context_groups()->m_list.constEnd()) { + const QGLTextureCacheKey cacheKey = {key, *it}; + m_cache.remove(cacheKey); + ++it; + } } bool QGLTextureCache::remove(QGLContext* ctx, GLuint textureId) { QWriteLocker locker(&m_lock); - QList<qint64> keys = m_cache.keys(); + QList<QGLTextureCacheKey> keys = m_cache.keys(); for (int i = 0; i < keys.size(); ++i) { QGLTexture *tex = m_cache.object(keys.at(i)); if (tex->id == textureId && tex->context == ctx) { @@ -1767,9 +1805,9 @@ bool QGLTextureCache::remove(QGLContext* ctx, GLuint textureId) void QGLTextureCache::removeContextTextures(QGLContext* ctx) { QWriteLocker locker(&m_lock); - QList<qint64> keys = m_cache.keys(); + QList<QGLTextureCacheKey> keys = m_cache.keys(); for (int i = 0; i < keys.size(); ++i) { - const qint64 &key = keys.at(i); + const QGLTextureCacheKey &key = keys.at(i); if (m_cache.object(key)->context == ctx) m_cache.remove(key); } @@ -1782,7 +1820,6 @@ void QGLTextureCache::removeContextTextures(QGLContext* ctx) void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey) { qt_gl_texture_cache()->remove(cacheKey); - Q_ASSERT(qt_gl_texture_cache()->getTexture(cacheKey) == 0); } @@ -2425,7 +2462,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G QGLTexture *QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum target) { Q_Q(QGLContext); - QGLTexture *texture = QGLTextureCache::instance()->getTexture(key); + QGLTexture *texture = QGLTextureCache::instance()->getTexture(q, key); if (texture && texture->target == target && (texture->context == q || QGLContext::areSharing(q, texture->context))) { diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index d92f963..16c225f 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -230,7 +230,7 @@ public: static void addShare(const QGLContext *context, const QGLContext *share); static void removeShare(const QGLContext *context); private: - QGLContextGroup(const QGLContext *context) : m_context(context), m_guards(0), m_refs(1) { } + QGLContextGroup(const QGLContext *context); QGLExtensionFuncs m_extensionFuncs; const QGLContext *m_context; // context group's representative @@ -522,17 +522,33 @@ public: QSize bindCompressedTexturePVR(const char *buf, int len); }; +struct QGLTextureCacheKey { + qint64 key; + QGLContextGroup *group; +}; + +inline bool operator==(const QGLTextureCacheKey &a, const QGLTextureCacheKey &b) +{ + return a.key == b.key && a.group == b.group; +} + +inline uint qHash(const QGLTextureCacheKey &key) +{ + return qHash(key.key) ^ qHash(key.group); +} + + class Q_AUTOTEST_EXPORT QGLTextureCache { public: QGLTextureCache(); ~QGLTextureCache(); void insert(QGLContext *ctx, qint64 key, QGLTexture *texture, int cost); - inline void remove(quint64 key); + void remove(qint64 key); inline int size(); inline void setMaxCost(int newMax); inline int maxCost(); - inline QGLTexture* getTexture(quint64 key); + inline QGLTexture* getTexture(QGLContext *ctx, qint64 key); bool remove(QGLContext *ctx, GLuint textureId); void removeContextTextures(QGLContext *ctx); @@ -542,7 +558,7 @@ public: static void cleanupBeforePixmapDestruction(QPixmapData* pixmap); private: - QCache<qint64, QGLTexture> m_cache; + QCache<QGLTextureCacheKey, QGLTexture> m_cache; QReadWriteLock m_lock; }; @@ -563,19 +579,13 @@ int QGLTextureCache::maxCost() return m_cache.maxCost(); } -QGLTexture* QGLTextureCache::getTexture(quint64 key) +QGLTexture* QGLTextureCache::getTexture(QGLContext *ctx, qint64 key) { QReadLocker locker(&m_lock); - return m_cache.object(key); + const QGLTextureCacheKey cacheKey = {key, QGLContextPrivate::contextGroup(ctx)}; + return m_cache.object(cacheKey); } -void QGLTextureCache::remove(quint64 key) -{ - QWriteLocker locker(&m_lock); - m_cache.remove(key); -} - - extern Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine(); bool qt_gl_preferGL2Engine(); |