aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp9
-rw-r--r--src/quick/items/qquickimage.cpp32
-rw-r--r--src/quick/items/qquickimage_p_p.h2
-rw-r--r--src/quick/items/qquickimagebase.cpp47
-rw-r--r--src/quick/items/qquickimagebase_p_p.h4
-rw-r--r--src/quick/items/qquickitem.cpp40
-rw-r--r--src/quick/items/qquickitem_p.h7
-rw-r--r--src/quick/items/qquickitemsmodule.cpp4
-rw-r--r--src/quick/items/qquickpositioners.cpp109
-rw-r--r--src/quick/items/qquickpositioners_p.h36
-rw-r--r--src/quick/items/qquickpositioners_p_p.h44
-rw-r--r--src/quick/items/qquickshadereffectsource.cpp40
-rw-r--r--src/quick/items/qquickshadereffectsource_p.h6
13 files changed, 290 insertions, 90 deletions
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 0eeba5d6cd..cf34523693 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -903,7 +903,7 @@ struct QQuickJSContext2DPixelData : public QV4::Object
V4_NEEDS_DESTROY
static QV4::ReturnedValue getIndexed(const QV4::Managed *m, uint index, bool *hasProperty);
- static void putIndexed(QV4::Managed *m, uint index, const QV4::Value &value);
+ static bool putIndexed(QV4::Managed *m, uint index, const QV4::Value &value);
static void proto_get_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
@@ -3079,13 +3079,13 @@ QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(const QV4::Managed *m,
return QV4::Encode::undefined();
}
-void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const QV4::Value &value)
+bool QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const QV4::Value &value)
{
Q_ASSERT(m->as<QQuickJSContext2DPixelData>());
QV4::ExecutionEngine *v4 = static_cast<QQuickJSContext2DPixelData *>(m)->engine();
QV4::Scope scope(v4);
if (scope.hasException())
- return;
+ return false;
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, static_cast<QQuickJSContext2DPixelData *>(m));
@@ -3111,7 +3111,10 @@ void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const Q
*pixel = qRgba(qRed(*pixel), qGreen(*pixel), qBlue(*pixel), v);
break;
}
+ return true;
}
+
+ return false;
}
/*!
\qmlmethod CanvasImageData QtQuick::Context2D::createImageData(real sw, real sh)
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index f71a2fbdbd..f3d7dc4b56 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -514,37 +514,41 @@ void QQuickImage::updatePaintedGeometry()
setImplicitSize(0, 0);
return;
}
- qreal w = widthValid() ? width() : d->pix.width();
- qreal widthScale = w / qreal(d->pix.width());
- qreal h = heightValid() ? height() : d->pix.height();
- qreal heightScale = h / qreal(d->pix.height());
+ const qreal pixWidth = d->pix.width() / d->devicePixelRatio;
+ const qreal pixHeight = d->pix.height() / d->devicePixelRatio;
+ const qreal w = widthValid() ? width() : pixWidth;
+ const qreal widthScale = w / pixWidth;
+ const qreal h = heightValid() ? height() : pixHeight;
+ const qreal heightScale = h / pixHeight;
if (widthScale <= heightScale) {
d->paintedWidth = w;
- d->paintedHeight = widthScale * qreal(d->pix.height());
+ d->paintedHeight = widthScale * pixHeight;
} else if (heightScale < widthScale) {
- d->paintedWidth = heightScale * qreal(d->pix.width());
+ d->paintedWidth = heightScale * pixWidth;
d->paintedHeight = h;
}
- qreal iHeight = (widthValid() && !heightValid()) ? d->paintedHeight : d->pix.height();
- qreal iWidth = (heightValid() && !widthValid()) ? d->paintedWidth : d->pix.width();
+ const qreal iHeight = (widthValid() && !heightValid()) ? d->paintedHeight : pixHeight;
+ const qreal iWidth = (heightValid() && !widthValid()) ? d->paintedWidth : pixWidth;
setImplicitSize(iWidth, iHeight);
} else if (d->fillMode == PreserveAspectCrop) {
if (!d->pix.width() || !d->pix.height())
return;
- qreal widthScale = width() / qreal(d->pix.width());
- qreal heightScale = height() / qreal(d->pix.height());
+ const qreal pixWidth = d->pix.width() / d->devicePixelRatio;
+ const qreal pixHeight = d->pix.height() / d->devicePixelRatio;
+ qreal widthScale = width() / pixWidth;
+ qreal heightScale = height() / pixHeight;
if (widthScale < heightScale) {
widthScale = heightScale;
} else if (heightScale < widthScale) {
heightScale = widthScale;
}
- d->paintedHeight = heightScale * qreal(d->pix.height());
- d->paintedWidth = widthScale * qreal(d->pix.width());
+ d->paintedHeight = heightScale * pixHeight;
+ d->paintedWidth = widthScale * pixWidth;
} else if (d->fillMode == Pad) {
- d->paintedWidth = d->pix.width();
- d->paintedHeight = d->pix.height();
+ d->paintedWidth = d->pix.width() / d->devicePixelRatio;
+ d->paintedHeight = d->pix.height() / d->devicePixelRatio;
} else {
d->paintedWidth = width();
d->paintedHeight = height();
diff --git a/src/quick/items/qquickimage_p_p.h b/src/quick/items/qquickimage_p_p.h
index 522dbca803..afc33def0f 100644
--- a/src/quick/items/qquickimage_p_p.h
+++ b/src/quick/items/qquickimage_p_p.h
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
class QQuickImageTextureProvider;
-class QQuickImagePrivate : public QQuickImageBasePrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickImagePrivate : public QQuickImageBasePrivate
{
Q_DECLARE_PUBLIC(QQuickImage)
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp
index 22d631e917..33d69f5032 100644
--- a/src/quick/items/qquickimagebase.cpp
+++ b/src/quick/items/qquickimagebase.cpp
@@ -49,6 +49,30 @@
QT_BEGIN_NAMESPACE
+// This function gives derived classes the chance set the devicePixelRatio
+// if they're not happy with our implementation of it.
+bool QQuickImageBasePrivate::updateDevicePixelRatio(qreal targetDevicePixelRatio)
+{
+ // QQuickImageProvider and SVG can generate a high resolution image when
+ // sourceSize is set (this function is only called if it's set).
+ // If sourceSize is not set then the provider default size will be used, as usual.
+ bool setDevicePixelRatio = false;
+ if (url.scheme() == QLatin1String("image")) {
+ setDevicePixelRatio = true;
+ } else {
+ QString stringUrl = url.path(QUrl::PrettyDecoded);
+ if (stringUrl.endsWith(QLatin1String("svg")) ||
+ stringUrl.endsWith(QLatin1String("svgz"))) {
+ setDevicePixelRatio = true;
+ }
+ }
+
+ if (setDevicePixelRatio)
+ devicePixelRatio = targetDevicePixelRatio;
+
+ return setDevicePixelRatio;
+}
+
QQuickImageBase::QQuickImageBase(QQuickItem *parent)
: QQuickImplicitSizeItem(*(new QQuickImageBasePrivate), parent)
{
@@ -221,26 +245,11 @@ void QQuickImageBase::load()
QUrl loadUrl = d->url;
- // QQuickImageProvider and SVG can generate a high resolution image when
- // sourceSize is set. If sourceSize is not set then the provider default size
- // will be used, as usual.
- bool setDevicePixelRatio = false;
- if (d->sourcesize.isValid()) {
- if (loadUrl.scheme() == QLatin1String("image")) {
- setDevicePixelRatio = true;
- } else {
- QString stringUrl = loadUrl.path(QUrl::PrettyDecoded);
- if (stringUrl.endsWith(QLatin1String("svg")) ||
- stringUrl.endsWith(QLatin1String("svgz"))) {
- setDevicePixelRatio = true;
- }
- }
-
- if (setDevicePixelRatio)
- d->devicePixelRatio = targetDevicePixelRatio;
- }
+ bool updatedDevicePixelRatio = false;
+ if (d->sourcesize.isValid())
+ updatedDevicePixelRatio = d->updateDevicePixelRatio(targetDevicePixelRatio);
- if (!setDevicePixelRatio) {
+ if (!updatedDevicePixelRatio) {
// (possible) local file: loadUrl and d->devicePixelRatio will be modified if
// an "@2x" file is found.
resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
diff --git a/src/quick/items/qquickimagebase_p_p.h b/src/quick/items/qquickimagebase_p_p.h
index d9b609c7fe..1b771166a2 100644
--- a/src/quick/items/qquickimagebase_p_p.h
+++ b/src/quick/items/qquickimagebase_p_p.h
@@ -59,7 +59,7 @@
QT_BEGIN_NAMESPACE
class QNetworkReply;
-class QQuickImageBasePrivate : public QQuickImplicitSizeItemPrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickImageBasePrivate : public QQuickImplicitSizeItemPrivate
{
Q_DECLARE_PUBLIC(QQuickImageBase)
@@ -75,6 +75,8 @@ public:
{
}
+ virtual bool updateDevicePixelRatio(qreal targetDevicePixelRatio);
+
QQuickPixmap pix;
QQuickImageBase::Status status;
QUrl url;
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 1a244b0dd9..aa2662489d 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -7867,6 +7867,7 @@ QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
, m_effect(0)
, m_effectSource(0)
, m_textureMirroring(QQuickShaderEffectSource::MirrorVertically)
+ , m_samples(0)
{
}
@@ -7941,6 +7942,7 @@ void QQuickItemLayer::activate()
m_effectSource->setWrapMode(m_wrapMode);
m_effectSource->setFormat(m_format);
m_effectSource->setTextureMirroring(m_textureMirroring);
+ m_effectSource->setSamples(m_samples);
if (m_effectComponent)
activateEffect();
@@ -8234,6 +8236,44 @@ void QQuickItemLayer::setTextureMirroring(QQuickShaderEffectSource::TextureMirro
}
/*!
+ \qmlproperty enumeration QtQuick::Item::layer.samples
+ \since 5.10
+
+ This property allows requesting multisampled rendering in the layer.
+
+ By default multisampling is enabled whenever multisampling is
+ enabled for the entire window, assuming the scenegraph renderer in
+ use and the underlying graphics API supports this.
+
+ By setting the value to 2, 4, etc. multisampled rendering can be requested
+ for a part of the scene without enabling multisampling for the entire
+ scene. This way multisampling is applied only to a given subtree, which can
+ lead to significant performance gains since multisampling is not applied to
+ other parts of the scene.
+
+ \note Enabling multisampling can be potentially expensive regardless of the
+ layer's size, as it incurs a hardware and driver dependent performance and
+ memory cost.
+
+ \note This property is only functional when support for multisample
+ renderbuffers and framebuffer blits is available. Otherwise the value is
+ silently ignored.
+ */
+
+void QQuickItemLayer::setSamples(int count)
+{
+ if (m_samples == count)
+ return;
+
+ m_samples = count;
+
+ if (m_effectSource)
+ m_effectSource->setSamples(m_samples);
+
+ emit samplesChanged(count);
+}
+
+/*!
\qmlproperty string QtQuick::Item::layer.samplerName
Holds the name of the effect's source texture property.
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index c0c9bd46bd..797ba42781 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -152,6 +152,8 @@ class QQuickItemLayer : public QObject, public QQuickItemChangeListener
Q_PROPERTY(QByteArray samplerName READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QQmlComponent *effect READ effect WRITE setEffect NOTIFY effectChanged)
Q_PROPERTY(QQuickShaderEffectSource::TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged)
+ Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged)
+
public:
QQuickItemLayer(QQuickItem *item);
~QQuickItemLayer();
@@ -189,6 +191,9 @@ public:
QQuickShaderEffectSource::TextureMirroring textureMirroring() const { return m_textureMirroring; }
void setTextureMirroring(QQuickShaderEffectSource::TextureMirroring mirroring);
+ int samples() const { return m_samples; }
+ void setSamples(int count);
+
QQuickShaderEffectSource *effectSource() const { return m_effectSource; }
void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) Q_DECL_OVERRIDE;
@@ -213,6 +218,7 @@ Q_SIGNALS:
void formatChanged(QQuickShaderEffectSource::Format format);
void sourceRectChanged(const QRectF &sourceRect);
void textureMirroringChanged(QQuickShaderEffectSource::TextureMirroring mirroring);
+ void samplesChanged(int count);
private:
friend class QQuickTransformAnimatorJob;
@@ -237,6 +243,7 @@ private:
QQuickItem *m_effect;
QQuickShaderEffectSource *m_effectSource;
QQuickShaderEffectSource::TextureMirroring m_textureMirroring;
+ int m_samples;
};
#endif
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index a8824de9c8..eeffe1ee48 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -385,6 +385,10 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterUncreatableType<QQuickBasePositioner, 9>(uri, 2, 9, "Positioner",
QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
#endif
+
+#if QT_CONFIG(quick_shadereffect)
+ qmlRegisterType<QQuickShaderEffectSource, 2>(uri, 2, 9, "ShaderEffectSource");
+#endif
}
static void initResources()
diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp
index 05d3ae0191..70fc5fa65f 100644
--- a/src/quick/items/qquickpositioners.cpp
+++ b/src/quick/items/qquickpositioners.cpp
@@ -44,15 +44,23 @@
#include <QtQml/qqmlinfo.h>
#include <QtCore/qcoreapplication.h>
-#include <QtQuick/private/qquickstate_p.h>
-#include <QtQuick/private/qquickstategroup_p.h>
-#include <private/qquickstatechangescript_p.h>
#include <QtQuick/private/qquicktransition_p.h>
QT_BEGIN_NAMESPACE
-static const QQuickItemPrivate::ChangeTypes watchedChanges
- = QQuickItemPrivate::Geometry
+// The default item change types that positioners are interested in.
+static const QQuickItemPrivate::ChangeTypes explicitSizeItemChangeTypes =
+ QQuickItemPrivate::Geometry
+ | QQuickItemPrivate::SiblingOrder
+ | QQuickItemPrivate::Visibility
+ | QQuickItemPrivate::Destroyed;
+
+// The item change types for positioners that are only interested in the implicit
+// size of the items they manage. These are used if useImplicitSize is true.
+// useImplicitSize should be set in the constructor, before any items are added.
+static const QQuickItemPrivate::ChangeTypes implicitSizeItemChangeTypes =
+ QQuickItemPrivate::ImplicitWidth
+ | QQuickItemPrivate::ImplicitHeight
| QQuickItemPrivate::SiblingOrder
| QQuickItemPrivate::Visibility
| QQuickItemPrivate::Destroyed;
@@ -60,13 +68,15 @@ static const QQuickItemPrivate::ChangeTypes watchedChanges
void QQuickBasePositionerPrivate::watchChanges(QQuickItem *other)
{
QQuickItemPrivate *otherPrivate = QQuickItemPrivate::get(other);
- otherPrivate->addItemChangeListener(this, watchedChanges);
+ otherPrivate->addItemChangeListener(this, useImplicitSize
+ ? implicitSizeItemChangeTypes : explicitSizeItemChangeTypes);
}
void QQuickBasePositionerPrivate::unwatchChanges(QQuickItem* other)
{
QQuickItemPrivate *otherPrivate = QQuickItemPrivate::get(other);
- otherPrivate->removeItemChangeListener(this, watchedChanges);
+ otherPrivate->removeItemChangeListener(this, useImplicitSize
+ ? implicitSizeItemChangeTypes : explicitSizeItemChangeTypes);
}
@@ -326,7 +336,7 @@ void QQuickBasePositioner::prePositioning()
if (wIdx < 0) {
d->watchChanges(child);
posItem.isNew = true;
- if (!childPrivate->explicitVisible || !child->width() || !child->height()) {
+ if (!childPrivate->explicitVisible || !d->itemWidth(child) || !d->itemHeight(child)) {
posItem.isVisible = false;
posItem.index = -1;
unpositionedItems.append(posItem);
@@ -348,7 +358,7 @@ void QQuickBasePositioner::prePositioning()
PositionedItem *item = &oldItems[wIdx];
// Items are only omitted from positioning if they are explicitly hidden
// i.e. their positioning is not affected if an ancestor is hidden.
- if (!childPrivate->explicitVisible || !child->width() || !child->height()) {
+ if (!childPrivate->explicitVisible || !d->itemWidth(child) || !d->itemHeight(child)) {
item->isVisible = false;
item->index = -1;
unpositionedItems.append(*item);
@@ -947,6 +957,7 @@ QQuickColumn::QQuickColumn(QQuickItem *parent)
void QQuickColumn::doPositioning(QSizeF *contentSize)
{
//Precondition: All items in the positioned list have a valid item pointer and should be positioned
+ QQuickBasePositionerPrivate *d = static_cast<QQuickBasePositionerPrivate*>(QQuickBasePositionerPrivate::get(this));
qreal voffset = topPadding();
const qreal padding = leftPadding() + rightPadding();
contentSize->setWidth(qMax(contentSize->width(), padding));
@@ -955,9 +966,9 @@ void QQuickColumn::doPositioning(QSizeF *contentSize)
PositionedItem &child = positionedItems[ii];
positionItem(child.itemX() + leftPadding() - child.leftPadding, voffset, &child);
child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
- contentSize->setWidth(qMax(contentSize->width(), child.item->width() + padding));
+ contentSize->setWidth(qMax(contentSize->width(), d->itemWidth(child.item) + padding));
- voffset += child.item->height();
+ voffset += d->itemHeight(child.item);
voffset += spacing();
}
@@ -1137,7 +1148,7 @@ public:
: QQuickBasePositionerPrivate()
{}
- void effectiveLayoutDirectionChange()
+ void effectiveLayoutDirectionChange() override
{
Q_Q(QQuickRow);
// For RTL layout the positioning changes when the width changes.
@@ -1225,9 +1236,9 @@ void QQuickRow::doPositioning(QSizeF *contentSize)
hoffsets << hoffset;
}
- contentSize->setHeight(qMax(contentSize->height(), child.item->height() + padding));
+ contentSize->setHeight(qMax(contentSize->height(), d->itemHeight(child.item) + padding));
- hoffset += child.item->width();
+ hoffset += d->itemWidth(child.item);
hoffset += spacing();
}
@@ -1248,7 +1259,7 @@ void QQuickRow::doPositioning(QSizeF *contentSize)
int acc = 0;
for (int ii = 0; ii < positionedItems.count(); ++ii) {
PositionedItem &child = positionedItems[ii];
- hoffset = end - hoffsets[acc++] - child.item->width();
+ hoffset = end - hoffsets[acc++] - d->itemWidth(child.item);
positionItem(hoffset, child.itemY() + topPadding() - child.topPadding, &child);
child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
}
@@ -1436,7 +1447,7 @@ public:
: QQuickBasePositionerPrivate()
{}
- void effectiveLayoutDirectionChange()
+ void effectiveLayoutDirectionChange() override
{
Q_Q(QQuickGrid);
// For RTL layout the positioning changes when the width changes.
@@ -1749,10 +1760,12 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
break;
const PositionedItem &child = positionedItems.at(childIndex++);
- if (child.item->width() > maxColWidth[j])
- maxColWidth[j] = child.item->width();
- if (child.item->height() > maxRowHeight[i])
- maxRowHeight[i] = child.item->height();
+ const qreal childWidth = d->itemWidth(child.item);
+ const qreal childHeight = d->itemHeight(child.item);
+ if (childWidth > maxColWidth[j])
+ maxColWidth[j] = childWidth;
+ if (childHeight > maxRowHeight[i])
+ maxRowHeight[i] = childHeight;
}
}
} else {
@@ -1767,10 +1780,12 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
break;
const PositionedItem &child = positionedItems.at(childIndex++);
- if (child.item->width() > maxColWidth[j])
- maxColWidth[j] = child.item->width();
- if (child.item->height() > maxRowHeight[i])
- maxRowHeight[i] = child.item->height();
+ const qreal childWidth = d->itemWidth(child.item);
+ const qreal childHeight = d->itemHeight(child.item);
+ if (childWidth > maxColWidth[j])
+ maxColWidth[j] = childWidth;
+ if (childHeight > maxRowHeight[i])
+ maxRowHeight[i] = childHeight;
}
}
}
@@ -1812,20 +1827,22 @@ void QQuickGrid::doPositioning(QSizeF *contentSize)
for (int i = 0; i < positionedItems.count(); ++i) {
PositionedItem &child = positionedItems[i];
qreal childXOffset = xoffset;
+ const qreal childWidth = d->itemWidth(child.item);
+ const qreal childHeight = d->itemHeight(child.item);
if (effectiveHAlign() == AlignRight)
- childXOffset += maxColWidth[curCol] - child.item->width();
+ childXOffset += maxColWidth[curCol] - childWidth;
else if (hItemAlign() == AlignHCenter)
- childXOffset += (maxColWidth[curCol] - child.item->width())/2.0;
+ childXOffset += (maxColWidth[curCol] - childWidth)/2.0;
if (!d->isLeftToRight())
childXOffset -= maxColWidth[curCol];
qreal alignYOffset = yoffset;
if (m_vItemAlign == AlignVCenter)
- alignYOffset += (maxRowHeight[curRow] - child.item->height())/2.0;
+ alignYOffset += (maxRowHeight[curRow] - childHeight)/2.0;
else if (m_vItemAlign == AlignBottom)
- alignYOffset += maxRowHeight[curRow] - child.item->height();
+ alignYOffset += maxRowHeight[curRow] - childHeight;
positionItem(childXOffset, alignYOffset, &child);
child.updatePadding(leftPadding(), topPadding(), rightPadding(), bottomPadding());
@@ -2023,7 +2040,7 @@ public:
: QQuickBasePositionerPrivate(), flow(QQuickFlow::LeftToRight)
{}
- void effectiveLayoutDirectionChange()
+ void effectiveLayoutDirectionChange() override
{
Q_Q(QQuickFlow);
// Don't postpone, as it might be the only trigger for visible changes.
@@ -2143,15 +2160,17 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
for (int i = 0; i < positionedItems.count(); ++i) {
PositionedItem &child = positionedItems[i];
+ const qreal childWidth = d->itemWidth(child.item);
+ const qreal childHeight = d->itemHeight(child.item);
if (d->flow == LeftToRight) {
- if (widthValid() && hoffset != hoffset1 && hoffset + child.item->width() + hoffset2 > width()) {
+ if (widthValid() && hoffset != hoffset1 && hoffset + childWidth + hoffset2 > width()) {
hoffset = hoffset1;
voffset += linemax + spacing();
linemax = 0;
}
} else {
- if (heightValid() && voffset != voffset1 && voffset + child.item->height() + bottomPadding() > height()) {
+ if (heightValid() && voffset != voffset1 && voffset + childHeight + bottomPadding() > height()) {
voffset = voffset1;
hoffset += linemax + spacing();
linemax = 0;
@@ -2168,17 +2187,17 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
child.bottomPadding = bottomPadding();
}
- contentSize->setWidth(qMax(contentSize->width(), hoffset + child.item->width() + hoffset2));
- contentSize->setHeight(qMax(contentSize->height(), voffset + child.item->height() + bottomPadding()));
+ contentSize->setWidth(qMax(contentSize->width(), hoffset + childWidth + hoffset2));
+ contentSize->setHeight(qMax(contentSize->height(), voffset + childHeight + bottomPadding()));
if (d->flow == LeftToRight) {
- hoffset += child.item->width();
+ hoffset += childWidth;
hoffset += spacing();
- linemax = qMax(linemax, child.item->height());
+ linemax = qMax(linemax, childHeight);
} else {
- voffset += child.item->height();
+ voffset += childHeight;
voffset += spacing();
- linemax = qMax(linemax, child.item->width());
+ linemax = qMax(linemax, childWidth);
}
}
@@ -2193,7 +2212,7 @@ void QQuickFlow::doPositioning(QSizeF *contentSize)
int acc = 0;
for (int i = 0; i < positionedItems.count(); ++i) {
PositionedItem &child = positionedItems[i];
- hoffset = end - hoffsets[acc++] - child.item->width();
+ hoffset = end - hoffsets[acc++] - d->itemWidth(child.item);
positionItemX(hoffset, &child);
child.leftPadding = leftPadding();
child.rightPadding = rightPadding();
@@ -2217,4 +2236,18 @@ void QQuickFlow::reportConflictingAnchors()
qmlWarning(this) << "Cannot specify anchors for items inside Flow." << " Flow will not function.";
}
+QQuickImplicitRow::QQuickImplicitRow(QQuickItem *parent)
+ : QQuickRow(parent)
+{
+ QQuickBasePositionerPrivate *d = QQuickBasePositioner::get(this);
+ d->useImplicitSize = true;
+}
+
+QQuickImplicitGrid::QQuickImplicitGrid(QQuickItem *parent)
+ : QQuickGrid(parent)
+{
+ QQuickBasePositionerPrivate *d = QQuickBasePositioner::get(this);
+ d->useImplicitSize = true;
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h
index ae6e795794..cfe163b4c1 100644
--- a/src/quick/items/qquickpositioners_p.h
+++ b/src/quick/items/qquickpositioners_p.h
@@ -58,7 +58,6 @@ QT_REQUIRE_CONFIG(quick_positioners);
#include "qquickimplicitsizeitem_p.h"
#include "qquickitemviewtransition_p.h"
-#include <QtQuick/private/qquickstate_p.h>
#include <private/qpodvector_p.h>
#include <QtCore/qobject.h>
@@ -68,7 +67,7 @@ QT_BEGIN_NAMESPACE
class QQuickBasePositionerPrivate;
-class QQuickPositionerAttached : public QObject
+class Q_QUICK_PRIVATE_EXPORT QQuickPositionerAttached : public QObject
{
Q_OBJECT
@@ -133,6 +132,11 @@ public:
static QQuickPositionerAttached *qmlAttachedProperties(QObject *obj);
+ static QQuickBasePositionerPrivate* get(QQuickBasePositioner *positioner)
+ {
+ return positioner->d_func();
+ }
+
void updateAttachedProperties(QQuickPositionerAttached *specificProperty = 0, QQuickItem *specificPropertyOwner = 0) const;
qreal padding() const;
@@ -183,7 +187,7 @@ protected:
virtual void doPositioning(QSizeF *contentSize)=0;
virtual void reportConflictingAnchors()=0;
- class PositionedItem
+ class Q_QUICK_PRIVATE_EXPORT PositionedItem
{
public :
PositionedItem(QQuickItem *i);
@@ -228,7 +232,7 @@ private:
Q_DECLARE_PRIVATE(QQuickBasePositioner)
};
-class Q_AUTOTEST_EXPORT QQuickColumn : public QQuickBasePositioner
+class Q_QUICK_PRIVATE_EXPORT QQuickColumn : public QQuickBasePositioner
{
Q_OBJECT
public:
@@ -242,7 +246,7 @@ private:
};
class QQuickRowPrivate;
-class Q_AUTOTEST_EXPORT QQuickRow: public QQuickBasePositioner
+class Q_QUICK_PRIVATE_EXPORT QQuickRow: public QQuickBasePositioner
{
Q_OBJECT
Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection NOTIFY layoutDirectionChanged)
@@ -267,7 +271,7 @@ private:
};
class QQuickGridPrivate;
-class Q_AUTOTEST_EXPORT QQuickGrid : public QQuickBasePositioner
+class Q_QUICK_PRIVATE_EXPORT QQuickGrid : public QQuickBasePositioner
{
Q_OBJECT
Q_PROPERTY(int rows READ rows WRITE setRows NOTIFY rowsChanged)
@@ -354,7 +358,7 @@ private:
};
class QQuickFlowPrivate;
-class Q_AUTOTEST_EXPORT QQuickFlow: public QQuickBasePositioner
+class Q_QUICK_PRIVATE_EXPORT QQuickFlow: public QQuickBasePositioner
{
Q_OBJECT
Q_PROPERTY(Flow flow READ flow WRITE setFlow NOTIFY flowChanged)
@@ -387,6 +391,22 @@ private:
Q_DECLARE_PRIVATE(QQuickFlow)
};
+class Q_QUICK_PRIVATE_EXPORT QQuickImplicitRow : public QQuickRow
+{
+ Q_OBJECT
+
+public:
+ QQuickImplicitRow(QQuickItem *parent = nullptr);
+};
+
+class Q_QUICK_PRIVATE_EXPORT QQuickImplicitGrid : public QQuickGrid
+{
+ Q_OBJECT
+
+public:
+ QQuickImplicitGrid(QQuickItem *parent = nullptr);
+};
+
QT_END_NAMESPACE
@@ -394,6 +414,8 @@ QML_DECLARE_TYPE(QQuickColumn)
QML_DECLARE_TYPE(QQuickRow)
QML_DECLARE_TYPE(QQuickGrid)
QML_DECLARE_TYPE(QQuickFlow)
+QML_DECLARE_TYPE(QQuickImplicitRow)
+QML_DECLARE_TYPE(QQuickImplicitGrid)
QML_DECLARE_TYPE(QQuickBasePositioner)
QML_DECLARE_TYPEINFO(QQuickBasePositioner, QML_HAS_ATTACHED_PROPERTIES)
diff --git a/src/quick/items/qquickpositioners_p_p.h b/src/quick/items/qquickpositioners_p_p.h
index 6dd84e6098..1a7051615c 100644
--- a/src/quick/items/qquickpositioners_p_p.h
+++ b/src/quick/items/qquickpositioners_p_p.h
@@ -58,9 +58,6 @@ QT_REQUIRE_CONFIG(quick_positioners);
#include "qquickpositioners_p.h"
#include "qquickimplicitsizeitem_p_p.h"
-#include <QtQuick/private/qquickstate_p.h>
-#include <private/qquicktransitionmanager_p_p.h>
-#include <private/qquickstatechangescript_p.h>
#include <private/qlazilyallocated_p.h>
#include <QtCore/qobject.h>
@@ -92,10 +89,14 @@ public:
QLazilyAllocated<ExtraData> extra;
QQuickBasePositionerPrivate()
- : spacing(0), type(QQuickBasePositioner::None)
- , transitioner(0), positioningDirty(false)
- , doingPositioning(false), anchorConflict(false), layoutDirection(Qt::LeftToRight)
-
+ : spacing(0)
+ , type(QQuickBasePositioner::None)
+ , transitioner(0)
+ , positioningDirty(false)
+ , doingPositioning(false)
+ , anchorConflict(false)
+ , useImplicitSize(false)
+ , layoutDirection(Qt::LeftToRight)
{
}
@@ -122,6 +123,7 @@ public:
bool positioningDirty : 1;
bool doingPositioning : 1;
bool anchorConflict : 1;
+ bool useImplicitSize : 1;
Qt::LayoutDirection layoutDirection;
@@ -177,6 +179,34 @@ public:
{
}
+ void itemImplicitWidthChanged(QQuickItem *) override
+ {
+ Q_ASSERT(useImplicitSize);
+ setPositioningDirty();
+ }
+
+ void itemImplicitHeightChanged(QQuickItem *) override
+ {
+ Q_ASSERT(useImplicitSize);
+ setPositioningDirty();
+ }
+
+ qreal itemWidth(QQuickItem *item) const
+ {
+ if (Q_LIKELY(!useImplicitSize))
+ return item->width();
+
+ return item->implicitWidth();
+ }
+
+ qreal itemHeight(QQuickItem *item) const
+ {
+ if (Q_LIKELY(!useImplicitSize))
+ return item->height();
+
+ return item->implicitHeight();
+ }
+
inline qreal padding() const { return extra.isAllocated() ? extra->padding : 0.0; }
void setTopPadding(qreal value, bool reset = false);
void setLeftPadding(qreal value, bool reset = false);
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp
index 1b37a746d3..c782ddb5f7 100644
--- a/src/quick/items/qquickshadereffectsource.cpp
+++ b/src/quick/items/qquickshadereffectsource.cpp
@@ -189,6 +189,7 @@ QQuickShaderEffectSource::QQuickShaderEffectSource(QQuickItem *parent)
, m_sourceItem(0)
, m_textureSize(0, 0)
, m_format(RGBA)
+ , m_samples(0)
, m_live(true)
, m_hideSource(false)
, m_mipmap(false)
@@ -582,6 +583,44 @@ void QQuickShaderEffectSource::setTextureMirroring(TextureMirroring mirroring)
}
/*!
+ \qmlproperty int QtQuick::ShaderEffectSource::samples
+ \since 5.10
+
+ This property allows requesting multisampled rendering.
+
+ By default multisampling is enabled whenever multisampling is enabled for
+ the entire window, assuming the scenegraph renderer in use and the
+ underlying graphics API supports this.
+
+ By setting the value to 2, 4, etc. multisampled rendering can be requested
+ for a part of the scene without enabling multisampling for the entire
+ scene. This way multisampling is applied only to a given subtree, which can
+ lead to significant performance gains since multisampling is not applied to
+ other parts of the scene.
+
+ \note Enabling multisampling can be potentially expensive regardless of the
+ layer's size, as it incurs a hardware and driver dependent performance and
+ memory cost.
+
+ \note This property is only functional when support for multisample
+ renderbuffers and framebuffer blits is available. Otherwise the value is
+ silently ignored.
+ */
+int QQuickShaderEffectSource::samples() const
+{
+ return m_samples;
+}
+
+void QQuickShaderEffectSource::setSamples(int count)
+{
+ if (count == m_samples)
+ return;
+ m_samples = count;
+ update();
+ emit samplesChanged();
+}
+
+/*!
\qmlmethod QtQuick::ShaderEffectSource::scheduleUpdate()
Schedules a re-rendering of the texture for the next frame.
@@ -683,6 +722,7 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint
m_texture->setHasMipmaps(m_mipmap);
m_texture->setMirrorHorizontal(m_textureMirroring & MirrorHorizontally);
m_texture->setMirrorVertical(m_textureMirroring & MirrorVertically);
+ m_texture->setSamples(m_samples);
if (m_grab)
m_texture->scheduleUpdate();
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index 5e7e354feb..d9f9079a3d 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -88,6 +88,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi
Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged)
Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 1)
+ Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION 2)
public:
enum WrapMode {
@@ -150,6 +151,9 @@ public:
Q_INVOKABLE void scheduleUpdate();
+ int samples() const;
+ void setSamples(int count);
+
Q_SIGNALS:
void wrapModeChanged();
void sourceItemChanged();
@@ -161,6 +165,7 @@ Q_SIGNALS:
void mipmapChanged();
void recursiveChanged();
void textureMirroringChanged();
+ void samplesChanged();
void scheduledUpdateCompleted();
@@ -185,6 +190,7 @@ private:
QRectF m_sourceRect;
QSize m_textureSize;
Format m_format;
+ int m_samples;
uint m_live : 1;
uint m_hideSource : 1;
uint m_mipmap : 1;