Make QQuickPaintedItem a texture provider.

Change-Id: I605dc35fcc2284a890851c41946cf95537e92d2e
Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
This commit is contained in:
Gunnar Sletta 2014-08-23 15:27:51 +02:00
parent 695a9605c6
commit 916ced089f
4 changed files with 84 additions and 1 deletions

View File

@ -42,6 +42,14 @@
QT_BEGIN_NAMESPACE
class QQuickPaintedItemTextureProvider : public QSGTextureProvider
{
public:
QSGPainterNode *node;
QSGTexture *texture() const { return node ? node->texture() : 0; }
void fireTextureChanged() { emit textureChanged(); }
};
/*!
\class QQuickPaintedItem
\brief The QQuickPaintedItem class provides a way to use the QPainter API in the
@ -63,6 +71,11 @@ QT_BEGIN_NAMESPACE
start by implementing its only pure virtual public function: paint(), which implements
the actual painting. To get the size of the area painted by the item, use
contentsBoundingRect().
Starting Qt 5.4, the QQuickPaintedItem is a
\l{QSGTextureProvider}{texture provider}
and can be used directly in \l {ShaderEffect}{ShaderEffects} and other
classes that consume texture providers.
*/
/*!
@ -115,6 +128,8 @@ QQuickPaintedItemPrivate::QQuickPaintedItemPrivate()
, opaquePainting(false)
, antialiasing(false)
, mipmap(false)
, textureProvider(0)
, node(0)
{
}
@ -125,6 +140,7 @@ QQuickPaintedItem::QQuickPaintedItem(QQuickItem *parent)
: QQuickItem(*(new QQuickPaintedItemPrivate), parent)
{
setFlag(ItemHasContents);
connect(this, SIGNAL(sceneGraphInvalidated()), this, SLOT(invalidateSG()));
}
/*!
@ -134,6 +150,7 @@ QQuickPaintedItem::QQuickPaintedItem(QQuickPaintedItemPrivate &dd, QQuickItem *p
: QQuickItem(dd, parent)
{
setFlag(ItemHasContents);
connect(this, SIGNAL(sceneGraphInvalidated()), this, SLOT(invalidateSG()));
}
/*!
@ -141,6 +158,9 @@ QQuickPaintedItem::QQuickPaintedItem(QQuickPaintedItemPrivate &dd, QQuickItem *p
*/
QQuickPaintedItem::~QQuickPaintedItem()
{
Q_D(QQuickPaintedItem);
if (d->textureProvider)
QQuickWindowQObjectCleanupJob::schedule(window(), d->textureProvider);
}
/*!
@ -494,12 +514,18 @@ QSGNode *QQuickPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat
if (width() <= 0 || height() <= 0) {
delete oldNode;
if (d->textureProvider) {
d->textureProvider->node = 0;
d->textureProvider->fireTextureChanged();
}
return 0;
}
QSGPainterNode *node = static_cast<QSGPainterNode *>(oldNode);
if (!node)
if (!node) {
node = new QSGPainterNode(this);
d->node = node;
}
QRectF br = contentsBoundingRect();
@ -517,7 +543,49 @@ QSGNode *QQuickPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat
d->dirtyRect = QRect();
if (d->textureProvider) {
d->textureProvider->node = node;
d->textureProvider->fireTextureChanged();
}
return node;
}
void QQuickPaintedItem::releaseResources()
{
Q_D(QQuickPaintedItem);
if (d->textureProvider) {
QQuickWindowQObjectCleanupJob::schedule(window(), d->textureProvider);
d->textureProvider = 0;
}
d->node = 0; // Managed by the scene graph, just clear the pointer.
}
void QQuickPaintedItem::invalidateSG()
{
Q_D(QQuickPaintedItem);
delete d->textureProvider;
d->textureProvider = 0;
d->node = 0; // Managed by the scene graph, just clear the pointer
}
bool QQuickPaintedItem::isTextureProvider() const
{
return true;
}
QSGTextureProvider *QQuickPaintedItem::textureProvider() const
{
Q_D(const QQuickPaintedItem);
QQuickWindow *w = window();
if (!w || !w->openglContext() || QThread::currentThread() != w->openglContext()->thread()) {
qWarning("QQuickPaintedItem::textureProvider: can only be queried on the rendering thread of an exposed window");
return 0;
}
if (!d->textureProvider)
d->textureProvider = new QQuickPaintedItemTextureProvider();
d->textureProvider->node = d->node;
return d->textureProvider;
}
QT_END_NAMESPACE

View File

@ -96,6 +96,9 @@ public:
virtual void paint(QPainter *painter) = 0;
bool isTextureProvider() const Q_DECL_OVERRIDE;
QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE;
Q_SIGNALS:
void fillColorChanged();
void contentsSizeChanged();
@ -105,6 +108,10 @@ Q_SIGNALS:
protected:
QQuickPaintedItem(QQuickPaintedItemPrivate &dd, QQuickItem *parent = 0);
virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
void releaseResources() Q_DECL_OVERRIDE;
private Q_SLOTS:
void invalidateSG();
private:
Q_DISABLE_COPY(QQuickPaintedItem)

View File

@ -39,6 +39,9 @@
QT_BEGIN_NAMESPACE
class QQuickPaintedItemTextureProvider;
class QSGPainterNode;
class QQuickPaintedItemPrivate : public QQuickItemPrivate
{
public:
@ -55,6 +58,9 @@ public:
bool opaquePainting: 1;
bool antialiasing: 1;
bool mipmap: 1;
mutable QQuickPaintedItemTextureProvider *textureProvider;
QSGPainterNode *node;
};
QT_END_NAMESPACE

View File

@ -99,6 +99,8 @@ public:
void paint();
QSGTexture *texture() const { return m_texture; }
private:
void updateTexture();
void updateGeometry();