summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Nichols <andy.nichols@digia.com>2014-08-19 16:15:09 +0200
committerLars Knoll <lars.knoll@digia.com>2014-08-25 15:29:03 +0300
commit3c5c6f6309d99286a3ecbbce014eb158f4f4013d (patch)
treeb705d7fc9e72002e2d68bbe61d3a529cb143db5f
parent3833d010c93b6c8d56ee8365e08ab47236e4af5a (diff)
Add support for rendering QQuickPaintedItem
Change-Id: I80dbd2003f53e21fa35ebd270ecc92cc03628454 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--softwarecontext/context.cpp6
-rw-r--r--softwarecontext/context.h1
-rw-r--r--softwarecontext/painternode.cpp178
-rw-r--r--softwarecontext/painternode.h93
-rw-r--r--softwarecontext/renderingvisitor.cpp12
-rw-r--r--softwarecontext/renderingvisitor.h2
-rw-r--r--softwarecontext/softwarecontext.pro6
7 files changed, 296 insertions, 2 deletions
diff --git a/softwarecontext/context.cpp b/softwarecontext/context.cpp
index 2bf4e7f0fc..1a8b07b1b4 100644
--- a/softwarecontext/context.cpp
+++ b/softwarecontext/context.cpp
@@ -22,6 +22,7 @@
#include "rectanglenode.h"
#include "imagenode.h"
+#include "painternode.h"
#include "pixmaptexture.h"
#include "glyphnode.h"
#include "ninepatchnode.h"
@@ -141,6 +142,11 @@ QSGImageNode *Context::createImageNode()
return new ImageNode();
}
+QSGPainterNode *Context::createPainterNode(QQuickPaintedItem *item)
+{
+ return new PainterNode(item);
+}
+
QSGGlyphNode *Context::createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode)
{
Q_UNUSED(rc);
diff --git a/softwarecontext/context.h b/softwarecontext/context.h
index 0a64ca0a06..0e685fdfa9 100644
--- a/softwarecontext/context.h
+++ b/softwarecontext/context.h
@@ -86,6 +86,7 @@ public:
virtual QSGRectangleNode *createRectangleNode();
virtual QSGImageNode *createImageNode();
+ virtual QSGPainterNode *createPainterNode(QQuickPaintedItem *item);
virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, bool preferNativeGlyphNode);
virtual QSGNinePatchNode *createNinePatchNode();
virtual QSGLayer *createLayer(QSGRenderContext *renderContext);
diff --git a/softwarecontext/painternode.cpp b/softwarecontext/painternode.cpp
new file mode 100644
index 0000000000..714368b675
--- /dev/null
+++ b/softwarecontext/painternode.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt SceneGraph Raster Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "painternode.h"
+#include <qmath.h>
+
+PainterNode::PainterNode(QQuickPaintedItem *item)
+ : QSGPainterNode()
+ , m_preferredRenderTarget(QQuickPaintedItem::Image)
+ , m_actualRenderTarget(QQuickPaintedItem::Image)
+ , m_item(item)
+ , m_dirtyContents(false)
+ , m_opaquePainting(false)
+ , m_linear_filtering(false)
+ , m_mipmapping(false)
+ , m_smoothPainting(false)
+ , m_extensionsChecked(false)
+ , m_multisamplingSupported(false)
+ , m_fastFBOResizing(false)
+ , m_fillColor(Qt::transparent)
+ , m_contentsScale(1.0)
+ , m_dirtyGeometry(false)
+{
+ setMaterial((QSGMaterial*)1);
+ setGeometry((QSGGeometry*)1);
+}
+
+void PainterNode::setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target)
+{
+ if (m_preferredRenderTarget == target)
+ return;
+
+ m_preferredRenderTarget = target;
+}
+
+void PainterNode::setSize(const QSize &size)
+{
+ if (size == m_size)
+ return;
+
+ m_size = size;
+
+ m_dirtyGeometry = true;
+}
+
+void PainterNode::setDirty(const QRect &dirtyRect)
+{
+ m_dirtyContents = true;
+ m_dirtyRect = dirtyRect;
+ markDirty(DirtyMaterial);
+}
+
+void PainterNode::setOpaquePainting(bool opaque)
+{
+ if (opaque == m_opaquePainting)
+ return;
+
+ m_opaquePainting = opaque;
+}
+
+void PainterNode::setLinearFiltering(bool linearFiltering)
+{
+ if (linearFiltering == m_linear_filtering)
+ return;
+
+ m_linear_filtering = linearFiltering;
+}
+
+void PainterNode::setMipmapping(bool mipmapping)
+{
+ if (mipmapping == m_mipmapping)
+ return;
+
+ m_mipmapping = mipmapping;
+}
+
+void PainterNode::setSmoothPainting(bool s)
+{
+ if (s == m_smoothPainting)
+ return;
+
+ m_smoothPainting = s;
+}
+
+void PainterNode::setFillColor(const QColor &c)
+{
+ if (c == m_fillColor)
+ return;
+
+ m_fillColor = c;
+ markDirty(DirtyMaterial);
+}
+
+void PainterNode::setContentsScale(qreal s)
+{
+ if (s == m_contentsScale)
+ return;
+
+ m_contentsScale = s;
+ markDirty(DirtyMaterial);
+}
+
+void PainterNode::setFastFBOResizing(bool dynamic)
+{
+ m_fastFBOResizing = dynamic;
+}
+
+QImage PainterNode::toImage() const
+{
+ return m_pixmap.toImage();
+}
+
+void PainterNode::update()
+{
+ if (m_dirtyGeometry) {
+ m_pixmap = QPixmap(m_size);
+ if (!m_opaquePainting)
+ m_pixmap.fill(Qt::transparent);
+ }
+
+ if (m_dirtyContents)
+ paint();
+
+ m_dirtyGeometry = false;
+ m_dirtyContents = false;
+}
+
+void PainterNode::paint(QPainter *painter)
+{
+ painter->drawPixmap(0, 0, m_size.width(), m_size.height(), m_pixmap);
+}
+
+void PainterNode::paint()
+{
+ QRect dirtyRect = m_dirtyRect.isNull() ? QRect(0, 0, m_size.width(), m_size.height()) : m_dirtyRect;
+
+ QPainter painter;
+
+ painter.begin(&m_pixmap);
+ if (m_smoothPainting) {
+ painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
+ }
+
+ painter.scale(m_contentsScale, m_contentsScale);
+
+ QRect sclip(qFloor(dirtyRect.x()/m_contentsScale),
+ qFloor(dirtyRect.y()/m_contentsScale),
+ qCeil(dirtyRect.width()/m_contentsScale+dirtyRect.x()/m_contentsScale-qFloor(dirtyRect.x()/m_contentsScale)),
+ qCeil(dirtyRect.height()/m_contentsScale+dirtyRect.y()/m_contentsScale-qFloor(dirtyRect.y()/m_contentsScale)));
+
+ if (!m_dirtyRect.isNull())
+ painter.setClipRect(sclip);
+
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ painter.fillRect(sclip, m_fillColor);
+ painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+
+ m_item->paint(&painter);
+ painter.end();
+
+ m_dirtyRect = QRect();
+}
diff --git a/softwarecontext/painternode.h b/softwarecontext/painternode.h
new file mode 100644
index 0000000000..046ae93d15
--- /dev/null
+++ b/softwarecontext/painternode.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the Qt SceneGraph Raster Add-on.
+**
+** $QT_BEGIN_LICENSE$
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef PAINTERNODE_H
+#define PAINTERNODE_H
+
+#include <private/qsgadaptationlayer_p.h>
+#include <QtQuick/qquickpainteditem.h>
+
+#include <QtGui/QPixmap>
+
+class PainterNode : public QSGPainterNode
+{
+public:
+ PainterNode(QQuickPaintedItem *item);
+
+ void setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target);
+
+ void setSize(const QSize &size);
+ QSize size() const { return m_size; }
+
+ void setDirty(const QRect &dirtyRect = QRect());
+
+ void setOpaquePainting(bool opaque);
+ bool opaquePainting() const { return m_opaquePainting; }
+
+ void setLinearFiltering(bool linearFiltering);
+ bool linearFiltering() const { return m_linear_filtering; }
+
+ void setMipmapping(bool mipmapping);
+ bool mipmapping() const { return m_mipmapping; }
+
+ void setSmoothPainting(bool s);
+ bool smoothPainting() const { return m_smoothPainting; }
+
+ void setFillColor(const QColor &c);
+ QColor fillColor() const { return m_fillColor; }
+
+ void setContentsScale(qreal s);
+ qreal contentsScale() const { return m_contentsScale; }
+
+ void setFastFBOResizing(bool dynamic);
+ bool fastFBOResizing() const { return m_fastFBOResizing; }
+
+ QImage toImage() const;
+ void update();
+
+ void paint(QPainter *painter);
+
+ void paint();
+
+private:
+
+ QQuickPaintedItem::RenderTarget m_preferredRenderTarget;
+ QQuickPaintedItem::RenderTarget m_actualRenderTarget;
+
+ QQuickPaintedItem *m_item;
+
+ QPixmap m_pixmap;
+
+ QSize m_size;
+ bool m_dirtyContents;
+ QRect m_dirtyRect;
+ bool m_opaquePainting;
+ bool m_linear_filtering;
+ bool m_mipmapping;
+ bool m_smoothPainting;
+ bool m_extensionsChecked;
+ bool m_multisamplingSupported;
+ bool m_fastFBOResizing;
+ QColor m_fillColor;
+ qreal m_contentsScale;
+
+ bool m_dirtyGeometry;
+};
+
+#endif // PAINTERNODE_H
diff --git a/softwarecontext/renderingvisitor.cpp b/softwarecontext/renderingvisitor.cpp
index f64139eab0..f90b23850e 100644
--- a/softwarecontext/renderingvisitor.cpp
+++ b/softwarecontext/renderingvisitor.cpp
@@ -23,6 +23,7 @@
#include "rectanglenode.h"
#include "glyphnode.h"
#include "ninepatchnode.h"
+#include "painternode.h"
RenderingVisitor::RenderingVisitor(QPainter *painter)
: painter(painter)
@@ -92,6 +93,17 @@ void RenderingVisitor::endVisit(QSGImageNode *)
{
}
+bool RenderingVisitor::visit(QSGPainterNode *node)
+{
+ static_cast<PainterNode*>(node)->paint(painter);
+ return true;
+}
+
+void RenderingVisitor::endVisit(QSGPainterNode *node)
+{
+
+}
+
bool RenderingVisitor::visit(QSGRectangleNode *node)
{
static_cast<RectangleNode*>(node)->paint(painter);
diff --git a/softwarecontext/renderingvisitor.h b/softwarecontext/renderingvisitor.h
index 397c2053c2..d65faa4293 100644
--- a/softwarecontext/renderingvisitor.h
+++ b/softwarecontext/renderingvisitor.h
@@ -37,6 +37,8 @@ public:
virtual void endVisit(QSGOpacityNode *node);
virtual bool visit(QSGImageNode *node);
virtual void endVisit(QSGImageNode *node);
+ virtual bool visit(QSGPainterNode *node);
+ virtual void endVisit(QSGPainterNode *node);
virtual bool visit(QSGRectangleNode *node);
virtual void endVisit(QSGRectangleNode *node);
virtual bool visit(QSGGlyphNode *node);
diff --git a/softwarecontext/softwarecontext.pro b/softwarecontext/softwarecontext.pro
index 61607a13cf..d60260c1eb 100644
--- a/softwarecontext/softwarecontext.pro
+++ b/softwarecontext/softwarecontext.pro
@@ -16,7 +16,8 @@ SOURCES += \
renderingvisitor.cpp \
ninepatchnode.cpp \
softwarelayer.cpp \
- threadedrenderloop.cpp
+ threadedrenderloop.cpp \
+ painternode.cpp
HEADERS += \
context.h \
@@ -29,7 +30,8 @@ HEADERS += \
renderingvisitor.h \
ninepatchnode.h \
softwarelayer.h \
- threadedrenderloop.h
+ threadedrenderloop.h \
+ painternode.h
OTHER_FILES += softwarecontext.json