aboutsummaryrefslogtreecommitdiffstats
path: root/src/imports/shapes
diff options
context:
space:
mode:
Diffstat (limited to 'src/imports/shapes')
-rw-r--r--src/imports/shapes/plugin.cpp1
-rw-r--r--src/imports/shapes/plugins.qmltypes219
-rw-r--r--src/imports/shapes/qquicknvprfunctions.cpp8
-rw-r--r--src/imports/shapes/qquickshape.cpp206
-rw-r--r--src/imports/shapes/qquickshape_p.h2
-rw-r--r--src/imports/shapes/qquickshape_p_p.h104
-rw-r--r--src/imports/shapes/qquickshapegenericrenderer.cpp11
-rw-r--r--src/imports/shapes/qquickshapegenericrenderer_p.h1
-rw-r--r--src/imports/shapes/qquickshapenvprrenderer.cpp98
-rw-r--r--src/imports/shapes/qquickshapenvprrenderer_p.h2
-rw-r--r--src/imports/shapes/qquickshapesoftwarerenderer.cpp8
-rw-r--r--src/imports/shapes/qquickshapesoftwarerenderer_p.h1
-rw-r--r--src/imports/shapes/shaders/blit.frag9
-rw-r--r--src/imports/shapes/shaders/blit.vert12
-rw-r--r--src/imports/shapes/shaders/blit_core.frag13
-rw-r--r--src/imports/shapes/shaders/blit_core.vert14
-rw-r--r--src/imports/shapes/shaders/lineargradient.frag9
-rw-r--r--src/imports/shapes/shaders/lineargradient.vert15
-rw-r--r--src/imports/shapes/shaders/lineargradient_core.frag12
-rw-r--r--src/imports/shapes/shaders/lineargradient_core.vert17
-rw-r--r--src/imports/shapes/shapes.pro2
-rw-r--r--src/imports/shapes/shapes.qrc12
22 files changed, 251 insertions, 525 deletions
diff --git a/src/imports/shapes/plugin.cpp b/src/imports/shapes/plugin.cpp
index ae0d02da93..1729fc88b4 100644
--- a/src/imports/shapes/plugin.cpp
+++ b/src/imports/shapes/plugin.cpp
@@ -47,6 +47,7 @@ static void initResources()
#ifdef QT_STATIC
Q_INIT_RESOURCE(qmake_QtQuick_Shapes);
#endif
+ Q_INIT_RESOURCE(shapes);
}
QT_BEGIN_NAMESPACE
diff --git a/src/imports/shapes/plugins.qmltypes b/src/imports/shapes/plugins.qmltypes
index 00d0050085..b8a7c532e0 100644
--- a/src/imports/shapes/plugins.qmltypes
+++ b/src/imports/shapes/plugins.qmltypes
@@ -4,196 +4,13 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -noforceqtquick QtQuick.Shapes 1.0'
+// 'qmlplugindump -nonrelocatable QtQuick.Shapes 1.0'
Module {
- dependencies: []
- Component {
- name: "QQuickItem"
- defaultProperty: "data"
- prototype: "QObject"
- Enum {
- name: "TransformOrigin"
- values: {
- "TopLeft": 0,
- "Top": 1,
- "TopRight": 2,
- "Left": 3,
- "Center": 4,
- "Right": 5,
- "BottomLeft": 6,
- "Bottom": 7,
- "BottomRight": 8
- }
- }
- Property { name: "parent"; type: "QQuickItem"; isPointer: true }
- Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
- Property { name: "resources"; type: "QObject"; isList: true; isReadonly: true }
- Property { name: "children"; type: "QQuickItem"; isList: true; isReadonly: true }
- Property { name: "x"; type: "double" }
- Property { name: "y"; type: "double" }
- Property { name: "z"; type: "double" }
- Property { name: "width"; type: "double" }
- Property { name: "height"; type: "double" }
- Property { name: "opacity"; type: "double" }
- Property { name: "enabled"; type: "bool" }
- Property { name: "visible"; type: "bool" }
- Property { name: "visibleChildren"; type: "QQuickItem"; isList: true; isReadonly: true }
- Property { name: "states"; type: "QQuickState"; isList: true; isReadonly: true }
- Property { name: "transitions"; type: "QQuickTransition"; isList: true; isReadonly: true }
- Property { name: "state"; type: "string" }
- Property { name: "childrenRect"; type: "QRectF"; isReadonly: true }
- Property { name: "anchors"; type: "QQuickAnchors"; isReadonly: true; isPointer: true }
- Property { name: "left"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "right"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "horizontalCenter"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "top"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "bottom"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "verticalCenter"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "baseline"; type: "QQuickAnchorLine"; isReadonly: true }
- Property { name: "baselineOffset"; type: "double" }
- Property { name: "clip"; type: "bool" }
- Property { name: "focus"; type: "bool" }
- Property { name: "activeFocus"; type: "bool"; isReadonly: true }
- Property { name: "activeFocusOnTab"; revision: 1; type: "bool" }
- Property { name: "rotation"; type: "double" }
- Property { name: "scale"; type: "double" }
- Property { name: "transformOrigin"; type: "TransformOrigin" }
- Property { name: "transformOriginPoint"; type: "QPointF"; isReadonly: true }
- Property { name: "transform"; type: "QQuickTransform"; isList: true; isReadonly: true }
- Property { name: "smooth"; type: "bool" }
- Property { name: "antialiasing"; type: "bool" }
- Property { name: "implicitWidth"; type: "double" }
- Property { name: "implicitHeight"; type: "double" }
- Property { name: "layer"; type: "QQuickItemLayer"; isReadonly: true; isPointer: true }
- Signal {
- name: "childrenRectChanged"
- Parameter { type: "QRectF" }
- }
- Signal {
- name: "baselineOffsetChanged"
- Parameter { type: "double" }
- }
- Signal {
- name: "stateChanged"
- Parameter { type: "string" }
- }
- Signal {
- name: "focusChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "activeFocusChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "activeFocusOnTabChanged"
- revision: 1
- Parameter { type: "bool" }
- }
- Signal {
- name: "parentChanged"
- Parameter { type: "QQuickItem"; isPointer: true }
- }
- Signal {
- name: "transformOriginChanged"
- Parameter { type: "TransformOrigin" }
- }
- Signal {
- name: "smoothChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "antialiasingChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "clipChanged"
- Parameter { type: "bool" }
- }
- Signal {
- name: "windowChanged"
- revision: 1
- Parameter { name: "window"; type: "QQuickWindow"; isPointer: true }
- }
- Method { name: "update" }
- Method {
- name: "grabToImage"
- revision: 2
- type: "bool"
- Parameter { name: "callback"; type: "QJSValue" }
- Parameter { name: "targetSize"; type: "QSize" }
- }
- Method {
- name: "grabToImage"
- revision: 2
- type: "bool"
- Parameter { name: "callback"; type: "QJSValue" }
- }
- Method {
- name: "contains"
- type: "bool"
- Parameter { name: "point"; type: "QPointF" }
- }
- Method {
- name: "mapFromItem"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "mapToItem"
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "mapFromGlobal"
- revision: 7
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method {
- name: "mapToGlobal"
- revision: 7
- Parameter { type: "QQmlV4Function"; isPointer: true }
- }
- Method { name: "forceActiveFocus" }
- Method {
- name: "forceActiveFocus"
- Parameter { name: "reason"; type: "Qt::FocusReason" }
- }
- Method {
- name: "nextItemInFocusChain"
- revision: 1
- type: "QQuickItem*"
- Parameter { name: "forward"; type: "bool" }
- }
- Method { name: "nextItemInFocusChain"; revision: 1; type: "QQuickItem*" }
- Method {
- name: "childAt"
- type: "QQuickItem*"
- Parameter { name: "x"; type: "double" }
- Parameter { name: "y"; type: "double" }
- }
- }
- Component {
- name: "QQuickShapeGradient"
- defaultProperty: "stops"
- prototype: "QObject"
- exports: ["QtQuick.Shapes/ShapeGradient 1.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Enum {
- name: "SpreadMode"
- values: {
- "PadSpread": 0,
- "RepeatSpread": 1,
- "ReflectSpread": 2
- }
- }
- Property { name: "stops"; type: "QObject"; isList: true; isReadonly: true }
- Property { name: "spread"; type: "SpreadMode" }
- Signal { name: "updated" }
- }
+ dependencies: ["QtQuick 2.8"]
Component {
name: "QQuickShape"
- defaultProperty: "elements"
+ defaultProperty: "data"
prototype: "QQuickItem"
exports: ["QtQuick.Shapes/Shape 1.0"]
exportMetaObjectRevisions: [0]
@@ -214,11 +31,28 @@ Module {
"Processing": 2
}
}
- Property { name: "renderer"; type: "RendererType"; isReadonly: true }
+ Property { name: "rendererType"; type: "RendererType"; isReadonly: true }
Property { name: "asynchronous"; type: "bool" }
- Property { name: "enableVendorExtensions"; type: "bool" }
+ Property { name: "vendorExtensionsEnabled"; type: "bool" }
Property { name: "status"; type: "Status"; isReadonly: true }
- Property { name: "elements"; type: "QQuickShapePath"; isList: true; isReadonly: true }
+ Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
+ }
+ Component {
+ name: "QQuickShapeGradient"
+ defaultProperty: "stops"
+ prototype: "QQuickGradient"
+ exports: ["QtQuick.Shapes/ShapeGradient 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "SpreadMode"
+ values: {
+ "PadSpread": 0,
+ "RepeatSpread": 1,
+ "ReflectSpread": 2
+ }
+ }
+ Property { name: "spread"; type: "SpreadMode" }
}
Component {
name: "QQuickShapeLinearGradient"
@@ -233,8 +67,8 @@ Module {
}
Component {
name: "QQuickShapePath"
- defaultProperty: "path"
- prototype: "QObject"
+ defaultProperty: "pathElements"
+ prototype: "QQuickPath"
exports: ["QtQuick.Shapes/ShapePath 1.0"]
exportMetaObjectRevisions: [0]
Enum {
@@ -267,7 +101,6 @@ Module {
"DashLine": 2
}
}
- Property { name: "path"; type: "QQuickPath"; isPointer: true }
Property { name: "strokeColor"; type: "QColor" }
Property { name: "strokeWidth"; type: "double" }
Property { name: "fillColor"; type: "QColor" }
@@ -279,6 +112,6 @@ Module {
Property { name: "dashOffset"; type: "double" }
Property { name: "dashPattern"; type: "QVector<qreal>" }
Property { name: "fillGradient"; type: "QQuickShapeGradient"; isPointer: true }
- Signal { name: "changed" }
+ Signal { name: "shapePathChanged" }
}
}
diff --git a/src/imports/shapes/qquicknvprfunctions.cpp b/src/imports/shapes/qquicknvprfunctions.cpp
index 0b92d4b4c0..409a59be7f 100644
--- a/src/imports/shapes/qquicknvprfunctions.cpp
+++ b/src/imports/shapes/qquicknvprfunctions.cpp
@@ -87,6 +87,8 @@ QSurfaceFormat QQuickNvprFunctions::format()
return fmt;
}
+#define PROC(type, name) reinterpret_cast<type>(ctx->getProcAddress(#name))
+
/*!
\return true if GL_NV_path_rendering is supported with the current OpenGL
context.
@@ -114,6 +116,10 @@ bool QQuickNvprFunctions::isSupported()
if (!ctx->hasExtension(QByteArrayLiteral("GL_NV_path_rendering")))
return false;
+ // Check that GL_NV_Path_rendering extension is at least API revision 1.3
+ if (!PROC(PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC, glProgramPathFragmentInputGenNV))
+ return false;
+
// Do not check for DSA as the string may not be exposed on ES
// drivers, yet the functions we need are resolvable.
#if 0
@@ -199,8 +205,6 @@ bool QQuickNvprFunctions::createFragmentOnlyPipeline(const char *fragmentShaderS
return true;
}
-#define PROC(type, name) reinterpret_cast<type>(ctx->getProcAddress(#name))
-
bool QQuickNvprFunctionsPrivate::resolve()
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
diff --git a/src/imports/shapes/qquickshape.cpp b/src/imports/shapes/qquickshape.cpp
index 1054af30de..b8a138507a 100644
--- a/src/imports/shapes/qquickshape.cpp
+++ b/src/imports/shapes/qquickshape.cpp
@@ -77,50 +77,6 @@ QQuickShapeStrokeFillParams::QQuickShapeStrokeFillParams()
dashPattern << 4 << 2; // 4 * strokeWidth dash followed by 2 * strokeWidth space
}
-QPainterPath QQuickShapePathCommands::toPainterPath() const
-{
- QPainterPath p;
- int coordIdx = 0;
- for (int i = 0; i < cmd.count(); ++i) {
- switch (cmd[i]) {
- case QQuickShapePathCommands::MoveTo:
- p.moveTo(coords[coordIdx], coords[coordIdx + 1]);
- coordIdx += 2;
- break;
- case QQuickShapePathCommands::LineTo:
- p.lineTo(coords[coordIdx], coords[coordIdx + 1]);
- coordIdx += 2;
- break;
- case QQuickShapePathCommands::QuadTo:
- p.quadTo(coords[coordIdx], coords[coordIdx + 1],
- coords[coordIdx + 2], coords[coordIdx + 3]);
- coordIdx += 4;
- break;
- case QQuickShapePathCommands::CubicTo:
- p.cubicTo(coords[coordIdx], coords[coordIdx + 1],
- coords[coordIdx + 2], coords[coordIdx + 3],
- coords[coordIdx + 4], coords[coordIdx + 5]);
- coordIdx += 6;
- break;
- case QQuickShapePathCommands::ArcTo:
- // does not map to the QPainterPath API; reuse the helper code from QQuickSvgParser
- QQuickSvgParser::pathArc(p,
- coords[coordIdx], coords[coordIdx + 1], // radius
- coords[coordIdx + 2], // xAxisRotation
- !qFuzzyIsNull(coords[coordIdx + 6]), // useLargeArc
- !qFuzzyIsNull(coords[coordIdx + 5]), // sweep flag
- coords[coordIdx + 3], coords[coordIdx + 4], // end
- p.currentPosition().x(), p.currentPosition().y());
- coordIdx += 7;
- break;
- default:
- qWarning("Unknown JS path command: %d", cmd[i]);
- break;
- }
- }
- return p;
-}
-
/*!
\qmltype ShapePath
\instantiates QQuickShapePath
@@ -131,7 +87,7 @@ QPainterPath QQuickShapePathCommands::toPainterPath() const
\brief Describes a Path and associated properties for stroking and filling
\since 5.10
- A Shape contains one or more ShapePath elements. At least one ShapePath is
+ A \l Shape contains one or more ShapePath elements. At least one ShapePath is
necessary in order to have a Shape output anything visible. A ShapePath
itself is a \l Path with additional properties describing the stroking and
filling parameters, such as the stroke width and color, the fill color or
@@ -171,6 +127,8 @@ QPainterPath QQuickShapePathCommands::toPainterPath() const
of 2 (ShapePath.RoundJoin):
\image visualpath-code-example.png
+
+ \sa {Qt Quick Examples - Shapes}, Shape
*/
QQuickShapePathPrivate::QQuickShapePathPrivate()
@@ -593,27 +551,6 @@ void QQuickShapePath::resetFillGradient()
useful since it allows adding visual items, like \l Rectangle or \l Image,
and non-visual objects, like \l Timer directly as children of Shape.
- \note It is important to be aware of performance implications, in particular
- when the application is running on the generic Shape implementation due to
- not having support for accelerated path rendering. The geometry generation
- happens entirely on the CPU in this case, and this is potentially
- expensive. Changing the set of path elements, changing the properties of
- these elements, or changing certain properties of the Shape itself all lead
- to retriangulation of the affected elements on every change. Therefore,
- applying animation to such properties can affect performance on less
- powerful systems. If animating properties other than stroke and fill colors
- is a must, it is recommended to target systems providing
- \c{GL_NV_path_rendering} where the cost of path property changes is much
- smaller.
-
- \note However, the data-driven, declarative nature of the Shape API often
- means better cacheability for the underlying CPU and GPU resources. A
- property change in one ShapePath will only lead to reprocessing the affected
- ShapePath, leaving other parts of the Shape unchanged. Therefore, a heavily
- changing (for example, animating) property can often result in a lower
- overall system load than with imperative painting approaches (for example,
- QPainter).
-
The following list summarizes the available Shape rendering approaches:
\list
@@ -634,12 +571,47 @@ void QQuickShapePath::resetFillGradient()
\endlist
- \sa Path, PathMove, PathLine, PathQuad, PathCubic, PathArc, PathSvg
+ When using Shape, it is important to be aware of potential performance
+ implications:
+
+ \li When the application is running with the generic, triangulation-based
+ Shape implementation, the geometry generation happens entirely on the
+ CPU. This is potentially expensive. Changing the set of path elements,
+ changing the properties of these elements, or changing certain properties of
+ the Shape itself all lead to retriangulation of the affected paths on every
+ change. Therefore, applying animation to such properties can affect
+ performance on less powerful systems.
+
+ \li However, the data-driven, declarative nature of the Shape API often
+ means better cacheability for the underlying CPU and GPU resources. A
+ property change in one ShapePath will only lead to reprocessing the affected
+ ShapePath, leaving other parts of the Shape unchanged. Therefore, a
+ frequently changing property can still result in a lower overall system load
+ than with imperative painting approaches (for example, QPainter).
+
+ \li If animating properties other than stroke and fill colors is a must, it
+ is recommended to target systems providing \c{GL_NV_path_rendering} where
+ the cost of property changes is smaller.
+
+ \li At the same time, attention must be paid to the number of Shape elements
+ in the scene, in particular when using this special accelerated approach for
+ \c{GL_NV_path_rendering}. The way such a Shape item is represented in the
+ scene graph is different from an ordinary geometry-based item, and incurs a
+ certain cost when it comes to OpenGL state changes.
+
+ \li As a general rule, scenes should avoid using separate Shape items when
+ it is not absolutely necessary. Prefer using one Shape item with multiple
+ ShapePath elements over multiple Shape items. Scenes that cannot avoid using
+ a large number of individual Shape items should consider setting
+ Shape.vendorExtensionsEnabled to \c false.
+
+ \endlist
+
+ \sa {Qt Quick Examples - Shapes}, Path, PathMove, PathLine, PathQuad, PathCubic, PathArc, PathSvg
*/
QQuickShapePrivate::QQuickShapePrivate()
- : componentComplete(true),
- spChanged(false),
+ : spChanged(false),
rendererType(QQuickShape::UnknownRenderer),
async(false),
status(QQuickShape::Null),
@@ -799,7 +771,7 @@ static void vpe_append(QQmlListProperty<QObject> *property, QObject *obj)
QQuickShapePrivate *d = QQuickShapePrivate::get(item);
QQuickShapePath *path = qobject_cast<QQuickShapePath *>(obj);
if (path)
- d->qmlData.sp.append(path);
+ d->sp.append(path);
QQuickItemPrivate::data_append(property, obj);
@@ -814,10 +786,10 @@ static void vpe_clear(QQmlListProperty<QObject> *property)
QQuickShape *item = static_cast<QQuickShape *>(property->object);
QQuickShapePrivate *d = QQuickShapePrivate::get(item);
- for (QQuickShapePath *p : d->qmlData.sp)
+ for (QQuickShapePath *p : d->sp)
QObject::disconnect(p, SIGNAL(shapePathChanged()), item, SLOT(_q_shapePathChanged()));
- d->qmlData.sp.clear();
+ d->sp.clear();
QQuickItemPrivate::data_clear(property);
@@ -847,16 +819,16 @@ QQmlListProperty<QObject> QQuickShape::data()
void QQuickShape::classBegin()
{
- Q_D(QQuickShape);
- d->componentComplete = false;
+ QQuickItem::classBegin();
}
void QQuickShape::componentComplete()
{
Q_D(QQuickShape);
- d->componentComplete = true;
- for (QQuickShapePath *p : d->qmlData.sp)
+ QQuickItem::componentComplete();
+
+ for (QQuickShapePath *p : d->sp)
connect(p, SIGNAL(shapePathChanged()), this, SLOT(_q_shapePathChanged()));
d->_q_shapePathChanged();
@@ -994,65 +966,37 @@ void QQuickShapePrivate::sync()
renderer->setAsyncCallback(q_asyncShapeReady, this);
}
- if (!jsData.isValid()) {
- // Standard route: The path and stroke/fill parameters are provided via
- // QML elements.
- const int count = qmlData.sp.count();
- renderer->beginSync(count);
-
- for (int i = 0; i < count; ++i) {
- QQuickShapePath *p = qmlData.sp[i];
- int &dirty(QQuickShapePathPrivate::get(p)->dirty);
-
- if (dirty & QQuickShapePathPrivate::DirtyPath)
- renderer->setPath(i, p);
- if (dirty & QQuickShapePathPrivate::DirtyStrokeColor)
- renderer->setStrokeColor(i, p->strokeColor());
- if (dirty & QQuickShapePathPrivate::DirtyStrokeWidth)
- renderer->setStrokeWidth(i, p->strokeWidth());
- if (dirty & QQuickShapePathPrivate::DirtyFillColor)
- renderer->setFillColor(i, p->fillColor());
- if (dirty & QQuickShapePathPrivate::DirtyFillRule)
- renderer->setFillRule(i, p->fillRule());
- if (dirty & QQuickShapePathPrivate::DirtyStyle) {
- renderer->setJoinStyle(i, p->joinStyle(), p->miterLimit());
- renderer->setCapStyle(i, p->capStyle());
- }
- if (dirty & QQuickShapePathPrivate::DirtyDash)
- renderer->setStrokeStyle(i, p->strokeStyle(), p->dashOffset(), p->dashPattern());
- if (dirty & QQuickShapePathPrivate::DirtyFillGradient)
- renderer->setFillGradient(i, p->fillGradient());
-
- dirty = 0;
+ const int count = sp.count();
+ renderer->beginSync(count);
+
+ for (int i = 0; i < count; ++i) {
+ QQuickShapePath *p = sp[i];
+ int &dirty(QQuickShapePathPrivate::get(p)->dirty);
+
+ if (dirty & QQuickShapePathPrivate::DirtyPath)
+ renderer->setPath(i, p);
+ if (dirty & QQuickShapePathPrivate::DirtyStrokeColor)
+ renderer->setStrokeColor(i, p->strokeColor());
+ if (dirty & QQuickShapePathPrivate::DirtyStrokeWidth)
+ renderer->setStrokeWidth(i, p->strokeWidth());
+ if (dirty & QQuickShapePathPrivate::DirtyFillColor)
+ renderer->setFillColor(i, p->fillColor());
+ if (dirty & QQuickShapePathPrivate::DirtyFillRule)
+ renderer->setFillRule(i, p->fillRule());
+ if (dirty & QQuickShapePathPrivate::DirtyStyle) {
+ renderer->setJoinStyle(i, p->joinStyle(), p->miterLimit());
+ renderer->setCapStyle(i, p->capStyle());
}
+ if (dirty & QQuickShapePathPrivate::DirtyDash)
+ renderer->setStrokeStyle(i, p->strokeStyle(), p->dashOffset(), p->dashPattern());
+ if (dirty & QQuickShapePathPrivate::DirtyFillGradient)
+ renderer->setFillGradient(i, p->fillGradient());
- renderer->endSync(useAsync);
- } else {
-
- // ### there is no public API to reach this code path atm
- Q_UNREACHABLE();
-
- // Path and stroke/fill params provided from JavaScript. This avoids
- // QObjects at the expense of not supporting changes afterwards.
- const int count = jsData.paths.count();
- renderer->beginSync(count);
-
- for (int i = 0; i < count; ++i) {
- renderer->setJSPath(i, jsData.paths[i]);
- const QQuickShapeStrokeFillParams sfp(jsData.sfp[i]);
- renderer->setStrokeColor(i, sfp.strokeColor);
- renderer->setStrokeWidth(i, sfp.strokeWidth);
- renderer->setFillColor(i, sfp.fillColor);
- renderer->setFillRule(i, sfp.fillRule);
- renderer->setJoinStyle(i, sfp.joinStyle, sfp.miterLimit);
- renderer->setCapStyle(i, sfp.capStyle);
- renderer->setStrokeStyle(i, sfp.strokeStyle, sfp.dashOffset, sfp.dashPattern);
- renderer->setFillGradient(i, sfp.fillGradient);
- }
-
- renderer->endSync(useAsync);
+ dirty = 0;
}
+ renderer->endSync(useAsync);
+
if (!useAsync)
setStatus(QQuickShape::Ready);
}
diff --git a/src/imports/shapes/qquickshape_p.h b/src/imports/shapes/qquickshape_p.h
index db0b449c6c..3a630aacbc 100644
--- a/src/imports/shapes/qquickshape_p.h
+++ b/src/imports/shapes/qquickshape_p.h
@@ -223,7 +223,7 @@ private:
class QQuickShape : public QQuickItem
{
Q_OBJECT
- Q_PROPERTY(RendererType renderer READ rendererType NOTIFY rendererChanged)
+ Q_PROPERTY(RendererType rendererType READ rendererType NOTIFY rendererChanged)
Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
Q_PROPERTY(bool vendorExtensionsEnabled READ vendorExtensionsEnabled WRITE setVendorExtensionsEnabled NOTIFY vendorExtensionsEnabledChanged)
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
diff --git a/src/imports/shapes/qquickshape_p_p.h b/src/imports/shapes/qquickshape_p_p.h
index 888488efcd..6ca752de56 100644
--- a/src/imports/shapes/qquickshape_p_p.h
+++ b/src/imports/shapes/qquickshape_p_p.h
@@ -62,39 +62,6 @@ QT_BEGIN_NAMESPACE
class QSGPlainTexture;
-struct QQuickShapePathCommands
-{
- enum Command {
- MoveTo,
- LineTo,
- QuadTo,
- CubicTo,
- ArcTo
- };
-
- QVector<Command> cmd;
- QVector<float> coords;
-
- QPainterPath toPainterPath() const;
-};
-
-struct QQuickShapeStrokeFillParams
-{
- QQuickShapeStrokeFillParams();
-
- QColor strokeColor;
- qreal strokeWidth;
- QColor fillColor;
- QQuickShapePath::FillRule fillRule;
- QQuickShapePath::JoinStyle joinStyle;
- int miterLimit;
- QQuickShapePath::CapStyle capStyle;
- QQuickShapePath::StrokeStyle strokeStyle;
- qreal dashOffset;
- QVector<qreal> dashPattern;
- QQuickShapeGradient *fillGradient;
-};
-
class QQuickAbstractPathRenderer
{
public:
@@ -110,11 +77,7 @@ public:
virtual void endSync(bool async) = 0;
virtual void setAsyncCallback(void (*)(void *), void *) { }
virtual Flags flags() const { return 0; }
- // - QML API
virtual void setPath(int index, const QQuickPath *path) = 0;
- // - JS API
- virtual void setJSPath(int index, const QQuickShapePathCommands &path) = 0;
- // - stroke/fill parameters
virtual void setStrokeColor(int index, const QColor &color) = 0;
virtual void setStrokeWidth(int index, qreal w) = 0;
virtual void setFillColor(int index, const QColor &color) = 0;
@@ -131,6 +94,23 @@ public:
Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickAbstractPathRenderer::Flags)
+struct QQuickShapeStrokeFillParams
+{
+ QQuickShapeStrokeFillParams();
+
+ QColor strokeColor;
+ qreal strokeWidth;
+ QColor fillColor;
+ QQuickShapePath::FillRule fillRule;
+ QQuickShapePath::JoinStyle joinStyle;
+ int miterLimit;
+ QQuickShapePath::CapStyle capStyle;
+ QQuickShapePath::StrokeStyle strokeStyle;
+ qreal dashOffset;
+ QVector<qreal> dashPattern;
+ QQuickShapeGradient *fillGradient;
+};
+
class QQuickShapePathPrivate : public QQuickPathPrivate
{
Q_DECLARE_PUBLIC(QQuickShapePath)
@@ -177,63 +157,15 @@ public:
static QQuickShapePrivate *get(QQuickShape *item) { return item->d_func(); }
- bool componentComplete;
bool spChanged;
QQuickShape::RendererType rendererType;
bool async;
QQuickShape::Status status;
QQuickAbstractPathRenderer *renderer;
-
- struct {
- QVector<QQuickShapePath *> sp;
- } qmlData;
-
- struct {
- bool isValid() const { Q_ASSERT(paths.count() == sfp.count()); return !paths.isEmpty(); }
- QVector<QQuickShapePathCommands> paths;
- QVector<QQuickShapeStrokeFillParams> sfp;
- } jsData;
-
+ QVector<QQuickShapePath *> sp;
bool enableVendorExts;
};
-class QQuickShapePathObject : public QObject
-{
- Q_OBJECT
-
-public:
- QQuickShapePathObject(QObject *parent = nullptr) : QObject(parent) { }
-
- void setV4Engine(QV4::ExecutionEngine *engine);
- QV4::ReturnedValue v4value() const { return m_v4value.value(); }
-
- QQuickShapePath path;
-
- void clear();
-
-private:
- QV4::PersistentValue m_v4value;
-};
-
-class QQuickShapeStrokeFillParamsObject : public QObject
-{
- Q_OBJECT
-
-public:
- QQuickShapeStrokeFillParamsObject(QObject *parent = nullptr) : QObject(parent) { }
-
- void setV4Engine(QV4::ExecutionEngine *engine);
- QV4::ReturnedValue v4value() const { return m_v4value.value(); }
-
- QQuickShapeStrokeFillParams sfp;
- QV4::PersistentValue v4fillGradient;
-
- void clear();
-
-private:
- QV4::PersistentValue m_v4value;
-};
-
#if QT_CONFIG(opengl)
class QQuickShapeGradientCache : public QOpenGLSharedResource
diff --git a/src/imports/shapes/qquickshapegenericrenderer.cpp b/src/imports/shapes/qquickshapegenericrenderer.cpp
index ca5f2a0e91..398106af3d 100644
--- a/src/imports/shapes/qquickshapegenericrenderer.cpp
+++ b/src/imports/shapes/qquickshapegenericrenderer.cpp
@@ -178,13 +178,6 @@ void QQuickShapeGenericRenderer::setPath(int index, const QQuickPath *path)
d.syncDirty |= DirtyFillGeom | DirtyStrokeGeom;
}
-void QQuickShapeGenericRenderer::setJSPath(int index, const QQuickShapePathCommands &path)
-{
- ShapePathData &d(m_sp[index]);
- d.path = path.toPainterPath();
- d.syncDirty |= DirtyFillGeom | DirtyStrokeGeom;
-}
-
void QQuickShapeGenericRenderer::setStrokeColor(int index, const QColor &color)
{
ShapePathData &d(m_sp[index]);
@@ -703,9 +696,9 @@ QSGMaterialType QQuickShapeLinearGradientShader::type;
QQuickShapeLinearGradientShader::QQuickShapeLinearGradientShader()
{
setShaderSourceFile(QOpenGLShader::Vertex,
- QStringLiteral(":/qt-project.org/items/shaders/lineargradient.vert"));
+ QStringLiteral(":/qt-project.org/shapes/shaders/lineargradient.vert"));
setShaderSourceFile(QOpenGLShader::Fragment,
- QStringLiteral(":/qt-project.org/items/shaders/lineargradient.frag"));
+ QStringLiteral(":/qt-project.org/shapes/shaders/lineargradient.frag"));
}
void QQuickShapeLinearGradientShader::initialize()
diff --git a/src/imports/shapes/qquickshapegenericrenderer_p.h b/src/imports/shapes/qquickshapegenericrenderer_p.h
index 1f36e3decf..dadeba3467 100644
--- a/src/imports/shapes/qquickshapegenericrenderer_p.h
+++ b/src/imports/shapes/qquickshapegenericrenderer_p.h
@@ -88,7 +88,6 @@ public:
void beginSync(int totalCount) override;
void setPath(int index, const QQuickPath *path) override;
- void setJSPath(int index, const QQuickShapePathCommands &path) override;
void setStrokeColor(int index, const QColor &color) override;
void setStrokeWidth(int index, qreal w) override;
void setFillColor(int index, const QColor &color) override;
diff --git a/src/imports/shapes/qquickshapenvprrenderer.cpp b/src/imports/shapes/qquickshapenvprrenderer.cpp
index f3f8d807ec..a859ca45b6 100644
--- a/src/imports/shapes/qquickshapenvprrenderer.cpp
+++ b/src/imports/shapes/qquickshapenvprrenderer.cpp
@@ -62,14 +62,6 @@ void QQuickShapeNvprRenderer::setPath(int index, const QQuickPath *path)
m_accDirty |= DirtyPath;
}
-void QQuickShapeNvprRenderer::setJSPath(int index, const QQuickShapePathCommands &path)
-{
- ShapePathGuiData &d(m_sp[index]);
- convertJSPath(path, &d);
- d.dirty |= DirtyPath;
- m_accDirty |= DirtyPath;
-}
-
void QQuickShapeNvprRenderer::setStrokeColor(int index, const QColor &color)
{
ShapePathGuiData &d(m_sp[index]);
@@ -296,82 +288,6 @@ void QQuickShapeNvprRenderer::convertPath(const QQuickPath *path, ShapePathGuiDa
d->path.cmd.append(GL_CLOSE_PATH_NV);
}
-void QQuickShapeNvprRenderer::convertJSPath(const QQuickShapePathCommands &path, ShapePathGuiData *d)
-{
- d->path = NvprPath();
- if (path.cmd.isEmpty())
- return;
-
- QPointF startPos(0, 0);
- QPointF pos(startPos);
- int coordIdx = 0;
-
- for (QQuickShapePathCommands::Command cmd : path.cmd) {
- switch (cmd) {
- case QQuickShapePathCommands::MoveTo:
- d->path.cmd.append(GL_MOVE_TO_NV);
- pos = QPointF(path.coords[coordIdx], path.coords[coordIdx + 1]);
- startPos = pos;
- d->path.coord.append(pos.x());
- d->path.coord.append(pos.y());
- coordIdx += 2;
- break;
- case QQuickShapePathCommands::LineTo:
- d->path.cmd.append(GL_LINE_TO_NV);
- pos = QPointF(path.coords[coordIdx], path.coords[coordIdx + 1]);
- d->path.coord.append(pos.x());
- d->path.coord.append(pos.y());
- coordIdx += 2;
- break;
- case QQuickShapePathCommands::QuadTo:
- d->path.cmd.append(GL_QUADRATIC_CURVE_TO_NV);
- d->path.coord.append(path.coords[coordIdx]);
- d->path.coord.append(path.coords[coordIdx + 1]);
- pos = QPointF(path.coords[coordIdx + 2], path.coords[coordIdx + 3]);
- d->path.coord.append(pos.x());
- d->path.coord.append(pos.y());
- coordIdx += 4;
- break;
- case QQuickShapePathCommands::CubicTo:
- d->path.cmd.append(GL_CUBIC_CURVE_TO_NV);
- d->path.coord.append(path.coords[coordIdx]);
- d->path.coord.append(path.coords[coordIdx + 1]);
- d->path.coord.append(path.coords[coordIdx + 2]);
- d->path.coord.append(path.coords[coordIdx + 3]);
- pos = QPointF(path.coords[coordIdx + 4], path.coords[coordIdx + 5]);
- d->path.coord.append(pos.x());
- d->path.coord.append(pos.y());
- coordIdx += 6;
- break;
- case QQuickShapePathCommands::ArcTo:
- {
- const bool sweepFlag = !qFuzzyIsNull(path.coords[coordIdx + 5]);
- const bool useLargeArc = !qFuzzyIsNull(path.coords[coordIdx + 6]);
- GLenum cmd;
- if (useLargeArc)
- cmd = sweepFlag ? GL_LARGE_CCW_ARC_TO_NV : GL_LARGE_CW_ARC_TO_NV;
- else
- cmd = sweepFlag ? GL_SMALL_CCW_ARC_TO_NV : GL_SMALL_CW_ARC_TO_NV;
- d->path.cmd.append(cmd);
- d->path.coord.append(path.coords[coordIdx]); // rx
- d->path.coord.append(path.coords[coordIdx + 1]); // ry
- d->path.coord.append(path.coords[coordIdx + 2]); // xrot
- pos = QPointF(path.coords[coordIdx + 3], path.coords[coordIdx + 4]);
- d->path.coord.append(pos.x());
- d->path.coord.append(pos.y());
- coordIdx += 7;
- }
- break;
- default:
- qWarning("Unknown JS path command: %d", cmd);
- break;
- }
- }
-
- if (pos == startPos)
- d->path.cmd.append(GL_CLOSE_PATH_NV);
-}
-
static inline QVector4D qsg_premultiply(const QColor &c, float globalOpacity)
{
const float o = c.alphaF() * globalOpacity;
@@ -454,11 +370,11 @@ void QQuickShapeNvprRenderer::updateNode()
}
if (dirty & DirtyDash) {
- dst.dashOffset = src.dashOffset;
+ // Multiply by strokeWidth because the Shape API follows QPen
+ // meaning the input dash pattern and dash offset here are in width units.
+ dst.dashOffset = src.dashOffset * src.strokeWidth;
if (src.dashActive) {
dst.dashPattern.resize(src.dashPattern.count());
- // Multiply by strokeWidth because the Shape API follows QPen
- // meaning the input dash pattern here is in width units.
for (int i = 0; i < src.dashPattern.count(); ++i)
dst.dashPattern[i] = GLfloat(src.dashPattern[i]) * src.strokeWidth;
} else {
@@ -835,11 +751,11 @@ bool QQuickNvprBlitter::create()
m_program = new QOpenGLShaderProgram;
if (QOpenGLContext::currentContext()->format().profile() == QSurfaceFormat::CoreProfile) {
- m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/items/shaders/shadereffect_core.vert"));
- m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/items/shaders/shadereffect_core.frag"));
+ m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/shapes/shaders/blit_core.vert"));
+ m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/shapes/shaders/blit_core.frag"));
} else {
- m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/items/shaders/shadereffect.vert"));
- m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/items/shaders/shadereffect.frag"));
+ m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/shapes/shaders/blit.vert"));
+ m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/shapes/shaders/blit.frag"));
}
m_program->bindAttributeLocation("qt_Vertex", 0);
m_program->bindAttributeLocation("qt_MultiTexCoord0", 1);
diff --git a/src/imports/shapes/qquickshapenvprrenderer_p.h b/src/imports/shapes/qquickshapenvprrenderer_p.h
index ec7ba498f9..7eb2924ab7 100644
--- a/src/imports/shapes/qquickshapenvprrenderer_p.h
+++ b/src/imports/shapes/qquickshapenvprrenderer_p.h
@@ -81,7 +81,6 @@ public:
void beginSync(int totalCount) override;
void setPath(int index, const QQuickPath *path) override;
- void setJSPath(int index, const QQuickShapePathCommands &path) override;
void setStrokeColor(int index, const QColor &color) override;
void setStrokeWidth(int index, qreal w) override;
void setFillColor(int index, const QColor &color) override;
@@ -122,7 +121,6 @@ private:
};
void convertPath(const QQuickPath *path, ShapePathGuiData *d);
- void convertJSPath(const QQuickShapePathCommands &path, ShapePathGuiData *d);
QQuickShapeNvprRenderNode *m_node = nullptr;
int m_accDirty = 0;
diff --git a/src/imports/shapes/qquickshapesoftwarerenderer.cpp b/src/imports/shapes/qquickshapesoftwarerenderer.cpp
index b3373106af..4e6e758697 100644
--- a/src/imports/shapes/qquickshapesoftwarerenderer.cpp
+++ b/src/imports/shapes/qquickshapesoftwarerenderer.cpp
@@ -58,14 +58,6 @@ void QQuickShapeSoftwareRenderer::setPath(int index, const QQuickPath *path)
m_accDirty |= DirtyPath;
}
-void QQuickShapeSoftwareRenderer::setJSPath(int index, const QQuickShapePathCommands &path)
-{
- ShapePathGuiData &d(m_sp[index]);
- d.path = path.toPainterPath();
- d.dirty |= DirtyPath;
- m_accDirty |= DirtyPath;
-}
-
void QQuickShapeSoftwareRenderer::setStrokeColor(int index, const QColor &color)
{
ShapePathGuiData &d(m_sp[index]);
diff --git a/src/imports/shapes/qquickshapesoftwarerenderer_p.h b/src/imports/shapes/qquickshapesoftwarerenderer_p.h
index 53982ce347..0abc2e37b0 100644
--- a/src/imports/shapes/qquickshapesoftwarerenderer_p.h
+++ b/src/imports/shapes/qquickshapesoftwarerenderer_p.h
@@ -73,7 +73,6 @@ public:
void beginSync(int totalCount) override;
void setPath(int index, const QQuickPath *path) override;
- void setJSPath(int index, const QQuickShapePathCommands &path) override;
void setStrokeColor(int index, const QColor &color) override;
void setStrokeWidth(int index, qreal w) override;
void setFillColor(int index, const QColor &color) override;
diff --git a/src/imports/shapes/shaders/blit.frag b/src/imports/shapes/shaders/blit.frag
new file mode 100644
index 0000000000..505f0db179
--- /dev/null
+++ b/src/imports/shapes/shaders/blit.frag
@@ -0,0 +1,9 @@
+varying highp vec2 qt_TexCoord0;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+
+void main()
+{
+ gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;
+}
diff --git a/src/imports/shapes/shaders/blit.vert b/src/imports/shapes/shaders/blit.vert
new file mode 100644
index 0000000000..f8306bd945
--- /dev/null
+++ b/src/imports/shapes/shaders/blit.vert
@@ -0,0 +1,12 @@
+uniform highp mat4 qt_Matrix;
+
+attribute highp vec4 qt_Vertex;
+attribute highp vec2 qt_MultiTexCoord0;
+
+varying highp vec2 qt_TexCoord0;
+
+void main()
+{
+ qt_TexCoord0 = qt_MultiTexCoord0;
+ gl_Position = qt_Matrix * qt_Vertex;
+}
diff --git a/src/imports/shapes/shaders/blit_core.frag b/src/imports/shapes/shaders/blit_core.frag
new file mode 100644
index 0000000000..7073808fba
--- /dev/null
+++ b/src/imports/shapes/shaders/blit_core.frag
@@ -0,0 +1,13 @@
+#version 150 core
+
+in vec2 qt_TexCoord0;
+
+out vec4 fragColor;
+
+uniform sampler2D source;
+uniform float qt_Opacity;
+
+void main()
+{
+ fragColor = texture(source, qt_TexCoord0) * qt_Opacity;
+}
diff --git a/src/imports/shapes/shaders/blit_core.vert b/src/imports/shapes/shaders/blit_core.vert
new file mode 100644
index 0000000000..5246441da3
--- /dev/null
+++ b/src/imports/shapes/shaders/blit_core.vert
@@ -0,0 +1,14 @@
+#version 150 core
+
+in vec4 qt_Vertex;
+in vec2 qt_MultiTexCoord0;
+
+out vec2 qt_TexCoord0;
+
+uniform mat4 qt_Matrix;
+
+void main()
+{
+ qt_TexCoord0 = qt_MultiTexCoord0;
+ gl_Position = qt_Matrix * qt_Vertex;
+}
diff --git a/src/imports/shapes/shaders/lineargradient.frag b/src/imports/shapes/shaders/lineargradient.frag
new file mode 100644
index 0000000000..7f4a739109
--- /dev/null
+++ b/src/imports/shapes/shaders/lineargradient.frag
@@ -0,0 +1,9 @@
+uniform sampler2D gradTabTexture;
+uniform highp float opacity;
+
+varying highp float gradTabIndex;
+
+void main()
+{
+ gl_FragColor = texture2D(gradTabTexture, vec2(gradTabIndex, 0.5)) * opacity;
+}
diff --git a/src/imports/shapes/shaders/lineargradient.vert b/src/imports/shapes/shaders/lineargradient.vert
new file mode 100644
index 0000000000..eb21b8886b
--- /dev/null
+++ b/src/imports/shapes/shaders/lineargradient.vert
@@ -0,0 +1,15 @@
+attribute vec4 vertexCoord;
+attribute vec4 vertexColor;
+
+uniform mat4 matrix;
+uniform vec2 gradStart;
+uniform vec2 gradEnd;
+
+varying float gradTabIndex;
+
+void main()
+{
+ vec2 gradVec = gradEnd - gradStart;
+ gradTabIndex = dot(gradVec, vertexCoord.xy - gradStart) / (gradVec.x * gradVec.x + gradVec.y * gradVec.y);
+ gl_Position = matrix * vertexCoord;
+}
diff --git a/src/imports/shapes/shaders/lineargradient_core.frag b/src/imports/shapes/shaders/lineargradient_core.frag
new file mode 100644
index 0000000000..5908acfa67
--- /dev/null
+++ b/src/imports/shapes/shaders/lineargradient_core.frag
@@ -0,0 +1,12 @@
+#version 150 core
+
+uniform sampler2D gradTabTexture;
+uniform float opacity;
+
+in float gradTabIndex;
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = texture(gradTabTexture, vec2(gradTabIndex, 0.5)) * opacity;
+}
diff --git a/src/imports/shapes/shaders/lineargradient_core.vert b/src/imports/shapes/shaders/lineargradient_core.vert
new file mode 100644
index 0000000000..60b56f38e3
--- /dev/null
+++ b/src/imports/shapes/shaders/lineargradient_core.vert
@@ -0,0 +1,17 @@
+#version 150 core
+
+in vec4 vertexCoord;
+in vec4 vertexColor;
+
+uniform mat4 matrix;
+uniform vec2 gradStart;
+uniform vec2 gradEnd;
+
+out float gradTabIndex;
+
+void main()
+{
+ vec2 gradVec = gradEnd - gradStart;
+ gradTabIndex = dot(gradVec, vertexCoord.xy - gradStart) / (gradVec.x * gradVec.x + gradVec.y * gradVec.y);
+ gl_Position = matrix * vertexCoord;
+}
diff --git a/src/imports/shapes/shapes.pro b/src/imports/shapes/shapes.pro
index 80e6a22142..4406474c3f 100644
--- a/src/imports/shapes/shapes.pro
+++ b/src/imports/shapes/shapes.pro
@@ -28,4 +28,6 @@ qtConfig(opengl) {
qquickshapenvprrenderer.cpp
}
+RESOURCES += shapes.qrc
+
load(qml_plugin)
diff --git a/src/imports/shapes/shapes.qrc b/src/imports/shapes/shapes.qrc
new file mode 100644
index 0000000000..65ee2007f9
--- /dev/null
+++ b/src/imports/shapes/shapes.qrc
@@ -0,0 +1,12 @@
+<RCC>
+ <qresource prefix="/qt-project.org/shapes">
+ <file>shaders/blit.vert</file>
+ <file>shaders/blit.frag</file>
+ <file>shaders/blit_core.frag</file>
+ <file>shaders/blit_core.vert</file>
+ <file>shaders/lineargradient.vert</file>
+ <file>shaders/lineargradient.frag</file>
+ <file>shaders/lineargradient_core.vert</file>
+ <file>shaders/lineargradient_core.frag</file>
+ </qresource>
+</RCC>