aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/context2d/qquickcanvasitem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items/context2d/qquickcanvasitem.cpp')
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp77
1 files changed, 41 insertions, 36 deletions
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 89a68e4f33..3b2b125c63 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -43,7 +43,7 @@
#include <private/qquickcanvascontext_p.h>
#include <private/qquickcontext2d_p.h>
#include <private/qquickcontext2dtexture_p.h>
-#include <qsgsimpletexturenode.h>
+#include <private/qsgadaptationlayer_p.h>
#include <QtQuick/private/qquickpixmapcache_p.h>
#include <QtGui/QGuiApplication>
@@ -59,24 +59,11 @@
QT_BEGIN_NAMESPACE
-class QQuickCanvasNode : public QSGSimpleTextureNode
-{
-public:
- QQuickCanvasNode() {
- qsgnode_set_description(this, QStringLiteral("canvasnode"));
- setOwnsTexture(false);
- }
-
- ~QQuickCanvasNode() {
- delete texture();
- }
-};
-
class QQuickCanvasTextureProvider : public QSGTextureProvider
{
public:
- QQuickCanvasNode *node;
- QSGTexture *texture() const Q_DECL_OVERRIDE { return node ? node->texture() : 0; }
+ QSGTexture *tex;
+ QSGTexture *texture() const Q_DECL_OVERRIDE { return tex; }
void fireTextureChanged() { emit textureChanged(); }
};
@@ -187,7 +174,8 @@ public:
QUrl baseUrl;
QMap<int, QV4::PersistentValue> animationCallbacks;
mutable QQuickCanvasTextureProvider *textureProvider;
- QQuickCanvasNode *node;
+ QSGInternalImageNode *node;
+ QSGTexture *nodeTexture;
};
QQuickCanvasItemPrivate::QQuickCanvasItemPrivate()
@@ -203,6 +191,7 @@ QQuickCanvasItemPrivate::QQuickCanvasItemPrivate()
, renderStrategy(QQuickCanvasItem::Immediate)
, textureProvider(0)
, node(0)
+ , nodeTexture(0)
{
implicitAntialiasing = true;
}
@@ -256,17 +245,18 @@ QQuickCanvasItemPrivate::~QQuickCanvasItemPrivate()
The Canvas item supports two render targets: \c Canvas.Image and
\c Canvas.FramebufferObject.
- The \c Canvas.Image render target is a \a QImage object. This render
- target supports background thread rendering, allowing complex or long
- running painting to be executed without blocking the UI.
+ The \c Canvas.Image render target is a \a QImage object. This render target
+ supports background thread rendering, allowing complex or long running
+ painting to be executed without blocking the UI. This is the only render
+ target that is supported by all Qt Quick backends.
The Canvas.FramebufferObject render target utilizes OpenGL hardware
acceleration rather than rendering into system memory, which in many cases
- results in faster rendering. Canvas.FramebufferObject relies on the
- OpenGL extensions \c GL_EXT_framebuffer_multisample and
- \c GL_EXT_framebuffer_blit for antialiasing. It will also use more
- graphics memory when rendering strategy is anything other than
- Canvas.Cooperative.
+ results in faster rendering. Canvas.FramebufferObject relies on the OpenGL
+ extensions \c GL_EXT_framebuffer_multisample and \c GL_EXT_framebuffer_blit
+ for antialiasing. It will also use more graphics memory when rendering
+ strategy is anything other than Canvas.Cooperative. Framebuffer objects may
+ not be available with Qt Quick backends other than OpenGL.
The default render target is Canvas.Image and the default renderStrategy is
Canvas.Immediate.
@@ -301,7 +291,14 @@ QQuickCanvasItemPrivate::~QQuickCanvasItemPrivate()
and can be used directly in \l {ShaderEffect}{ShaderEffects} and other
classes that consume texture providers.
- \sa Context2D
+ \note In general large canvases, frequent updates, and animation should be
+ avoided with the Canvas.Image render target. This is because with
+ accelerated graphics APIs each update will lead to a texture upload. Also,
+ if possible, prefer QQuickPaintedItem and implement drawing in C++ via
+ QPainter instead of the more expensive and likely less performing
+ JavaScript and Context2D approach.
+
+ \sa Context2D QQuickPaintedItem
*/
QQuickCanvasItem::QQuickCanvasItem(QQuickItem *parent)
@@ -712,7 +709,7 @@ void QQuickCanvasItem::updatePolish()
for (auto it = animationCallbacks.cbegin(), end = animationCallbacks.cend(); it != end; ++it) {
QV4::ScopedFunctionObject f(scope, it.value().value());
callData->args[0] = QV4::Primitive::fromUInt32(QDateTime::currentMSecsSinceEpoch() / 1000);
- f->call(callData);
+ f->call(scope, callData);
}
}
else {
@@ -739,16 +736,16 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
if (!d->context || d->canvasWindow.size().isEmpty()) {
if (d->textureProvider) {
- d->textureProvider->node = 0;
+ d->textureProvider->tex = 0;
d->textureProvider->fireTextureChanged();
}
delete oldNode;
return 0;
}
- QQuickCanvasNode *node = static_cast<QQuickCanvasNode*>(oldNode);
+ QSGInternalImageNode *node = static_cast<QSGInternalImageNode *>(oldNode);
if (!node) {
- node = new QQuickCanvasNode();
+ node = QQuickWindowPrivate::get(window())->context->sceneGraphContext()->createInternalImageNode();
d->node = node;
}
@@ -765,22 +762,27 @@ QSGNode *QQuickCanvasItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData
QQuickContext2D *ctx = qobject_cast<QQuickContext2D *>(d->context);
QQuickContext2DTexture *factory = ctx->texture();
- QSGTexture *texture = factory->textureForNextFrame(node->texture(), window());
+ QSGTexture *texture = factory->textureForNextFrame(d->nodeTexture, window());
if (!texture) {
delete node;
d->node = 0;
+ delete d->nodeTexture;
+ d->nodeTexture = 0;
if (d->textureProvider) {
- d->textureProvider->node = 0;
+ d->textureProvider->tex = 0;
d->textureProvider->fireTextureChanged();
}
return 0;
}
+ d->nodeTexture = texture;
node->setTexture(texture);
- node->setRect(QRectF(QPoint(0, 0), d->canvasWindow.size()));
+ node->setTargetRect(QRectF(QPoint(0, 0), d->canvasWindow.size()));
+ node->setInnerTargetRect(QRectF(QPoint(0, 0), d->canvasWindow.size()));
+ node->update();
if (d->textureProvider) {
- d->textureProvider->node = node;
+ d->textureProvider->tex = d->nodeTexture;
d->textureProvider->fireTextureChanged();
}
return node;
@@ -800,14 +802,17 @@ QSGTextureProvider *QQuickCanvasItem::textureProvider() const
return QQuickItem::textureProvider();
Q_D(const QQuickCanvasItem);
+#ifndef QT_NO_OPENGL
QQuickWindow *w = window();
- if (!w || !w->openglContext() || QThread::currentThread() != w->openglContext()->thread()) {
+ if (!w || !w->isSceneGraphInitialized()
+ || QThread::currentThread() != QQuickWindowPrivate::get(w)->context->thread()) {
qWarning("QQuickCanvasItem::textureProvider: can only be queried on the rendering thread of an exposed window");
return 0;
}
+#endif
if (!d->textureProvider)
d->textureProvider = new QQuickCanvasTextureProvider;
- d->textureProvider->node = d->node;
+ d->textureProvider->tex = d->nodeTexture;
return d->textureProvider;
}