aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2017-01-10 10:29:38 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2017-01-23 13:56:13 +0000
commit72cfdac50b752b8f2d45929265cf4f09cb990bd2 (patch)
tree00d33e0aa3919af657e9b41004ca3f8aa0cfcad6 /src/quick/items
parent5575226f6b25bcf507c3412677756e07ce671cef (diff)
Add PathItem.status to report async processing progress
Change-Id: I09ccdf9c542ebca56187284a0d1776b64c98bfe8 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickpathitem.cpp38
-rw-r--r--src/quick/items/qquickpathitem_p.h11
-rw-r--r--src/quick/items/qquickpathitem_p_p.h11
-rw-r--r--src/quick/items/qquickpathitemgenericrenderer.cpp15
-rw-r--r--src/quick/items/qquickpathitemgenericrenderer_p.h7
5 files changed, 78 insertions, 4 deletions
diff --git a/src/quick/items/qquickpathitem.cpp b/src/quick/items/qquickpathitem.cpp
index 964d997806..306e79dc1e 100644
--- a/src/quick/items/qquickpathitem.cpp
+++ b/src/quick/items/qquickpathitem.cpp
@@ -362,6 +362,7 @@ QQuickPathItemPrivate::QQuickPathItemPrivate()
vpChanged(false),
rendererType(QQuickPathItem::UnknownRenderer),
async(false),
+ status(QQuickPathItem::Null),
renderer(nullptr)
{
}
@@ -378,6 +379,15 @@ void QQuickPathItemPrivate::_q_visualPathChanged()
q->polish();
}
+void QQuickPathItemPrivate::setStatus(QQuickPathItem::Status newStatus)
+{
+ Q_Q(QQuickPathItem);
+ if (status != newStatus) {
+ status = newStatus;
+ emit q->statusChanged();
+ }
+}
+
QQuickPathItem::QQuickPathItem(QQuickItem *parent)
: QQuickItem(*(new QQuickPathItemPrivate), parent)
{
@@ -411,6 +421,12 @@ void QQuickPathItem::setAsynchronous(bool async)
}
}
+QQuickPathItem::Status QQuickPathItem::status() const
+{
+ Q_D(const QQuickPathItem);
+ return d->status;
+}
+
static QQuickVisualPath *vpe_at(QQmlListProperty<QQuickVisualPath> *property, int index)
{
QQuickPathItemPrivate *d = QQuickPathItemPrivate::get(static_cast<QQuickPathItem *>(property->object));
@@ -492,8 +508,9 @@ void QQuickPathItem::updatePolish()
emit rendererChanged();
}
- // endSync() is where expensive calculations may happen, depending on the
- // backend. Therefore do this only when the item is visible.
+ // endSync() is where expensive calculations may happen (or get kicked off
+ // on worker threads), depending on the backend. Therefore do this only
+ // when the item is visible.
if (isVisible())
d->sync();
@@ -593,8 +610,20 @@ QSGNode *QQuickPathItemPrivate::createNode()
return node;
}
+static void q_asyncPathItemReady(void *data)
+{
+ QQuickPathItemPrivate *self = static_cast<QQuickPathItemPrivate *>(data);
+ self->setStatus(QQuickPathItem::Ready);
+}
+
void QQuickPathItemPrivate::sync()
{
+ const bool useAsync = async && renderer->flags().testFlag(QQuickAbstractPathRenderer::SupportsAsync);
+ if (useAsync) {
+ setStatus(QQuickPathItem::Processing);
+ renderer->setAsyncCallback(q_asyncPathItemReady, this);
+ }
+
const int count = vp.count();
renderer->beginSync(count);
@@ -624,7 +653,10 @@ void QQuickPathItemPrivate::sync()
dirty = 0;
}
- renderer->endSync(async);
+ renderer->endSync(useAsync);
+
+ if (!useAsync)
+ setStatus(QQuickPathItem::Ready);
}
// ***** gradient support *****
diff --git a/src/quick/items/qquickpathitem_p.h b/src/quick/items/qquickpathitem_p.h
index 7c962d01fc..1b36348cd2 100644
--- a/src/quick/items/qquickpathitem_p.h
+++ b/src/quick/items/qquickpathitem_p.h
@@ -264,6 +264,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathItem : public QQuickItem
Q_OBJECT
Q_PROPERTY(RendererType renderer READ rendererType NOTIFY rendererChanged)
Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(QQmlListProperty<QQuickVisualPath> visualPaths READ visualPaths)
Q_CLASSINFO("DefaultProperty", "visualPaths")
@@ -276,6 +277,13 @@ public:
};
Q_ENUM(RendererType)
+ enum Status {
+ Null,
+ Ready,
+ Processing
+ };
+ Q_ENUM(Status)
+
QQuickPathItem(QQuickItem *parent = nullptr);
~QQuickPathItem();
@@ -284,6 +292,8 @@ public:
bool asynchronous() const;
void setAsynchronous(bool async);
+ Status status() const;
+
QQmlListProperty<QQuickVisualPath> visualPaths();
protected:
@@ -296,6 +306,7 @@ protected:
Q_SIGNALS:
void rendererChanged();
void asynchronousChanged();
+ void statusChanged();
private:
Q_DISABLE_COPY(QQuickPathItem)
diff --git a/src/quick/items/qquickpathitem_p_p.h b/src/quick/items/qquickpathitem_p_p.h
index faf7b1e451..3c63ec6dc2 100644
--- a/src/quick/items/qquickpathitem_p_p.h
+++ b/src/quick/items/qquickpathitem_p_p.h
@@ -65,6 +65,11 @@ class QSGPlainTexture;
class QQuickAbstractPathRenderer
{
public:
+ enum Flag {
+ SupportsAsync = 0x01
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
virtual ~QQuickAbstractPathRenderer() { }
// Gui thread
@@ -80,11 +85,15 @@ public:
qreal dashOffset, const QVector<qreal> &dashPattern) = 0;
virtual void setFillGradient(int index, QQuickPathGradient *gradient) = 0;
virtual void endSync(bool async) = 0;
+ virtual void setAsyncCallback(void (*)(void *), void *) { }
+ virtual Flags flags() const { return 0; }
// Render thread, with gui blocked
virtual void updateNode() = 0;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickAbstractPathRenderer::Flags)
+
class QQuickVisualPathPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QQuickVisualPath)
@@ -138,6 +147,7 @@ public:
void sync();
void _q_visualPathChanged();
+ void setStatus(QQuickPathItem::Status newStatus);
static QQuickPathItemPrivate *get(QQuickPathItem *item) { return item->d_func(); }
@@ -145,6 +155,7 @@ public:
bool vpChanged;
QQuickPathItem::RendererType rendererType;
bool async;
+ QQuickPathItem::Status status;
QQuickAbstractPathRenderer *renderer;
QVector<QQuickVisualPath *> vp;
};
diff --git a/src/quick/items/qquickpathitemgenericrenderer.cpp b/src/quick/items/qquickpathitemgenericrenderer.cpp
index 6e4c89742a..59b03e0fd2 100644
--- a/src/quick/items/qquickpathitemgenericrenderer.cpp
+++ b/src/quick/items/qquickpathitemgenericrenderer.cpp
@@ -210,8 +210,16 @@ void QQuickPathItemStrokeRunnable::run()
emit done(this);
}
+void QQuickPathItemGenericRenderer::setAsyncCallback(void (*callback)(void *), void *data)
+{
+ m_asyncCallback = callback;
+ m_asyncCallbackData = data;
+}
+
void QQuickPathItemGenericRenderer::endSync(bool async)
{
+ bool didKickOffAsync = false;
+
for (int i = 0; i < m_vp.count(); ++i) {
VisualPathData &d(m_vp[i]);
if (!d.syncDirty)
@@ -264,6 +272,7 @@ void QQuickPathItemGenericRenderer::endSync(bool async)
}
r->deleteLater();
});
+ didKickOffAsync = true;
threadPool.start(r);
} else {
triangulateFill(d.path, d.fillColor, &d.fillVertices, &d.fillIndices);
@@ -290,6 +299,7 @@ void QQuickPathItemGenericRenderer::endSync(bool async)
}
r->deleteLater();
});
+ didKickOffAsync = true;
threadPool.start(r);
} else {
triangulateStroke(d.path, d.pen, d.strokeColor, &d.strokeVertices,
@@ -298,6 +308,9 @@ void QQuickPathItemGenericRenderer::endSync(bool async)
}
}
}
+
+ if (!didKickOffAsync && async && m_asyncCallback)
+ m_asyncCallback(m_asyncCallbackData);
}
void QQuickPathItemGenericRenderer::maybeUpdateAsyncItem()
@@ -308,6 +321,8 @@ void QQuickPathItemGenericRenderer::maybeUpdateAsyncItem()
}
m_accDirty |= DirtyGeom;
m_item->update();
+ if (m_asyncCallback)
+ m_asyncCallback(m_asyncCallbackData);
}
// the stroke/fill triangulation functions may be invoked either on the gui
diff --git a/src/quick/items/qquickpathitemgenericrenderer_p.h b/src/quick/items/qquickpathitemgenericrenderer_p.h
index a4ed090004..3193c27cb3 100644
--- a/src/quick/items/qquickpathitemgenericrenderer_p.h
+++ b/src/quick/items/qquickpathitemgenericrenderer_p.h
@@ -77,7 +77,8 @@ public:
QQuickPathItemGenericRenderer(QQuickItem *item)
: m_item(item),
m_rootNode(nullptr),
- m_accDirty(0)
+ m_accDirty(0),
+ m_asyncCallback(nullptr)
{ }
void beginSync(int totalCount) override;
@@ -92,6 +93,8 @@ public:
qreal dashOffset, const QVector<qreal> &dashPattern) override;
void setFillGradient(int index, QQuickPathGradient *gradient) override;
void endSync(bool async) override;
+ void setAsyncCallback(void (*)(void *), void *) override;
+ Flags flags() const override { return SupportsAsync; }
void updateNode() override;
@@ -140,6 +143,8 @@ private:
QQuickPathItemGenericNode *m_rootNode;
QVector<VisualPathData> m_vp;
int m_accDirty;
+ void (*m_asyncCallback)(void *);
+ void *m_asyncCallbackData;
};
class QQuickPathItemFillRunnable : public QObject, public QRunnable