aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-10-24 01:01:06 +0200
committerUlf Hermann <ulf.hermann@qt.io>2019-10-24 15:43:53 +0200
commite99469da2d99e1877276f7b37e5e8d699d8b14ee (patch)
tree87167f1f4cc8e1b851097052e60edbaae32e00af /src
parentfbe32d83b3e16bc51866daf5635cd36e1f70753b (diff)
parent328b97a0acdf294f6ba3c902d23ece374a0f11ba (diff)
Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"
Diffstat (limited to 'src')
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc20
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp4
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h2
-rw-r--r--src/qml/jsruntime/qv4stackframe_p.h2
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp2
-rw-r--r--src/qml/qml/ftw/qflagpointer_p.h16
-rw-r--r--src/qml/qml/ftw/qqmlthread.cpp3
-rw-r--r--src/qml/qml/qqmlcontext.cpp3
-rw-r--r--src/qml/qml/qqmlimport.cpp3
-rw-r--r--src/qml/qml/qqmlproperty.cpp12
-rw-r--r--src/qml/qml/qqmlpropertyvalidator.cpp4
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp12
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp4
-rw-r--r--src/quick/scenegraph/util/qsgopenglatlastexture.cpp12
14 files changed, 75 insertions, 24 deletions
diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
index c4ecaf367c..401e099ebf 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
@@ -464,22 +464,24 @@ Unlike an ordinary property, an alias has the following restrictions:
must be provided when the alias is first declared.
\li It cannot refer to \l {Attached Properties and Attached Signal Handlers}
{attached properties}.
-\li It cannot refer to grouped properties; the following code will not work:
+\li It cannot refer to properties inside a hierarchy with depth 3 or greater. The
+ following code will not work:
\code
- property alias color: rectangle.border.color
+ property alias color: myItem.myRect.border.color
- Rectangle {
- id: rectangle
+ Item {
+ id: myItem
+ property Rectangle myRect
}
\endcode
- However, aliases to \l {QML Basic Types}{value type} properties do work:
+ However, aliases to properties that are up to two levels deep will work.
+
\code
- property alias rectX: object.rectProperty.x
+ property alias color: rectangle.border.color
- Item {
- id: object
- property rect rectProperty
+ Rectangle {
+ id: rectangle
}
\endcode
\endlist
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 2b5e8bd2b9..5a81f24e06 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -1622,7 +1622,7 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const
int methodMatchScore = 0;
for (int ii = 0; ii < methodArgumentCount; ++ii) {
- methodMatchScore += MatchScore((v = Value::fromStaticValue(callArgs->args[ii])),
+ methodMatchScore += MatchScore((v = QV4::Value::fromStaticValue(callArgs->args[ii])),
methodArgTypes[ii]);
}
@@ -2268,7 +2268,7 @@ ReturnedValue QMetaObjectWrapper::callOverloadedConstructor(QV4::ExecutionEngine
int methodMatchScore = 0;
for (int ii = 0; ii < methodArgumentCount; ++ii) {
- methodMatchScore += MatchScore((v = Value::fromStaticValue(callArgs->args[ii])),
+ methodMatchScore += MatchScore((v = QV4::Value::fromStaticValue(callArgs->args[ii])),
methodArgTypes[ii]);
}
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index e4aceef3ee..12a6381e6f 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -70,7 +70,7 @@ struct ScopedValue;
#define CHECK_EXCEPTION() \
do { \
- if (scope.hasException()) { \
+ if (scope.hasException() || scope.engine->isInterrupted.loadAcquire()) { \
return QV4::Encode::undefined(); \
} \
} while (false)
diff --git a/src/qml/jsruntime/qv4stackframe_p.h b/src/qml/jsruntime/qv4stackframe_p.h
index bf689a74bc..616fa9a5a9 100644
--- a/src/qml/jsruntime/qv4stackframe_p.h
+++ b/src/qml/jsruntime/qv4stackframe_p.h
@@ -117,7 +117,7 @@ struct Q_QML_EXPORT CppStackFrame {
void setupJSFrame(Value *stackSpace, const Value &function, const Heap::ExecutionContext *scope,
const Value &thisObject, const Value &newTarget = Value::undefinedValue()) {
setupJSFrame(stackSpace, function, scope, thisObject, newTarget,
- v4Function->nFormals, v4Function->compiledFunction->nRegisters);
+ v4Function->compiledFunction->nFormals, v4Function->compiledFunction->nRegisters);
}
void setupJSFrame(Value *stackSpace, const Value &function, const Heap::ExecutionContext *scope,
const Value &thisObject, const Value &newTarget, uint nFormals, uint nRegisters)
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 27d518f5c6..ad5a6ebc8c 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -364,7 +364,7 @@ static inline Heap::CallContext *getScope(QV4::Value *stack, int level)
static inline const QV4::Value &constant(Function *function, int index)
{
- return function->compilationUnit->constants[index].asValue<Value>();
+ return function->compilationUnit->constants[index].asValue<QV4::Value>();
}
static bool compareEqualInt(QV4::Value &accumulator, QV4::Value lhs, int rhs)
diff --git a/src/qml/qml/ftw/qflagpointer_p.h b/src/qml/qml/ftw/qflagpointer_p.h
index 71b41cd30b..a10e57aeca 100644
--- a/src/qml/qml/ftw/qflagpointer_p.h
+++ b/src/qml/qml/ftw/qflagpointer_p.h
@@ -55,6 +55,17 @@
QT_BEGIN_NAMESPACE
+namespace QtPrivate {
+template <typename T> struct QFlagPointerAlignment
+{
+ enum : size_t { Value = Q_ALIGNOF(T) };
+};
+template <> struct QFlagPointerAlignment<void>
+{
+ enum : size_t { Value = ~size_t(0) };
+};
+}
+
template<typename T>
class QFlagPointer {
public:
@@ -133,6 +144,7 @@ template<typename T>
QFlagPointer<T>::QFlagPointer(T *v)
: ptr_value(quintptr(v))
{
+ Q_STATIC_ASSERT_X(Q_ALIGNOF(T) >= 4, "Type T does not have sufficient alignment");
Q_ASSERT((ptr_value & FlagsMask) == 0);
}
@@ -247,6 +259,8 @@ template<typename T, typename T2>
QBiPointer<T, T2>::QBiPointer(T *v)
: ptr_value(quintptr(v))
{
+ Q_STATIC_ASSERT_X(QtPrivate::QFlagPointerAlignment<T>::Value >= 4,
+ "Type T does not have sufficient alignment");
Q_ASSERT((quintptr(v) & FlagsMask) == 0);
}
@@ -254,6 +268,8 @@ template<typename T, typename T2>
QBiPointer<T, T2>::QBiPointer(T2 *v)
: ptr_value(quintptr(v) | Flag2Bit)
{
+ Q_STATIC_ASSERT_X(QtPrivate::QFlagPointerAlignment<T2>::Value >= 4,
+ "Type T2 does not have sufficient alignment");
Q_ASSERT((quintptr(v) & FlagsMask) == 0);
}
diff --git a/src/qml/qml/ftw/qqmlthread.cpp b/src/qml/qml/ftw/qqmlthread.cpp
index e961ed3d0d..7d2ad354d6 100644
--- a/src/qml/qml/ftw/qqmlthread.cpp
+++ b/src/qml/qml/ftw/qqmlthread.cpp
@@ -131,6 +131,9 @@ QQmlThreadPrivate::QQmlThreadPrivate(QQmlThread *q)
m_mainThreadWaiting(false), mainSync(nullptr), m_mainObject(this)
{
setObjectName(QStringLiteral("QQmlThread"));
+ // This size is aligned with the recursion depth limits in the parser/codegen. In case of
+ // absurd content we want to hit the recursion checks instead of running out of stack.
+ setStackSize(8 * 1024 * 1024);
}
bool QQmlThreadPrivate::event(QEvent *e)
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index 254b6cc3db..9157bb95c3 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -532,6 +532,9 @@ QObject *QQmlContextPrivate::context_at(QQmlListProperty<QObject> *prop, int ind
void QQmlContextPrivate::dropDestroyedQObject(const QString &name, QObject *destroyed)
{
+ if (!data->isValid())
+ return;
+
const int idx = data->propertyNames().value(name);
Q_ASSERT(idx >= 0);
if (qvariant_cast<QObject *>(propertyValues[idx]) != destroyed)
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 73546bd795..21ca24d38b 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -1824,7 +1824,8 @@ QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader,
if (qmldirPath.size() > 25 && qmldirPath.at(0) == QLatin1Char(':') && qmldirPath.at(1) == QLatin1Char('/') &&
qmldirPath.startsWith(QStringLiteral(":/android_rcc_bundle/qml/"), Qt::CaseInsensitive)) {
QString pluginName = qmldirPath.mid(21) + Slash + baseName;
- auto bundledPath = resolvedPath + QLatin1String("lib") + pluginName.replace(QLatin1Char('/'), QLatin1Char('_'));
+ pluginName.replace(QLatin1Char('/'), QLatin1Char('_'));
+ QString bundledPath = resolvedPath + QLatin1String("lib") + pluginName;
for (const QString &suffix : suffixes) {
const QString absolutePath = typeLoader->absoluteFilePath(bundledPath + suffix);
if (!absolutePath.isEmpty())
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index eff3e94fbd..9e6819891c 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -1373,8 +1373,9 @@ bool QQmlPropertyPrivate::write(QObject *object,
}
}
if (!ok) {
- // the only other option is that they are assigning a single value
+ // the only other options are that they are assigning a single value
// to a sequence type property (eg, an int to a QList<int> property).
+ // or that we encountered an interface type
// Note that we've already handled single-value assignment to QList<QUrl> properties.
if (variantType == QVariant::Int && propertyType == qMetaTypeId<QList<int> >()) {
QList<int> list;
@@ -1405,6 +1406,15 @@ bool QQmlPropertyPrivate::write(QObject *object,
}
}
+ if (!ok && QQmlMetaType::isInterface(propertyType)) {
+ auto valueAsQObject = qvariant_cast<QObject *>(value);
+ if (valueAsQObject && valueAsQObject->qt_metacast(QQmlMetaType::interfaceIId(propertyType))) {
+ // this case can occur when object has an interface type
+ // and the variant contains a type implementing the interface
+ return property.writeProperty(object, const_cast<void *>(value.constData()), flags);
+ }
+ }
+
if (ok) {
return property.writeProperty(object, const_cast<void *>(v.constData()), flags);
} else {
diff --git a/src/qml/qml/qqmlpropertyvalidator.cpp b/src/qml/qml/qqmlpropertyvalidator.cpp
index d7361ea2c6..238a535b89 100644
--- a/src/qml/qml/qqmlpropertyvalidator.cpp
+++ b/src/qml/qml/qqmlpropertyvalidator.cpp
@@ -728,12 +728,12 @@ QQmlJS::DiagnosticMessage QQmlPropertyValidator::validateObjectBinding(QQmlPrope
return noError;
} else if (isPrimitiveType(propType)) {
auto typeName = QString::fromUtf8(QMetaType::typeName(propType));
- return qQmlCompileError(binding->location, tr("Can not assign value of type \"%1\" to property \"%2\", expecting \"%3\"")
+ return qQmlCompileError(binding->location, tr("Cannot assign value of type \"%1\" to property \"%2\", expecting \"%3\"")
.arg(rhsType())
.arg(propertyName)
.arg(typeName));
} else if (QQmlValueTypeFactory::isValueType(propType)) {
- return qQmlCompileError(binding->location, tr("Can not assign value of type \"%1\" to property \"%2\", expecting an object")
+ return qQmlCompileError(binding->location, tr("Cannot assign value of type \"%1\" to property \"%2\", expecting an object")
.arg(rhsType()).arg(propertyName));
} else if (propType == qMetaTypeId<QQmlScriptString>()) {
return qQmlCompileError(binding->valueLocation, tr("Invalid property assignment: script expected"));
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp
index d3dc4978f2..46b2c6386c 100644
--- a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp
@@ -88,10 +88,20 @@ Texture *Atlas::create(const QByteArray &data, int dataLength, int dataOffset, c
void Atlas::generateTexture()
{
+ int bytesPerBlock = 8;
+ switch (m_format) {
+ case QOpenGLTexture::RGBA8_ETC2_EAC:
+ case QOpenGLTexture::RGBA_DXT3:
+ case QOpenGLTexture::RGBA_DXT5:
+ bytesPerBlock = 16;
+ default:
+ break;
+ }
+
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
funcs->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_format,
m_size.width(), m_size.height(), 0,
- (m_size.width() * m_size.height()) / 2,
+ (m_size.width() / 4 * m_size.height() / 4) * bytesPerBlock,
nullptr);
}
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 86d9590863..dc1f97de54 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -807,9 +807,7 @@ void QSGRenderThread::syncAndRender(QImage *grabImage)
}
}
if (current) {
- const QSize outputSize = rhi ? cd->swapchain->currentPixelSize() : windowSize;
-
- d->renderSceneGraph(outputSize);
+ d->renderSceneGraph(windowSize, rhi ? cd->swapchain->currentPixelSize() : QSize());
if (profileFrames)
renderTime = threadTimer.nsecsElapsed();
diff --git a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
index ae7d9cf8cc..75a874424a 100644
--- a/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgopenglatlastexture.cpp
@@ -150,6 +150,10 @@ QSGTexture *Manager::create(const QSGCompressedTextureFactory *factory)
case QOpenGLTexture::RGB8_ETC2:
case QOpenGLTexture::RGBA8_ETC2_EAC:
case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
+ case QOpenGLTexture::RGB_DXT1:
+ case QOpenGLTexture::RGBA_DXT1:
+ case QOpenGLTexture::RGBA_DXT3:
+ case QOpenGLTexture::RGBA_DXT5:
break;
default:
return t;
@@ -158,8 +162,12 @@ QSGTexture *Manager::create(const QSGCompressedTextureFactory *factory)
QSize size = factory->m_textureData.size();
if (size.width() < m_atlas_size_limit && size.height() < m_atlas_size_limit) {
QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*>::iterator i = m_atlases.find(format);
- if (i == m_atlases.end())
- i = m_atlases.insert(format, new QSGCompressedAtlasTexture::Atlas(m_atlas_size, format));
+ if (i == m_atlases.end()) {
+ // must be multiple of 4
+ QSize paddedSize(((m_atlas_size.width() + 3) / 4) * 4, ((m_atlas_size.height() + 3) / 4) * 4);
+ i = m_atlases.insert(format, new QSGCompressedAtlasTexture::Atlas(paddedSize, format));
+ }
+
// must be multiple of 4
QSize paddedSize(((size.width() + 3) / 4) * 4, ((size.height() + 3) / 4) * 4);
QByteArray data = factory->m_textureData.data();