aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@nokia.com>2012-03-07 22:00:57 +0100
committerLars Knoll <lars.knoll@nokia.com>2012-03-07 22:01:11 +0100
commit616bbd1988f3b92f7d980b6c9a1278f11b712573 (patch)
treec6f9489bc1b53649130be21de858870f574db906 /src/quick/scenegraph
parent3bc907d155034fe64efc8cb6056b48f0c6401bfb (diff)
parent70966df1be02dd94ecf9a122ff9e4976245aeb92 (diff)
Merge remote-tracking branch 'origin/master' into api_changes
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp2
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp27
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgcontextplugin.cpp18
-rw-r--r--src/quick/scenegraph/qsgcontextplugin_p.h4
-rw-r--r--src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp35
-rw-r--r--src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h1
7 files changed, 71 insertions, 18 deletions
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index 92045c55f4..9608ebe861 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -243,6 +243,8 @@ void QSGDistanceFieldGlyphCache::setGlyphsPosition(const QList<GlyphPosition> &g
for (int i = 0; i < count; ++i) {
GlyphPosition glyph = glyphs.at(i);
+ Q_ASSERT(m_cacheData->glyphPaths.contains(glyph.glyph));
+
QPainterPath path = m_cacheData->glyphPaths.value(glyph.glyph);
QRectF br = path.boundingRect();
TexCoord c;
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index ffc64b6edc..02fbaa1a7f 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -109,6 +109,7 @@ public:
QOpenGLContext *gl;
QHash<QSGMaterialType *, QSGMaterialShader *> materials;
+ QMutex textureMutex;
QHash<QQuickTextureFactory *, QSGTexture *> textures;
QSGDistanceFieldGlyphCacheManager *distanceFieldCacheManager;
@@ -118,6 +119,13 @@ public:
bool distanceFieldDisabled;
};
+class QSGTextureCleanupEvent : public QEvent
+{
+public:
+ QSGTextureCleanupEvent(QSGTexture *t) : QEvent(QEvent::User), texture(t) { }
+ ~QSGTextureCleanupEvent() { delete texture; }
+ QSGTexture *texture;
+};
/*!
\class QSGContext
@@ -146,8 +154,10 @@ QSGContext::~QSGContext()
void QSGContext::invalidate()
{
Q_D(QSGContext);
+ d->textureMutex.lock();
qDeleteAll(d->textures.values());
d->textures.clear();
+ d->textureMutex.unlock();
qDeleteAll(d->materials.values());
d->materials.clear();
delete d->distanceFieldCacheManager;
@@ -165,6 +175,7 @@ QSGTexture *QSGContext::textureForFactory(QQuickTextureFactory *factory, QQuickC
if (!factory)
return 0;
+ d->textureMutex.lock();
QSGTexture *texture = d->textures.value(factory);
if (!texture) {
if (QQuickDefaultTextureFactory *dtf = qobject_cast<QQuickDefaultTextureFactory *>(factory))
@@ -172,8 +183,9 @@ QSGTexture *QSGContext::textureForFactory(QQuickTextureFactory *factory, QQuickC
else
texture = factory->createTexture(canvas);
d->textures.insert(factory, texture);
- connect(factory, SIGNAL(destroyed(QObject *)), this, SLOT(textureFactoryDestroyed(QObject *)));
+ connect(factory, SIGNAL(destroyed(QObject *)), this, SLOT(textureFactoryDestroyed(QObject *)), Qt::DirectConnection);
}
+ d->textureMutex.unlock();
return texture;
}
@@ -183,9 +195,16 @@ void QSGContext::textureFactoryDestroyed(QObject *o)
Q_D(QSGContext);
QQuickTextureFactory *f = static_cast<QQuickTextureFactory *>(o);
- // This function will only be called on the scene graph thread, so it is
- // safe to directly delete the texture here.
- delete d->textures.take(f);
+ d->textureMutex.lock();
+ QSGTexture *t = d->textures.take(f);
+ d->textureMutex.unlock();
+
+ if (t) {
+ if (t->thread() == thread())
+ t->deleteLater();
+ else
+ QCoreApplication::postEvent(this, new QSGTextureCleanupEvent(t));
+ }
}
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 0f8b5ae1de..dfb960f420 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -68,6 +68,7 @@ class QSGTexture;
class QSGMaterial;
class QSGMaterialShader;
class QSGEngine;
+class QQuickWindowManager;
class QOpenGLContext;
class QOpenGLFramebufferObject;
@@ -122,6 +123,7 @@ public:
virtual QAnimationDriver *createAnimationDriver(QObject *parent);
static QQuickTextureFactory *createTextureFactoryFromImage(const QImage &image);
+ static QQuickWindowManager *createWindowManager();
public slots:
diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp
index b8a66fd0c0..bd1c4cece8 100644
--- a/src/quick/scenegraph/qsgcontextplugin.cpp
+++ b/src/quick/scenegraph/qsgcontextplugin.cpp
@@ -152,5 +152,23 @@ QQuickTextureFactory *QSGContext::createTextureFactoryFromImage(const QImage &im
}
+/*!
+ \fn QQuickWindowManager *createWindowManager()
+
+ Calls into the scene graph adaptation if available and creates a hardware
+ specific window manager.
+ */
+
+QQuickWindowManager *QSGContext::createWindowManager()
+{
+ QSGAdaptionPluginData *plugin = contextFactory();
+ if (plugin->factory)
+ return plugin->factory->createWindowManager();
+ return 0;
+}
+
+
+
+
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgcontextplugin_p.h b/src/quick/scenegraph/qsgcontextplugin_p.h
index acff222fb0..2c4531c239 100644
--- a/src/quick/scenegraph/qsgcontextplugin_p.h
+++ b/src/quick/scenegraph/qsgcontextplugin_p.h
@@ -53,11 +53,14 @@ QT_BEGIN_NAMESPACE
class QSGContext;
+class QQuickWindowManager;
+
struct Q_QUICK_EXPORT QSGContextFactoryInterface : public QFactoryInterface
{
virtual QSGContext *create(const QString &key) const = 0;
virtual QQuickTextureFactory *createTextureFactoryFromImage(const QImage &image) = 0;
+ virtual QQuickWindowManager *createWindowManager() = 0;
};
#define QSGContextFactoryInterface_iid \
@@ -76,6 +79,7 @@ public:
virtual QSGContext *create(const QString &key) const = 0;
virtual QQuickTextureFactory *createTextureFactoryFromImage(const QImage &) { return 0; }
+ virtual QQuickWindowManager *createWindowManager() { return 0; }
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp
index 46bd141909..76fb9036f4 100644
--- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache.cpp
@@ -126,6 +126,7 @@ void QSGSharedDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs
#endif
m_requestedGlyphsThatHaveNotBeenReturned.unite(glyphs);
+ m_requestedGlyphs.unite(glyphs);
QVector<quint32> glyphsVector;
glyphsVector.reserve(glyphs.size());
@@ -198,6 +199,8 @@ void QSGSharedDistanceFieldGlyphCache::releaseGlyphs(const QSet<glyph_t> &glyphs
m_cacheId.constData(), glyphs.size());
#endif
+ m_requestedGlyphs.subtract(glyphs);
+
QVector<quint32> glyphsVector;
glyphsVector.reserve(glyphs.size());
@@ -588,19 +591,21 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsUpdated(const QByteArray &cach
#endif
for (int i=0; i<itemIds.size(); ++i) {
- PendingGlyph &pendingGlyph = m_pendingReadyGlyphs[itemIds.at(i)];
- void *oldBuffer = pendingGlyph.buffer;
- Q_ASSERT(bufferSize.height() >= pendingGlyph.bufferSize.height());
+ if (m_requestedGlyphs.contains(itemIds.at(i))) {
+ PendingGlyph &pendingGlyph = m_pendingReadyGlyphs[itemIds.at(i)];
+ void *oldBuffer = pendingGlyph.buffer;
+ Q_ASSERT(bufferSize.height() >= pendingGlyph.bufferSize.height());
- pendingGlyph.buffer = bufferId;
- pendingGlyph.position = positions.at(i);
- pendingGlyph.bufferSize = bufferSize;
+ pendingGlyph.buffer = bufferId;
+ pendingGlyph.position = positions.at(i);
+ pendingGlyph.bufferSize = bufferSize;
- m_sharedGraphicsCache->referenceBuffer(bufferId);
- if (oldBuffer != 0)
- m_sharedGraphicsCache->dereferenceBuffer(oldBuffer);
+ m_sharedGraphicsCache->referenceBuffer(bufferId);
+ if (oldBuffer != 0)
+ m_sharedGraphicsCache->dereferenceBuffer(oldBuffer);
- m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i));
+ m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i));
+ }
}
}
@@ -616,8 +621,10 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsInvalidated(const QByteArray &
if (m_cacheId != cacheId)
return;
- for (int i=0; i<itemIds.size(); ++i)
- m_pendingInvalidatedGlyphs.insert(itemIds.at(i));
+ for (int i=0; i<itemIds.size(); ++i) {
+ if (m_requestedGlyphs.contains(itemIds.at(i)))
+ m_pendingInvalidatedGlyphs.insert(itemIds.at(i));
+ }
}
emit glyphsPending();
@@ -638,8 +645,8 @@ void QSGSharedDistanceFieldGlyphCache::reportItemsMissing(const QByteArray &cach
#endif
for (int i=0; i<itemIds.size(); ++i) {
- m_pendingMissingGlyphs.insert(itemIds.at(i));
- m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i));
+ if (m_requestedGlyphsThatHaveNotBeenReturned.remove(itemIds.at(i)))
+ m_pendingMissingGlyphs.insert(itemIds.at(i));
}
}
diff --git a/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h
index 3052f20813..4a91b4473a 100644
--- a/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgshareddistancefieldglyphcache_p.h
@@ -87,6 +87,7 @@ private:
void saveTexture(GLuint textureId, int width, int height);
QSet<quint32> m_requestedGlyphsThatHaveNotBeenReturned;
+ QSet<quint32> m_requestedGlyphs;
QWaitCondition m_pendingGlyphsCondition;
QByteArray m_cacheId;
QPlatformSharedGraphicsCache *m_sharedGraphicsCache;