diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2016-12-03 18:59:56 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2016-12-03 19:07:39 +0100 |
commit | 012142e97ee7a9cc1e7740d1730085efd37bc91f (patch) | |
tree | ffd825cb5ccc4d05191baf3c95a99de26bf8b7f3 /src/quick/scenegraph | |
parent | 90fa3414156522ef89f9ebe8cefd6dad303ce06c (diff) | |
parent | ab54d0cab57121055914ff9a750f5ad975fe7525 (diff) |
Merge remote-tracking branch 'origin/dev' into wip/scenegraphng
Change-Id: I9433075d0865f2492ff785ee0b28e8733863be44
Diffstat (limited to 'src/quick/scenegraph')
50 files changed, 408 insertions, 307 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp index 80112c1121..d71b0c3e2a 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp @@ -47,7 +47,9 @@ #include "qsgsoftwarepublicnodes_p.h" #include "qsgsoftwarelayer_p.h" #include "qsgsoftwarerenderer_p.h" +#if QT_CONFIG(quick_sprite) #include "qsgsoftwarespritenode_p.h" +#endif #include <QtCore/QCoreApplication> #include <QtCore/QElapsedTimer> @@ -184,10 +186,12 @@ QSGNinePatchNode *QSGSoftwareContext::createNinePatchNode() return new QSGSoftwareNinePatchNode; } +#if QT_CONFIG(quick_sprite) QSGSpriteNode *QSGSoftwareContext::createSpriteNode() { return new QSGSoftwareSpriteNode; } +#endif QSGRendererInterface::GraphicsApi QSGSoftwareContext::graphicsApi() const { @@ -211,7 +215,7 @@ QSGRendererInterface::ShaderSourceTypes QSGSoftwareContext::shaderSourceType() c void *QSGSoftwareContext::getResource(QQuickWindow *window, Resource resource) const { - if (resource == Painter && window && window->isSceneGraphInitialized()) + if (resource == PainterResource && window && window->isSceneGraphInitialized()) return static_cast<QSGSoftwareRenderContext *>(QQuickWindowPrivate::get(window)->context)->m_activePainter; return nullptr; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h index dcc137b4b4..1f14717416 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext_p.h @@ -98,7 +98,9 @@ public: QSGRectangleNode *createRectangleNode() override; QSGImageNode *createImageNode() override; QSGNinePatchNode *createNinePatchNode() override; +#if QT_CONFIG(quick_sprite) QSGSpriteNode *createSpriteNode() override; +#endif GraphicsApi graphicsApi() const override; ShaderType shaderType() const override; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp index 7b9e749532..59c47db0c4 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp @@ -45,7 +45,9 @@ #include "qsgsoftwarepublicnodes_p.h" #include "qsgsoftwarepainternode_p.h" #include "qsgsoftwarepixmaptexture_p.h" +#if QT_CONFIG(quick_sprite) #include "qsgsoftwarespritenode_p.h" +#endif #include <qsgsimplerectnode.h> #include <qsgsimpletexturenode.h> @@ -91,9 +93,11 @@ QSGSoftwareRenderableNode::QSGSoftwareRenderableNode(NodeType type, QSGNode *nod case QSGSoftwareRenderableNode::SimpleImage: m_handle.simpleImageNode = static_cast<QSGImageNode*>(node); break; +#if QT_CONFIG(quick_sprite) case QSGSoftwareRenderableNode::SpriteNode: m_handle.spriteNode = static_cast<QSGSoftwareSpriteNode*>(node); break; +#endif case QSGSoftwareRenderableNode::RenderNode: m_handle.renderNode = static_cast<QSGRenderNode*>(node); break; @@ -182,10 +186,12 @@ void QSGSoftwareRenderableNode::update() boundingRect = m_handle.simpleImageNode->rect().toRect(); break; +#if QT_CONFIG(quick_sprite) case QSGSoftwareRenderableNode::SpriteNode: m_isOpaque = m_handle.spriteNode->isOpaque(); boundingRect = m_handle.spriteNode->rect().toRect(); break; +#endif case QSGSoftwareRenderableNode::RenderNode: if (m_handle.renderNode->flags().testFlag(QSGRenderNode::OpaqueRendering) && !m_transform.isRotating()) m_isOpaque = true; @@ -317,9 +323,11 @@ QRegion QSGSoftwareRenderableNode::renderNode(QPainter *painter, bool forceOpaqu case QSGSoftwareRenderableNode::SimpleImage: static_cast<QSGSoftwareImageNode *>(m_handle.simpleImageNode)->paint(painter); break; +#if QT_CONFIG(quick_sprite) case QSGSoftwareRenderableNode::SpriteNode: static_cast<QSGSoftwareSpriteNode *>(m_handle.spriteNode)->paint(painter); break; +#endif default: break; } diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h index 0626b1e657..473578c185 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode_p.h @@ -51,6 +51,8 @@ // We mean it. // +#include <QtQuick/private/qtquickglobal_p.h> + #include <QtGui/QRegion> #include <QtCore/QRect> #include <QtGui/QTransform> @@ -84,7 +86,9 @@ public: NinePatch, SimpleRectangle, SimpleImage, +#if QT_CONFIG(quick_sprite) SpriteNode, +#endif RenderNode }; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp index 12dbf63353..4937565aa9 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater.cpp @@ -181,6 +181,7 @@ void QSGSoftwareRenderableNodeUpdater::endVisit(QSGRootNode *) { } +#if QT_CONFIG(quick_sprite) bool QSGSoftwareRenderableNodeUpdater::visit(QSGSpriteNode *node) { return updateRenderableNode(QSGSoftwareRenderableNode::SpriteNode, node); @@ -190,6 +191,7 @@ void QSGSoftwareRenderableNodeUpdater::endVisit(QSGSpriteNode *) { } +#endif bool QSGSoftwareRenderableNodeUpdater::visit(QSGRenderNode *node) { diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h index f204867236..ca16f77c22 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenodeupdater_p.h @@ -86,8 +86,10 @@ public: void endVisit(QSGGlyphNode *) override; bool visit(QSGRootNode *) override; void endVisit(QSGRootNode *) override; +#if QT_CONFIG(quick_sprite) bool visit(QSGSpriteNode *) override; void endVisit(QSGSpriteNode *) override; +#endif bool visit(QSGRenderNode *) override; void endVisit(QSGRenderNode *) override; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder.cpp index 4e34517dad..70dce71801 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder.cpp @@ -141,6 +141,7 @@ void QSGSoftwareRenderListBuilder::endVisit(QSGRootNode *) { } +#if QT_CONFIG(quick_sprite) bool QSGSoftwareRenderListBuilder::visit(QSGSpriteNode *node) { return addRenderableNode(node); @@ -150,6 +151,7 @@ void QSGSoftwareRenderListBuilder::endVisit(QSGSpriteNode *) { } +#endif bool QSGSoftwareRenderListBuilder::visit(QSGRenderNode *node) { diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder_p.h index 807cb7fdbe..f5db30269f 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderlistbuilder_p.h @@ -80,8 +80,10 @@ public: void endVisit(QSGGlyphNode *) override; bool visit(QSGRootNode *) override; void endVisit(QSGRootNode *) override; +#if QT_CONFIG(quick_sprite) bool visit(QSGSpriteNode *) override; void endVisit(QSGSpriteNode *) override; +#endif bool visit(QSGRenderNode *) override; void endVisit(QSGRenderNode *) override; diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode_p.h index 284ed3dff5..577a30c051 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode_p.h @@ -51,6 +51,10 @@ // We mean it. // +#include <private/qtquickglobal_p.h> + +QT_REQUIRE_CONFIG(quick_sprite); + #include <private/qsgadaptationlayer_p.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/adaptations/software/software.pri b/src/quick/scenegraph/adaptations/software/software.pri index 97644fc36a..de5f01cdee 100644 --- a/src/quick/scenegraph/adaptations/software/software.pri +++ b/src/quick/scenegraph/adaptations/software/software.pri @@ -19,7 +19,6 @@ SOURCES += \ $$PWD/qsgsoftwarerenderloop.cpp \ $$PWD/qsgsoftwarelayer.cpp \ $$PWD/qsgsoftwareadaptation.cpp \ - $$PWD/qsgsoftwarespritenode.cpp \ $$PWD/qsgsoftwarethreadedrenderloop.cpp HEADERS += \ @@ -39,5 +38,11 @@ HEADERS += \ $$PWD/qsgsoftwarerenderloop_p.h \ $$PWD/qsgsoftwarelayer_p.h \ $$PWD/qsgsoftwareadaptation_p.h \ - $$PWD/qsgsoftwarespritenode_p.h \ $$PWD/qsgsoftwarethreadedrenderloop_p.h + +qtConfig(quick-sprite) { + SOURCES += \ + $$PWD/qsgsoftwarespritenode.cpp + HEADERS += \ + $$PWD/qsgsoftwarespritenode_p.h +} diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 49bbbf0ba8..81aa641e03 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -90,7 +90,7 @@ DECLARE_DEBUG_VAR(noclip) static QElapsedTimer qsg_renderer_timer; #define QSGNODE_TRAVERSE(NODE) for (QSGNode *child = NODE->firstChild(); child; child = child->nextSibling()) -#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild; child; child = child->nextSibling) +#define SHADOWNODE_TRAVERSE(NODE) for (Node *child = NODE->firstChild(); child; child = child->sibling()) static inline int size_of_type(GLenum type) { @@ -510,7 +510,7 @@ void Updater::updateRootTransforms(Node *node, Node *root, const QMatrix4x4 &com while (n != root) { if (n->type() == QSGNode::TransformNodeType) m = static_cast<QSGTransformNode *>(n->sgNode)->matrix() * m; - n = n->parent; + n = n->parent(); } m = combined * m; @@ -1013,16 +1013,8 @@ void Renderer::nodeWasAdded(QSGNode *node, Node *shadowParent) Node *snode = m_nodeAllocator.allocate(); snode->sgNode = node; m_nodes.insert(node, snode); - if (shadowParent) { - snode->parent = shadowParent; - if (shadowParent->lastChild) { - shadowParent->lastChild->nextSibling = snode; - shadowParent->lastChild = snode; - } else { - shadowParent->firstChild = snode; - shadowParent->lastChild = snode; - } - } + if (shadowParent) + shadowParent->append(snode); if (node->type() == QSGNode::GeometryNodeType) { snode->data = m_elementAllocator.allocate(); @@ -1054,17 +1046,12 @@ void Renderer::nodeWasRemoved(Node *node) // here, because we delete 'child' (when recursed, down below), so we'd // have a use-after-free. { - Node *child = node->firstChild; - Node *nextChild = 0; - + Node *child = node->firstChild(); while (child) { - // Get the next child now before we proceed - nextChild = child->nextSibling; - // Remove (and delete) child + node->remove(child); nodeWasRemoved(child); - - child = nextChild; + child = node->firstChild(); } } @@ -1110,6 +1097,7 @@ void Renderer::nodeWasRemoved(Node *node) } Q_ASSERT(m_nodes.contains(node->sgNode)); + m_nodeAllocator.release(m_nodes.take(node->sgNode)); } @@ -1120,13 +1108,13 @@ void Renderer::turnNodeIntoBatchRoot(Node *node) node->isBatchRoot = true; node->becameBatchRoot = true; - Node *p = node->parent; + Node *p = node->parent(); while (p) { if (p->type() == QSGNode::ClipNodeType || p->isBatchRoot) { registerBatchRoot(node, p); break; } - p = p->parent; + p = p->parent(); } SHADOWNODE_TRAVERSE(node) @@ -1255,33 +1243,18 @@ void Renderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state) | QSGNode::DirtyForceUpdate); if (dirtyChain != 0) { dirtyChain = QSGNode::DirtyState(dirtyChain << 16); - Node *sn = shadowNode->parent; + Node *sn = shadowNode->parent(); while (sn) { sn->dirtyState |= dirtyChain; - sn = sn->parent; + sn = sn->parent(); } } // Delete happens at the very end because it deletes the shadownode. if (state & QSGNode::DirtyNodeRemoved) { - Node *parent = shadowNode->parent; - if (parent) { - Q_ASSERT(parent->firstChild); - Q_ASSERT(parent->lastChild); - shadowNode->parent = 0; - Node *child = parent->firstChild; - if (child == shadowNode) { - parent->firstChild = shadowNode->nextSibling; - if (parent->lastChild == shadowNode) - parent->lastChild = 0; - } else { - while (child->nextSibling != shadowNode) - child = child->nextSibling; - child->nextSibling = shadowNode->nextSibling; - if (shadowNode == parent->lastChild) - parent->lastChild = child; - } - } + Node *parent = shadowNode->parent(); + if (parent) + parent->remove(shadowNode); nodeWasRemoved(shadowNode); Q_ASSERT(m_nodes.value(node) == 0); } diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h index d5e94cea3e..322192944b 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h @@ -451,11 +451,73 @@ struct Batch struct Node { QSGNode *sgNode; - Node *parent; void *data; - Node *firstChild; - Node *nextSibling; - Node *lastChild; + + Node *m_parent; + Node *m_child; + Node *m_next; + Node *m_prev; + + Node *parent() const { return m_parent; } + + void append(Node *child) { + Q_ASSERT(child); + Q_ASSERT(!hasChild(child)); + Q_ASSERT(child->m_parent == 0); + Q_ASSERT(child->m_next == 0); + Q_ASSERT(child->m_prev == 0); + + if (!m_child) { + child->m_next = child; + child->m_prev = child; + m_child = child; + } else { + m_child->m_prev->m_next = child; + child->m_prev = m_child->m_prev; + m_child->m_prev = child; + child->m_next = m_child; + } + child->setParent(this); + } + + void remove(Node *child) { + Q_ASSERT(child); + Q_ASSERT(hasChild(child)); + + // only child.. + if (child->m_next == child) { + m_child = 0; + } else { + if (m_child == child) + m_child = child->m_next; + child->m_next->m_prev = child->m_prev; + child->m_prev->m_next = child->m_next; + } + child->m_next = 0; + child->m_prev = 0; + child->setParent(0); + } + + Node *firstChild() const { return m_child; } + + Node *sibling() const { + Q_ASSERT(m_parent); + return m_next == m_parent->m_child ? 0 : m_next; + } + + void setParent(Node *p) { + Q_ASSERT(m_parent == 0 || p == 0); + m_parent = p; + } + + bool hasChild(Node *child) const { + Node *n = m_child; + while (n && n != child) + n = n->sibling(); + return n; + } + + QSGNode::DirtyState dirtyState; diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp index 239557d527..b43a2bc2ba 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.cpp +++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp @@ -54,18 +54,18 @@ QT_BEGIN_NAMESPACE QSGGeometry::Attribute QSGGeometry::Attribute::create(int attributeIndex, int tupleSize, int primitiveType, bool isPrimitive) { - Attribute a = { attributeIndex, tupleSize, primitiveType, isPrimitive, UNKNOWN, 0 }; + Attribute a = { attributeIndex, tupleSize, primitiveType, isPrimitive, UnknownAttribute, 0 }; return a; } -QSGGeometry::Attribute QSGGeometry::Attribute::createWithSemantic(int pos, int tupleSize, int type, Semantic semantic) +QSGGeometry::Attribute QSGGeometry::Attribute::createWithAttributeType(int pos, int tupleSize, int primitiveType, AttributeType attributeType) { Attribute a; a.position = pos; a.tupleSize = tupleSize; - a.type = type; - a.isVertexCoordinate = semantic == POSITION; - a.semantic = semantic; + a.type = primitiveType; + a.isVertexCoordinate = attributeType == PositionAttribute; + a.attributeType = attributeType; a.reserved = 0; return a; } @@ -78,7 +78,7 @@ QSGGeometry::Attribute QSGGeometry::Attribute::createWithSemantic(int pos, int t const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_Point2D() { static Attribute data[] = { - Attribute::createWithSemantic(0, 2, TypeFloat, Attribute::POSITION) + Attribute::createWithAttributeType(0, 2, FloatType, PositionAttribute) }; static AttributeSet attrs = { 1, sizeof(float) * 2, data }; return attrs; @@ -91,8 +91,8 @@ const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_Point2D() const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_TexturedPoint2D() { static Attribute data[] = { - Attribute::createWithSemantic(0, 2, TypeFloat, Attribute::POSITION), - Attribute::createWithSemantic(1, 2, TypeFloat, Attribute::TEXCOORD) + Attribute::createWithAttributeType(0, 2, FloatType, PositionAttribute), + Attribute::createWithAttributeType(1, 2, FloatType, TexCoordAttribute) }; static AttributeSet attrs = { 2, sizeof(float) * 4, data }; return attrs; @@ -105,8 +105,8 @@ const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_TexturedPoint2D( const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_ColoredPoint2D() { static Attribute data[] = { - Attribute::createWithSemantic(0, 2, TypeFloat, Attribute::POSITION), - Attribute::createWithSemantic(1, 4, TypeUnsignedByte, Attribute::COLOR) + Attribute::createWithAttributeType(0, 2, FloatType, PositionAttribute), + Attribute::createWithAttributeType(1, 4, UnsignedByteType, ColorAttribute) }; static AttributeSet attrs = { 2, 2 * sizeof(float) + 4 * sizeof(char), data }; return attrs; @@ -134,12 +134,31 @@ const QSGGeometry::AttributeSet &QSGGeometry::defaultAttributes_ColoredPoint2D() \fn QSGGeometry::Attribute QSGGeometry::Attribute::create(int pos, int tupleSize, int primitiveType, bool isPosition) Creates a new QSGGeometry::Attribute for attribute register \a pos with \a - tupleSize. The \a primitiveType can be any of the supported OpenGL types, - such as \c GL_FLOAT or \c GL_UNSIGNED_BYTE. + tupleSize. The \a primitiveType can be any of the supported types from + QSGGeometry::Type, such as QSGGeometry::FloatType or + QSGGeometry::UnsignedByteType. - If the attribute describes the position for the vertex, the \a isPosition hint - should be set to \c true. The scene graph renderer may use this information - to perform optimizations. + If the attribute describes the position for the vertex, the \a isPosition + hint should be set to \c true. The scene graph renderer may use this + information to perform optimizations. + + \note Scene graph backends for APIs other than OpenGL may require an + accurate description of attributes' usage, and therefore it is recommended + to use createWithAttributeType() instead. + + Use the create function to construct the attribute, rather than an + initialization list, to ensure that all fields are initialized. + */ + +/*! + \fn QSGGeometry::Attribute QSGGeometry::Attribute::createWithAttributeType(int pos, int tupleSize, int primitiveType, AttributeType attributeType) + + Creates a new QSGGeometry::Attribute for attribute register \a pos with \a + tupleSize. The \a primitiveType can be any of the supported types from + QSGGeometry::Type, such as QSGGeometry::FloatType or + QSGGeometry::UnsignedByteType. + + \a attributeType describes the intended use of the attribute. Use the create function to construct the attribute, rather than an initialization list, to ensure that all fields are initialized. @@ -430,9 +449,9 @@ QSGGeometry::QSGGeometry(const QSGGeometry::AttributeSet &attributes, "GL_UNSIGNED_INT is not supported, geometry will not render" ); #endif - if (indexType != TypeUnsignedByte - && indexType != TypeUnsignedShort - && indexType != TypeUnsignedInt) { + if (indexType != UnsignedByteType + && indexType != UnsignedShortType + && indexType != UnsignedIntType) { qFatal("QSGGeometry: Unsupported index type, %x.\n", indexType); } @@ -549,13 +568,13 @@ const void *QSGGeometry::indexData() const GL_UNSIGNED_BYTE, etc. QSGGeometry provies its own type in order to be able to provide the same API with non-OpenGL backends as well. - \value TypeByte - \value TypeUnsignedByte - \value TypeShort - \value TypeUnsignedShort - \value TypeInt - \value TypeUnsignedInt - \value TypeFloat + \value ByteType + \value UnsignedByteType + \value ShortType + \value UnsignedShortType + \value IntType + \value UnsignedIntType + \value FloatType */ /*! @@ -653,8 +672,8 @@ void QSGGeometry::allocate(int vertexCount, int indexCount) m_index_data_offset = -1; m_owns_data = false; } else { - Q_ASSERT(m_index_type == TypeUnsignedInt || m_index_type == TypeUnsignedShort); - int indexByteSize = indexCount * (m_index_type == TypeUnsignedShort ? sizeof(quint16) : sizeof(quint32)); + Q_ASSERT(m_index_type == UnsignedIntType || m_index_type == UnsignedShortType); + int indexByteSize = indexCount * (m_index_type == UnsignedShortType ? sizeof(quint16) : sizeof(quint32)); m_data = (void *) malloc(vertexByteSize + indexByteSize); m_index_data_offset = vertexByteSize; m_owns_data = true; diff --git a/src/quick/scenegraph/coreapi/qsggeometry.h b/src/quick/scenegraph/coreapi/qsggeometry.h index ae7b2f494c..7a916610e3 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.h +++ b/src/quick/scenegraph/coreapi/qsggeometry.h @@ -51,30 +51,60 @@ class QSGGeometryData; class Q_QUICK_EXPORT QSGGeometry { public: + enum AttributeType { + UnknownAttribute, + PositionAttribute, + ColorAttribute, + TexCoordAttribute, + TexCoord1Attribute, + TexCoord2Attribute + }; + + enum DataPattern { + AlwaysUploadPattern = 0, + StreamPattern = 1, + DynamicPattern = 2, + StaticPattern = 3 + }; + + // Equivalents to GL_* drawing modes. + // Keep in sync with GL headers. + enum DrawingMode { + DrawPoints = 0x0000, + DrawLines = 0x0001, + DrawLineLoop = 0x0002, + DrawLineStrip = 0x0003, + DrawTriangles = 0x0004, + DrawTriangleStrip = 0x0005, + DrawTriangleFan = 0x0006 + }; + + // Equivalents to GL_BYTE and similar type constants. + // Keep in sync with GL headers. + enum Type { + ByteType = 0x1400, + UnsignedByteType = 0x1401, + ShortType = 0x1402, + UnsignedShortType = 0x1403, + IntType = 0x1404, + UnsignedIntType = 0x1405, + FloatType = 0x1406 + }; struct Q_QUICK_EXPORT Attribute { - enum Semantic { - UNKNOWN, - POSITION, - COLOR, - TEXCOORD, - TEXCOORD1, - TEXCOORD2 - }; - int position; int tupleSize; int type; uint isVertexCoordinate : 1; - Semantic semantic : 4; + AttributeType attributeType : 4; uint reserved : 27; static Attribute create(int pos, int tupleSize, int primitiveType, bool isPosition = false); - static Attribute createWithSemantic(int pos, int tupleSize, int type, Semantic semantic); + static Attribute createWithAttributeType(int pos, int tupleSize, int primitiveType, AttributeType attributeType); }; struct AttributeSet { @@ -109,39 +139,10 @@ public: static const AttributeSet &defaultAttributes_TexturedPoint2D(); static const AttributeSet &defaultAttributes_ColoredPoint2D(); - enum DataPattern { - AlwaysUploadPattern = 0, - StreamPattern = 1, - DynamicPattern = 2, - StaticPattern = 3 - }; - - // Equivalents to GL_* drawing modes. - enum DrawingMode { - DrawPoints = 0x0000, - DrawLines = 0x0001, - DrawLineLoop = 0x0002, - DrawLineStrip = 0x0003, - DrawTriangles = 0x0004, - DrawTriangleStrip = 0x0005, - DrawTriangleFan = 0x0006 - }; - - // Equivalents to GL_BYTE and similar type constants. - enum Type { - TypeByte = 0x1400, - TypeUnsignedByte = 0x1401, - TypeShort = 0x1402, - TypeUnsignedShort = 0x1403, - TypeInt = 0x1404, - TypeUnsignedInt = 0x1405, - TypeFloat = 0x1406 - }; - QSGGeometry(const QSGGeometry::AttributeSet &attribs, int vertexCount, int indexCount = 0, - int indexType = TypeUnsignedShort); + int indexType = UnsignedShortType); virtual ~QSGGeometry(); // must use unsigned int to be compatible with the old GLenum to keep BC @@ -223,25 +224,25 @@ private: inline uint *QSGGeometry::indexDataAsUInt() { - Q_ASSERT(m_index_type == TypeUnsignedInt); + Q_ASSERT(m_index_type == UnsignedIntType); return static_cast<uint *>(indexData()); } inline quint16 *QSGGeometry::indexDataAsUShort() { - Q_ASSERT(m_index_type == TypeUnsignedShort); + Q_ASSERT(m_index_type == UnsignedShortType); return static_cast<quint16 *>(indexData()); } inline const uint *QSGGeometry::indexDataAsUInt() const { - Q_ASSERT(m_index_type == TypeUnsignedInt); + Q_ASSERT(m_index_type == UnsignedIntType); return static_cast<const uint *>(indexData()); } inline const quint16 *QSGGeometry::indexDataAsUShort() const { - Q_ASSERT(m_index_type == TypeUnsignedShort); + Q_ASSERT(m_index_type == UnsignedShortType); return static_cast<const quint16 *>(indexData()); } @@ -250,7 +251,7 @@ inline QSGGeometry::Point2D *QSGGeometry::vertexDataAsPoint2D() Q_ASSERT(m_attributes.count == 1); Q_ASSERT(m_attributes.stride == 2 * sizeof(float)); Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == TypeFloat); + Q_ASSERT(m_attributes.attributes[0].type == FloatType); Q_ASSERT(m_attributes.attributes[0].position == 0); return static_cast<Point2D *>(m_data); } @@ -261,10 +262,10 @@ inline QSGGeometry::TexturedPoint2D *QSGGeometry::vertexDataAsTexturedPoint2D() Q_ASSERT(m_attributes.stride == 4 * sizeof(float)); Q_ASSERT(m_attributes.attributes[0].position == 0); Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == TypeFloat); + Q_ASSERT(m_attributes.attributes[0].type == FloatType); Q_ASSERT(m_attributes.attributes[1].position == 1); Q_ASSERT(m_attributes.attributes[1].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[1].type == TypeFloat); + Q_ASSERT(m_attributes.attributes[1].type == FloatType); return static_cast<TexturedPoint2D *>(m_data); } @@ -274,10 +275,10 @@ inline QSGGeometry::ColoredPoint2D *QSGGeometry::vertexDataAsColoredPoint2D() Q_ASSERT(m_attributes.stride == 2 * sizeof(float) + 4 * sizeof(char)); Q_ASSERT(m_attributes.attributes[0].position == 0); Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == TypeFloat); + Q_ASSERT(m_attributes.attributes[0].type == FloatType); Q_ASSERT(m_attributes.attributes[1].position == 1); Q_ASSERT(m_attributes.attributes[1].tupleSize == 4); - Q_ASSERT(m_attributes.attributes[1].type == TypeUnsignedByte); + Q_ASSERT(m_attributes.attributes[1].type == UnsignedByteType); return static_cast<ColoredPoint2D *>(m_data); } @@ -286,7 +287,7 @@ inline const QSGGeometry::Point2D *QSGGeometry::vertexDataAsPoint2D() const Q_ASSERT(m_attributes.count == 1); Q_ASSERT(m_attributes.stride == 2 * sizeof(float)); Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == TypeFloat); + Q_ASSERT(m_attributes.attributes[0].type == FloatType); Q_ASSERT(m_attributes.attributes[0].position == 0); return static_cast<const Point2D *>(m_data); } @@ -297,10 +298,10 @@ inline const QSGGeometry::TexturedPoint2D *QSGGeometry::vertexDataAsTexturedPoin Q_ASSERT(m_attributes.stride == 4 * sizeof(float)); Q_ASSERT(m_attributes.attributes[0].position == 0); Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == TypeFloat); + Q_ASSERT(m_attributes.attributes[0].type == FloatType); Q_ASSERT(m_attributes.attributes[1].position == 1); Q_ASSERT(m_attributes.attributes[1].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[1].type == TypeFloat); + Q_ASSERT(m_attributes.attributes[1].type == FloatType); return static_cast<const TexturedPoint2D *>(m_data); } @@ -310,18 +311,18 @@ inline const QSGGeometry::ColoredPoint2D *QSGGeometry::vertexDataAsColoredPoint2 Q_ASSERT(m_attributes.stride == 2 * sizeof(float) + 4 * sizeof(char)); Q_ASSERT(m_attributes.attributes[0].position == 0); Q_ASSERT(m_attributes.attributes[0].tupleSize == 2); - Q_ASSERT(m_attributes.attributes[0].type == TypeFloat); + Q_ASSERT(m_attributes.attributes[0].type == FloatType); Q_ASSERT(m_attributes.attributes[1].position == 1); Q_ASSERT(m_attributes.attributes[1].tupleSize == 4); - Q_ASSERT(m_attributes.attributes[1].type == TypeUnsignedByte); + Q_ASSERT(m_attributes.attributes[1].type == UnsignedByteType); return static_cast<const ColoredPoint2D *>(m_data); } int QSGGeometry::sizeOfIndex() const { - if (m_index_type == TypeUnsignedShort) return 2; - else if (m_index_type == TypeUnsignedByte) return 1; - else if (m_index_type == TypeUnsignedInt) return 4; + if (m_index_type == UnsignedShortType) return 2; + else if (m_index_type == UnsignedByteType) return 1; + else if (m_index_type == UnsignedIntType) return 4; return 0; } diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp index 13598bbe1d..502ae56c63 100644 --- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp +++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp @@ -364,8 +364,8 @@ void QSGMaterialShader::compile() { Q_ASSERT_X(!m_program.isLinked(), "QSGSMaterialShader::compile()", "Compile called multiple times!"); - program()->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader()); - program()->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader()); + program()->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader()); + program()->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader()); char const *const *attr = attributeNames(); #ifndef QT_NO_DEBUG diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp index 2211f88973..a1e1ef8c27 100644 --- a/src/quick/scenegraph/coreapi/qsgnode.cpp +++ b/src/quick/scenegraph/coreapi/qsgnode.cpp @@ -1490,7 +1490,7 @@ QDebug operator<<(QDebug d, const QSGGeometryNode *n) d << "#V:" << g->vertexCount() << "#I:" << g->indexCount(); - if (g->attributeCount() > 0 && g->attributes()->type == QSGGeometry::TypeFloat) { + if (g->attributeCount() > 0 && g->attributes()->type == QSGGeometry::FloatType) { float x1 = 1e10, x2 = -1e10, y1=1e10, y2=-1e10; int stride = g->sizeOfVertex(); for (int i = 0; i < g->vertexCount(); ++i) { diff --git a/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp b/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp index fa543aecad..d309044e8f 100644 --- a/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp +++ b/src/quick/scenegraph/coreapi/qsgrendererinterface.cpp @@ -81,10 +81,10 @@ QT_BEGIN_NAMESPACE /*! \enum QSGRendererInterface::Resource - \value Device The graphics device, when applicable. - \value CommandQueue The graphics command queue used by the scenegraph, when applicable. - \value CommandList The command list or buffer used by the scenegraph, when applicable. - \value Painter The active QPainter used by the scenegraph, when running with the software backend. + \value DeviceResource The graphics device, when applicable. + \value CommandQueueResource The graphics command queue used by the scenegraph, when applicable. + \value CommandListResource The command list or buffer used by the scenegraph, when applicable. + \value PainterResource The active QPainter used by the scenegraph, when running with the software backend. */ /*! diff --git a/src/quick/scenegraph/coreapi/qsgrendererinterface.h b/src/quick/scenegraph/coreapi/qsgrendererinterface.h index a50b362aeb..cf8fcf9015 100644 --- a/src/quick/scenegraph/coreapi/qsgrendererinterface.h +++ b/src/quick/scenegraph/coreapi/qsgrendererinterface.h @@ -57,10 +57,10 @@ public: }; enum Resource { - Device, - CommandQueue, - CommandList, - Painter + DeviceResource, + CommandQueueResource, + CommandListResource, + PainterResource }; enum ShaderType { diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index e219ddd82e..9923fa6e24 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -122,7 +122,7 @@ void QSGDistanceFieldGlyphCache::populate(const QVector<glyph_t> &glyphs) int count = glyphs.count(); for (int i = 0; i < count; ++i) { glyph_t glyphIndex = glyphs.at(i); - if ((int) glyphIndex >= glyphCount()) { + if ((int) glyphIndex >= glyphCount() && glyphCount() > 0) { qWarning("Warning: distance-field glyph is not available with index %d", glyphIndex); continue; } diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h index a74b38dba8..5880c67af0 100644 --- a/src/quick/scenegraph/qsgadaptationlayer_p.h +++ b/src/quick/scenegraph/qsgadaptationlayer_p.h @@ -108,8 +108,10 @@ public: virtual void endVisit(QSGGlyphNode *) = 0; virtual bool visit(QSGRootNode *) = 0; virtual void endVisit(QSGRootNode *) = 0; +#if QT_CONFIG(quick_sprite) virtual bool visit(QSGSpriteNode *) = 0; virtual void endVisit(QSGSpriteNode *) = 0; +#endif virtual bool visit(QSGRenderNode *) = 0; virtual void endVisit(QSGRenderNode *) = 0; @@ -213,6 +215,8 @@ Q_SIGNALS: void scheduledUpdateCompleted(); }; +#if QT_CONFIG(quick_sprite) + class Q_QUICK_PRIVATE_EXPORT QSGSpriteNode : public QSGVisitableNode { public: @@ -230,6 +234,8 @@ public: virtual void accept(QSGNodeVisitorEx *visitor) { if (visitor->visit(this)) visitor->visitChildren(this); visitor->endVisit(this); } }; +#endif + class Q_QUICK_PRIVATE_EXPORT QSGGuiThreadShaderEffectManager : public QObject { Q_OBJECT diff --git a/src/quick/scenegraph/qsgbasicinternalimagenode.cpp b/src/quick/scenegraph/qsgbasicinternalimagenode.cpp index 685a51550d..c8699218ba 100644 --- a/src/quick/scenegraph/qsgbasicinternalimagenode.cpp +++ b/src/quick/scenegraph/qsgbasicinternalimagenode.cpp @@ -55,10 +55,10 @@ namespace const QSGGeometry::AttributeSet &smoothAttributeSet() { static QSGGeometry::Attribute data[] = { - QSGGeometry::Attribute::createWithSemantic(0, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::POSITION), - QSGGeometry::Attribute::createWithSemantic(1, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::TEXCOORD), - QSGGeometry::Attribute::createWithSemantic(2, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::TEXCOORD1), - QSGGeometry::Attribute::createWithSemantic(3, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::TEXCOORD2) + QSGGeometry::Attribute::createWithAttributeType(0, 2, QSGGeometry::FloatType, QSGGeometry::PositionAttribute), + QSGGeometry::Attribute::createWithAttributeType(1, 2, QSGGeometry::FloatType, QSGGeometry::TexCoordAttribute), + QSGGeometry::Attribute::createWithAttributeType(2, 2, QSGGeometry::FloatType, QSGGeometry::TexCoord1Attribute), + QSGGeometry::Attribute::createWithAttributeType(3, 2, QSGGeometry::FloatType, QSGGeometry::TexCoord2Attribute) }; static QSGGeometry::AttributeSet attrs = { 4, sizeof(SmoothVertex), data }; return attrs; @@ -427,7 +427,7 @@ QSGGeometry *QSGBasicInternalImageNode::updateGeometry(const QRectF &targetRect, if (!geometry) { geometry = new QSGGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), hCells * vCells * 4, hCells * vCells * 6, - QSGGeometry::TypeUnsignedShort); + QSGGeometry::UnsignedShortType); } else { geometry->allocate(hCells * vCells * 4, hCells * vCells * 6); } diff --git a/src/quick/scenegraph/qsgbasicinternalrectanglenode.cpp b/src/quick/scenegraph/qsgbasicinternalrectanglenode.cpp index 8fc850b60c..df124cce35 100644 --- a/src/quick/scenegraph/qsgbasicinternalrectanglenode.cpp +++ b/src/quick/scenegraph/qsgbasicinternalrectanglenode.cpp @@ -87,9 +87,9 @@ namespace const QSGGeometry::AttributeSet &smoothAttributeSet() { static QSGGeometry::Attribute data[] = { - QSGGeometry::Attribute::createWithSemantic(0, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::POSITION), - QSGGeometry::Attribute::createWithSemantic(1, 4, QSGGeometry::TypeUnsignedByte, QSGGeometry::Attribute::COLOR), - QSGGeometry::Attribute::createWithSemantic(2, 2, QSGGeometry::TypeFloat, QSGGeometry::Attribute::TEXCOORD) + QSGGeometry::Attribute::createWithAttributeType(0, 2, QSGGeometry::FloatType, QSGGeometry::PositionAttribute), + QSGGeometry::Attribute::createWithAttributeType(1, 4, QSGGeometry::UnsignedByteType, QSGGeometry::ColorAttribute), + QSGGeometry::Attribute::createWithAttributeType(2, 2, QSGGeometry::FloatType, QSGGeometry::TexCoordAttribute) }; static QSGGeometry::AttributeSet attrs = { 3, sizeof(SmoothVertex), data }; return attrs; diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index 688fc7db08..d52f69c7a3 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -307,10 +307,6 @@ QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent) QSize QSGContext::minimumFBOSize() const { -#ifdef Q_OS_MAC - if (QSysInfo::MacintoshVersion < QSysInfo::MV_10_8) - return QSize(33, 33); -#endif return QSize(1, 1); } diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index 899278843e..6b9db105e7 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -178,7 +178,9 @@ public: virtual QSGGuiThreadShaderEffectManager *createGuiThreadShaderEffectManager(); virtual QSGShaderEffectNode *createShaderEffectNode(QSGRenderContext *renderContext, QSGGuiThreadShaderEffectManager *mgr); +#if QT_CONFIG(quick_sprite) virtual QSGSpriteNode *createSpriteNode() = 0; +#endif virtual QAnimationDriver *createAnimationDriver(QObject *parent); virtual QSize minimumFBOSize() const; diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp index 3751891455..7fab9aeae8 100644 --- a/src/quick/scenegraph/qsgcontextplugin.cpp +++ b/src/quick/scenegraph/qsgcontextplugin.cpp @@ -148,9 +148,9 @@ QSGAdaptationBackendData *contextFactory() } } +#ifndef QT_NO_LIBRARY // Then try the plugins. if (!backendData->factory) { -#ifndef QT_NO_LIBRARY const int index = loader()->indexOf(requestedBackend); if (index != -1) backendData->factory = qobject_cast<QSGContextFactoryInterface*>(loader()->instance(index)); diff --git a/src/quick/scenegraph/qsgdefaultcontext.cpp b/src/quick/scenegraph/qsgdefaultcontext.cpp index 6964b74dc8..405f1d86a4 100644 --- a/src/quick/scenegraph/qsgdefaultcontext.cpp +++ b/src/quick/scenegraph/qsgdefaultcontext.cpp @@ -52,7 +52,9 @@ #include <QtQuick/private/qsgdefaultrectanglenode_p.h> #include <QtQuick/private/qsgdefaultimagenode_p.h> #include <QtQuick/private/qsgdefaultninepatchnode_p.h> +#if QT_CONFIG(quick_sprite) #include <QtQuick/private/qsgdefaultspritenode_p.h> +#endif #include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLFramebufferObject> @@ -258,10 +260,12 @@ QSGNinePatchNode *QSGDefaultContext::createNinePatchNode() return new QSGDefaultNinePatchNode; } +#if QT_CONFIG(quick_sprite) QSGSpriteNode *QSGDefaultContext::createSpriteNode() { return new QSGDefaultSpriteNode; } +#endif QSGRendererInterface::GraphicsApi QSGDefaultContext::graphicsApi() const { diff --git a/src/quick/scenegraph/qsgdefaultcontext_p.h b/src/quick/scenegraph/qsgdefaultcontext_p.h index 88db5e1e9a..ab319502ef 100644 --- a/src/quick/scenegraph/qsgdefaultcontext_p.h +++ b/src/quick/scenegraph/qsgdefaultcontext_p.h @@ -76,7 +76,9 @@ public: QSGRectangleNode *createRectangleNode() override; QSGImageNode *createImageNode() override; QSGNinePatchNode *createNinePatchNode() override; +#if QT_CONFIG(quick_sprite) QSGSpriteNode *createSpriteNode() override; +#endif void setDistanceFieldEnabled(bool enabled); bool isDistanceFieldEnabled() const; diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h index 9ad99e5c54..0fefb95328 100644 --- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h +++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h @@ -119,19 +119,13 @@ private: const QString source = QLatin1String(qopenglslMainWithTexCoordsVertexShader) + QLatin1String(qopenglslUntransformedPositionVertexShader); - QOpenGLShader *vertexShader = new QOpenGLShader(QOpenGLShader::Vertex, m_blitProgram); - vertexShader->compileSourceCode(source); - - m_blitProgram->addShader(vertexShader); + m_blitProgram->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, source); } { const QString source = QLatin1String(qopenglslMainFragmentShader) + QLatin1String(qopenglslImageSrcFragmentShader); - QOpenGLShader *fragmentShader = new QOpenGLShader(QOpenGLShader::Fragment, m_blitProgram); - fragmentShader->compileSourceCode(source); - - m_blitProgram->addShader(fragmentShader); + m_blitProgram->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, source); } m_blitProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); m_blitProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp index 3501f30487..b001899915 100644 --- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp +++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp @@ -240,7 +240,8 @@ bool QSG24BitTextMaskShader::useSRGB() const // m_useSRGB is true, but if some QOGLFBO was bound check it's texture format: QOpenGLContext *ctx = QOpenGLContext::currentContext(); QOpenGLFramebufferObject *qfbo = QOpenGLContextPrivate::get(ctx)->qgl_current_fbo; - return !qfbo || qfbo->format().internalTextureFormat() == GL_SRGB8_ALPHA8_EXT; + bool fboInvalid = QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid; + return !qfbo || fboInvalid || qfbo->format().internalTextureFormat() == GL_SRGB8_ALPHA8_EXT; #else return m_useSRGB; #endif diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp index 6f10611ba3..2c5b4ff5c8 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -99,12 +99,12 @@ void QSGDefaultRenderContext::initialize(void *context) #ifdef Q_OS_LINUX const char *vendor = (const char *) funcs->glGetString(GL_VENDOR); - if (strstr(vendor, "nouveau")) + if (vendor && strstr(vendor, "nouveau")) m_brokenIBOs = true; const char *renderer = (const char *) funcs->glGetString(GL_RENDERER); - if (strstr(renderer, "llvmpipe")) + if (renderer && strstr(renderer, "llvmpipe")) m_serializedRender = true; - if (strstr(vendor, "Hisilicon Technologies") && strstr(renderer, "Immersion.16")) + if (vendor && renderer && strstr(vendor, "Hisilicon Technologies") && strstr(renderer, "Immersion.16")) m_brokenIBOs = true; #endif @@ -262,8 +262,8 @@ void QSGDefaultRenderContext::compileShader(QSGMaterialShader *shader, QSGMateri "QSGRenderContext::compile()", "materials with custom compile step cannot have custom vertex/fragment code"); QOpenGLShaderProgram *p = shader->program(); - p->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexCode ? vertexCode : shader->vertexShader()); - p->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentCode ? fragmentCode : shader->fragmentShader()); + p->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexCode ? vertexCode : shader->vertexShader()); + p->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentCode ? fragmentCode : shader->fragmentShader()); p->link(); if (!p->isLinked()) qWarning() << "shader compilation failed:" << endl << p->log(); diff --git a/src/quick/scenegraph/qsgdefaultspritenode.cpp b/src/quick/scenegraph/qsgdefaultspritenode.cpp index 89b26f8660..5eb8fb6e08 100644 --- a/src/quick/scenegraph/qsgdefaultspritenode.cpp +++ b/src/quick/scenegraph/qsgdefaultspritenode.cpp @@ -150,8 +150,8 @@ QSGMaterialShader *QQuickSpriteMaterial::createShader() const } static QSGGeometry::Attribute Sprite_Attributes[] = { - QSGGeometry::Attribute::create(0, 2, QSGGeometry::TypeFloat, true), // pos - QSGGeometry::Attribute::create(1, 2, QSGGeometry::TypeFloat), // tex + QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType, true), // pos + QSGGeometry::Attribute::create(1, 2, QSGGeometry::FloatType), // tex }; static QSGGeometry::AttributeSet Sprite_AttributeSet = diff --git a/src/quick/scenegraph/qsgdefaultspritenode_p.h b/src/quick/scenegraph/qsgdefaultspritenode_p.h index cb76bf8d83..78aa8cc0cf 100644 --- a/src/quick/scenegraph/qsgdefaultspritenode_p.h +++ b/src/quick/scenegraph/qsgdefaultspritenode_p.h @@ -51,6 +51,10 @@ // We mean it. // +#include <private/qtquickglobal_p.h> + +QT_REQUIRE_CONFIG(quick_sprite); + #include <private/qsgadaptationlayer_p.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index a59f9ddcc7..9ddbe5aa1d 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -61,8 +61,10 @@ #ifndef QT_NO_OPENGL # include <QtGui/QOpenGLContext> # include <private/qsgdefaultrendercontext_p.h> +#if QT_CONFIG(quick_shadereffect) # include <private/qquickopenglshadereffectnode_p.h> #endif +#endif #ifdef Q_OS_WIN # include <QtCore/qt_windows.h> @@ -326,7 +328,7 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window) if (Q_UNLIKELY(!current)) qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context"; -#ifndef QT_NO_OPENGL +#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache(); #endif diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 6b9c67b2bd..693012154e 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -63,7 +63,9 @@ #include <private/qqmldebugserviceinterfaces_p.h> #include <private/qqmldebugconnector_p.h> +#if QT_CONFIG(quick_shadereffect) #include <private/qquickopenglshadereffectnode_p.h> +#endif #include <private/qsgdefaultrendercontext_p.h> /* @@ -487,7 +489,9 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor, QQuickWindowPrivate *dd = QQuickWindowPrivate::get(window); +#if QT_CONFIG(quick_shadereffect) QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache(); +#endif // The canvas nodes must be cleaned up regardless if we are in the destructor.. if (wipeSG) { diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index 743e524a36..2a2d8be657 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -55,7 +55,7 @@ #include <private/qquickprofiler_p.h> #include <private/qquickanimatorcontroller_p.h> -#ifndef QT_NO_OPENGL +#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) #include <private/qquickopenglshadereffectnode_p.h> #endif @@ -84,18 +84,17 @@ QSGWindowsRenderLoop::QSGWindowsRenderLoop() { m_rc = static_cast<QSGDefaultRenderContext *>(m_sg->createRenderContext()); - m_animationDriver = m_sg->createAnimationDriver(m_sg); - m_animationDriver->install(); - - connect(m_animationDriver, SIGNAL(started()), this, SLOT(started())); - connect(m_animationDriver, SIGNAL(stopped()), this, SLOT(stopped())); - m_vsyncDelta = 1000 / QGuiApplication::primaryScreen()->refreshRate(); if (m_vsyncDelta <= 0) m_vsyncDelta = 16; RLDEBUG("Windows Render Loop created"); + m_animationDriver = m_sg->createAnimationDriver(m_sg); + connect(m_animationDriver, SIGNAL(started()), this, SLOT(started())); + connect(m_animationDriver, SIGNAL(stopped()), this, SLOT(stopped())); + m_animationDriver->install(); + qsg_render_timer.start(); } @@ -245,7 +244,7 @@ void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window) if (Q_UNLIKELY(!current)) qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context"; -#ifndef QT_NO_OPENGL +#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache(); #endif diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri index a659ca5e10..edf4aa08c5 100644 --- a/src/quick/scenegraph/scenegraph.pri +++ b/src/quick/scenegraph/scenegraph.pri @@ -113,7 +113,6 @@ qtConfig(opengl(es1|es2)?) { $$PWD/qsgdefaultinternalrectanglenode.cpp \ $$PWD/qsgdefaultrendercontext.cpp \ $$PWD/qsgdefaultcontext.cpp \ - $$PWD/qsgdefaultspritenode.cpp \ $$PWD/util/qsgdefaultpainternode.cpp \ $$PWD/util/qsgdefaultrectanglenode.cpp \ $$PWD/util/qsgdefaultimagenode.cpp \ @@ -129,7 +128,6 @@ qtConfig(opengl(es1|es2)?) { $$PWD/qsgdefaultglyphnode_p_p.h \ $$PWD/qsgdefaultinternalimagenode_p.h \ $$PWD/qsgdefaultinternalrectanglenode_p.h \ - $$PWD/qsgdefaultspritenode_p.h \ $$PWD/qsgdefaultrendercontext_p.h \ $$PWD/qsgdefaultcontext_p.h \ $$PWD/util/qsgdefaultpainternode_p.h \ @@ -139,6 +137,13 @@ qtConfig(opengl(es1|es2)?) { $$PWD/qsgdefaultlayer_p.h \ $$PWD/qsgthreadedrenderloop_p.h \ $$PWD/qsgwindowsrenderloop_p.h + + qtConfig(quick-sprite) { + SOURCES += \ + $$PWD/qsgdefaultspritenode.cpp + HEADERS += \ + $$PWD/qsgdefaultspritenode_p.h + } } # Built-in, non-plugin-based adaptations diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp index 40c3293c7b..b6abb55bd3 100644 --- a/src/quick/scenegraph/util/qsgatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgatlastexture.cpp @@ -117,8 +117,9 @@ QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel) if (image.width() < m_atlas_size_limit && image.height() < m_atlas_size_limit) { if (!m_atlas) m_atlas = new Atlas(m_atlas_size); + // t may be null for atlas allocation failure t = m_atlas->create(image); - if (!hasAlphaChannel && t->hasAlphaChannel()) + if (t && !hasAlphaChannel && t->hasAlphaChannel()) t->setHasAlphaChannel(false); } return t; diff --git a/src/quick/scenegraph/util/qsgdefaultimagenode.cpp b/src/quick/scenegraph/util/qsgdefaultimagenode.cpp index 6afe591dca..63773887a0 100644 --- a/src/quick/scenegraph/util/qsgdefaultimagenode.cpp +++ b/src/quick/scenegraph/util/qsgdefaultimagenode.cpp @@ -173,33 +173,4 @@ bool QSGDefaultImageNode::ownsTexture() const return m_ownsTexture; } -void QSGDefaultImageNode::rebuildGeometry(QSGGeometry *g, - QSGTexture *texture, - const QRectF &rect, - QRectF sourceRect, - TextureCoordinatesTransformMode texCoordMode) -{ - if (!texture) - return; - - if (!sourceRect.width() || !sourceRect.height()) { - QSize ts = texture->textureSize(); - sourceRect = QRectF(0, 0, ts.width(), ts.height()); - } - - // Maybe transform the texture coordinates - if (texCoordMode.testFlag(QSGImageNode::MirrorHorizontally)) { - float tmp = sourceRect.left(); - sourceRect.setLeft(sourceRect.right()); - sourceRect.setRight(tmp); - } - if (texCoordMode.testFlag(QSGImageNode::MirrorVertically)) { - float tmp = sourceRect.top(); - sourceRect.setTop(sourceRect.bottom()); - sourceRect.setBottom(tmp); - } - - QSGGeometry::updateTexturedRectGeometry(g, rect, texture->convertToNormalizedSourceRect(sourceRect)); -} - QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgdefaultimagenode_p.h b/src/quick/scenegraph/util/qsgdefaultimagenode_p.h index eb6c487c18..bb9ebec885 100644 --- a/src/quick/scenegraph/util/qsgdefaultimagenode_p.h +++ b/src/quick/scenegraph/util/qsgdefaultimagenode_p.h @@ -85,12 +85,6 @@ public: void setOwnsTexture(bool owns) override; bool ownsTexture() const override; - static void rebuildGeometry(QSGGeometry *g, - QSGTexture *texture, - const QRectF &rect, - QRectF sourceRect, - TextureCoordinatesTransformMode texCoordMode); - private: QSGGeometry m_geometry; QSGOpaqueTextureMaterial m_opaque_material; diff --git a/src/quick/scenegraph/util/qsgdefaultninepatchnode.cpp b/src/quick/scenegraph/util/qsgdefaultninepatchnode.cpp index e5a53a3617..6023a9af93 100644 --- a/src/quick/scenegraph/util/qsgdefaultninepatchnode.cpp +++ b/src/quick/scenegraph/util/qsgdefaultninepatchnode.cpp @@ -81,56 +81,4 @@ void QSGDefaultNinePatchNode::update() markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial); } -void QSGDefaultNinePatchNode::rebuildGeometry(QSGTexture *texture, QSGGeometry *geometry, const QVector4D &padding, - const QRectF &bounds, qreal dpr) -{ - if (padding.x() <= 0 && padding.y() <= 0 && padding.z() <= 0 && padding.w() <= 0) { - geometry->allocate(4, 0); - QSGGeometry::updateTexturedRectGeometry(geometry, bounds, texture->normalizedTextureSubRect()); - return; - } - - QRectF tc = texture->normalizedTextureSubRect(); - QSize ts = texture->textureSize(); - ts.setHeight(ts.height() / dpr); - ts.setWidth(ts.width() / dpr); - - qreal invtw = tc.width() / ts.width(); - qreal invth = tc.height() / ts.height(); - - struct Coord { qreal p; qreal t; }; - Coord cx[4] = { { bounds.left(), tc.left() }, - { bounds.left() + padding.x(), tc.left() + padding.x() * invtw }, - { bounds.right() - padding.z(), tc.right() - padding.z() * invtw }, - { bounds.right(), tc.right() } - }; - Coord cy[4] = { { bounds.top(), tc.top() }, - { bounds.top() + padding.y(), tc.top() + padding.y() * invth }, - { bounds.bottom() - padding.w(), tc.bottom() - padding.w() * invth }, - { bounds.bottom(), tc.bottom() } - }; - - geometry->allocate(16, 28); - QSGGeometry::TexturedPoint2D *v = geometry->vertexDataAsTexturedPoint2D(); - for (int y = 0; y < 4; ++y) { - for (int x = 0; x < 4; ++x) { - v->set(cx[x].p, cy[y].p, cx[x].t, cy[y].t); - ++v; - } - } - - quint16 *i = geometry->indexDataAsUShort(); - for (int r = 0; r < 3; ++r) { - if (r > 0) - *i++ = 4 * r; - for (int c = 0; c < 4; ++c) { - i[0] = 4 * r + c; - i[1] = 4 * r + c + 4; - i += 2; - } - if (r < 2) - *i++ = 4 * r + 3 + 4; - } -} - QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgdefaultninepatchnode_p.h b/src/quick/scenegraph/util/qsgdefaultninepatchnode_p.h index 675cf48f47..3752a75ac6 100644 --- a/src/quick/scenegraph/util/qsgdefaultninepatchnode_p.h +++ b/src/quick/scenegraph/util/qsgdefaultninepatchnode_p.h @@ -70,9 +70,6 @@ public: void setPadding(qreal left, qreal top, qreal right, qreal bottom) override; void update() override; - static void rebuildGeometry(QSGTexture *texture, QSGGeometry *geometry, const QVector4D &padding, - const QRectF &bounds, qreal dpr); - private: QRectF m_bounds; qreal m_devicePixelRatio; diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp index e1aea290a3..389b9e0b4e 100644 --- a/src/quick/scenegraph/util/qsgdefaultpainternode.cpp +++ b/src/quick/scenegraph/util/qsgdefaultpainternode.cpp @@ -443,9 +443,21 @@ void QSGDefaultPainterNode::setContentsScale(qreal s) markDirty(DirtyMaterial); } -void QSGDefaultPainterNode::setFastFBOResizing(bool dynamic) +void QSGDefaultPainterNode::setFastFBOResizing(bool fastResizing) { - m_fastFBOResizing = dynamic; + if (m_fastFBOResizing == fastResizing) + return; + + m_fastFBOResizing = fastResizing; + updateFBOSize(); + + if ((m_preferredRenderTarget == QQuickPaintedItem::FramebufferObject + || m_preferredRenderTarget == QQuickPaintedItem::InvertedYFramebufferObject) + && (!m_fbo || (m_fbo && m_fbo->size() != m_fboSize))) { + m_dirtyRenderTarget = true; + m_dirtyGeometry = true; + m_dirtyTexture = true; + } } QImage QSGDefaultPainterNode::toImage() const diff --git a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h index a433b3292a..084fc1e004 100644 --- a/src/quick/scenegraph/util/qsgdefaultpainternode_p.h +++ b/src/quick/scenegraph/util/qsgdefaultpainternode_p.h @@ -109,7 +109,7 @@ public: void setContentsScale(qreal s) override; qreal contentsScale() const { return m_contentsScale; } - void setFastFBOResizing(bool dynamic) override; + void setFastFBOResizing(bool fastResizing) override; bool fastFBOResizing() const { return m_fastFBOResizing; } void setTextureSize(const QSize &textureSize) override; diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp index 65a6bcd52c..79e43e3820 100644 --- a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp +++ b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp @@ -84,32 +84,12 @@ QSGDistanceFieldGlyphCacheManager::~QSGDistanceFieldGlyphCacheManager() QSGDistanceFieldGlyphCache *QSGDistanceFieldGlyphCacheManager::cache(const QRawFont &font) { - return m_caches.value(fontKey(font), 0); + return m_caches.value(font, 0); } void QSGDistanceFieldGlyphCacheManager::insertCache(const QRawFont &font, QSGDistanceFieldGlyphCache *cache) { - m_caches.insert(fontKey(font), cache); -} - -QString QSGDistanceFieldGlyphCacheManager::fontKey(const QRawFont &font) -{ - QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine; - if (!fe->faceId().filename.isEmpty()) { - QByteArray keyName = fe->faceId().filename; - if (font.style() != QFont::StyleNormal) - keyName += QByteArray(" I"); - if (font.weight() != QFont::Normal) - keyName += ' ' + QByteArray::number(font.weight()); - keyName += QByteArray(" DF"); - return QString::fromUtf8(keyName); - } else { - return QString::fromLatin1("%1_%2_%3_%4") - .arg(font.familyName()) - .arg(font.styleName()) - .arg(font.weight()) - .arg(font.style()); - } + m_caches.insert(font, cache); } QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil_p.h b/src/quick/scenegraph/util/qsgdistancefieldutil_p.h index 354a48a81e..ad366cb4d4 100644 --- a/src/quick/scenegraph/util/qsgdistancefieldutil_p.h +++ b/src/quick/scenegraph/util/qsgdistancefieldutil_p.h @@ -80,9 +80,7 @@ public: void setAntialiasingSpreadFunc(AntialiasingSpreadFunc func) { m_antialiasingSpread_func = func; } private: - static QString fontKey(const QRawFont &font); - - QHash<QString, QSGDistanceFieldGlyphCache *> m_caches; + QHash<QRawFont, QSGDistanceFieldGlyphCache *> m_caches; ThresholdFunc m_threshold_func; AntialiasingSpreadFunc m_antialiasingSpread_func; diff --git a/src/quick/scenegraph/util/qsgimagenode.cpp b/src/quick/scenegraph/util/qsgimagenode.cpp index a78bfc1c66..c03c91d1cb 100644 --- a/src/quick/scenegraph/util/qsgimagenode.cpp +++ b/src/quick/scenegraph/util/qsgimagenode.cpp @@ -187,4 +187,33 @@ QT_BEGIN_NAMESPACE \return \c true if the node takes ownership of the texture; otherwise \c false. */ +void QSGImageNode::rebuildGeometry(QSGGeometry *g, + QSGTexture *texture, + const QRectF &rect, + QRectF sourceRect, + TextureCoordinatesTransformMode texCoordMode) +{ + if (!texture) + return; + + if (!sourceRect.width() || !sourceRect.height()) { + QSize ts = texture->textureSize(); + sourceRect = QRectF(0, 0, ts.width(), ts.height()); + } + + // Maybe transform the texture coordinates + if (texCoordMode.testFlag(QSGImageNode::MirrorHorizontally)) { + float tmp = sourceRect.left(); + sourceRect.setLeft(sourceRect.right()); + sourceRect.setRight(tmp); + } + if (texCoordMode.testFlag(QSGImageNode::MirrorVertically)) { + float tmp = sourceRect.top(); + sourceRect.setTop(sourceRect.bottom()); + sourceRect.setBottom(tmp); + } + + QSGGeometry::updateTexturedRectGeometry(g, rect, texture->convertToNormalizedSourceRect(sourceRect)); +} + QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgimagenode.h b/src/quick/scenegraph/util/qsgimagenode.h index 7eab42c4e6..d25e732e4b 100644 --- a/src/quick/scenegraph/util/qsgimagenode.h +++ b/src/quick/scenegraph/util/qsgimagenode.h @@ -79,6 +79,12 @@ public: virtual void setOwnsTexture(bool owns) = 0; virtual bool ownsTexture() const = 0; + + static void rebuildGeometry(QSGGeometry *g, + QSGTexture *texture, + const QRectF &rect, + QRectF sourceRect, + TextureCoordinatesTransformMode texCoordMode); }; Q_DECLARE_OPERATORS_FOR_FLAGS(QSGImageNode::TextureCoordinatesTransformMode) diff --git a/src/quick/scenegraph/util/qsgninepatchnode.cpp b/src/quick/scenegraph/util/qsgninepatchnode.cpp index 9c167ca76f..33568b5488 100644 --- a/src/quick/scenegraph/util/qsgninepatchnode.cpp +++ b/src/quick/scenegraph/util/qsgninepatchnode.cpp @@ -74,4 +74,56 @@ QT_BEGIN_NAMESPACE \internal */ +void QSGNinePatchNode::rebuildGeometry(QSGTexture *texture, QSGGeometry *geometry, const QVector4D &padding, + const QRectF &bounds, qreal dpr) +{ + if (padding.x() <= 0 && padding.y() <= 0 && padding.z() <= 0 && padding.w() <= 0) { + geometry->allocate(4, 0); + QSGGeometry::updateTexturedRectGeometry(geometry, bounds, texture->normalizedTextureSubRect()); + return; + } + + QRectF tc = texture->normalizedTextureSubRect(); + QSize ts = texture->textureSize(); + ts.setHeight(ts.height() / dpr); + ts.setWidth(ts.width() / dpr); + + qreal invtw = tc.width() / ts.width(); + qreal invth = tc.height() / ts.height(); + + struct Coord { qreal p; qreal t; }; + Coord cx[4] = { { bounds.left(), tc.left() }, + { bounds.left() + padding.x(), tc.left() + padding.x() * invtw }, + { bounds.right() - padding.z(), tc.right() - padding.z() * invtw }, + { bounds.right(), tc.right() } + }; + Coord cy[4] = { { bounds.top(), tc.top() }, + { bounds.top() + padding.y(), tc.top() + padding.y() * invth }, + { bounds.bottom() - padding.w(), tc.bottom() - padding.w() * invth }, + { bounds.bottom(), tc.bottom() } + }; + + geometry->allocate(16, 28); + QSGGeometry::TexturedPoint2D *v = geometry->vertexDataAsTexturedPoint2D(); + for (int y = 0; y < 4; ++y) { + for (int x = 0; x < 4; ++x) { + v->set(cx[x].p, cy[y].p, cx[x].t, cy[y].t); + ++v; + } + } + + quint16 *i = geometry->indexDataAsUShort(); + for (int r = 0; r < 3; ++r) { + if (r > 0) + *i++ = 4 * r; + for (int c = 0; c < 4; ++c) { + i[0] = 4 * r + c; + i[1] = 4 * r + c + 4; + i += 2; + } + if (r < 2) + *i++ = 4 * r + 3 + 4; + } +} + QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgninepatchnode.h b/src/quick/scenegraph/util/qsgninepatchnode.h index 8677a432ba..8509cbd326 100644 --- a/src/quick/scenegraph/util/qsgninepatchnode.h +++ b/src/quick/scenegraph/util/qsgninepatchnode.h @@ -55,6 +55,10 @@ public: virtual void setDevicePixelRatio(qreal ratio) = 0; virtual void setPadding(qreal left, qreal top, qreal right, qreal bottom) = 0; virtual void update() = 0; + + static void rebuildGeometry(QSGTexture *texture, QSGGeometry *geometry, + const QVector4D &padding, + const QRectF &bounds, qreal dpr); }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp index 25af1997a8..d8f92919cb 100644 --- a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp +++ b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp @@ -217,11 +217,11 @@ void QSGShaderSourceBuilder::initializeProgramFromFiles(QOpenGLShaderProgram *pr QSGShaderSourceBuilder builder; builder.appendSourceFile(vertexShader); - program->addShaderFromSourceCode(QOpenGLShader::Vertex, builder.source()); + program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, builder.source()); builder.clear(); builder.appendSourceFile(fragmentShader); - program->addShaderFromSourceCode(QOpenGLShader::Fragment, builder.source()); + program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, builder.source()); } QByteArray QSGShaderSourceBuilder::source() const |