5#include <QtGui/private/qtriangulator_p.h>
6#include <QtGui/private/qtriangulatingstroker_p.h>
8#include <QSGVertexColorMaterial>
29 c.getRgbF(&
r, &
g, &
b, &
a);
45#ifdef QSG_RUNTIME_DESCRIPTION
78 for (ShapePathData &
d : m_sp) {
80 d.pendingFill->orphaned =
true;
82 d.pendingStroke->orphaned =
true;
91 if (m_sp.size() != totalCount) {
92 m_sp.resize(totalCount);
96 *countChanged =
false;
98 for (ShapePathData &
d : m_sp)
104 ShapePathData &
d(m_sp[
index]);
111 ShapePathData &
d(m_sp[
index]);
112 const bool wasTransparent =
d.strokeColor.a == 0;
114 const bool isTransparent =
d.strokeColor.a == 0;
116 if (wasTransparent && !isTransparent)
122 ShapePathData &
d(m_sp[
index]);
131 ShapePathData &
d(m_sp[
index]);
132 const bool wasTransparent =
d.fillColor.a == 0;
134 const bool isTransparent =
d.fillColor.a == 0;
136 if (wasTransparent && !isTransparent)
142 ShapePathData &
d(m_sp[
index]);
149 ShapePathData &
d(m_sp[
index]);
151 d.pen.setMiterLimit(miterLimit);
157 ShapePathData &
d(m_sp[
index]);
165 ShapePathData &
d(m_sp[
index]);
168 d.pen.setDashPattern(dashPattern);
169 d.pen.setDashOffset(dashOffset);
176 ShapePathData &
d(m_sp[
index]);
179 d.fillGradient.spread = gradient->
spread();
186 d.fillGradient.a =
QPointF(
g->centerX(),
g->centerY());
187 d.fillGradient.b =
QPointF(
g->focalX(),
g->focalY());
188 d.fillGradient.v0 =
g->centerRadius();
189 d.fillGradient.v1 =
g->focalRadius();
192 d.fillGradient.a =
QPointF(
g->centerX(),
g->centerY());
193 d.fillGradient.v0 =
g->angle();
206 m_triangulationScale =
scale;
224 m_asyncCallback = callback;
225 m_asyncCallbackData =
data;
231static void deletePathWorkThreadPool()
233 delete pathWorkThreadPool;
234 pathWorkThreadPool =
nullptr;
240#if !QT_CONFIG(thread)
246 bool didKickOffAsync =
false;
248 for (
int i = 0;
i < m_sp.size(); ++
i) {
249 ShapePathData &
d(m_sp[
i]);
253 m_accDirty |=
d.syncDirty;
260 d.effectiveDirty |=
d.syncDirty;
262 if (
d.path.isEmpty()) {
263 d.fillVertices.clear();
264 d.fillIndices.clear();
265 d.strokeVertices.clear();
270 if (async && !pathWorkThreadPool) {
284 static bool supportsElementIndexUint = testFeatureIndexUint(m_item);
286 d.path.setFillRule(
d.fillRule);
293 d.pendingFill->orphaned =
true;
296 r->fillColor =
d.fillColor;
297 r->supportsElementIndexUint = supportsElementIndexUint;
298 r->triangulationScale = m_triangulationScale;
304 if (!
r->orphaned &&
i < m_sp.size()) {
305 ShapePathData &d(m_sp[i]);
306 d.fillVertices = r->fillVertices;
307 d.fillIndices = r->fillIndices;
308 d.indexType = r->indexType;
309 d.pendingFill = nullptr;
310 d.effectiveDirty |= DirtyFillGeom;
311 maybeUpdateAsyncItem();
315 didKickOffAsync =
true;
320 pathWorkThreadPool->
start(
r);
324 supportsElementIndexUint,
325 m_triangulationScale);
334 d.pendingStroke->orphaned =
true;
338 r->strokeColor =
d.strokeColor;
340 r->triangulationScale = m_triangulationScale;
342 if (!
r->orphaned &&
i < m_sp.size()) {
343 ShapePathData &d(m_sp[i]);
344 d.strokeVertices = r->strokeVertices;
345 d.pendingStroke = nullptr;
346 d.effectiveDirty |= DirtyStrokeGeom;
347 maybeUpdateAsyncItem();
351 didKickOffAsync =
true;
356 pathWorkThreadPool->
start(
r);
365 if (!didKickOffAsync && async && m_asyncCallback)
366 m_asyncCallback(m_asyncCallbackData);
369void QQuickShapeGenericRenderer::maybeUpdateAsyncItem()
371 for (
const ShapePathData &
d :
std::as_const(m_sp)) {
372 if (
d.pendingFill ||
d.pendingStroke)
378 m_asyncCallback(m_asyncCallbackData);
388 bool supportsElementIndexUint,
389 qreal triangulationScale)
395 fillVertices->
resize(vertexCount);
398 for (
int i = 0;
i < vertexCount; ++
i)
399 vdst[
i].
set(vsrc[
i * 2] / triangulationScale, vsrc[
i * 2 + 1] / triangulationScale, fillColor);
401 size_t indexByteSize;
420 const QSize &clipSize,
421 qreal triangulationScale)
425 const qreal inverseScale = 1.0 / triangulationScale;
431 stroker.
process(vp, pen, clip, {});
435 dashStroker.
process(vp, pen, clip, {});
438 stroker.
process(dashStroke, pen, clip, {});
442 strokeVertices->
clear();
447 strokeVertices->
resize(vertexCount);
449 const float *vsrc = stroker.
vertices();
450 for (
int i = 0;
i < vertexCount; ++
i)
451 vdst[
i].
set(vsrc[
i * 2], vsrc[
i * 2 + 1], strokeColor);
456 if (m_rootNode != node) {
465 if (!m_rootNode || !m_accDirty)
481 for (ShapePathData &
d : m_sp) {
485 prevNode->
m_next = *nodePtr;
494 if (!
d.effectiveDirty) {
500 if (
d.fillColor.a == 0) {
513 if (
d.strokeWidth < 0.0f ||
d.strokeColor.a == 0) {
522 updateFillNode(&
d, node);
523 updateStrokeNode(&
d, node);
525 d.effectiveDirty = 0;
531 if (*nodePtr && prevNode) {
542 if (
d->fillGradientActive) {
544 n->m_fillGradient =
d->fillGradient;
558 updateShadowDataInNode(
d,
n);
561 if (
d->fillVertices.isEmpty()) {
562 if (
g->vertexCount() ||
g->indexCount()) {
569 if (
d->fillGradientActive) {
571 switch (
d->fillGradientActive) {
582 Q_UNREACHABLE_RETURN();
584 n->activateMaterial(m_item->
window(), gradMat);
597 for (
int i = 0;
i <
g->vertexCount(); ++
i)
598 vdst[
i].
set(vdst[
i].
x, vdst[
i].
y,
d->fillColor);
605 ?
d->fillIndices.size() * 2 :
d->fillIndices.size();
606 if (
g->indexType() !=
d->indexType) {
608 d->fillVertices.size(), indexCount,
d->indexType);
611 g->allocate(
d->fillVertices.size(), indexCount);
614 memcpy(
g->vertexData(),
d->fillVertices.constData(),
g->vertexCount() *
g->sizeOfVertex());
615 memcpy(
g->indexData(),
d->fillIndices.constData(),
g->indexCount() *
g->sizeOfIndex());
629 if (
d->strokeVertices.isEmpty()) {
630 if (
g->vertexCount() ||
g->indexCount()) {
642 if (!
g->vertexCount())
647 for (
int i = 0;
i <
g->vertexCount(); ++
i)
648 vdst[
i].
set(vdst[
i].
x, vdst[
i].
y,
d->strokeColor);
652 g->allocate(
d->strokeVertices.size(), 0);
654 memcpy(
g->vertexData(),
d->strokeVertices.constData(),
g->vertexCount() *
g->sizeOfVertex());
664 qWarning(
"Vertex-color material: Unsupported graphics API %d", api);
676 qWarning(
"Linear gradient material: Unsupported graphics API %d", api);
688 qWarning(
"Radial gradient material: Unsupported graphics API %d", api);
700 qWarning(
"Conical gradient material: Unsupported graphics API %d", api);
713 Q_ASSERT(oldMaterial ==
nullptr || newMaterial->
type() == oldMaterial->
type());
715 bool changed =
false;
719 if (
state.isMatrixDirty()) {
721 memcpy(
buf->data(),
m.constData(), 64);
730 memcpy(
buf->data() + 64, &m_gradA, 8);
736 memcpy(
buf->data() + 72, &m_gradB, 8);
740 if (
state.isOpacityDirty()) {
741 const float opacity =
state.opacity();
742 memcpy(
buf->data() + 80, &opacity, 4);
786 if (
int d = ga->
a.
x() - gb->
a.
x())
788 if (
int d = ga->
a.
y() - gb->
a.
y())
790 if (
int d = ga->
b.
x() - gb->
b.
x())
792 if (
int d = ga->
b.
y() - gb->
b.
y())
801 if (
int d = ga->
stops[
i].second.rgba() - gb->
stops[
i].second.rgba())
823 Q_ASSERT(oldMaterial ==
nullptr || newMaterial->
type() == oldMaterial->
type());
825 bool changed =
false;
829 if (
state.isMatrixDirty()) {
831 memcpy(
buf->data(),
m.constData(), 64);
845 Q_ASSERT(
sizeof(m_focalPoint) == 8);
846 memcpy(
buf->data() + 64, &m_focalPoint, 8);
850 if (!oldMaterial || m_focalToCenter.
x() != focalToCenter.
x() || m_focalToCenter.
y() != focalToCenter.
y()) {
851 m_focalToCenter =
QVector2D(focalToCenter.
x(), focalToCenter.
y());
852 Q_ASSERT(
sizeof(m_focalToCenter) == 8);
853 memcpy(
buf->data() + 72, &m_focalToCenter, 8);
857 if (!oldMaterial || m_centerRadius != centerRadius) {
858 m_centerRadius = centerRadius;
859 memcpy(
buf->data() + 80, &m_centerRadius, 4);
863 if (!oldMaterial || m_focalRadius != focalRadius) {
864 m_focalRadius = focalRadius;
865 memcpy(
buf->data() + 84, &m_focalRadius, 4);
869 if (
state.isOpacityDirty()) {
870 const float opacity =
state.opacity();
871 memcpy(
buf->data() + 88, &opacity, 4);
915 if (
int d = ga->
a.
x() - gb->
a.
x())
917 if (
int d = ga->
a.
y() - gb->
a.
y())
919 if (
int d = ga->
b.
x() - gb->
b.
x())
921 if (
int d = ga->
b.
y() - gb->
b.
y())
924 if (
int d = ga->
v0 - gb->
v0)
926 if (
int d = ga->
v1 - gb->
v1)
935 if (
int d = ga->
stops[
i].second.rgba() - gb->
stops[
i].second.rgba())
957 Q_ASSERT(oldMaterial ==
nullptr || newMaterial->
type() == oldMaterial->
type());
959 bool changed =
false;
963 if (
state.isMatrixDirty()) {
965 memcpy(
buf->data(),
m.constData(), 64);
974 if (!oldMaterial || m_centerPoint.
x() != centerPoint.
x() || m_centerPoint.
y() != centerPoint.
y()) {
975 m_centerPoint =
QVector2D(centerPoint.
x(), centerPoint.
y());
976 Q_ASSERT(
sizeof(m_centerPoint) == 8);
977 memcpy(
buf->data() + 64, &m_centerPoint, 8);
981 if (!oldMaterial || m_angle !=
angle) {
983 memcpy(
buf->data() + 72, &m_angle, 4);
987 if (
state.isOpacityDirty()) {
988 const float opacity =
state.opacity();
989 memcpy(
buf->data() + 76, &opacity, 4);
1030 if (
int d = ga->
a.
x() - gb->
a.
x())
1032 if (
int d = ga->
a.
y() - gb->
a.
y())
1035 if (
int d = ga->
v0 - gb->
v0)
1044 if (
int d = ga->
stops[
i].second.rgba() - gb->
stops[
i].second.rgba())
1059#include "moc_qquickshapegenericrenderer_p.cpp"
The QColor class provides colors based on RGB, HSV or CMYK values.
QPainterPath::ElementType * elementTypes() const
void process(const QVectorPath &path, const QPen &pen, const QRectF &clip, QPainter::RenderHints hints)
void setInvScale(qreal invScale)
QGraphicsWidget * window() const
qsizetype size() const noexcept
const_pointer constData() const noexcept
void resize(qsizetype size)
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Qt::PenStyle style() const
Returns the pen style.
\inmodule QtCore\reentrant
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
QGradientStops gradientStops() const
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
QQuickWindow * window() const
Returns the window in which this item is rendered.
qreal width
This property holds the width of this item.
qreal height
This property holds the height of this item.
void update()
Schedules a call to updatePaintNode() for this item.
QSGMaterialType * type() const override
This function is called by the scene graph to query an identifier that is unique to the QSGMaterialSh...
int compare(const QSGMaterial *other) const override
Compares this material to other and returns 0 if they are equal; -1 if this material should sort befo...
QSGMaterialShader * createShader(QSGRendererInterface::RenderMode renderMode) const override
This function returns a new instance of a the QSGMaterialShader implementation used to render geometr...
QQuickShapeGenericStrokeFillNode * node() const
QQuickShapeConicalGradientRhiShader()
void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to prepare use of sampled images in the shader,...
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
bool supportsElementIndexUint
QQuickShapeGenericRenderer::Color4ub fillColor
QSGGeometry::Type indexType
QQuickShapeGenericRenderer::VertexContainerType fillVertices
QQuickShapeGenericRenderer::IndexContainerType fillIndices
void done(QQuickShapeFillRunnable *self)
void run() override
Implement this pure virtual function in your subclass.
static QSGMaterial * createLinearGradient(QQuickWindow *window, QQuickShapeGenericStrokeFillNode *node)
static QSGMaterial * createConicalGradient(QQuickWindow *window, QQuickShapeGenericStrokeFillNode *node)
static QSGMaterial * createVertexColor(QQuickWindow *window)
static QSGMaterial * createRadialGradient(QQuickWindow *window, QQuickShapeGenericStrokeFillNode *node)
QQuickShapeGenericStrokeFillNode * m_fillNode
QQuickShapeGenericStrokeFillNode * m_strokeNode
QQuickShapeGenericNode * m_next
void setAsyncCallback(void(*)(void *), void *) override
void setTriangulationScale(qreal scale) override
void setFillGradient(int index, QQuickShapeGradient *gradient) override
static void triangulateFill(const QPainterPath &path, const Color4ub &fillColor, VertexContainerType *fillVertices, IndexContainerType *fillIndices, QSGGeometry::Type *indexType, bool supportsElementIndexUint, qreal triangulationScale)
void setStrokeColor(int index, const QColor &color) override
void setFillRule(int index, QQuickShapePath::FillRule fillRule) override
void setFillColor(int index, const QColor &color) override
void setJoinStyle(int index, QQuickShapePath::JoinStyle joinStyle, int miterLimit) override
void setStrokeWidth(int index, qreal w) override
~QQuickShapeGenericRenderer()
void setRootNode(QQuickShapeGenericNode *node)
void beginSync(int totalCount, bool *countChanged) override
void setCapStyle(int index, QQuickShapePath::CapStyle capStyle) override
static void triangulateStroke(const QPainterPath &path, const QPen &pen, const Color4ub &strokeColor, VertexContainerType *strokeVertices, const QSize &clipSize, qreal triangulationScale)
void updateNode() override
void setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle, qreal dashOffset, const QVector< qreal > &dashPattern) override
void setPath(int index, const QQuickPath *path) override
void endSync(bool async) override
QQuickAbstractPathRenderer::GradientDesc m_fillGradient
QQuickShapeGenericStrokeFillNode(QQuickWindow *window)
void activateMaterial(QQuickWindow *window, Material m)
QSGTexture * get(const QQuickShapeGradientCacheKey &grad)
static QQuickShapeGradientCache * cacheForRhi(QRhi *rhi)
QSGMaterialShader * createShader(QSGRendererInterface::RenderMode renderMode) const override
This function returns a new instance of a the QSGMaterialShader implementation used to render geometr...
int compare(const QSGMaterial *other) const override
Compares this material to other and returns 0 if they are equal; -1 if this material should sort befo...
QSGMaterialType * type() const override
This function is called by the scene graph to query an identifier that is unique to the QSGMaterialSh...
QQuickShapeGenericStrokeFillNode * node() const
void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to prepare use of sampled images in the shader,...
QQuickShapeLinearGradientRhiShader()
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
QQuickShapeGenericStrokeFillNode * node() const
QSGMaterialType * type() const override
This function is called by the scene graph to query an identifier that is unique to the QSGMaterialSh...
QSGMaterialShader * createShader(QSGRendererInterface::RenderMode renderMode) const override
This function returns a new instance of a the QSGMaterialShader implementation used to render geometr...
int compare(const QSGMaterial *other) const override
Compares this material to other and returns 0 if they are equal; -1 if this material should sort befo...
bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to get the contents of the shader program's uniform buffer...
QQuickShapeRadialGradientRhiShader()
void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override
This function is called by the scene graph to prepare use of sampled images in the shader,...
QQuickShapeGenericRenderer::Color4ub strokeColor
QQuickShapeGenericRenderer::VertexContainerType strokeVertices
void done(QQuickShapeStrokeRunnable *self)
void run() override
Implement this pure virtual function in your subclass.
static QQuickWindowPrivate * get(QQuickWindow *c)
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
\inmodule QtCore\reentrant
void setAutoDelete(bool autoDelete)
Enables auto-deletion if autoDelete is true; otherwise auto-deletion is disabled.
void setGeometry(QSGGeometry *geometry)
Sets the geometry of this node to geometry.
QSGMaterial * material() const
Returns the material of the QSGGeometryNode.
void setMaterial(QSGMaterial *material)
Sets the material of this geometry node to material.
The QSGGeometry class provides low-level storage for graphics primitives in the \l{Qt Quick Scene Gra...
static const AttributeSet & defaultAttributes_ColoredPoint2D()
Convenience function which returns attributes to be used for per vertex colored 2D drawing.
void allocate(int vertexCount, int indexCount=0)
Resizes the vertex and index data of this geometry object to fit vertexCount vertices and indexCount ...
Type
Specifies the component type in the vertex data.
Encapsulates the current rendering state during a call to QSGMaterialShader::updateUniformData() and ...
The QSGMaterialShader class represents a graphics API independent shader program.
void setShaderFileName(Stage stage, const QString &filename)
Sets the filename for the shader for the specified stage.
The QSGMaterial class encapsulates rendering state for a shader program.
virtual QSGMaterialType * type() const =0
This function is called by the scene graph to query an identifier that is unique to the QSGMaterialSh...
void removeChildNode(QSGNode *node)
Removes node from this node's list of children.
void appendChildNode(QSGNode *node)
Appends node to this node's list of children.
void setFlag(Flag, bool=true)
Sets the flag f on this node if enabled is true; otherwise clears the flag.
RenderMode
\value RenderMode2D Normal 2D rendering \value RenderMode2DNoDepthBuffer Normal 2D rendering with dep...
static bool isApiRhiBased(GraphicsApi api)
virtual GraphicsApi graphicsApi() const =0
Returns the graphics API that is in use by the Qt Quick scenegraph.
GraphicsApi
\value Unknown An unknown graphics API is in use \value Software The Qt Quick 2D Renderer is in use \...
virtual void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
Call this function to enqueue image upload operations to resourceUpdates, in case there are any pendi...
The QSGVertexColorMaterial class provides a convenient way of rendering per-vertex colored geometry i...
T * data() const noexcept
Returns the value of the pointer referenced by this object.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
void start(QRunnable *runnable, int priority=0)
Reserves a thread and uses it to run runnable, unless this thread will make the current thread count ...
void setMaxThreadCount(int maxThreadCount)
static int idealThreadCount() noexcept
const float * vertices() const
void setInvScale(qreal invScale)
void process(const QVectorPath &path, const QPen &pen, const QRectF &clip, QPainter::RenderHints hints)
The QVector2D class represents a vector or vertex in 2D space.
constexpr float y() const noexcept
Returns the y coordinate of this point.
constexpr float x() const noexcept
Returns the x coordinate of this point.
const void * data() const
Combined button and popup list for selecting options.
void qAddPostRoutine(QtCleanUpFunction p)
int qRound(qfloat16 d) noexcept
constexpr float qDegreesToRadians(float degrees)
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLsizei const GLchar *const * path
GLenum GLenum GLenum GLenum GLenum scale
const QVectorPath & qtVectorPathForPath(const QPainterPath &path)
static QQuickShapeGenericRenderer::Color4ub colorToColor4ub(const QColor &c)
void qsgnode_set_description(QSGNode *node, const QString &description)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
Q_GUI_EXPORT QTriangleSet qTriangulate(const qreal *polygon, int count, uint hint, const QTransform &matrix, bool allowUintIndices)
QFuture< QSet< QChar > > set
[10]
void set(float nx, float ny, QQuickShapeGenericRenderer::Color4ub ncolor)
QQuickShapeGenericRenderer::Color4ub color
QQuickShapeGradient::SpreadMode spread
The QSGMaterialType class is used as a unique type token in combination with QSGMaterial.
QVertexIndexVector indices