aboutsummaryrefslogtreecommitdiffstats
path: root/src/particles/qquickimageparticle.cpp
diff options
context:
space:
mode:
authorAlan Alpert <416365416c@gmail.com>2013-09-13 16:34:07 -0700
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-30 23:33:08 +0100
commit2c750b45709fa164b758c5ec9e0e9ee744c51555 (patch)
tree01effa56bed73276b79b7f7dabf24c9fce7668de /src/particles/qquickimageparticle.cpp
parent639553f024f7b03706553ebb34825591be75eed2 (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.cpp56
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
}
}