aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-11-23 10:49:37 +0100
committerLiang Qi <liang.qi@qt.io>2016-11-23 10:49:37 +0100
commit5d4cbf4094c9b290626aab89e4bd92edd29ce49f (patch)
treeeac893652c724f057fba493688b16e212fd844dd /src/quick/scenegraph
parent13cf5f02ce788f19a73e5d5c3da76e57291761a5 (diff)
parent07cde200e55ee03bf9e2f9af89c20f91072deccc (diff)
Merge remote-tracking branch 'origin/5.8' into dev
Conflicts: src/qml/jsruntime/qv4object_p.h Change-Id: Iff4d3aba7710a999b8befdc493cbe959e1ce02f9
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp57
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h70
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendererinterface.cpp8
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendererinterface.h8
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp3
-rw-r--r--src/quick/scenegraph/util/qsgdefaultimagenode.cpp29
-rw-r--r--src/quick/scenegraph/util/qsgdefaultimagenode_p.h6
-rw-r--r--src/quick/scenegraph/util/qsgdefaultninepatchnode.cpp52
-rw-r--r--src/quick/scenegraph/util/qsgdefaultninepatchnode_p.h3
-rw-r--r--src/quick/scenegraph/util/qsgdistancefieldutil.cpp24
-rw-r--r--src/quick/scenegraph/util/qsgdistancefieldutil_p.h4
-rw-r--r--src/quick/scenegraph/util/qsgimagenode.cpp29
-rw-r--r--src/quick/scenegraph/util/qsgimagenode.h6
-rw-r--r--src/quick/scenegraph/util/qsgninepatchnode.cpp52
-rw-r--r--src/quick/scenegraph/util/qsgninepatchnode.h4
16 files changed, 186 insertions, 171 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
index 05d5daa686..d71b0c3e2a 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
@@ -215,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/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/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/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/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