shapes: Privately expose the tringulator scale
For many typical uses in Qt Quick the hardcoded TRI_SCALE = 1 was just fine. However, this is not quite sufficient for Qt Location's purposes since the triangulator in QtGui may run out of precision when zooming in a map and having to deal with large coordinates. To overcome this one would pass in a transform with a < 1 scale to the triangulator and then apply the same scaling in reverse to the generated vertex positions (e.g. this is what the OpenGL paint engine does). But to allow doing this, there needs to be an internal way at least, so that one can send the desired scale down to the default Shape rendering backend. Pick-to: 6.5 Change-Id: I4e7f72b79d317ebc31e9d661f4a93723854e3504 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
6ac764a4d9
commit
bcfcaeb87b
|
@ -1003,6 +1003,7 @@ void QQuickShapePrivate::sync()
|
||||||
const int count = sp.size();
|
const int count = sp.size();
|
||||||
bool countChanged = false;
|
bool countChanged = false;
|
||||||
renderer->beginSync(count, &countChanged);
|
renderer->beginSync(count, &countChanged);
|
||||||
|
renderer->setTriangulationScale(triangulationScale);
|
||||||
|
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
QQuickShapePath *p = sp[i];
|
QQuickShapePath *p = sp[i];
|
||||||
|
|
|
@ -65,6 +65,7 @@ public:
|
||||||
virtual void setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle,
|
virtual void setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle,
|
||||||
qreal dashOffset, const QVector<qreal> &dashPattern) = 0;
|
qreal dashOffset, const QVector<qreal> &dashPattern) = 0;
|
||||||
virtual void setFillGradient(int index, QQuickShapeGradient *gradient) = 0;
|
virtual void setFillGradient(int index, QQuickShapeGradient *gradient) = 0;
|
||||||
|
virtual void setTriangulationScale(qreal) { }
|
||||||
|
|
||||||
// Render thread, with gui blocked
|
// Render thread, with gui blocked
|
||||||
virtual void updateNode() = 0;
|
virtual void updateNode() = 0;
|
||||||
|
@ -150,6 +151,7 @@ public:
|
||||||
bool async = false;
|
bool async = false;
|
||||||
bool enableVendorExts = false;
|
bool enableVendorExts = false;
|
||||||
bool syncTimingActive = false;
|
bool syncTimingActive = false;
|
||||||
|
qreal triangulationScale = 1.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct QQuickShapeGradientCacheKey
|
struct QQuickShapeGradientCacheKey
|
||||||
|
|
|
@ -13,8 +13,6 @@
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
static const qreal TRI_SCALE = 1;
|
|
||||||
|
|
||||||
struct ColoredVertex // must match QSGGeometry::ColoredPoint2D
|
struct ColoredVertex // must match QSGGeometry::ColoredPoint2D
|
||||||
{
|
{
|
||||||
float x, y;
|
float x, y;
|
||||||
|
@ -198,15 +196,22 @@ void QQuickShapeGenericRenderer::setFillGradient(int index, QQuickShapeGradient
|
||||||
d.syncDirty |= DirtyFillGradient;
|
d.syncDirty |= DirtyFillGradient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QQuickShapeGenericRenderer::setTriangulationScale(qreal scale)
|
||||||
|
{
|
||||||
|
// No dirty, this is called at the start of every sync. Just store the value.
|
||||||
|
m_triangulationScale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
void QQuickShapeFillRunnable::run()
|
void QQuickShapeFillRunnable::run()
|
||||||
{
|
{
|
||||||
QQuickShapeGenericRenderer::triangulateFill(path, fillColor, &fillVertices, &fillIndices, &indexType, supportsElementIndexUint);
|
QQuickShapeGenericRenderer::triangulateFill(path, fillColor, &fillVertices, &fillIndices, &indexType,
|
||||||
|
supportsElementIndexUint, triangulationScale);
|
||||||
emit done(this);
|
emit done(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QQuickShapeStrokeRunnable::run()
|
void QQuickShapeStrokeRunnable::run()
|
||||||
{
|
{
|
||||||
QQuickShapeGenericRenderer::triangulateStroke(path, pen, strokeColor, &strokeVertices, clipSize);
|
QQuickShapeGenericRenderer::triangulateStroke(path, pen, strokeColor, &strokeVertices, clipSize, triangulationScale);
|
||||||
emit done(this);
|
emit done(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,6 +291,7 @@ void QQuickShapeGenericRenderer::endSync(bool async)
|
||||||
r->path = d.path;
|
r->path = d.path;
|
||||||
r->fillColor = d.fillColor;
|
r->fillColor = d.fillColor;
|
||||||
r->supportsElementIndexUint = supportsElementIndexUint;
|
r->supportsElementIndexUint = supportsElementIndexUint;
|
||||||
|
r->triangulationScale = m_triangulationScale;
|
||||||
// Unlikely in practice but in theory m_sp could be
|
// Unlikely in practice but in theory m_sp could be
|
||||||
// resized. Therefore, capture 'i' instead of 'd'.
|
// resized. Therefore, capture 'i' instead of 'd'.
|
||||||
QObject::connect(r, &QQuickShapeFillRunnable::done, qApp, [this, i](QQuickShapeFillRunnable *r) {
|
QObject::connect(r, &QQuickShapeFillRunnable::done, qApp, [this, i](QQuickShapeFillRunnable *r) {
|
||||||
|
@ -310,7 +316,9 @@ void QQuickShapeGenericRenderer::endSync(bool async)
|
||||||
pathWorkThreadPool->start(r);
|
pathWorkThreadPool->start(r);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
triangulateFill(d.path, d.fillColor, &d.fillVertices, &d.fillIndices, &d.indexType, supportsElementIndexUint);
|
triangulateFill(d.path, d.fillColor, &d.fillVertices, &d.fillIndices, &d.indexType,
|
||||||
|
supportsElementIndexUint,
|
||||||
|
m_triangulationScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,6 +333,7 @@ void QQuickShapeGenericRenderer::endSync(bool async)
|
||||||
r->pen = d.pen;
|
r->pen = d.pen;
|
||||||
r->strokeColor = d.strokeColor;
|
r->strokeColor = d.strokeColor;
|
||||||
r->clipSize = QSize(m_item->width(), m_item->height());
|
r->clipSize = QSize(m_item->width(), m_item->height());
|
||||||
|
r->triangulationScale = m_triangulationScale;
|
||||||
QObject::connect(r, &QQuickShapeStrokeRunnable::done, qApp, [this, i](QQuickShapeStrokeRunnable *r) {
|
QObject::connect(r, &QQuickShapeStrokeRunnable::done, qApp, [this, i](QQuickShapeStrokeRunnable *r) {
|
||||||
if (!r->orphaned && i < m_sp.size()) {
|
if (!r->orphaned && i < m_sp.size()) {
|
||||||
ShapePathData &d(m_sp[i]);
|
ShapePathData &d(m_sp[i]);
|
||||||
|
@ -344,7 +353,7 @@ void QQuickShapeGenericRenderer::endSync(bool async)
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
triangulateStroke(d.path, d.pen, d.strokeColor, &d.strokeVertices,
|
triangulateStroke(d.path, d.pen, d.strokeColor, &d.strokeVertices,
|
||||||
QSize(m_item->width(), m_item->height()));
|
QSize(m_item->width(), m_item->height()), m_triangulationScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,17 +381,18 @@ void QQuickShapeGenericRenderer::triangulateFill(const QPainterPath &path,
|
||||||
VertexContainerType *fillVertices,
|
VertexContainerType *fillVertices,
|
||||||
IndexContainerType *fillIndices,
|
IndexContainerType *fillIndices,
|
||||||
QSGGeometry::Type *indexType,
|
QSGGeometry::Type *indexType,
|
||||||
bool supportsElementIndexUint)
|
bool supportsElementIndexUint,
|
||||||
|
qreal triangulationScale)
|
||||||
{
|
{
|
||||||
const QVectorPath &vp = qtVectorPathForPath(path);
|
const QVectorPath &vp = qtVectorPathForPath(path);
|
||||||
|
|
||||||
QTriangleSet ts = qTriangulate(vp, QTransform::fromScale(TRI_SCALE, TRI_SCALE), 1, supportsElementIndexUint);
|
QTriangleSet ts = qTriangulate(vp, QTransform::fromScale(triangulationScale, triangulationScale), 1, supportsElementIndexUint);
|
||||||
const int vertexCount = ts.vertices.size() / 2; // just a qreal vector with x,y hence the / 2
|
const int vertexCount = ts.vertices.size() / 2; // just a qreal vector with x,y hence the / 2
|
||||||
fillVertices->resize(vertexCount);
|
fillVertices->resize(vertexCount);
|
||||||
ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(fillVertices->data());
|
ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(fillVertices->data());
|
||||||
const qreal *vsrc = ts.vertices.constData();
|
const qreal *vsrc = ts.vertices.constData();
|
||||||
for (int i = 0; i < vertexCount; ++i)
|
for (int i = 0; i < vertexCount; ++i)
|
||||||
vdst[i].set(vsrc[i * 2] / TRI_SCALE, vsrc[i * 2 + 1] / TRI_SCALE, fillColor);
|
vdst[i].set(vsrc[i * 2] / triangulationScale, vsrc[i * 2 + 1] / triangulationScale, fillColor);
|
||||||
|
|
||||||
size_t indexByteSize;
|
size_t indexByteSize;
|
||||||
if (ts.indices.type() == QVertexIndexVector::UnsignedShort) {
|
if (ts.indices.type() == QVertexIndexVector::UnsignedShort) {
|
||||||
|
@ -403,11 +413,12 @@ void QQuickShapeGenericRenderer::triangulateStroke(const QPainterPath &path,
|
||||||
const QPen &pen,
|
const QPen &pen,
|
||||||
const Color4ub &strokeColor,
|
const Color4ub &strokeColor,
|
||||||
VertexContainerType *strokeVertices,
|
VertexContainerType *strokeVertices,
|
||||||
const QSize &clipSize)
|
const QSize &clipSize,
|
||||||
|
qreal triangulationScale)
|
||||||
{
|
{
|
||||||
const QVectorPath &vp = qtVectorPathForPath(path);
|
const QVectorPath &vp = qtVectorPathForPath(path);
|
||||||
const QRectF clip(QPointF(0, 0), clipSize);
|
const QRectF clip(QPointF(0, 0), clipSize);
|
||||||
const qreal inverseScale = 1.0 / TRI_SCALE;
|
const qreal inverseScale = 1.0 / triangulationScale;
|
||||||
|
|
||||||
QTriangulatingStroker stroker;
|
QTriangulatingStroker stroker;
|
||||||
stroker.setInvScale(inverseScale);
|
stroker.setInvScale(inverseScale);
|
||||||
|
|
|
@ -63,6 +63,7 @@ public:
|
||||||
void setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle,
|
void setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle,
|
||||||
qreal dashOffset, const QVector<qreal> &dashPattern) override;
|
qreal dashOffset, const QVector<qreal> &dashPattern) override;
|
||||||
void setFillGradient(int index, QQuickShapeGradient *gradient) override;
|
void setFillGradient(int index, QQuickShapeGradient *gradient) override;
|
||||||
|
void setTriangulationScale(qreal scale) override;
|
||||||
void endSync(bool async) override;
|
void endSync(bool async) override;
|
||||||
void setAsyncCallback(void (*)(void *), void *) override;
|
void setAsyncCallback(void (*)(void *), void *) override;
|
||||||
Flags flags() const override { return SupportsAsync; }
|
Flags flags() const override { return SupportsAsync; }
|
||||||
|
@ -80,12 +81,14 @@ public:
|
||||||
VertexContainerType *fillVertices,
|
VertexContainerType *fillVertices,
|
||||||
IndexContainerType *fillIndices,
|
IndexContainerType *fillIndices,
|
||||||
QSGGeometry::Type *indexType,
|
QSGGeometry::Type *indexType,
|
||||||
bool supportsElementIndexUint);
|
bool supportsElementIndexUint,
|
||||||
|
qreal triangulationScale);
|
||||||
static void triangulateStroke(const QPainterPath &path,
|
static void triangulateStroke(const QPainterPath &path,
|
||||||
const QPen &pen,
|
const QPen &pen,
|
||||||
const Color4ub &strokeColor,
|
const Color4ub &strokeColor,
|
||||||
VertexContainerType *strokeVertices,
|
VertexContainerType *strokeVertices,
|
||||||
const QSize &clipSize);
|
const QSize &clipSize,
|
||||||
|
qreal triangulationScale);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void maybeUpdateAsyncItem();
|
void maybeUpdateAsyncItem();
|
||||||
|
@ -120,6 +123,7 @@ private:
|
||||||
int m_accDirty;
|
int m_accDirty;
|
||||||
void (*m_asyncCallback)(void *);
|
void (*m_asyncCallback)(void *);
|
||||||
void *m_asyncCallbackData;
|
void *m_asyncCallbackData;
|
||||||
|
float m_triangulationScale = 1.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QQuickShapeFillRunnable : public QObject, public QRunnable
|
class QQuickShapeFillRunnable : public QObject, public QRunnable
|
||||||
|
@ -135,6 +139,7 @@ public:
|
||||||
QPainterPath path;
|
QPainterPath path;
|
||||||
QQuickShapeGenericRenderer::Color4ub fillColor;
|
QQuickShapeGenericRenderer::Color4ub fillColor;
|
||||||
bool supportsElementIndexUint;
|
bool supportsElementIndexUint;
|
||||||
|
qreal triangulationScale;
|
||||||
|
|
||||||
// output
|
// output
|
||||||
QQuickShapeGenericRenderer::VertexContainerType fillVertices;
|
QQuickShapeGenericRenderer::VertexContainerType fillVertices;
|
||||||
|
@ -159,6 +164,7 @@ public:
|
||||||
QPen pen;
|
QPen pen;
|
||||||
QQuickShapeGenericRenderer::Color4ub strokeColor;
|
QQuickShapeGenericRenderer::Color4ub strokeColor;
|
||||||
QSize clipSize;
|
QSize clipSize;
|
||||||
|
qreal triangulationScale;
|
||||||
|
|
||||||
// output
|
// output
|
||||||
QQuickShapeGenericRenderer::VertexContainerType strokeVertices;
|
QQuickShapeGenericRenderer::VertexContainerType strokeVertices;
|
||||||
|
|
Loading…
Reference in New Issue