diff options
author | Andy Nichols <andy.nichols@digia.com> | 2014-08-19 16:15:09 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@digia.com> | 2014-08-25 15:29:03 +0300 |
commit | 3c5c6f6309d99286a3ecbbce014eb158f4f4013d (patch) | |
tree | b705d7fc9e72002e2d68bbe61d3a529cb143db5f /softwarecontext | |
parent | 3833d010c93b6c8d56ee8365e08ab47236e4af5a (diff) |
Add support for rendering QQuickPaintedItem
Change-Id: I80dbd2003f53e21fa35ebd270ecc92cc03628454
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'softwarecontext')
-rw-r--r-- | softwarecontext/context.cpp | 6 | ||||
-rw-r--r-- | softwarecontext/context.h | 1 | ||||
-rw-r--r-- | softwarecontext/painternode.cpp | 178 | ||||
-rw-r--r-- | softwarecontext/painternode.h | 93 | ||||
-rw-r--r-- | softwarecontext/renderingvisitor.cpp | 12 | ||||
-rw-r--r-- | softwarecontext/renderingvisitor.h | 2 | ||||
-rw-r--r-- | softwarecontext/softwarecontext.pro | 6 |
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 |