diff options
author | Alan Alpert <416365416c@gmail.com> | 2013-09-13 16:34:07 -0700 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-30 23:33:08 +0100 |
commit | 2c750b45709fa164b758c5ec9e0e9ee744c51555 (patch) | |
tree | 01effa56bed73276b79b7f7dabf24c9fce7668de /src/particles/qquickimageparticle.cpp | |
parent | 639553f024f7b03706553ebb34825591be75eed2 (diff) |
Load image data on main thread
QQuickPixmap use should be done on the main thread, if not it can lead
to an exception when creating the file loading thread (owned by the
engine).
Change-Id: Id59cec4312ecdee537dcba85778bd90ea4433b2e
Reviewed-by: Gunnar Sletta <gunnar.sletta@digia.com>
Diffstat (limited to 'src/particles/qquickimageparticle.cpp')
-rw-r--r-- | src/particles/qquickimageparticle.cpp | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp index 036dfb901e..01cd487664 100644 --- a/src/particles/qquickimageparticle.cpp +++ b/src/particles/qquickimageparticle.cpp @@ -846,7 +846,7 @@ QQuickImageParticle::QQuickImageParticle(QQuickItem* parent) , m_lastLevel(Unknown) , m_debugMode(false) , m_entryEffect(Fade) - , m_buildingNodes(false) + , m_startedImageLoading(0) { setFlag(ItemHasContents); } @@ -1293,39 +1293,47 @@ bool QQuickImageParticle::loadingSomething() || (m_spriteEngine && m_spriteEngine->isLoading()); } -void QQuickImageParticle::buildParticleNodes()//Starts async parts, like loading images. +void QQuickImageParticle::mainThreadFetchImageData() { - if (m_rootNode || loadingSomething()) - return; + if (m_image) {//ImageData created on setSource + m_image->pix.clear(this); + m_image->pix.load(qmlEngine(this), m_image->source); + } - if (!m_buildingNodes) { - if (m_image) {//ImageData created on setSource - m_image->pix.clear(this); - m_image->pix.load(qmlEngine(this), m_image->source); - } + if (m_spriteEngine) + m_spriteEngine->startAssemblingImage(); - if (m_spriteEngine) - m_spriteEngine->startAssemblingImage(); + if (m_colorTable) + m_colorTable->pix.load(qmlEngine(this), m_colorTable->source); - if (m_colorTable) - m_colorTable->pix.load(qmlEngine(this), m_colorTable->source); + if (m_sizeTable) + m_sizeTable->pix.load(qmlEngine(this), m_sizeTable->source); - if (m_sizeTable) - m_sizeTable->pix.load(qmlEngine(this), m_sizeTable->source); + if (m_opacityTable) + m_opacityTable->pix.load(qmlEngine(this), m_opacityTable->source); - if (m_opacityTable) - m_opacityTable->pix.load(qmlEngine(this), m_opacityTable->source); + m_startedImageLoading = 2; +} - m_buildingNodes = true; - if (loadingSomething()) - return; +void QQuickImageParticle::buildParticleNodes() +{ + // Starts async parts, like loading images, on gui thread + // Not on individual properties, because we delay until system is running + if (m_rootNode || loadingSomething()) + return; + + if (m_startedImageLoading == 0) { + m_startedImageLoading = 1; + QQuickImageParticle::staticMetaObject.invokeMethod(this, "mainThreadFetchImageData", Qt::QueuedConnection); + } else if (m_startedImageLoading == 2) { //stage 1 is in gui thread + finishBuildParticleNodes(); //rest happens in render thread } - finishBuildParticleNodes(); + + //No mutex, because it's slow and a compare that fails due to a race condition means just a dropped frame } void QQuickImageParticle::finishBuildParticleNodes() { - m_buildingNodes = false; #ifdef QT_OPENGL_ES_2 if (m_count * 4 > 0xffff) { printf("ImageParticle: Too many particles - maximum 16,000 per ImageParticle.\n");//ES 2 vertex count limit is ushort @@ -1574,7 +1582,7 @@ QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) m_material = 0; m_pleaseReset = false; - m_buildingNodes = false;//Cancel a part-way build + m_startedImageLoading = 0;//Cancel a part-way build (may still have a pending load) } if (m_system && m_system->isRunning() && !m_system->isPaused()){ @@ -1583,7 +1591,7 @@ QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *) update(); foreach (QSGGeometryNode* node, m_nodes) node->markDirty(QSGNode::DirtyGeometry); - } else if (m_buildingNodes) { + } else if (m_startedImageLoading < 2) { update();//To call prepareNextFrame() again from the renderThread } } |