aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar@sletta.org>2014-08-23 14:13:53 +0200
committerGunnar Sletta <gunnar@sletta.org>2014-08-26 06:12:51 +0200
commitb0149afd075e8fa5b86bbe90501f46c4c63a52da (patch)
tree9b4484324186dd463e14f4516e1ea50932cde385 /src
parente7ceacda70857f68a4c406c898bcd9b517ac1b43 (diff)
Make Canvas a texture provider.
Change-Id: I8b5c9d8a5ed9ef9079eafb30ef0cb73786204ee6 Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp83
-rw-r--r--src/quick/items/context2d/qquickcanvasitem_p.h3
2 files changed, 76 insertions, 10 deletions
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 8d317f7fad..878cc70586 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -52,6 +52,23 @@
QT_BEGIN_NAMESPACE
+class QQuickCanvasNode : public QSGSimpleTextureNode
+{
+public:
+ QQuickCanvasNode() {
+ qsgnode_set_description(this, QStringLiteral("canvasnode"));
+ setOwnsTexture(true);
+ }
+};
+
+class QQuickCanvasTextureProvider : public QSGTextureProvider
+{
+public:
+ QQuickCanvasNode *node;
+ QSGTexture *texture() const Q_DECL_OVERRIDE { return node ? node->texture() : 0; }
+ void fireTextureChanged() { emit textureChanged(); }
+};
+
QQuickCanvasPixmap::QQuickCanvasPixmap(const QImage& image)
: m_pixmap(0)
, m_image(image)
@@ -158,6 +175,8 @@ public:
QHash<QUrl, QQmlRefPointer<QQuickCanvasPixmap> > pixmaps;
QUrl baseUrl;
QMap<int, QV4::PersistentValue> animationCallbacks;
+ mutable QQuickCanvasTextureProvider *textureProvider;
+ QQuickCanvasNode *node;
};
QQuickCanvasItemPrivate::QQuickCanvasItemPrivate()
@@ -171,6 +190,8 @@ QQuickCanvasItemPrivate::QQuickCanvasItemPrivate()
, available(false)
, renderTarget(QQuickCanvasItem::Image)
, renderStrategy(QQuickCanvasItem::Immediate)
+ , textureProvider(0)
+ , node(0)
{
implicitAntialiasing = true;
}
@@ -269,6 +290,11 @@ QQuickCanvasItemPrivate::~QQuickCanvasItemPrivate()
them in the \c onImageLoaded handler.
\endlist
+ Starting Qt 5.4, the Canvas is a
+ \l{QSGTextureProvider}{texture provider}
+ and can be used directly in \l {ShaderEffect}{ShaderEffects} and other
+ classes that consume texture providers.
+
\sa Context2D
*/
@@ -283,6 +309,8 @@ QQuickCanvasItem::~QQuickCanvasItem()
{
Q_D(QQuickCanvasItem);
delete d->context;
+ if (d->textureProvider)
+ QQuickWindowQObjectCleanupJob::schedule(window(), d->textureProvider);
}
/*!
@@ -597,6 +625,11 @@ void QQuickCanvasItem::releaseResources()
delete d->context;
d->context = 0;
}
+ d->node = 0; // managed by the scene graph, just reset the pointer
+ if (d->textureProvider) {
+ QQuickWindowQObjectCleanupJob::schedule(window(), d->textureProvider);
+ d->textureProvider = 0;
+ }
}
void QQuickCanvasItem::invalidateSG()
@@ -604,6 +637,9 @@ void QQuickCanvasItem::invalidateSG()
Q_D(QQuickCanvasItem);
d->context->deleteLater();
d->context = 0;
+ d->node = 0; // managed by the scene graph, just reset the pointer
+ delete d->textureProvider;
+ d->textureProvider = 0;
}
void QQuickCanvasItem::componentComplete()
@@ -678,27 +714,25 @@ void QQuickCanvasItem::updatePolish()
}
}
-class QQuickCanvasNode : public QSGSimpleTextureNode
-{
-public:
- ~QQuickCanvasNode()
- {
- delete texture();
- }
-};
-
QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
Q_D(QQuickCanvasItem);
if (!d->context || d->canvasWindow.size().isEmpty()) {
+ if (d->textureProvider) {
+ d->textureProvider->node = 0;
+ d->textureProvider->fireTextureChanged();
+ }
delete oldNode;
return 0;
}
QQuickCanvasNode *node = static_cast<QQuickCanvasNode*>(oldNode);
- if (!node)
+ if (!node) {
node = new QQuickCanvasNode();
+ d->node = node;
+ }
+
if (d->smooth)
node->setFiltering(QSGTexture::Linear);
@@ -715,14 +749,43 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
QSGTexture *texture = factory->textureForNextFrame(node->texture());
if (!texture) {
delete node;
+ d->node = 0;
+ if (d->textureProvider) {
+ d->textureProvider->node = 0;
+ d->textureProvider->fireTextureChanged();
+ }
return 0;
}
node->setTexture(texture);
node->setRect(QRectF(QPoint(0, 0), d->canvasWindow.size()));
+
+ if (d->textureProvider) {
+ d->textureProvider->node = node;
+ d->textureProvider->fireTextureChanged();
+ }
return node;
}
+bool QQuickCanvasItem::isTextureProvider() const
+{
+ return true;
+}
+
+QSGTextureProvider *QQuickCanvasItem::textureProvider() const
+{
+ Q_D(const QQuickCanvasItem);
+ QQuickWindow *w = window();
+ if (!w || !w->openglContext() || QThread::currentThread() != w->openglContext()->thread()) {
+ qWarning("QQuickCanvasItem::textureProvider: can only be queried on the rendering thread of an exposed window");
+ return 0;
+ }
+ if (!d->textureProvider)
+ d->textureProvider = new QQuickCanvasTextureProvider;
+ d->textureProvider->node = d->node;
+ return d->textureProvider;
+}
+
/*!
\qmlmethod object QtQuick::Canvas::getContext(string contextId, any... args)
diff --git a/src/quick/items/context2d/qquickcanvasitem_p.h b/src/quick/items/context2d/qquickcanvasitem_p.h
index 62970098e9..95bc6f395f 100644
--- a/src/quick/items/context2d/qquickcanvasitem_p.h
+++ b/src/quick/items/context2d/qquickcanvasitem_p.h
@@ -133,6 +133,9 @@ public:
Q_INVOKABLE QString toDataURL(const QString& type = QLatin1String("image/png")) const;
QQmlRefPointer<QQuickCanvasPixmap> loadedPixmap(const QUrl& url);
+ bool isTextureProvider() const Q_DECL_OVERRIDE;
+ QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE;
+
Q_SIGNALS:
void paint(const QRect &region);
void painted();