diff options
24 files changed, 281 insertions, 162 deletions
diff --git a/examples/qml/networkaccessmanagerfactory/main.cpp b/examples/qml/networkaccessmanagerfactory/main.cpp index 95dfb5990d..a0fddf50c6 100644 --- a/examples/qml/networkaccessmanagerfactory/main.cpp +++ b/examples/qml/networkaccessmanagerfactory/main.cpp @@ -133,7 +133,8 @@ int main(int argc, char ** argv) source = QUrl::fromLocalFile(parser.positionalArguments().first()); QQuickView view; - view.engine()->setNetworkAccessManagerFactory(new MyNetworkAccessManagerFactory); + MyNetworkAccessManagerFactory networkManagerFactory; + view.engine()->setNetworkAccessManagerFactory(&networkManagerFactory); view.setSource(source); view.show(); diff --git a/src/3rdparty/masm/assembler/ARM64Assembler.h b/src/3rdparty/masm/assembler/ARM64Assembler.h index 008f03bccf..1787e921e8 100644 --- a/src/3rdparty/masm/assembler/ARM64Assembler.h +++ b/src/3rdparty/masm/assembler/ARM64Assembler.h @@ -39,6 +39,10 @@ #include <libkern/OSCacheControl.h> #endif +#if OS(INTEGRITY) +#include <INTEGRITY.h> +#endif + #define CHECK_DATASIZE_OF(datasize) ASSERT(datasize == 32 || datasize == 64) #define DATASIZE_OF(datasize) ((datasize == 64) ? Datasize_64 : Datasize_32) #define MEMOPSIZE_OF(datasize) ((datasize == 8 || datasize == 128) ? MemOpSize_8_or_128 : (datasize == 16) ? MemOpSize_16 : (datasize == 32) ? MemOpSize_32 : MemOpSize_64) @@ -3039,6 +3043,8 @@ public: UNUSED_PARAM(code); UNUSED_PARAM(size); #endif +#elif OS(INTEGRITY) + ManageCaches((Address)code, size, ACCESS_DST_COHERENT); #else #error "The cacheFlush support is missing on this platform." #endif diff --git a/src/3rdparty/masm/assembler/AbstractMacroAssembler.h b/src/3rdparty/masm/assembler/AbstractMacroAssembler.h index 6fac27fdf1..1076384900 100644 --- a/src/3rdparty/masm/assembler/AbstractMacroAssembler.h +++ b/src/3rdparty/masm/assembler/AbstractMacroAssembler.h @@ -327,7 +327,13 @@ public: template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend struct DFG::OSRExit; + +#if CPU(ARM_THUMB2) || CPU(ARM64) || defined(V4_BOOTSTRAP) + using Jump = typename AssemblerType::template Jump<Label>; + friend Jump; +#else friend class Jump; +#endif friend class JumpReplacementWatchpoint; friend class MacroAssemblerCodeRef; template <typename, template <typename> class> friend class LinkBufferBase; diff --git a/src/3rdparty/masm/assembler/MacroAssemblerARM64.h b/src/3rdparty/masm/assembler/MacroAssemblerARM64.h index 1f94eb9032..ba0d7e93f8 100644 --- a/src/3rdparty/masm/assembler/MacroAssemblerARM64.h +++ b/src/3rdparty/masm/assembler/MacroAssemblerARM64.h @@ -3101,40 +3101,22 @@ private: } template<int datasize> - ALWAYS_INLINE void loadUnsignedImmediate(RegisterID rt, RegisterID rn, unsigned pimm) - { - m_assembler.ldr<datasize>(rt, rn, pimm); - } + void loadUnsignedImmediate(RegisterID rt, RegisterID rn, unsigned pimm); template<int datasize> - ALWAYS_INLINE void loadUnscaledImmediate(RegisterID rt, RegisterID rn, int simm) - { - m_assembler.ldur<datasize>(rt, rn, simm); - } + void loadUnscaledImmediate(RegisterID rt, RegisterID rn, int simm); template<int datasize> - ALWAYS_INLINE void loadSignedAddressedByUnsignedImmediate(RegisterID rt, RegisterID rn, unsigned pimm) - { - loadUnsignedImmediate<datasize>(rt, rn, pimm); - } + void loadSignedAddressedByUnsignedImmediate(RegisterID rt, RegisterID rn, unsigned pimm); template<int datasize> - ALWAYS_INLINE void loadSignedAddressedByUnscaledImmediate(RegisterID rt, RegisterID rn, int simm) - { - loadUnscaledImmediate<datasize>(rt, rn, simm); - } + void loadSignedAddressedByUnscaledImmediate(RegisterID rt, RegisterID rn, int simm); template<int datasize> - ALWAYS_INLINE void storeUnsignedImmediate(RegisterID rt, RegisterID rn, unsigned pimm) - { - m_assembler.str<datasize>(rt, rn, pimm); - } + void storeUnsignedImmediate(RegisterID rt, RegisterID rn, unsigned pimm); template<int datasize> - ALWAYS_INLINE void storeUnscaledImmediate(RegisterID rt, RegisterID rn, int simm) - { - m_assembler.stur<datasize>(rt, rn, simm); - } + void storeUnscaledImmediate(RegisterID rt, RegisterID rn, int simm); void moveWithFixedWidth(TrustedImm32 imm, RegisterID dest) { @@ -3299,74 +3281,19 @@ private: } template<int datasize> - ALWAYS_INLINE bool tryLoadWithOffset(RegisterID rt, RegisterID rn, int32_t offset) - { - if (ARM64Assembler::canEncodeSImmOffset(offset)) { - loadUnscaledImmediate<datasize>(rt, rn, offset); - return true; - } - if (ARM64Assembler::canEncodePImmOffset<datasize>(offset)) { - loadUnsignedImmediate<datasize>(rt, rn, static_cast<unsigned>(offset)); - return true; - } - return false; - } + bool tryLoadWithOffset(RegisterID rt, RegisterID rn, int32_t offset); template<int datasize> - ALWAYS_INLINE bool tryLoadSignedWithOffset(RegisterID rt, RegisterID rn, int32_t offset) - { - if (ARM64Assembler::canEncodeSImmOffset(offset)) { - loadSignedAddressedByUnscaledImmediate<datasize>(rt, rn, offset); - return true; - } - if (ARM64Assembler::canEncodePImmOffset<datasize>(offset)) { - loadSignedAddressedByUnsignedImmediate<datasize>(rt, rn, static_cast<unsigned>(offset)); - return true; - } - return false; - } + bool tryLoadSignedWithOffset(RegisterID rt, RegisterID rn, int32_t offset); template<int datasize> - ALWAYS_INLINE bool tryLoadWithOffset(FPRegisterID rt, RegisterID rn, int32_t offset) - { - if (ARM64Assembler::canEncodeSImmOffset(offset)) { - m_assembler.ldur<datasize>(rt, rn, offset); - return true; - } - if (ARM64Assembler::canEncodePImmOffset<datasize>(offset)) { - m_assembler.ldr<datasize>(rt, rn, static_cast<unsigned>(offset)); - return true; - } - return false; - } + bool tryLoadWithOffset(FPRegisterID rt, RegisterID rn, int32_t offset); template<int datasize> - ALWAYS_INLINE bool tryStoreWithOffset(RegisterID rt, RegisterID rn, int32_t offset) - { - if (ARM64Assembler::canEncodeSImmOffset(offset)) { - storeUnscaledImmediate<datasize>(rt, rn, offset); - return true; - } - if (ARM64Assembler::canEncodePImmOffset<datasize>(offset)) { - storeUnsignedImmediate<datasize>(rt, rn, static_cast<unsigned>(offset)); - return true; - } - return false; - } + bool tryStoreWithOffset(RegisterID rt, RegisterID rn, int32_t offset); template<int datasize> - ALWAYS_INLINE bool tryStoreWithOffset(FPRegisterID rt, RegisterID rn, int32_t offset) - { - if (ARM64Assembler::canEncodeSImmOffset(offset)) { - m_assembler.stur<datasize>(rt, rn, offset); - return true; - } - if (ARM64Assembler::canEncodePImmOffset<datasize>(offset)) { - m_assembler.str<datasize>(rt, rn, static_cast<unsigned>(offset)); - return true; - } - return false; - } + bool tryStoreWithOffset(FPRegisterID rt, RegisterID rn, int32_t offset); Jump jumpAfterFloatingPointCompare(DoubleCondition cond) { @@ -3413,6 +3340,43 @@ private: bool m_allowScratchRegister = true; }; +template<int datasize> +ALWAYS_INLINE void MacroAssemblerARM64::loadUnsignedImmediate(RegisterID rt, RegisterID rn, unsigned pimm) +{ + m_assembler.ldr<datasize>(rt, rn, pimm); +} + +template<int datasize> +ALWAYS_INLINE void MacroAssemblerARM64::loadUnscaledImmediate(RegisterID rt, RegisterID rn, int simm) +{ + m_assembler.ldur<datasize>(rt, rn, simm); +} + +template<int datasize> +ALWAYS_INLINE void MacroAssemblerARM64::loadSignedAddressedByUnsignedImmediate(RegisterID rt, RegisterID rn, unsigned pimm) +{ + loadUnsignedImmediate<datasize>(rt, rn, pimm); +} + +template<int datasize> +ALWAYS_INLINE void MacroAssemblerARM64::loadSignedAddressedByUnscaledImmediate(RegisterID rt, RegisterID rn, int simm) +{ + loadUnscaledImmediate<datasize>(rt, rn, simm); +} + +template<int datasize> +ALWAYS_INLINE void MacroAssemblerARM64::storeUnsignedImmediate(RegisterID rt, RegisterID rn, unsigned pimm) +{ + m_assembler.str<datasize>(rt, rn, pimm); +} + +template<int datasize> +ALWAYS_INLINE void MacroAssemblerARM64::storeUnscaledImmediate(RegisterID rt, RegisterID rn, int simm) +{ + m_assembler.stur<datasize>(rt, rn, simm); +} + + // Extend the {load,store}{Unsigned,Unscaled}Immediate templated general register methods to cover all load/store sizes template<> ALWAYS_INLINE void MacroAssemblerARM64::loadUnsignedImmediate<8>(RegisterID rt, RegisterID rn, unsigned pimm) @@ -3486,6 +3450,77 @@ ALWAYS_INLINE void MacroAssemblerARM64::storeUnscaledImmediate<16>(RegisterID rt m_assembler.sturh(rt, rn, simm); } +template<int datasize> +ALWAYS_INLINE bool MacroAssemblerARM64::tryLoadSignedWithOffset(RegisterID rt, RegisterID rn, int32_t offset) +{ + if (ARM64Assembler::canEncodeSImmOffset(offset)) { + loadSignedAddressedByUnscaledImmediate<datasize>(rt, rn, offset); + return true; + } + if (ARM64Assembler::canEncodePImmOffset<datasize>(offset)) { + loadSignedAddressedByUnsignedImmediate<datasize>(rt, rn, static_cast<unsigned>(offset)); + return true; + } + return false; +} + +template<int datasize> +ALWAYS_INLINE bool MacroAssemblerARM64::tryStoreWithOffset(RegisterID rt, RegisterID rn, int32_t offset) +{ + if (ARM64Assembler::canEncodeSImmOffset(offset)) { + storeUnscaledImmediate<datasize>(rt, rn, offset); + return true; + } + if (ARM64Assembler::canEncodePImmOffset<datasize>(offset)) { + storeUnsignedImmediate<datasize>(rt, rn, static_cast<unsigned>(offset)); + return true; + } + return false; +} + +template<int datasize> +ALWAYS_INLINE bool MacroAssemblerARM64::tryStoreWithOffset(FPRegisterID rt, RegisterID rn, int32_t offset) +{ + if (ARM64Assembler::canEncodeSImmOffset(offset)) { + m_assembler.stur<datasize>(rt, rn, offset); + return true; + } + if (ARM64Assembler::canEncodePImmOffset<datasize>(offset)) { + m_assembler.str<datasize>(rt, rn, static_cast<unsigned>(offset)); + return true; + } + return false; +} + + +template<int datasize> +ALWAYS_INLINE bool MacroAssemblerARM64::tryLoadWithOffset(RegisterID rt, RegisterID rn, int32_t offset) +{ + if (ARM64Assembler::canEncodeSImmOffset(offset)) { + loadUnscaledImmediate<datasize>(rt, rn, offset); + return true; + } + if (ARM64Assembler::canEncodePImmOffset<datasize>(offset)) { + loadUnsignedImmediate<datasize>(rt, rn, static_cast<unsigned>(offset)); + return true; + } + return false; +} + +template<int datasize> +ALWAYS_INLINE bool MacroAssemblerARM64::tryLoadWithOffset(FPRegisterID rt, RegisterID rn, int32_t offset) + { + if (ARM64Assembler::canEncodeSImmOffset(offset)) { + m_assembler.ldur<datasize>(rt, rn, offset); + return true; + } + if (ARM64Assembler::canEncodePImmOffset<datasize>(offset)) { + m_assembler.ldr<datasize>(rt, rn, static_cast<unsigned>(offset)); + return true; + } + return false; + } + } // namespace JSC #endif // ENABLE(ASSEMBLER) diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h index 3b84b5c986..1ab28588fb 100644 --- a/src/3rdparty/masm/stubs/ExecutableAllocator.h +++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h @@ -45,6 +45,10 @@ #include <private/qv4executableallocator_p.h> +#if OS(INTEGRITY) +#include "OSAllocator.h" +#endif + #if OS(WINDOWS) #include <windows.h> #else @@ -118,6 +122,8 @@ struct ExecutableAllocator { Q_UNREACHABLE(); } # endif +# elif OS(INTEGRITY) + OSAllocator::setMemoryAttributes(addr, /*writable*/ true, /*executable*/ false); # else int mode = PROT_READ | PROT_WRITE; if (mprotect(addr, size, mode) != 0) { @@ -152,6 +158,8 @@ struct ExecutableAllocator { Q_UNREACHABLE(); } # endif +# elif OS(INTEGRITY) + OSAllocator::setMemoryAttributes(addr, /*writable*/ false, /*executable*/ true); # else int mode = PROT_READ | PROT_EXEC; if (mprotect(addr, size, mode) != 0) { diff --git a/src/3rdparty/masm/wtf/OSAllocator.h b/src/3rdparty/masm/wtf/OSAllocator.h index 933b3cda0a..366dd73993 100644 --- a/src/3rdparty/masm/wtf/OSAllocator.h +++ b/src/3rdparty/masm/wtf/OSAllocator.h @@ -73,6 +73,10 @@ public: static T* reallocateCommitted(T*, size_t oldSize, size_t newSize, Usage = UnknownUsage, bool writable = true, bool executable = false); static bool canAllocateExecutableMemory(); + +#if defined(Q_OS_INTEGRITY) + static void setMemoryAttributes(void* addr, bool writable, bool executable); +#endif }; inline void* OSAllocator::reserveAndCommit(size_t reserveSize, size_t commitSize, Usage usage, bool writable, bool executable) diff --git a/src/3rdparty/masm/wtf/OSAllocatorIntegrity.cpp b/src/3rdparty/masm/wtf/OSAllocatorIntegrity.cpp index 451ca147d1..7addf9e5c2 100644 --- a/src/3rdparty/masm/wtf/OSAllocatorIntegrity.cpp +++ b/src/3rdparty/masm/wtf/OSAllocatorIntegrity.cpp @@ -123,6 +123,12 @@ Error setAttributes(MemoryRegion mr, bool writable, bool executable) return SetMemoryRegionAttributes(mr, attributes); } +void OSAllocator::setMemoryAttributes(void* addr, bool writable, bool executable) +{ + const MRPair* pair = memoryRegionsContainer.getMRPair((Address)addr); + CheckSuccess(setAttributes(pair->vmr, writable, executable)); +} + void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable, bool executable) { MemoryRegion VMR; @@ -229,4 +235,10 @@ void OSAllocator::releaseDecommitted(void* address, size_t bytes) memoryRegionsContainer.deleteMRPair(pair); } } + +bool OSAllocator::canAllocateExecutableMemory() +{ + return true; +} + } // namespace WTF diff --git a/src/3rdparty/masm/wtf/Platform.h b/src/3rdparty/masm/wtf/Platform.h index 4f37245495..5905f42f45 100644 --- a/src/3rdparty/masm/wtf/Platform.h +++ b/src/3rdparty/masm/wtf/Platform.h @@ -171,6 +171,11 @@ #define WTF_CPU_ARM64 1 #endif +/* CPU(ARM64) - INTEGRITY */ +#if (defined(__ARM64__)) +#define WTF_CPU_ARM64 1 +#endif + /* CPU(ARM) - ARM, any version*/ #define WTF_ARM_ARCH_AT_LEAST(N) (CPU(ARM) && WTF_ARM_ARCH_VERSION >= N) diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp index d2fb78d72a..abd7793a74 100644 --- a/src/particles/qquickimageparticle.cpp +++ b/src/particles/qquickimageparticle.cpp @@ -1321,7 +1321,7 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node) m_material = SpriteMaterial::createMaterial(); if (imageLoaded) getState<ImageMaterialData>(m_material)->texture = QSGPlainTexture::fromImage(image); - getState<ImageMaterialData>(m_material)->animSheetSize = QSizeF(image.size()); + getState<ImageMaterialData>(m_material)->animSheetSize = QSizeF(image.size() / image.devicePixelRatioF()); if (m_spriteEngine) m_spriteEngine->setCount(m_count); Q_FALLTHROUGH(); diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index b97468ab7b..348ddb25d9 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -409,7 +409,7 @@ bool QJSValue::isObject() const QV4::Value *val = QJSValuePrivate::getValue(this); if (!val) return false; - return val->as<Object>(); + return val->as<QV4::Object>(); } /*! @@ -649,7 +649,7 @@ QVariant QJSValue::toVariant() const QV4::Value *val = QJSValuePrivate::valueForData(this, &scratch); Q_ASSERT(val); - if (Object *o = val->as<Object>()) + if (QV4::Object *o = val->as<QV4::Object>()) return o->engine()->toVariant(*val, /*typeHint*/ -1, /*createJSValueForObjects*/ false); if (String *s = val->stringValue()) @@ -849,7 +849,7 @@ QJSValue QJSValue::prototype() const if (!engine) return QJSValue(); QV4::Scope scope(engine); - ScopedObject o(scope, QJSValuePrivate::getValue(this)->as<Object>()); + ScopedObject o(scope, QJSValuePrivate::getValue(this)->as<QV4::Object>()); if (!o) return QJSValue(); ScopedObject p(scope, o->prototype()); @@ -931,7 +931,7 @@ static bool js_equal(const QString &string, const QV4::Value &value) return RuntimeHelpers::stringToNumber(string) == value.asDouble(); if (value.isBoolean()) return RuntimeHelpers::stringToNumber(string) == double(value.booleanValue()); - if (Object *o = value.objectValue()) { + if (QV4::Object *o = value.objectValue()) { Scope scope(o->engine()); ScopedValue p(scope, RuntimeHelpers::toPrimitive(value, PREFERREDTYPE_HINT)); return js_equal(string, p); diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index 9cc63a98c5..6cf1e7d78a 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -101,7 +101,7 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); } # define V4_ENABLE_JIT # endif #elif defined(Q_PROCESSOR_ARM_64) && (QT_POINTER_SIZE == 8) -# if defined(Q_OS_LINUX) || defined(Q_OS_QNX) +# if defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_INTEGRITY) # define V4_ENABLE_JIT # endif //#elif defined(Q_PROCESSOR_MIPS_32) && defined(Q_OS_LINUX) diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 157de0e96e..c49abd6fef 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -106,10 +106,10 @@ QPair<QObject *, int> QObjectMethod::extractQtMethod(const QV4::FunctionObject * return qMakePair((QObject *)nullptr, -1); } -static QPair<QObject *, int> extractQtSignal(const Value &value) +static QPair<QObject *, int> extractQtSignal(const QV4::Value &value) { if (value.isObject()) { - QV4::ExecutionEngine *v4 = value.as<Object>()->engine(); + QV4::ExecutionEngine *v4 = value.as<QV4::Object>()->engine(); QV4::Scope scope(v4); QV4::ScopedFunctionObject function(scope, value); if (function) @@ -1112,7 +1112,7 @@ struct CallArgument { inline void *dataPtr(); inline void initAsType(int type); - inline void fromValue(int type, ExecutionEngine *, const Value &); + inline void fromValue(int type, ExecutionEngine *, const QV4::Value &); inline ReturnedValue toValue(ExecutionEngine *); private: @@ -1310,7 +1310,7 @@ static int MatchScore(const QV4::Value &actual, int conversionType) return 10; } } - } else if (const Object *obj = actual.as<Object>()) { + } else if (const QV4::Object *obj = actual.as<QV4::Object>()) { if (obj->as<QV4::VariantObject>()) { if (conversionType == qMetaTypeId<QVariant>()) return 0; @@ -1729,7 +1729,7 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q || callType == qMetaTypeId<std::vector<QUrl>>() || callType == qMetaTypeId<std::vector<QModelIndex>>()) { queryEngine = true; - const QV4::Object* object = value.as<Object>(); + const QV4::Object* object = value.as<QV4::Object>(); if (callType == qMetaTypeId<std::vector<int>>()) { stdVectorIntPtr = nullptr; fromContainerValue<std::vector<int>>(object, callType, &CallArgument::stdVectorIntPtr, queryEngine); diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index e5a02fdc22..61176b3706 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -200,7 +200,7 @@ void StringPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("trim"), method_trim); } -static Heap::String *thisAsString(ExecutionEngine *v4, const Value *thisObject) +static Heap::String *thisAsString(ExecutionEngine *v4, const QV4::Value *thisObject) { if (String *s = thisObject->stringValue()) return s->d(); @@ -209,7 +209,7 @@ static Heap::String *thisAsString(ExecutionEngine *v4, const Value *thisObject) return thisObject->toString(v4); } -static QString getThisString(ExecutionEngine *v4, const Value *thisObject) +static QString getThisString(ExecutionEngine *v4, const QV4::Value *thisObject) { if (String *s = thisObject->stringValue()) return s->toQString(); diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index f2c9f836ae..8e5b14d0ea 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -345,7 +345,7 @@ static struct InstrCount { if (engine->hasException) \ goto catchException -static inline Heap::CallContext *getScope(Value *stack, int level) +static inline Heap::CallContext *getScope(QV4::Value *stack, int level) { Heap::ExecutionContext *scope = static_cast<ExecutionContext &>(stack[CallData::Context]).d(); while (level > 0) { @@ -362,7 +362,7 @@ static inline const QV4::Value &constant(Function *function, int index) } -static bool compareEqual(Value lhs, Value rhs) +static bool compareEqual(QV4::Value lhs, QV4::Value rhs) { redo: if (lhs.asReturnedValue() == rhs.asReturnedValue()) @@ -376,22 +376,22 @@ static bool compareEqual(Value lhs, Value rhs) } switch (lt) { - case Value::QT_ManagedOrUndefined: + case QV4::Value::QT_ManagedOrUndefined: if (lhs.isUndefined()) return rhs.isNullOrUndefined(); Q_FALLTHROUGH(); - case Value::QT_ManagedOrUndefined1: - case Value::QT_ManagedOrUndefined2: - case Value::QT_ManagedOrUndefined3: + case QV4::Value::QT_ManagedOrUndefined1: + case QV4::Value::QT_ManagedOrUndefined2: + case QV4::Value::QT_ManagedOrUndefined3: // LHS: Managed switch (rt) { - case Value::QT_ManagedOrUndefined: + case QV4::Value::QT_ManagedOrUndefined: if (rhs.isUndefined()) return false; Q_FALLTHROUGH(); - case Value::QT_ManagedOrUndefined1: - case Value::QT_ManagedOrUndefined2: - case Value::QT_ManagedOrUndefined3: { + case QV4::Value::QT_ManagedOrUndefined1: + case QV4::Value::QT_ManagedOrUndefined2: + case QV4::Value::QT_ManagedOrUndefined3: { // RHS: Managed Heap::Base *l = lhs.m(); Heap::Base *r = rhs.m(); @@ -409,12 +409,12 @@ static bool compareEqual(Value lhs, Value rhs) } return false; } - case Value::QT_Empty: + case QV4::Value::QT_Empty: Q_UNREACHABLE(); - case Value::QT_Null: + case QV4::Value::QT_Null: return false; - case Value::QT_Bool: - case Value::QT_Int: + case QV4::Value::QT_Bool: + case QV4::Value::QT_Int: rhs = Primitive::fromDouble(rhs.int_32()); // fall through default: // double @@ -424,22 +424,22 @@ static bool compareEqual(Value lhs, Value rhs) lhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(lhs), PREFERREDTYPE_HINT)); } goto redo; - case Value::QT_Empty: + case QV4::Value::QT_Empty: Q_UNREACHABLE(); - case Value::QT_Null: + case QV4::Value::QT_Null: return rhs.isNull(); - case Value::QT_Bool: - case Value::QT_Int: + case QV4::Value::QT_Bool: + case QV4::Value::QT_Int: switch (rt) { - case Value::QT_ManagedOrUndefined: - case Value::QT_ManagedOrUndefined1: - case Value::QT_ManagedOrUndefined2: - case Value::QT_ManagedOrUndefined3: - case Value::QT_Empty: - case Value::QT_Null: + case QV4::Value::QT_ManagedOrUndefined: + case QV4::Value::QT_ManagedOrUndefined1: + case QV4::Value::QT_ManagedOrUndefined2: + case QV4::Value::QT_ManagedOrUndefined3: + case QV4::Value::QT_Empty: + case QV4::Value::QT_Null: Q_UNREACHABLE(); - case Value::QT_Bool: - case Value::QT_Int: + case QV4::Value::QT_Bool: + case QV4::Value::QT_Int: return lhs.int_32() == rhs.int_32(); default: // double return lhs.int_32() == rhs.doubleValue(); @@ -450,29 +450,29 @@ static bool compareEqual(Value lhs, Value rhs) } } -static bool compareEqualInt(Value &accumulator, Value lhs, int rhs) +static bool compareEqualInt(QV4::Value &accumulator, QV4::Value lhs, int rhs) { redo: switch (lhs.quickType()) { - case Value::QT_ManagedOrUndefined: + case QV4::Value::QT_ManagedOrUndefined: if (lhs.isUndefined()) return false; Q_FALLTHROUGH(); - case Value::QT_ManagedOrUndefined1: - case Value::QT_ManagedOrUndefined2: - case Value::QT_ManagedOrUndefined3: + case QV4::Value::QT_ManagedOrUndefined1: + case QV4::Value::QT_ManagedOrUndefined2: + case QV4::Value::QT_ManagedOrUndefined3: // LHS: Managed if (lhs.m()->internalClass->vtable->isString) return RuntimeHelpers::stringToNumber(static_cast<String &>(lhs).toQString()) == rhs; accumulator = lhs; lhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(accumulator), PREFERREDTYPE_HINT)); goto redo; - case Value::QT_Empty: + case QV4::Value::QT_Empty: Q_UNREACHABLE(); - case Value::QT_Null: + case QV4::Value::QT_Null: return false; - case Value::QT_Bool: - case Value::QT_Int: + case QV4::Value::QT_Bool: + case QV4::Value::QT_Int: return lhs.int_32() == rhs; default: // double return lhs.doubleValue() == rhs; @@ -500,11 +500,11 @@ static bool compareEqualInt(Value &accumulator, Value lhs, int rhs) } \ } while (false) -QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject, const Value *argv, int argc) +QV4::ReturnedValue VME::exec(const FunctionObject *fo, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { qt_v4ResolvePendingBreakpointsHook(); ExecutionEngine *engine; - Value *stack; + QV4::Value *stack; CppStackFrame frame; frame.originalArguments = argv; frame.originalArgumentsCount = argc; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 1ae39423e9..d62d91456f 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1205,6 +1205,8 @@ void QQmlEnginePrivate::registerFinalizeCallback(QObject *obj, int index) support. The factory must be set before executing the engine. + + \note QQmlEngine does not take ownership of the factory. */ void QQmlEngine::setNetworkAccessManagerFactory(QQmlNetworkAccessManagerFactory *factory) { diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp index d361efc79b..c2f1390ada 100644 --- a/src/quick/items/qquickanimatedsprite.cpp +++ b/src/quick/items/qquickanimatedsprite.cpp @@ -537,6 +537,8 @@ void QQuickAnimatedSprite::setSource(QUrl arg) Q_D(QQuickAnimatedSprite); if (d->m_sprite->m_source != arg) { + const qreal targetDevicePixelRatio = (window() ? window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio()); + d->m_sprite->setDevicePixelRatio(targetDevicePixelRatio); d->m_sprite->setSource(arg); Q_EMIT sourceChanged(arg); reloadImage(); @@ -723,7 +725,7 @@ QSGSpriteNode* QQuickAnimatedSprite::initNode() QSGSpriteNode *node = d->sceneGraphContext()->createSpriteNode(); - d->m_sheetSize = QSize(image.size()); + d->m_sheetSize = QSize(image.size() / image.devicePixelRatioF()); node->setTexture(window()->createTextureFromImage(image)); d->m_spriteEngine->start(0); node->setTime(0.0f); diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 1be4bafe28..3343ea3fa7 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -1572,6 +1572,13 @@ void QQuickPointerTouchEvent::clearGrabbers() const { } } +Qt::TouchPointStates QQuickPointerTouchEvent::touchPointStates() const +{ + return m_event + ? static_cast<QTouchEvent*>(m_event)->touchPointStates() + : Qt::TouchPointStates(); +} + /*! Returns whether the given \a handler is the exclusive grabber of any touchpoint within this event. @@ -1586,17 +1593,17 @@ bool QQuickPointerTouchEvent::hasExclusiveGrabber(const QQuickPointerHandler *ha bool QQuickPointerTouchEvent::isPressEvent() const { - return static_cast<QTouchEvent*>(m_event)->touchPointStates() & Qt::TouchPointPressed; + return touchPointStates() & Qt::TouchPointPressed; } bool QQuickPointerTouchEvent::isUpdateEvent() const { - return static_cast<QTouchEvent*>(m_event)->touchPointStates() & (Qt::TouchPointMoved | Qt::TouchPointStationary); + return touchPointStates() & (Qt::TouchPointMoved | Qt::TouchPointStationary); } bool QQuickPointerTouchEvent::isReleaseEvent() const { - return static_cast<QTouchEvent*>(m_event)->touchPointStates() & Qt::TouchPointReleased; + return touchPointStates() & Qt::TouchPointReleased; } QVector<QPointF> QQuickPointerEvent::unacceptedPressedPointScenePositions() const diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index 2a1e9dc184..00ee0e18f9 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -510,6 +510,8 @@ public: QTouchEvent *asTouchEvent() const; private: + Qt::TouchPointStates touchPointStates() const; + int m_pointCount = 0; QVector<QQuickEventTouchPoint *> m_touchPoints; mutable QMouseEvent m_synthMouseEvent; diff --git a/src/quick/items/qquickimagebase_p.h b/src/quick/items/qquickimagebase_p.h index eb04a1d162..d8d0be9b8c 100644 --- a/src/quick/items/qquickimagebase_p.h +++ b/src/quick/items/qquickimagebase_p.h @@ -98,7 +98,7 @@ public: virtual void setAutoTransform(bool transform); bool autoTransform() const; - void resolve2xLocalFile(const QUrl &url, qreal targetDevicePixelRatio, QUrl *sourceUrl, qreal *sourceDevicePixelRatio); + static void resolve2xLocalFile(const QUrl &url, qreal targetDevicePixelRatio, QUrl *sourceUrl, qreal *sourceDevicePixelRatio); // Use a virtual rather than a signal->signal to avoid the huge // connect/conneciton overhead for this rare case. diff --git a/src/quick/items/qquicksprite.cpp b/src/quick/items/qquicksprite.cpp index 6b8567439b..8c59a68982 100644 --- a/src/quick/items/qquicksprite.cpp +++ b/src/quick/items/qquicksprite.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "qquicksprite_p.h" +#include "qquickimagebase_p.h" #include <qqml.h> #include <QDebug> #include <QRandomGenerator> @@ -222,6 +223,7 @@ QQuickSprite::QQuickSprite(QObject *parent) , m_frameDuration(unsetDuration) , m_frameDurationVariation(0) , m_frameSync(false) + , m_devicePixelRatio(1.0) { } @@ -265,7 +267,10 @@ void QQuickSprite::startImageLoading() if (!e) qWarning() << "QQuickSprite: Cannot find QQmlEngine - this class is only for use in QML and may not work"; } - m_pix.load(e, m_source); + QUrl loadUrl = m_source; + QQuickImageBase::resolve2xLocalFile(m_source, m_devicePixelRatio, &loadUrl, &m_devicePixelRatio); + + m_pix.load(e, loadUrl); } } diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h index 8e119a80a9..fab9e75190 100644 --- a/src/quick/items/qquicksprite_p.h +++ b/src/quick/items/qquicksprite_p.h @@ -168,6 +168,16 @@ public: return m_frameSync; } + void setDevicePixelRatio(qreal dpr) + { + m_devicePixelRatio = dpr; + } + + qreal devicePixelRatio() const + { + return m_devicePixelRatio; + } + Q_SIGNALS: void sourceChanged(QUrl arg); @@ -308,6 +318,7 @@ private: friend class QQuickAnimatedSprite; friend class QQuickSpriteEngine; friend class QQuickStochasticEngine; + int m_generatedCount; int m_framesPerRow; int m_rowY; @@ -325,6 +336,7 @@ private: int m_frameDuration; int m_frameDurationVariation; bool m_frameSync; + qreal m_devicePixelRatio; QQuickPixmap m_pix; }; diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp index 1fd15e61e3..03f0fa94a4 100644 --- a/src/quick/items/qquickspriteengine.cpp +++ b/src/quick/items/qquickspriteengine.cpp @@ -390,6 +390,7 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize) int w = 0; m_maxFrames = 0; m_imageStateCount = 0; + qreal pixelRatio = 1.0; for (QQuickSprite* state : qAsConst(m_sprites)) { if (state->frames() > m_maxFrames) @@ -413,6 +414,8 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize) if (!state->m_frameHeight) state->m_frameHeight = img.height(); + pixelRatio = qMax(pixelRatio, state->devicePixelRatio()); + if (state->frames() * state->frameWidth() > maxSize){ struct helper{ static int divRoundUp(int a, int b){return (a+b-1)/b;} @@ -437,43 +440,58 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize) } } + if (h > maxSize){ + qWarning() << "SpriteEngine: Too many animations to fit in one texture..."; + qWarning() << "SpriteEngine: Your texture max size today is " << maxSize; + return QImage(); + } + //maxFrames is max number in a line of the texture - QImage image(w, h, QImage::Format_ARGB32_Premultiplied); + QImage image(w * pixelRatio, h * pixelRatio, QImage::Format_ARGB32_Premultiplied); + image.setDevicePixelRatio(pixelRatio); image.fill(0); QPainter p(&image); int y = 0; for (QQuickSprite* state : qAsConst(m_sprites)) { QImage img(state->m_pix.image()); - int frameWidth = state->m_frameWidth; - int frameHeight = state->m_frameHeight; - if (img.height() == frameHeight && img.width() < maxSize){//Simple case - p.drawImage(0,y,img.copy(state->m_frameX,0,state->m_frames * frameWidth, frameHeight)); + const int frameWidth = state->m_frameWidth; + const int frameHeight = state->m_frameHeight; + const int imgHeight = img.height() / state->devicePixelRatio(); + const int imgWidth = img.width() / state->devicePixelRatio(); + if (imgHeight == frameHeight && imgWidth < maxSize){ //Simple case + p.drawImage(QRect(0, y, state->m_frames * frameWidth, frameHeight), + img, + QRect(state->m_frameX * state->devicePixelRatio(), 0, state->m_frames * frameWidth * state->devicePixelRatio(), frameHeight * state->devicePixelRatio())); state->m_rowStartX = 0; state->m_rowY = y; y += frameHeight; - }else{//Chopping up image case - state->m_framesPerRow = image.width()/frameWidth; + } else { //Chopping up image case + state->m_framesPerRow = w/frameWidth; state->m_rowY = y; int x = 0; int curX = state->m_frameX; int curY = state->m_frameY; int framesLeft = state->frames(); while (framesLeft > 0){ - if (image.width() - x + curX <= img.width()){//finish a row in image (dest) - int copied = image.width() - x; + if (w - x + curX <= imgWidth){//finish a row in image (dest) + int copied = w - x; framesLeft -= copied/frameWidth; - p.drawImage(x,y,img.copy(curX,curY,copied,frameHeight)); + p.drawImage(QRect(x, y, copied, frameHeight), + img, + QRect(curX * state->devicePixelRatio(), curY * state->devicePixelRatio(), copied * state->devicePixelRatio(), frameHeight * state->devicePixelRatio())); y += frameHeight; curX += copied; x = 0; - if (curX == img.width()){ + if (curX == imgWidth){ curX = 0; curY += frameHeight; } }else{//finish a row in img (src) - int copied = img.width() - curX; + int copied = imgWidth - curX; framesLeft -= copied/frameWidth; - p.drawImage(x,y,img.copy(curX,curY,copied,frameHeight)); + p.drawImage(QRect(x, y, copied, frameHeight), + img, + QRect(curX * state->devicePixelRatio(), curY * state->devicePixelRatio(), copied * state->devicePixelRatio(), frameHeight * state->devicePixelRatio())); curY += frameHeight; x += copied; curX = 0; @@ -484,12 +502,6 @@ QImage QQuickSpriteEngine::assembledImage(int maxSize) } } - if (image.height() > maxSize){ - qWarning() << "SpriteEngine: Too many animations to fit in one texture..."; - qWarning() << "SpriteEngine: Your texture max size today is " << maxSize; - return QImage(); - } - #ifdef SPRITE_IMAGE_DEBUG QString fPath = QDir::tempPath() + "/SpriteImage.%1.png"; int acc = 0; diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp index 72761ab82b..df6a6e336e 100644 --- a/src/quick/items/qquickspritesequence.cpp +++ b/src/quick/items/qquickspritesequence.cpp @@ -226,7 +226,7 @@ QSGSpriteNode *QQuickSpriteSequence::initNode() QSGSpriteNode *node = d->sceneGraphContext()->createSpriteNode(); - d->m_sheetSize = QSize(image.size()); + d->m_sheetSize = QSize(image.size() / image.devicePixelRatioF()); node->setTexture(window()->createTextureFromImage(image)); d->m_spriteEngine->start(0); node->setTime(0.0f); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp index ba7bbc2d11..d4e5e98d68 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp @@ -123,7 +123,7 @@ void QSGSoftwareSpriteNode::paint(QPainter *painter) // XXX try to do some kind of interpolation between sourceA and sourceB using time painter->drawPixmap(QRectF(0, 0, m_size.width(), m_size.height()), pixmap, - QRectF(m_sourceA, m_spriteSize)); + QRectF(m_sourceA * pixmap.devicePixelRatioF(), m_spriteSize * pixmap.devicePixelRatioF())); } bool QSGSoftwareSpriteNode::isOpaque() const |