aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/scenegraph
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2016-12-03 21:30:12 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2016-12-19 17:03:46 +0000
commitc9023c28764e70cd1c6f9cfc3506e6185299548e (patch)
tree1578cf3ea1f97b024f036b923cb1e02fee0b92cc /src/quick/scenegraph
parent25277124d8b7581a9390702ad3d4bcd4be8dedd7 (diff)
Add QQuickPathItem and its backend infra
The generic backend uses the triangulator from QtGui, but is in fact OpenGL-only for now due to materials. The NVPR backend uses GL_NV_path_rendering on NVIDIA hardware with OpenGL 4.3+ or OpenGL ES 3.1+. The software backend simply uses QPainter. With the generic backend each PathItem is backed by a non-visual root node and 0, 1 or 2 child geometry nodes, depending on the presence of visible stroking and filling. The potentially expensive triangulation happens on updatePolish(), on the gui thread. This is proven to provide much smoother results when compared to doing the geometry generation on the render thread in updatePaintNode(), in particular on power-limited embedded devices. The NVPR backend uses a QSGRenderNode in DepthAware mode so that the batch renderer can continue to rely on the depth buffer and use opaque batches. Due to not relying on slow CPU-side triangulation, this backend uses 5-10 times less CPU, even when properties of the path or its elements are animated. The path itself is specified with the PathView's Path, PathLine, PathArc, PathQuad, etc. types. This allows for consistency with PathView and the 2D Canvas and avoids a naming mess in the API. However, there won't be a 100% symmetry: backends like NVPR will not rely on QPainterPath but process the path elements on their own (as QPainterPath is essentially useless with these APIs), which can lead to differences in the supported path elements. The supported common set is currently Move, Line, Quad, Cubic, Arc. The patch introduces PathMove, which is essentially PathLine but maps to moveTo instead of lineTo. More types may get added later (e.g. NVPR can do a wide variety of optimized rounded rects, but this requires directly specifying a GL_ROUNDED_RECTx_NV command, thus neededing a dedicated Path type on our side too) For filling with gradients only linear gradients are supported at the moment. In addition to the declarative API, a more lightweight, QObject-less JS-callable API should be considered as well for the future. Change-Id: I335ad64b425ee279505d60e3e57ac6841e1cbd24 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp4
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp3
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp2
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp24
-rw-r--r--src/quick/scenegraph/util/qsgtexture.h3
-rw-r--r--src/quick/scenegraph/util/qsgtexture_p.h4
-rw-r--r--src/quick/scenegraph/util/qsgtexturematerial.cpp4
7 files changed, 31 insertions, 13 deletions
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index 8de205fc98..b8ed190b33 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -978,6 +978,10 @@ void Renderer::nodeChangedBatchRoot(Node *node, Node *root)
e->root = root;
e->boundsComputed = false;
}
+ } else if (node->type() == QSGNode::RenderNodeType) {
+ RenderNodeElement *e = node->renderNodeElement();
+ if (e)
+ e->root = root;
}
SHADOWNODE_TRAVERSE(node)
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index 5915d51f2b..1bc0210b72 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -160,10 +160,7 @@ QSGRenderNode::StateFlags QSGRenderNode::changedStates() const
\list
\li glDepthMask(false)
\li glDisable(GL_DEPTH_TEST)
- \li glStencilMask(0)
- \li glEnable(GL_STENCIL_TEST)/glDisable(GL_STENCIL_TEST) depending on clip
\li glStencilFunc(GL_EQUAL, state.stencilValue, 0xff) depending on clip
- \li glEnable(GL_SCISSOR_TEST)/glDisable(GL_SCISSOR_TEST) depending on clip
\li glScissor(state.scissorRect.x(), state.scissorRect.y(),
state.scissorRect.width(), state.scissorRect.height()) depending on clip
\li glEnable(GL_BLEND)
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index 2c5b4ff5c8..aaf4635c0c 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -260,7 +260,7 @@ void QSGDefaultRenderContext::compileShader(QSGMaterialShader *shader, QSGMateri
if (vertexCode || fragmentCode) {
Q_ASSERT_X((material->flags() & QSGMaterial::CustomCompileStep) == 0,
"QSGRenderContext::compile()",
- "materials with custom compile step cannot have custom vertex/fragment code");
+ "materials with custom compile step cannot have modified vertex or fragment code");
QOpenGLShaderProgram *p = shader->program();
p->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexCode ? vertexCode : shader->vertexShader());
p->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentCode ? fragmentCode : shader->fragmentShader());
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index 47248f2f37..d761eac62f 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -251,11 +251,15 @@ static void qt_debug_remove_texture(QSGTexture* texture)
Specifies how the texture should treat texture coordinates.
- \value Repeat Only the factional part of the texture coordiante is
+ \value Repeat Only the fractional part of the texture coordinate is
used, causing values above 1 and below 0 to repeat.
\value ClampToEdge Values above 1 are clamped to 1 and values
below 0 are clamped to 0.
+
+ \value MirroredRepeat When the texture coordinate is even, only the
+ fractional part is used. When odd, the texture coordinate is set to
+ \c{1 - fractional part}. This value has been introduced in Qt 5.10.
*/
/*!
@@ -550,7 +554,9 @@ void QSGTexture::updateBindOptions(bool force)
if (force || d->wrapChanged) {
#ifndef QT_NO_DEBUG
- if (d->horizontalWrap == Repeat || d->verticalWrap == Repeat) {
+ if (d->horizontalWrap == Repeat || d->verticalWrap == Repeat
+ || d->horizontalWrap == MirroredRepeat || d->verticalWrap == MirroredRepeat)
+ {
bool npotSupported = QOpenGLFunctions(QOpenGLContext::currentContext()).hasOpenGLFeature(QOpenGLFunctions::NPOTTextures);
QSize size = textureSize();
bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height());
@@ -558,8 +564,18 @@ void QSGTexture::updateBindOptions(bool force)
qWarning("Scene Graph: This system does not support the REPEAT wrap mode for non-power-of-two textures.");
}
#endif
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, d->horizontalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, d->verticalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
+ GLenum wrapS = GL_CLAMP_TO_EDGE;
+ if (d->horizontalWrap == Repeat)
+ wrapS = GL_REPEAT;
+ else if (d->horizontalWrap == MirroredRepeat)
+ wrapS = GL_MIRRORED_REPEAT;
+ GLenum wrapT = GL_CLAMP_TO_EDGE;
+ if (d->verticalWrap == Repeat)
+ wrapT = GL_REPEAT;
+ else if (d->verticalWrap == MirroredRepeat)
+ wrapT = GL_MIRRORED_REPEAT;
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
d->wrapChanged = false;
}
#else
diff --git a/src/quick/scenegraph/util/qsgtexture.h b/src/quick/scenegraph/util/qsgtexture.h
index f0509b58ae..2b29525efd 100644
--- a/src/quick/scenegraph/util/qsgtexture.h
+++ b/src/quick/scenegraph/util/qsgtexture.h
@@ -58,7 +58,8 @@ public:
enum WrapMode {
Repeat,
- ClampToEdge
+ ClampToEdge,
+ MirroredRepeat
};
enum Filtering {
diff --git a/src/quick/scenegraph/util/qsgtexture_p.h b/src/quick/scenegraph/util/qsgtexture_p.h
index b6fcfc31c4..3a10d85b4d 100644
--- a/src/quick/scenegraph/util/qsgtexture_p.h
+++ b/src/quick/scenegraph/util/qsgtexture_p.h
@@ -70,8 +70,8 @@ public:
uint wrapChanged : 1;
uint filteringChanged : 1;
- uint horizontalWrap : 1;
- uint verticalWrap : 1;
+ uint horizontalWrap : 2;
+ uint verticalWrap : 2;
uint mipmapMode : 2;
uint filterMode : 2;
};
diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp
index 9326ea640d..fcafbba6a2 100644
--- a/src/quick/scenegraph/util/qsgtexturematerial.cpp
+++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp
@@ -278,7 +278,7 @@ void QSGOpaqueTextureMaterial::setTexture(QSGTexture *texture)
Returns this material's horizontal wrap mode.
- The default horizontal wrap mode is \c QSGTexutre::ClampToEdge.
+ The default horizontal wrap mode is \c QSGTexture::ClampToEdge.
*/
@@ -299,7 +299,7 @@ void QSGOpaqueTextureMaterial::setTexture(QSGTexture *texture)
Returns this material's vertical wrap mode.
- The default vertical wrap mode is \c QSGTexutre::ClampToEdge.
+ The default vertical wrap mode is \c QSGTexture::ClampToEdge.
*/