aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@qt.io>2018-06-04 10:45:14 +0200
committerMorten Johan Sørvig <morten.sorvig@qt.io>2018-06-04 10:45:14 +0200
commit3ca5f33c8b9c273f0169ec4c11417328f8071e97 (patch)
tree155da80482fb4593ca074f7a1bf9b22d031dba4a /src
parent5f4698c4e7952d64e78e3a06de5ac28d68415b19 (diff)
parentb7a1bcd83a8f68185b617b860cef6f2d2d7c8d9b (diff)
Merge remote-tracking branch 'gerrit/5.11' into wip/webassembly
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/masm/assembler/ARM64Assembler.h6
-rw-r--r--src/3rdparty/masm/assembler/AbstractMacroAssembler.h6
-rw-r--r--src/3rdparty/masm/assembler/MacroAssemblerARM64.h203
-rw-r--r--src/3rdparty/masm/stubs/ExecutableAllocator.h8
-rw-r--r--src/3rdparty/masm/wtf/OSAllocator.h4
-rw-r--r--src/3rdparty/masm/wtf/OSAllocatorIntegrity.cpp12
-rw-r--r--src/3rdparty/masm/wtf/Platform.h5
-rw-r--r--src/imports/imports.pro6
-rw-r--r--src/particles/qquickimageparticle.cpp2
-rw-r--r--src/plugins/qmltooling/packetprotocol/packetprotocol.pro4
-rw-r--r--src/plugins/qmltooling/packetprotocol/qversionedpacket_p.h (renamed from src/plugins/qmltooling/packetprotocol/qqmldebugpacket_p.h)18
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp68
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp46
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp5
-rw-r--r--src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp5
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp1
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h3
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h3
-rw-r--r--src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp5
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp3
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp30
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h10
-rw-r--r--src/qml/compiler/qv4codegen.cpp2
-rw-r--r--src/qml/debugger/qqmlprofilerdefinitions_p.h27
-rw-r--r--src/qml/jit/qv4assembler.cpp3
-rw-r--r--src/qml/jsapi/qjsvalue.cpp8
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp7
-rw-r--r--src/qml/jsruntime/qv4function.cpp9
-rw-r--r--src/qml/jsruntime/qv4global_p.h2
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp10
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp2
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp74
-rw-r--r--src/qml/qml/qqmlcontext.cpp13
-rw-r--r--src/qml/qml/qqmlcontext_p.h5
-rw-r--r--src/qml/qml/qqmlengine.cpp2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp11
-rw-r--r--src/qml/qml/qqmlmetatype_p.h2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp4
-rw-r--r--src/qml/qml/qqmltypeloader.cpp62
-rw-r--r--src/qml/qml/qqmltypeloader_p.h6
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp2
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp7
-rw-r--r--src/qml/types/qqmllistmodel.cpp4
-rw-r--r--src/qmldebug/qmldebug.pro5
-rw-r--r--src/qmldebug/qqmlenginecontrolclient.cpp3
-rw-r--r--src/qmldebug/qqmlprofilerclient.cpp1
-rw-r--r--src/qmldebug/qqmlprofilerclient_p.h4
-rw-r--r--src/qmldebug/qqmlprofilerclient_p_p.h6
-rw-r--r--src/qmldebug/qqmlprofilerclientdefinitions_p.h163
-rw-r--r--src/qmldebug/qqmlprofilerevent_p.h4
-rw-r--r--src/qmldebug/qqmlprofilereventtype.cpp26
-rw-r--r--src/qmldebug/qqmlprofilereventtype_p.h5
-rw-r--r--src/qmldebug/qqmlprofilertypedevent.cpp91
-rw-r--r--src/qmltest/quicktest.cpp8
-rw-r--r--src/quick/configure.json1
-rw-r--r--src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc5
-rw-r--r--src/quick/handlers/qquickmultipointhandler.cpp2
-rw-r--r--src/quick/handlers/qquickpinchhandler.cpp7
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp2
-rw-r--r--src/quick/items/qquickanimatedimage.cpp16
-rw-r--r--src/quick/items/qquickanimatedsprite.cpp4
-rw-r--r--src/quick/items/qquickevents.cpp34
-rw-r--r--src/quick/items/qquickevents_p_p.h10
-rw-r--r--src/quick/items/qquickimagebase_p.h2
-rw-r--r--src/quick/items/qquickitem.cpp11
-rw-r--r--src/quick/items/qquicklistview.cpp7
-rw-r--r--src/quick/items/qquickmousearea.cpp2
-rw-r--r--src/quick/items/qquicksprite.cpp7
-rw-r--r--src/quick/items/qquicksprite_p.h12
-rw-r--r--src/quick/items/qquickspriteengine.cpp50
-rw-r--r--src/quick/items/qquickspritesequence.cpp2
-rw-r--r--src/quick/items/qquicktextcontrol.cpp8
-rw-r--r--src/quick/items/qquickwindow.cpp9
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp11
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp117
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h10
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp12
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h3
-rw-r--r--src/quick/scenegraph/scenegraph.pri1
-rw-r--r--src/src.pro4
90 files changed, 886 insertions, 522 deletions
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 a81ef4589a..edb688923b 100644
--- a/src/3rdparty/masm/wtf/Platform.h
+++ b/src/3rdparty/masm/wtf/Platform.h
@@ -172,6 +172,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/imports/imports.pro b/src/imports/imports.pro
index 5d7e434884..e188602277 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -17,14 +17,14 @@ qtHaveModule(quick) {
handlers \
layouts \
qtquick2 \
- window \
- testlib
+ window
+ qtHaveModule(testlib): SUBDIRS += testlib
qtConfig(systemsemaphore): SUBDIRS += sharedimage
qtConfig(quick-particles): \
SUBDIRS += particles
- SUBDIRS += shapes
+ qtConfig(quick-path): SUBDIRS += shapes
}
qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel
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/plugins/qmltooling/packetprotocol/packetprotocol.pro b/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
index 990d3169ad..a188b87a81 100644
--- a/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
+++ b/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
@@ -1,11 +1,11 @@
TARGET = QtPacketProtocol
-QT = core-private qml-private
+QT = core-private
CONFIG += static internal_module
HEADERS = \
qpacketprotocol_p.h \
qpacket_p.h \
- qqmldebugpacket_p.h
+ qversionedpacket_p.h
SOURCES = \
qpacketprotocol.cpp \
diff --git a/src/plugins/qmltooling/packetprotocol/qqmldebugpacket_p.h b/src/plugins/qmltooling/packetprotocol/qversionedpacket_p.h
index 9a0f8cd82d..635072adbc 100644
--- a/src/plugins/qmltooling/packetprotocol/qqmldebugpacket_p.h
+++ b/src/plugins/qmltooling/packetprotocol/qversionedpacket_p.h
@@ -37,14 +37,11 @@
**
****************************************************************************/
-#ifndef QQMLDEBUGPACKET_P_H
-#define QQMLDEBUGPACKET_P_H
+#ifndef QVERSIONEDPACKET_P_H
+#define QVERSIONEDPACKET_P_H
#include "qpacket_p.h"
-#include <QtCore/qbuffer.h>
-#include <QtQml/private/qqmldebugconnector_p.h>
-
//
// W A R N I N G
// -------------
@@ -58,14 +55,15 @@
QT_BEGIN_NAMESPACE
-// QPacket with a fixed data stream version, centrally set by QQmlDebugServer
-class QQmlDebugPacket : public QPacket
+// QPacket with a fixed data stream version, centrally set by some Connector
+template<class Connector>
+class QVersionedPacket : public QPacket
{
public:
- QQmlDebugPacket() : QPacket(QQmlDebugConnector::dataStreamVersion()) {}
- QQmlDebugPacket(const QByteArray &ba) : QPacket(QQmlDebugConnector::dataStreamVersion(), ba) {}
+ QVersionedPacket(const QByteArray &ba) : QPacket(Connector::dataStreamVersion(), ba) {}
+ QVersionedPacket() : QPacket(Connector::dataStreamVersion()) {}
};
QT_END_NAMESPACE
-#endif // QQMLDEBUGPACKET_P_H
+#endif // QVERSIONEDPACKET_P_H
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
index 236109d041..17bae6d695 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
@@ -55,11 +55,19 @@
#include <QtCore/qdebug.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qfileinfo.h>
+#include <QtCore/qjsonvalue.h>
+#include <QtCore/qjsonobject.h>
+#include <QtCore/qjsonarray.h>
+#include <QtCore/qjsondocument.h>
+
#include <private/qmetaobject_p.h>
-#include <private/qqmldebugpacket_p.h>
+#include <private/qqmldebugconnector_p.h>
+#include <private/qversionedpacket_p.h>
QT_BEGIN_NAMESPACE
+using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
+
QQmlEngineDebugServiceImpl::QQmlEngineDebugServiceImpl(QObject *parent) :
QQmlEngineDebugService(2, parent), m_watch(new QQmlWatcher(this)), m_statesDelegate(nullptr)
{
@@ -208,34 +216,40 @@ QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const
return contents;
}
- if (QQmlValueTypeFactory::isValueType(userType)) {
- switch (userType) {
- case QMetaType::QRect:
- case QMetaType::QRectF:
- case QMetaType::QPoint:
- case QMetaType::QPointF:
- case QMetaType::QSize:
- case QMetaType::QSizeF:
- case QMetaType::QFont:
- // Don't call the toString() method on those. The stream operators are better.
- return value;
- default:
- break;
- }
-
- const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(userType);
- if (mo) {
- int toStringIndex = mo->indexOfMethod("toString()");
- if (toStringIndex != -1) {
- QMetaMethod mm = mo->method(toStringIndex);
- QString s;
- if (mm.invokeOnGadget(value.data(), Q_RETURN_ARG(QString, s)))
- return s;
+ switch (userType) {
+ case QMetaType::QRect:
+ case QMetaType::QRectF:
+ case QMetaType::QPoint:
+ case QMetaType::QPointF:
+ case QMetaType::QSize:
+ case QMetaType::QSizeF:
+ case QMetaType::QFont:
+ // Don't call the toString() method on those. The stream operators are better.
+ return value;
+ case QMetaType::QJsonValue:
+ return value.toJsonValue().toVariant();
+ case QMetaType::QJsonObject:
+ return value.toJsonObject().toVariantMap();
+ case QMetaType::QJsonArray:
+ return value.toJsonArray().toVariantList();
+ case QMetaType::QJsonDocument:
+ return value.toJsonDocument().toVariant();
+ default:
+ if (QQmlValueTypeFactory::isValueType(userType)) {
+ const QMetaObject *mo = QQmlValueTypeFactory::metaObjectForMetaType(userType);
+ if (mo) {
+ int toStringIndex = mo->indexOfMethod("toString()");
+ if (toStringIndex != -1) {
+ QMetaMethod mm = mo->method(toStringIndex);
+ QString s;
+ if (mm.invokeOnGadget(value.data(), Q_RETURN_ARG(QString, s)))
+ return s;
+ }
}
- }
- // We expect all QML value types to either have a toString() method or stream operators
- return value;
+ // We expect all QML value types to either have a toString() method or stream operators
+ return value;
+ }
}
if (QQmlMetaType::isQObject(userType)) {
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index c86f3d1803..95e6d5704c 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -72,16 +72,12 @@ QV4::Heap::ExecutionContext *QV4DataCollector::findContext(int frame)
return f ? f->context()->d() : nullptr;
}
-QV4::Heap::CallContext *QV4DataCollector::findScope(QV4::Heap::ExecutionContext *ctx, int scope)
+QV4::Heap::ExecutionContext *QV4DataCollector::findScope(QV4::Heap::ExecutionContext *ctx, int scope)
{
- if (!ctx)
- return nullptr;
-
for (; scope > 0 && ctx; --scope)
ctx = ctx->outer;
- return (ctx && ctx->type == QV4::Heap::ExecutionContext::Type_CallContext) ?
- static_cast<QV4::Heap::CallContext *>(ctx) : nullptr;
+ return ctx;
}
QVector<QV4::Heap::ExecutionContext::ContextType> QV4DataCollector::getScopeTypes(int frame)
@@ -108,6 +104,7 @@ int QV4DataCollector::encodeScopeType(QV4::Heap::ExecutionContext::ContextType s
case QV4::Heap::ExecutionContext::Type_CallContext:
return 1;
case QV4::Heap::ExecutionContext::Type_QmlContext:
+ return 3;
default:
return -1;
}
@@ -259,31 +256,32 @@ bool QV4DataCollector::isValidRef(QV4DataCollector::Ref ref) const
bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr)
{
- QStringList names;
-
QV4::Scope scope(engine());
- QV4::Scoped<QV4::CallContext> ctxt(scope, findScope(findContext(frameNr), scopeNr));
+ QV4::Scoped<QV4::ExecutionContext> ctxt(scope, findScope(findContext(frameNr), scopeNr));
if (!ctxt)
return false;
- Refs collectedRefs;
- QV4::ScopedValue v(scope);
- QV4::InternalClass *ic = ctxt->internalClass();
- for (uint i = 0; i < ic->size; ++i) {
- QString name = ic->nameMap[i]->string;
- names.append(name);
- v = ctxt->d()->locals[i];
- collectedRefs.append(collect(v));
- }
-
QV4::ScopedObject scopeObject(scope, engine()->newObject());
+ if (ctxt->d()->type == QV4::Heap::ExecutionContext::Type_CallContext) {
+ QStringList names;
+ Refs collectedRefs;
+
+ QV4::ScopedValue v(scope);
+ QV4::InternalClass *ic = ctxt->internalClass();
+ for (uint i = 0; i < ic->size; ++i) {
+ QString name = ic->nameMap[i]->string;
+ names.append(name);
+ v = static_cast<QV4::Heap::CallContext *>(ctxt->d())->locals[i];
+ collectedRefs.append(collect(v));
+ }
- Q_ASSERT(names.size() == collectedRefs.size());
- QV4::ScopedString propName(scope);
- for (int i = 0, ei = collectedRefs.size(); i != ei; ++i) {
- propName = engine()->newString(names.at(i));
- scopeObject->put(propName, QV4::Value::fromReturnedValue(getValue(collectedRefs.at(i))));
+ Q_ASSERT(names.size() == collectedRefs.size());
+ QV4::ScopedString propName(scope);
+ for (int i = 0, ei = collectedRefs.size(); i != ei; ++i) {
+ propName = engine()->newString(names.at(i));
+ scopeObject->put(propName, (v = getValue(collectedRefs.at(i))));
+ }
}
Ref scopeObjectRef = addRef(scopeObject);
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
index 87be009de5..5494e10e9a 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
@@ -58,7 +58,7 @@ public:
typedef uint Ref;
typedef QVector<uint> Refs;
- static QV4::Heap::CallContext *findScope(QV4::Heap::ExecutionContext *ctxt, int scope);
+ static QV4::Heap::ExecutionContext *findScope(QV4::Heap::ExecutionContext *ctxt, int scope);
static int encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType);
QVector<QV4::Heap::ExecutionContext::ContextType> getScopeTypes(int frame);
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
index 61209e08cb..32de8e9027 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
@@ -45,7 +45,7 @@
#include <private/qv4function_p.h>
#include <private/qqmldebugconnector_p.h>
#include <private/qv8engine_p.h>
-#include <private/qqmldebugpacket_p.h>
+#include <private/qversionedpacket_p.h>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>
@@ -70,6 +70,8 @@ QT_BEGIN_NAMESPACE
class V8CommandHandler;
class UnknownV8CommandHandler;
+using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
+
int QV4DebugServiceImpl::sequence = 0;
class V8CommandHandler
diff --git a/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
index 7ce83daed6..bac4e01df1 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
@@ -44,7 +44,8 @@
#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qabstractanimation_p.h>
#include <private/qqmlcomponent_p.h>
-#include <private/qqmldebugpacket_p.h>
+#include <private/qqmldebugconnector_p.h>
+#include <private/qversionedpacket_p.h>
#include <QtGui/qwindow.h>
@@ -63,6 +64,8 @@
QT_BEGIN_NAMESPACE
+using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
+
const char REQUEST[] = "request";
const char RESPONSE[] = "response";
const char EVENT[] = "event";
diff --git a/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp
index 2bf9210b37..4f6cb9364d 100644
--- a/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp
@@ -40,10 +40,12 @@
#include "qdebugmessageservice.h"
#include <private/qqmldebugconnector_p.h>
-#include <private/qqmldebugpacket_p.h>
+#include <private/qversionedpacket_p.h>
QT_BEGIN_NAMESPACE
+using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
+
void DebugMessageHandler(QtMsgType type, const QMessageLogContext &ctxt,
const QString &buf)
{
diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
index 93ac875e2d..bf73440a39 100644
--- a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
+++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
@@ -40,7 +40,7 @@
#include "qqmlnativedebugconnector.h"
#include <private/qhooks_p.h>
-#include <private/qqmldebugpacket_p.h>
+#include <private/qversionedpacket_p.h>
#include <QtQml/qjsengine.h>
#include <QtCore/qdebug.h>
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
index e17fe92983..b19115aa60 100644
--- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
@@ -49,7 +49,7 @@
#include <private/qv4objectiterator_p.h>
#include <private/qv4identifier_p.h>
#include <private/qv4runtime_p.h>
-#include <private/qqmldebugpacket_p.h>
+#include <private/qversionedpacket_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
#include <QtQml/qjsengine.h>
@@ -65,6 +65,8 @@
QT_BEGIN_NAMESPACE
+using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
+
class BreakPoint
{
public:
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
index 4eedb4bd51..f76add448f 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
@@ -38,11 +38,14 @@
****************************************************************************/
#include "qqmlenginecontrolservice.h"
-#include <private/qqmldebugpacket_p.h>
+#include <private/qqmldebugconnector_p.h>
+#include <private/qversionedpacket_p.h>
#include <QJSEngine>
QT_BEGIN_NAMESPACE
+using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
+
QQmlEngineControlServiceImpl::QQmlEngineControlServiceImpl(QObject *parent) :
QQmlEngineControlService(1, parent)
{
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
index 5ff1b1f97e..19104927f2 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
@@ -38,8 +38,8 @@
****************************************************************************/
#include "qqmlprofileradapter.h"
+#include "qqmlprofilerservice.h"
-#include <private/qqmldebugpacket_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
index 7014249c83..21a5663f59 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
@@ -43,7 +43,6 @@
#include "qqmlprofilerservicefactory.h"
#include <private/qjsengine_p.h>
-#include <private/qqmldebugpacket_p.h>
#include <private/qqmldebugpluginmanager_p.h>
#include <QtCore/qurl.h>
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
index a8c3047421..2b92a478c1 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
@@ -56,6 +56,8 @@
#include <private/qqmlprofilerdefinitions_p.h>
#include <private/qqmlabstractprofileradapter_p.h>
#include <private/qqmlboundsignal_p.h>
+#include <private/qqmldebugconnector_p.h>
+#include <private/qversionedpacket_p.h>
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qmetaobject.h>
@@ -70,6 +72,7 @@
QT_BEGIN_NAMESPACE
class QUrl;
+using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
class QQmlProfilerServiceImpl :
public QQmlConfigurableDebugService<QQmlProfilerService>,
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
index 7ac378acd9..2211c82fc5 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
@@ -51,9 +51,10 @@
// We mean it.
//
+#include "qqmlprofilerservice.h"
+
#include <private/qv4profiling_p.h>
#include <private/qqmlabstractprofileradapter_p.h>
-#include <private/qqmldebugpacket_p.h>
#include <QStack>
#include <QList>
diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp
index a05d11664d..2c152e4cd5 100644
--- a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp
@@ -40,12 +40,15 @@
#include "qquickprofileradapter.h"
#include <QCoreApplication>
-#include <private/qqmldebugpacket_p.h>
+#include <private/qqmldebugconnector_p.h>
+#include <private/qversionedpacket_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qquickprofiler_p.h>
QT_BEGIN_NAMESPACE
+using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
+
QQuickProfilerAdapter::QQuickProfilerAdapter(QObject *parent) :
QQmlAbstractProfilerAdapter(parent), next(0)
{
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
index 1814e28b83..c1e86f0b3c 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
@@ -47,7 +47,7 @@
#include <private/qqmldebugpluginmanager_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qpacketprotocol_p.h>
-#include <private/qqmldebugpacket_p.h>
+#include <private/qversionedpacket_p.h>
#include <QtCore/QAtomicInt>
#include <QtCore/QDir>
@@ -83,6 +83,7 @@ QT_BEGIN_NAMESPACE
Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugServerConnection)
const int protocolVersion = 1;
+using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
class QQmlDebugServerImpl;
class QQmlDebugServerThread : public QThread
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 4a1b27d7aa..8a1b3744ee 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -322,16 +322,16 @@ Document::Document(bool debugMode)
{
}
-ScriptDirectivesCollector::ScriptDirectivesCollector(QQmlJS::Engine *engine, QV4::Compiler::JSUnitGenerator *unitGenerator)
- : engine(engine)
- , jsGenerator(unitGenerator)
- , hasPragmaLibrary(false)
+ScriptDirectivesCollector::ScriptDirectivesCollector(Document *doc)
+ : document(doc)
+ , engine(&doc->jsParserEngine)
+ , jsGenerator(&doc->jsGenerator)
{
}
void ScriptDirectivesCollector::pragmaLibrary()
{
- hasPragmaLibrary = true;
+ document->jsModule.unitFlags |= QV4::CompiledData::Unit::IsSharedLibrary;
}
void ScriptDirectivesCollector::importFile(const QString &jsfile, const QString &module, int lineNumber, int column)
@@ -342,7 +342,7 @@ void ScriptDirectivesCollector::importFile(const QString &jsfile, const QString
import->qualifierIndex = jsGenerator->registerString(module);
import->location.line = lineNumber;
import->location.column = column;
- imports << import;
+ document->imports << import;
}
void ScriptDirectivesCollector::importModule(const QString &uri, const QString &version, const QString &module, int lineNumber, int column)
@@ -358,7 +358,7 @@ void ScriptDirectivesCollector::importModule(const QString &uri, const QString &
import->qualifierIndex = jsGenerator->registerString(module);
import->location.line = lineNumber;
import->location.column = column;
- imports << import;
+ document->imports << import;
}
IRBuilder::IRBuilder(const QSet<QString> &illegalNames)
@@ -2414,6 +2414,22 @@ QmlIR::Object *IRLoader::loadObject(const QV4::CompiledData::Object *serializedO
object->qmlSignals->append(s);
}
+ for (uint i = 0; i < serializedObject->nEnums; ++i) {
+ const QV4::CompiledData::Enum *serializedEnum = serializedObject->enumAt(i);
+ QmlIR::Enum *e = pool->New<QmlIR::Enum>();
+ e->nameIndex = serializedEnum->nameIndex;
+ e->location = serializedEnum->location;
+ e->enumValues = pool->New<QmlIR::PoolList<QmlIR::EnumValue> >();
+
+ for (uint i = 0; i < serializedEnum->nEnumValues; ++i) {
+ QmlIR::EnumValue *v = pool->New<QmlIR::EnumValue>();
+ *static_cast<QV4::CompiledData::EnumValue*>(v) = *serializedEnum->enumValueAt(i);
+ e->enumValues->append(v);
+ }
+
+ object->qmlEnums->append(e);
+ }
+
const QV4::CompiledData::Property *serializedProperty = serializedObject->propertyTable();
for (uint i = 0; i < serializedObject->nProperties; ++i, ++serializedProperty) {
QmlIR::Property *p = pool->New<QmlIR::Property>();
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index c2cf18e3c4..689b232b1c 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -462,14 +462,14 @@ struct Q_QML_PRIVATE_EXPORT Document
static void removeScriptPragmas(QString &script);
};
-struct Q_QML_PRIVATE_EXPORT ScriptDirectivesCollector : public QQmlJS::Directives
+class Q_QML_PRIVATE_EXPORT ScriptDirectivesCollector : public QQmlJS::Directives
{
- ScriptDirectivesCollector(QQmlJS::Engine *engine, QV4::Compiler::JSUnitGenerator *unitGenerator);
-
+ QmlIR::Document *document;
QQmlJS::Engine *engine;
QV4::Compiler::JSUnitGenerator *jsGenerator;
- QList<const QV4::CompiledData::Import *> imports;
- bool hasPragmaLibrary;
+
+public:
+ ScriptDirectivesCollector(QmlIR::Document *doc);
void pragmaLibrary() override;
void importFile(const QString &jsfile, const QString &module, int lineNumber, int column) override;
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index c281275da1..e831fd48f5 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -2075,6 +2075,8 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
_context->functionIndex = _module->functions.count() - 1;
_context->hasDirectEval |= (_context->compilationMode == EvalCode || _context->compilationMode == GlobalCode || _module->debugMode); // Conditional breakpoints are like eval in the function
+ if (_module->debugMode) // allow the debugger to see overwritten arguments
+ _context->argumentsCanEscape = true;
// When a user writes the following QML signal binding:
// onSignal: function() { doSomethingUsefull }
diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h
index f84a2c44e2..7b972c5d0d 100644
--- a/src/qml/debugger/qqmlprofilerdefinitions_p.h
+++ b/src/qml/debugger/qqmlprofilerdefinitions_p.h
@@ -96,11 +96,6 @@ struct QQmlProfilerDefinitions {
MaximumRangeType
};
- enum BindingType {
- QmlBinding,
- MaximumBindingType
- };
-
enum PixmapEventType {
PixmapSizeKnown,
PixmapReferenceCountChanged,
@@ -129,8 +124,6 @@ struct QQmlProfilerDefinitions {
NumGUIThreadFrameTypes = MaximumSceneGraphFrameType - NumRenderThreadFrameTypes
};
- typedef QV4::Profiling::MemoryType MemoryType;
-
enum ProfileFeature {
ProfileJavaScript,
ProfileMemory,
@@ -162,26 +155,6 @@ struct QQmlProfilerDefinitions {
MaximumInputEventType
};
-
- static ProfileFeature featureFromRangeType(RangeType range)
- {
- switch (range) {
- case Painting:
- return ProfilePainting;
- case Compiling:
- return ProfileCompiling;
- case Creating:
- return ProfileCreating;
- case Binding:
- return ProfileBinding;
- case HandlingSignal:
- return ProfileHandlingSignal;
- case Javascript:
- return ProfileJavaScript;
- default:
- return MaximumProfileFeature;
- }
- }
};
QT_END_NAMESPACE
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index c3e16c4093..9786293e4c 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -62,7 +62,6 @@ namespace JIT {
#define callHelper(x) PlatformAssemblerCommon::callRuntime(#x, reinterpret_cast<void *>(&x))
const QV4::Value::ValueTypeInternal IntegerTag = QV4::Value::ValueTypeInternal::Integer;
-const int IsIntegerConvertible_Shift = QV4::Value::IsIntegerConvertible_Shift;
static ReturnedValue toNumberHelper(ReturnedValue v)
{
@@ -873,7 +872,7 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
Jump unopIntPath(std::function<Jump(void)> fastPath)
{
- urshift64(AccumulatorRegister, TrustedImm32(IsIntegerConvertible_Shift), ScratchRegister);
+ urshift64(AccumulatorRegister, TrustedImm32(Value::IsIntegerConvertible_Shift), ScratchRegister);
Jump accNotIntConvertible = branch32(NotEqual, TrustedImm32(1), ScratchRegister);
// both integer
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/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index bc9b3013d1..5bbe312146 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -55,7 +55,7 @@
#include <wtf/MathExtras.h>
-#ifdef Q_OS_LINUX
+#if defined(Q_OS_LINUX) && QT_CONFIG(timezone)
/*
See QTBUG-56899. Although we don't (yet) have a proper way to reset the
system zone, the code below, that uses QTimeZone::systemTimeZone(), works
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 5521633db7..835933c043 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -769,16 +769,19 @@ QQmlContextData *ExecutionEngine::callingQmlContext() const
QString CppStackFrame::source() const
{
- return v4Function->sourceFile();
+ return v4Function ? v4Function->sourceFile() : QString();
}
QString CppStackFrame::function() const
{
- return v4Function->name()->toQString();
+ return v4Function ? v4Function->name()->toQString() : QString();
}
int CppStackFrame::lineNumber() const
{
+ if (!v4Function)
+ return -1;
+
auto findLine = [](const CompiledData::CodeOffsetToLine &entry, uint offset) {
return entry.codeOffset < offset;
};
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 83e861138b..6fca9ecd45 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -112,6 +112,11 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr
internalClass = engine->internalClasses[EngineBase::Class_CallContext];
+ // first locals
+ const quint32_le *localsIndices = compiledFunction->localsTable();
+ for (quint32 i = 0; i < compiledFunction->nLocals; ++i)
+ internalClass = internalClass->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[localsIndices[i]]), Attr_NotConfigurable);
+
Scope scope(engine);
ScopedString arg(scope);
for (const QString &parameterName : parameterNames) {
@@ -119,10 +124,6 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr
internalClass = internalClass->addMember(arg, Attr_NotConfigurable);
}
nFormals = parameters.size();
-
- const quint32_le *localsIndices = compiledFunction->localsTable();
- for (quint32 i = 0; i < compiledFunction->nLocals; ++i)
- internalClass = internalClass->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[localsIndices[i]]), Attr_NotConfigurable);
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 9b13d4e341..1fa4bae049 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/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index 9da854e7d7..3bfcf358bf 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -533,6 +533,8 @@ void InternalClass::updateInternalClassIdRecursive()
id = engine->newInternalClassId();
for (auto &t : transitions) {
Q_ASSERT(t.lookup);
+ if (t.flags == InternalClassTransition::VTableChange || t.flags == InternalClassTransition::PrototypeChange)
+ continue;
t.lookup->updateInternalClassIdRecursive();
}
}
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 816c259b9b..d63d42478a 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -102,10 +102,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)
@@ -1106,7 +1106,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:
@@ -1304,7 +1304,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;
@@ -1720,7 +1720,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/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 0211ad1011..9729228511 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1408,7 +1408,7 @@ ReturnedValue Runtime::method_mod(const Value &left, const Value &right)
{
TRACE2(left, right);
- if (Value::integerCompatible(left, right) && right.integerValue() != 0) {
+ if (Value::integerCompatible(left, right) && left.integerValue() > 0 && right.integerValue() > 0) {
int intRes = left.integerValue() % right.integerValue();
if (intRes != 0 || left.integerValue() >= 0)
return Encode(intRes);
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 6adb25f964..fe7c2bd654 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()->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/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index 5dd3278b4c..3dcfa92416 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -536,7 +536,7 @@ QQmlContextData::QQmlContextData()
QQmlContextData::QQmlContextData(QQmlContext *ctxt)
: engine(nullptr), isInternal(false), isJSContext(false),
isPragmaLibraryContext(false), unresolvedNames(false), hasEmittedDestruction(false), isRootObjectInCreation(false),
- publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1),
+ stronglyReferencedByParent(false), publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1),
contextObject(nullptr), nextChild(nullptr), prevChild(nullptr),
expressions(nullptr), contextObjects(nullptr), idValues(nullptr), idValueCount(0),
componentAttached(nullptr)
@@ -577,7 +577,10 @@ void QQmlContextData::invalidate()
while (childContexts) {
Q_ASSERT(childContexts != this);
- childContexts->invalidate();
+ if (childContexts->stronglyReferencedByParent && !--childContexts->refCount)
+ childContexts->destroy();
+ else
+ childContexts->invalidate();
}
if (prevChild) {
@@ -672,12 +675,16 @@ void QQmlContextData::destroy()
delete this;
}
-void QQmlContextData::setParent(QQmlContextData *p)
+void QQmlContextData::setParent(QQmlContextData *p, bool stronglyReferencedByParent)
{
if (p == parent)
return;
if (p) {
+ Q_ASSERT(!parent);
parent = p;
+ this->stronglyReferencedByParent = stronglyReferencedByParent;
+ if (stronglyReferencedByParent)
+ ++refCount; // balanced in QQmlContextData::invalidate()
engine = p->engine;
nextChild = p->childContexts;
if (nextChild) nextChild->prevChild = &nextChild;
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index 5dfee48848..290b7fc7ee 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -126,7 +126,7 @@ public:
QQmlContextData *parent = nullptr;
QQmlEngine *engine;
- void setParent(QQmlContextData *);
+ void setParent(QQmlContextData *, bool stronglyReferencedByParent = false);
void refreshExpressions();
void addObject(QObject *);
@@ -144,7 +144,8 @@ public:
quint32 unresolvedNames:1; // True if expressions in this context failed to resolve a toplevel name
quint32 hasEmittedDestruction:1;
quint32 isRootObjectInCreation:1;
- quint32 dummy:26;
+ quint32 stronglyReferencedByParent:1;
+ quint32 dummy:25;
QQmlContext *publicContext;
// The incubator that is constructing this context if any
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 7e11177caa..b27bf3779a 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -1196,6 +1196,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/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 8fda7f6f77..d842a7795f 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -424,7 +424,7 @@ QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQm
d->version_min = type.versionMinor;
d->extraData.sd->singletonInstanceInfo = new SingletonInstanceInfo;
- d->extraData.sd->singletonInstanceInfo->url = type.url;
+ d->extraData.sd->singletonInstanceInfo->url = QQmlTypeLoader::normalize(type.url);
d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
}
@@ -477,7 +477,7 @@ QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQm
d->version_maj = type.versionMajor;
d->version_min = type.versionMinor;
- d->extraData.fd->url = type.url;
+ d->extraData.fd->url = QQmlTypeLoader::normalize(type.url);
}
QQmlType::QQmlType()
@@ -1710,7 +1710,7 @@ QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::Registe
addTypeToData(dtype.priv(), data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
- files->insertMulti(type.url, dtype.priv());
+ files->insertMulti(QQmlTypeLoader::normalize(type.url), dtype.priv());
return dtype;
}
@@ -1731,7 +1731,7 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit
addTypeToData(dtype.priv(), data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
- files->insertMulti(type.url, dtype.priv());
+ files->insertMulti(QQmlTypeLoader::normalize(type.url), dtype.priv());
return dtype;
}
@@ -2253,8 +2253,9 @@ QQmlType QQmlMetaType::qmlType(int userType)
Returns null if no such type is registered.
*/
-QQmlType QQmlMetaType::qmlType(const QUrl &url, bool includeNonFileImports /* = false */)
+QQmlType QQmlMetaType::qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports /* = false */)
{
+ const QUrl url = QQmlTypeLoader::normalize(unNormalizedUrl);
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index cd7afc8a01..51bf485a3e 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -96,7 +96,7 @@ public:
static QQmlType qmlType(const QMetaObject *);
static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor);
static QQmlType qmlType(int);
- static QQmlType qmlType(const QUrl &url, bool includeNonFileImports = false);
+ static QQmlType qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports = false);
static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject);
static QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion);
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 7051fb51da..5aaf79c9e5 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -1217,9 +1217,9 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
}
ddata = QQmlData::get(instance, /*create*/true);
- ddata->lineNumber = obj->location.line;
- ddata->columnNumber = obj->location.column;
}
+ ddata->lineNumber = obj->location.line;
+ ddata->columnNumber = obj->location.column;
ddata->setImplicitDestructible();
if (static_cast<quint32>(index) == /*root object*/0 || ddata->rootObjectInCreation) {
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 1cab827b9f..f4c612b187 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -358,9 +358,8 @@ qreal QQmlDataBlob::progress() const
/*!
Returns the physical url of the data. Initially this is the same as
-finalUrl(), but if a network redirect happens while fetching the data, this url
-is updated to reflect the new location. Also, if a URL interceptor is set, it
-will work on this URL and leave finalUrl() alone.
+finalUrl(), but if a URL interceptor is set, it will work on this URL
+and leave finalUrl() alone.
\sa finalUrl()
*/
@@ -381,8 +380,12 @@ QString QQmlDataBlob::urlString() const
Returns the logical URL to be used for resolving further URLs referred to in
the code.
-This is the blob url passed to the constructor. If a network redirect
-happens while fetching the data, this url remains the same.
+This is the blob url passed to the constructor. If a URL interceptor rewrites
+the URL, this one stays the same. If a network redirect happens while fetching
+the data, this url is updated to reflect the new location. Therefore, if both
+an interception and a redirection happen, the final url will indirectly
+incorporate the result of the interception, potentially breaking further
+lookups.
\sa url()
*/
@@ -1184,15 +1187,15 @@ void QQmlTypeLoader::networkReplyFinished(QNetworkReply *reply)
QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (redirect.isValid()) {
QUrl url = reply->url().resolved(redirect.toUrl());
- blob->m_url = url;
- blob->m_urlString.clear();
+ blob->m_finalUrl = url;
+ blob->m_finalUrlString.clear();
QNetworkReply *reply = m_thread->networkAccessManager()->get(QNetworkRequest(url));
QObject *nrp = m_thread->networkReplyProxy();
QObject::connect(reply, SIGNAL(finished()), nrp, SLOT(finished()));
m_networkReplies.insert(reply, blob);
#ifdef DATABLOB_DEBUG
- qWarning("QQmlDataBlob: redirected to %s", qPrintable(blob->urlString()));
+ qWarning("QQmlDataBlob: redirected to %s", qPrintable(blob->finalUrlString()));
#endif
return;
}
@@ -1648,14 +1651,24 @@ QQmlImportDatabase *QQmlTypeLoader::importDatabase() const
return &QQmlEnginePrivate::get(engine())->importDatabase;
}
+QUrl QQmlTypeLoader::normalize(const QUrl &unNormalizedUrl)
+{
+ QUrl normalized(unNormalizedUrl);
+ if (normalized.scheme() == QLatin1String("qrc"))
+ normalized.setHost(QString()); // map qrc:///a.qml to qrc:/a.qml
+ return normalized;
+}
+
/*!
Returns a QQmlTypeData for the specified \a url. The QQmlTypeData may be cached.
*/
-QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode)
+QQmlTypeData *QQmlTypeLoader::getType(const QUrl &unNormalizedUrl, Mode mode)
{
- Q_ASSERT(!url.isRelative() &&
- (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() ||
- !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url))));
+ Q_ASSERT(!unNormalizedUrl.isRelative() &&
+ (QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl).isEmpty() ||
+ !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl))));
+
+ const QUrl url = normalize(unNormalizedUrl);
LockHolder<QQmlTypeLoader> holder(this);
@@ -1713,11 +1726,13 @@ QQmlTypeData *QQmlTypeLoader::getType(const QByteArray &data, const QUrl &url, M
/*!
Return a QQmlScriptBlob for \a url. The QQmlScriptData may be cached.
*/
-QQmlScriptBlob *QQmlTypeLoader::getScript(const QUrl &url)
+QQmlScriptBlob *QQmlTypeLoader::getScript(const QUrl &unNormalizedUrl)
{
- Q_ASSERT(!url.isRelative() &&
- (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() ||
- !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url))));
+ Q_ASSERT(!unNormalizedUrl.isRelative() &&
+ (QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl).isEmpty() ||
+ !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl))));
+
+ const QUrl url = normalize(unNormalizedUrl);
LockHolder<QQmlTypeLoader> holder(this);
@@ -1833,15 +1848,7 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path)
if (*value)
absoluteFilePath = path;
} else {
- bool exists = false;
-#ifdef Q_OS_UNIX
- struct stat statBuf;
- // XXX Avoid encoding entire path. Should store encoded dirpath in cache
- if (::stat(QFile::encodeName(path).constData(), &statBuf) == 0)
- exists = S_ISREG(statBuf.st_mode);
-#else
- exists = QFile::exists(path);
-#endif
+ bool exists = QFile::exists(path);
fileSet->insert(fileName, new bool(exists));
if (exists)
absoluteFilePath = path;
@@ -3010,7 +3017,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
return;
}
- QmlIR::ScriptDirectivesCollector collector(&irUnit.jsParserEngine, &irUnit.jsGenerator);
+ QmlIR::ScriptDirectivesCollector collector(&irUnit);
QList<QQmlError> errors;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = QV4::Script::precompile(
@@ -3026,9 +3033,6 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
unit.adopt(new QV4::CompiledData::CompilationUnit);
}
irUnit.javaScriptCompilationUnit = unit;
- irUnit.imports = collector.imports;
- if (collector.hasPragmaLibrary)
- irUnit.jsModule.unitFlags |= QV4::CompiledData::Unit::IsSharedLibrary;
QmlIR::QmlUnitGenerator qmlGenerator;
QV4::CompiledData::Unit *unitData = qmlGenerator.generate(irUnit);
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 5988632547..e75719866d 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -305,10 +305,12 @@ public:
QQmlImportDatabase *importDatabase() const;
- QQmlTypeData *getType(const QUrl &url, Mode mode = PreferSynchronous);
+ static QUrl normalize(const QUrl &unNormalizedUrl);
+
+ QQmlTypeData *getType(const QUrl &unNormalizedUrl, Mode mode = PreferSynchronous);
QQmlTypeData *getType(const QByteArray &, const QUrl &url, Mode mode = PreferSynchronous);
- QQmlScriptBlob *getScript(const QUrl &);
+ QQmlScriptBlob *getScript(const QUrl &unNormalizedUrl);
QQmlQmldirData *getQmldir(const QUrl &);
QString absoluteFilePath(const QString &path);
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 9e7c84011b..221754a29a 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1697,7 +1697,7 @@ ReturnedValue ConsoleObject::method_count(const FunctionObject *b, const Value *
QString scriptName = frame->source();
- int value = v8engine->consoleCountHelper(scriptName, frame->lineNumber(), -1);
+ int value = v8engine->consoleCountHelper(scriptName, frame->lineNumber(), 0);
QString message = name + QLatin1String(": ") + QString::number(value);
QMessageLogger(qPrintable(scriptName), frame->lineNumber(),
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 44166e4aa8..eb02e8045a 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -874,10 +874,11 @@ void QQmlDelegateModelPrivate::removeCacheItem(QQmlDelegateModelItem *cacheItem)
void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incubationTask, QQmlIncubator::Status status)
{
- Q_Q(QQmlDelegateModel);
if (!isDoneIncubating(status))
return;
+ const QList<QQmlError> incubationTaskErrors = incubationTask->errors();
+
QQmlDelegateModelItem *cacheItem = incubationTask->incubating;
cacheItem->incubationTask = nullptr;
incubationTask->incubating = nullptr;
@@ -891,7 +892,7 @@ void QQmlDelegateModelPrivate::incubatorStatusChanged(QQDMIncubationTask *incuba
emitCreatedItem(incubationTask, cacheItem->object);
cacheItem->releaseObject();
} else if (status == QQmlIncubator::Error) {
- qmlWarning(q, m_delegate->errors()) << "Error creating delegate";
+ qmlWarning(m_delegate, incubationTaskErrors + m_delegate->errors()) << "Error creating delegate";
}
if (!cacheItem->isObjectReferenced()) {
@@ -988,7 +989,7 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ
if (QQmlAdaptorModelProxyInterface *proxy
= qobject_cast<QQmlAdaptorModelProxyInterface *>(cacheItem)) {
ctxt = new QQmlContextData;
- ctxt->setParent(cacheItem->contextData);
+ ctxt->setParent(cacheItem->contextData, /*stronglyReferencedByParent*/true);
ctxt->contextObject = proxy->proxiedObject();
}
}
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index c4e33d572d..877968faf4 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -1463,8 +1463,8 @@ void ModelNodeMetaObject::emitDirectNotifies(const int *changedRoles, int roleCo
QQmlData *ddata = QQmlData::get(object(), /*create*/false);
if (!ddata)
return;
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlEngine(m_model));
- if (!ep)
+ // There's nothing to emit if we're a list model in a worker thread.
+ if (!qmlEngine(m_model))
return;
for (int i = 0; i < roleCount; ++i) {
const int changedRole = changedRoles[i];
diff --git a/src/qmldebug/qmldebug.pro b/src/qmldebug/qmldebug.pro
index 2539414d8f..2c1b71797d 100644
--- a/src/qmldebug/qmldebug.pro
+++ b/src/qmldebug/qmldebug.pro
@@ -1,5 +1,5 @@
TARGET = QtQmlDebug
-QT = core-private network packetprotocol-private qml-private
+QT = core-private network packetprotocol-private
CONFIG += static internal_module
load(qt_module)
@@ -28,4 +28,5 @@ HEADERS += \
qqmlprofilereventlocation_p.h \
qqmlprofilereventreceiver_p.h \
qqmlprofilereventtype_p.h \
- qqmlprofilertypedevent_p.h
+ qqmlprofilertypedevent_p.h \
+ qqmlprofilerclientdefinitions_p.h
diff --git a/src/qmldebug/qqmlenginecontrolclient.cpp b/src/qmldebug/qqmlenginecontrolclient.cpp
index 13f216ce38..45d672d4bc 100644
--- a/src/qmldebug/qqmlenginecontrolclient.cpp
+++ b/src/qmldebug/qqmlenginecontrolclient.cpp
@@ -41,7 +41,6 @@
#include "qqmlenginecontrolclient_p_p.h"
#include "qqmldebugconnection_p.h"
-#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qpacket_p.h>
QT_BEGIN_NAMESPACE
@@ -142,7 +141,7 @@ void QQmlEngineControlClient::messageReceived(const QByteArray &data)
}
QQmlEngineControlClientPrivate::QQmlEngineControlClientPrivate(QQmlDebugConnection *connection) :
- QQmlDebugClientPrivate(QQmlEngineControlService::s_key, connection)
+ QQmlDebugClientPrivate(QLatin1String("EngineControl"), connection)
{
}
diff --git a/src/qmldebug/qqmlprofilerclient.cpp b/src/qmldebug/qqmlprofilerclient.cpp
index d2a2d24f13..661b43f164 100644
--- a/src/qmldebug/qqmlprofilerclient.cpp
+++ b/src/qmldebug/qqmlprofilerclient.cpp
@@ -39,7 +39,6 @@
#include "qqmlprofilerclient_p_p.h"
#include "qqmldebugconnection_p.h"
-#include <private/qqmldebugserviceinterfaces_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qmldebug/qqmlprofilerclient_p.h b/src/qmldebug/qqmlprofilerclient_p.h
index 68a32a1a5a..7b8e286f5b 100644
--- a/src/qmldebug/qqmlprofilerclient_p.h
+++ b/src/qmldebug/qqmlprofilerclient_p.h
@@ -43,8 +43,8 @@
#include "qqmldebugclient_p.h"
#include "qqmlprofilereventlocation_p.h"
#include "qqmlprofilereventreceiver_p.h"
+#include "qqmlprofilerclientdefinitions_p.h"
-#include <private/qqmlprofilerdefinitions_p.h>
#include <private/qpacket_p.h>
//
@@ -61,7 +61,7 @@
QT_BEGIN_NAMESPACE
class QQmlProfilerClientPrivate;
-class QQmlProfilerClient : public QQmlDebugClient, public QQmlProfilerDefinitions
+class QQmlProfilerClient : public QQmlDebugClient
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQmlProfilerClient)
diff --git a/src/qmldebug/qqmlprofilerclient_p_p.h b/src/qmldebug/qqmlprofilerclient_p_p.h
index 0caef8e448..994c08cafc 100644
--- a/src/qmldebug/qqmlprofilerclient_p_p.h
+++ b/src/qmldebug/qqmlprofilerclient_p_p.h
@@ -45,10 +45,10 @@
#include "qqmlenginecontrolclient_p.h"
#include "qqmlprofilerclient_p.h"
#include "qqmlprofilertypedevent_p.h"
-
-#include <private/qqmlprofilerdefinitions_p.h>
+#include "qqmlprofilerclientdefinitions_p.h"
#include <QtCore/qqueue.h>
+#include <QtCore/qstack.h>
//
// W A R N I N G
@@ -63,7 +63,7 @@
QT_BEGIN_NAMESPACE
-class QQmlProfilerClientPrivate : public QQmlDebugClientPrivate, public QQmlProfilerDefinitions {
+class QQmlProfilerClientPrivate : public QQmlDebugClientPrivate {
Q_DECLARE_PUBLIC(QQmlProfilerClient)
public:
QQmlProfilerClientPrivate(QQmlDebugConnection *connection,
diff --git a/src/qmldebug/qqmlprofilerclientdefinitions_p.h b/src/qmldebug/qqmlprofilerclientdefinitions_p.h
new file mode 100644
index 0000000000..be1c6318af
--- /dev/null
+++ b/src/qmldebug/qqmlprofilerclientdefinitions_p.h
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLPROFILERCLIENTDEFINITIONS_P_H
+#define QQMLPROFILERCLIENTDEFINITIONS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+enum Message {
+ Event,
+ RangeStart,
+ RangeData,
+ RangeLocation,
+ RangeEnd,
+ Complete, // end of transmission
+ PixmapCacheEvent,
+ SceneGraphFrame,
+ MemoryAllocation,
+ DebugMessage,
+
+ MaximumMessage
+};
+
+enum EventType {
+ FramePaint,
+ Mouse,
+ Key,
+ AnimationFrame,
+ EndTrace,
+ StartTrace,
+
+ MaximumEventType
+};
+
+enum RangeType {
+ Painting,
+ Compiling,
+ Creating,
+ Binding, //running a binding
+ HandlingSignal, //running a signal handler
+ Javascript,
+
+ MaximumRangeType
+};
+
+enum PixmapEventType {
+ PixmapSizeKnown,
+ PixmapReferenceCountChanged,
+ PixmapCacheCountChanged,
+ PixmapLoadingStarted,
+ PixmapLoadingFinished,
+ PixmapLoadingError,
+
+ MaximumPixmapEventType
+};
+
+enum SceneGraphFrameType {
+ SceneGraphRendererFrame, // Render Thread
+ SceneGraphAdaptationLayerFrame, // Render Thread
+ SceneGraphContextFrame, // Render Thread
+ SceneGraphRenderLoopFrame, // Render Thread
+ SceneGraphTexturePrepare, // Render Thread
+ SceneGraphTextureDeletion, // Render Thread
+ SceneGraphPolishAndSync, // GUI Thread
+ SceneGraphWindowsRenderShow, // Unused
+ SceneGraphWindowsAnimations, // GUI Thread
+ SceneGraphPolishFrame, // GUI Thread
+
+ MaximumSceneGraphFrameType,
+ NumRenderThreadFrameTypes = SceneGraphPolishAndSync,
+ NumGUIThreadFrameTypes = MaximumSceneGraphFrameType - NumRenderThreadFrameTypes
+};
+
+enum MemoryType {
+ HeapPage,
+ LargeItem,
+ SmallItem
+};
+
+enum ProfileFeature {
+ ProfileJavaScript,
+ ProfileMemory,
+ ProfilePixmapCache,
+ ProfileSceneGraph,
+ ProfileAnimations,
+ ProfilePainting,
+ ProfileCompiling,
+ ProfileCreating,
+ ProfileBinding,
+ ProfileHandlingSignal,
+ ProfileInputEvents,
+ ProfileDebugMessages,
+
+ MaximumProfileFeature
+};
+
+enum InputEventType {
+ InputKeyPress,
+ InputKeyRelease,
+ InputKeyUnknown,
+
+ InputMousePress,
+ InputMouseRelease,
+ InputMouseMove,
+ InputMouseDoubleClick,
+ InputMouseWheel,
+ InputMouseUnknown,
+
+ MaximumInputEventType
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLPROFILERCLIENTDEFINITIONS_P_H
diff --git a/src/qmldebug/qqmlprofilerevent_p.h b/src/qmldebug/qqmlprofilerevent_p.h
index 49a0c9e347..1e205d8dbb 100644
--- a/src/qmldebug/qqmlprofilerevent_p.h
+++ b/src/qmldebug/qqmlprofilerevent_p.h
@@ -40,7 +40,7 @@
#ifndef QQMLPROFILEREVENT_P_H
#define QQMLPROFILEREVENT_P_H
-#include <private/qqmlprofilerdefinitions_p.h>
+#include "qqmlprofilerclientdefinitions_p.h"
#include <QtCore/qstring.h>
#include <QtCore/qbytearray.h>
@@ -63,7 +63,7 @@
QT_BEGIN_NAMESPACE
-struct QQmlProfilerEvent : public QQmlProfilerDefinitions {
+struct QQmlProfilerEvent {
QQmlProfilerEvent() :
m_timestamp(-1), m_typeIndex(-1), m_dataType(Inline8Bit), m_dataLength(0)
{}
diff --git a/src/qmldebug/qqmlprofilereventtype.cpp b/src/qmldebug/qqmlprofilereventtype.cpp
index b0aad3fc5b..c92e914d74 100644
--- a/src/qmldebug/qqmlprofilereventtype.cpp
+++ b/src/qmldebug/qqmlprofilereventtype.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qqmlprofilereventtype_p.h"
+#include "qqmlprofilerclientdefinitions_p.h"
#include <QtCore/qdatastream.h>
@@ -49,8 +50,8 @@ QDataStream &operator>>(QDataStream &stream, QQmlProfilerEventType &type)
quint8 rangeType;
stream >> type.m_displayName >> type.m_data >> type.m_location >> message >> rangeType
>> type.m_detailType;
- type.m_message = static_cast<QQmlProfilerDefinitions::Message>(message);
- type.m_rangeType = static_cast<QQmlProfilerDefinitions::RangeType>(rangeType);
+ type.m_message = static_cast<Message>(message);
+ type.m_rangeType = static_cast<RangeType>(rangeType);
return stream;
}
@@ -61,7 +62,7 @@ QDataStream &operator<<(QDataStream &stream, const QQmlProfilerEventType &type)
<< type.m_detailType;
}
-QQmlProfilerDefinitions::ProfileFeature QQmlProfilerEventType::feature() const
+ProfileFeature QQmlProfilerEventType::feature() const
{
switch (m_message) {
case Event: {
@@ -84,7 +85,24 @@ QQmlProfilerDefinitions::ProfileFeature QQmlProfilerEventType::feature() const
case DebugMessage:
return ProfileDebugMessages;
default:
- return featureFromRangeType(m_rangeType);
+ break;
+ }
+
+ switch (m_rangeType) {
+ case Painting:
+ return ProfilePainting;
+ case Compiling:
+ return ProfileCompiling;
+ case Creating:
+ return ProfileCreating;
+ case Binding:
+ return ProfileBinding;
+ case HandlingSignal:
+ return ProfileHandlingSignal;
+ case Javascript:
+ return ProfileJavaScript;
+ default:
+ return MaximumProfileFeature;
}
}
diff --git a/src/qmldebug/qqmlprofilereventtype_p.h b/src/qmldebug/qqmlprofilereventtype_p.h
index 7bd67f9ca8..7189df53ef 100644
--- a/src/qmldebug/qqmlprofilereventtype_p.h
+++ b/src/qmldebug/qqmlprofilereventtype_p.h
@@ -41,8 +41,7 @@
#define QQMLPROFILEREVENTTYPE_P_H
#include "qqmlprofilereventlocation_p.h"
-
-#include <private/qqmlprofilerdefinitions_p.h>
+#include "qqmlprofilerclientdefinitions_p.h"
#include <QtCore/qstring.h>
#include <QtCore/qmetatype.h>
@@ -61,7 +60,7 @@
QT_BEGIN_NAMESPACE
-class QQmlProfilerEventType : public QQmlProfilerDefinitions {
+class QQmlProfilerEventType {
public:
QQmlProfilerEventType(Message message = MaximumMessage, RangeType rangeType = MaximumRangeType,
int detailType = -1,
diff --git a/src/qmldebug/qqmlprofilertypedevent.cpp b/src/qmldebug/qqmlprofilertypedevent.cpp
index 9b00481e17..31a36bd052 100644
--- a/src/qmldebug/qqmlprofilertypedevent.cpp
+++ b/src/qmldebug/qqmlprofilertypedevent.cpp
@@ -38,6 +38,8 @@
****************************************************************************/
#include "qqmlprofilertypedevent_p.h"
+#include "qqmlprofilerclientdefinitions_p.h"
+
#include <QtCore/qvarlengtharray.h>
QT_BEGIN_NAMESPACE
@@ -50,15 +52,15 @@ QDataStream &operator>>(QDataStream &stream, QQmlProfilerTypedEvent &event)
stream >> time >> messageType;
- if (messageType < 0 || messageType > QQmlProfilerDefinitions::MaximumMessage)
- messageType = QQmlProfilerDefinitions::MaximumMessage;
+ if (messageType < 0 || messageType > MaximumMessage)
+ messageType = MaximumMessage;
- QQmlProfilerDefinitions::RangeType rangeType = QQmlProfilerDefinitions::MaximumRangeType;
+ RangeType rangeType = MaximumRangeType;
if (!stream.atEnd()) {
stream >> subtype;
- rangeType = static_cast<QQmlProfilerDefinitions::RangeType>(subtype);
- if (rangeType < 0 || rangeType > QQmlProfilerDefinitions::MaximumRangeType)
- rangeType = QQmlProfilerDefinitions::MaximumRangeType;
+ rangeType = static_cast<RangeType>(subtype);
+ if (rangeType < 0 || rangeType > MaximumRangeType)
+ rangeType = MaximumRangeType;
} else {
subtype = -1;
}
@@ -68,13 +70,13 @@ QDataStream &operator>>(QDataStream &stream, QQmlProfilerTypedEvent &event)
event.serverTypeId = 0;
switch (messageType) {
- case QQmlProfilerDefinitions::Event: {
+ case Event: {
event.type = QQmlProfilerEventType(
- static_cast<QQmlProfilerDefinitions::Message>(messageType),
- QQmlProfilerDefinitions::MaximumRangeType, subtype);
+ static_cast<Message>(messageType),
+ MaximumRangeType, subtype);
switch (subtype) {
- case QQmlProfilerDefinitions::StartTrace:
- case QQmlProfilerDefinitions::EndTrace: {
+ case StartTrace:
+ case EndTrace: {
QVarLengthArray<qint32> engineIds;
while (!stream.atEnd()) {
qint32 id;
@@ -84,7 +86,7 @@ QDataStream &operator>>(QDataStream &stream, QQmlProfilerTypedEvent &event)
event.event.setNumbers<QVarLengthArray<qint32>, qint32>(engineIds);
break;
}
- case QQmlProfilerDefinitions::AnimationFrame: {
+ case AnimationFrame: {
qint32 frameRate, animationCount;
qint32 threadId;
stream >> frameRate >> animationCount;
@@ -96,11 +98,9 @@ QDataStream &operator>>(QDataStream &stream, QQmlProfilerTypedEvent &event)
event.event.setNumbers<qint32>({frameRate, animationCount, threadId});
break;
}
- case QQmlProfilerDefinitions::Mouse:
- case QQmlProfilerDefinitions::Key:
- int inputType = (subtype == QQmlProfilerDefinitions::Key
- ? QQmlProfilerDefinitions::InputKeyUnknown
- : QQmlProfilerDefinitions::InputMouseUnknown);
+ case Mouse:
+ case Key:
+ int inputType = (subtype == Key ? InputKeyUnknown : InputMouseUnknown);
if (!stream.atEnd())
stream >> inputType;
qint32 a = -1;
@@ -116,13 +116,13 @@ QDataStream &operator>>(QDataStream &stream, QQmlProfilerTypedEvent &event)
break;
}
- case QQmlProfilerDefinitions::Complete: {
+ case Complete: {
event.type = QQmlProfilerEventType(
- static_cast<QQmlProfilerDefinitions::Message>(messageType),
- QQmlProfilerDefinitions::MaximumRangeType, subtype);
+ static_cast<Message>(messageType),
+ MaximumRangeType, subtype);
break;
}
- case QQmlProfilerDefinitions::SceneGraphFrame: {
+ case SceneGraphFrame: {
QVarLengthArray<qint64> params;
qint64 param;
@@ -132,41 +132,40 @@ QDataStream &operator>>(QDataStream &stream, QQmlProfilerTypedEvent &event)
}
event.type = QQmlProfilerEventType(
- static_cast<QQmlProfilerDefinitions::Message>(messageType),
- QQmlProfilerDefinitions::MaximumRangeType, subtype);
+ static_cast<Message>(messageType),
+ MaximumRangeType, subtype);
event.event.setNumbers<QVarLengthArray<qint64>, qint64>(params);
break;
}
- case QQmlProfilerDefinitions::PixmapCacheEvent: {
+ case PixmapCacheEvent: {
qint32 width = 0, height = 0, refcount = 0;
QString filename;
stream >> filename;
- if (subtype == QQmlProfilerDefinitions::PixmapReferenceCountChanged
- || subtype == QQmlProfilerDefinitions::PixmapCacheCountChanged) {
+ if (subtype == PixmapReferenceCountChanged || subtype == PixmapCacheCountChanged) {
stream >> refcount;
- } else if (subtype == QQmlProfilerDefinitions::PixmapSizeKnown) {
+ } else if (subtype == PixmapSizeKnown) {
stream >> width >> height;
refcount = 1;
}
event.type = QQmlProfilerEventType(
- static_cast<QQmlProfilerDefinitions::Message>(messageType),
- QQmlProfilerDefinitions::MaximumRangeType, subtype,
+ static_cast<Message>(messageType),
+ MaximumRangeType, subtype,
QQmlProfilerEventLocation(filename, 0, 0));
event.event.setNumbers<qint32>({width, height, refcount});
break;
}
- case QQmlProfilerDefinitions::MemoryAllocation: {
+ case MemoryAllocation: {
qint64 delta;
stream >> delta;
event.type = QQmlProfilerEventType(
- static_cast<QQmlProfilerDefinitions::Message>(messageType),
- QQmlProfilerDefinitions::MaximumRangeType, subtype);
+ static_cast<Message>(messageType),
+ MaximumRangeType, subtype);
event.event.setNumbers<qint64>({delta});
break;
}
- case QQmlProfilerDefinitions::RangeStart: {
+ case RangeStart: {
if (!stream.atEnd()) {
qint64 typeId;
stream >> typeId;
@@ -175,22 +174,22 @@ QDataStream &operator>>(QDataStream &stream, QQmlProfilerTypedEvent &event)
// otherwise it's the old binding type of 4 bytes
}
- event.type = QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage, rangeType, -1);
- event.event.setRangeStage(QQmlProfilerDefinitions::RangeStart);
+ event.type = QQmlProfilerEventType(MaximumMessage, rangeType, -1);
+ event.event.setRangeStage(RangeStart);
break;
}
- case QQmlProfilerDefinitions::RangeData: {
+ case RangeData: {
QString data;
stream >> data;
- event.type = QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage, rangeType, -1,
+ event.type = QQmlProfilerEventType(MaximumMessage, rangeType, -1,
QQmlProfilerEventLocation(), data);
- event.event.setRangeStage(QQmlProfilerDefinitions::RangeData);
+ event.event.setRangeStage(RangeData);
if (!stream.atEnd())
stream >> event.serverTypeId;
break;
}
- case QQmlProfilerDefinitions::RangeLocation: {
+ case RangeLocation: {
QString filename;
qint32 line = 0;
qint32 column = 0;
@@ -202,21 +201,21 @@ QDataStream &operator>>(QDataStream &stream, QQmlProfilerTypedEvent &event)
stream >> event.serverTypeId;
}
- event.type = QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage, rangeType, -1,
+ event.type = QQmlProfilerEventType(MaximumMessage, rangeType, -1,
QQmlProfilerEventLocation(filename, line, column));
- event.event.setRangeStage(QQmlProfilerDefinitions::RangeLocation);
+ event.event.setRangeStage(RangeLocation);
break;
}
- case QQmlProfilerDefinitions::RangeEnd: {
- event.type = QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage, rangeType, -1);
- event.event.setRangeStage(QQmlProfilerDefinitions::RangeEnd);
+ case RangeEnd: {
+ event.type = QQmlProfilerEventType(MaximumMessage, rangeType, -1);
+ event.event.setRangeStage(RangeEnd);
break;
}
default:
event.event.setNumbers<char>({});
event.type = QQmlProfilerEventType(
- static_cast<QQmlProfilerDefinitions::Message>(messageType),
- QQmlProfilerDefinitions::MaximumRangeType, subtype);
+ static_cast<Message>(messageType),
+ MaximumRangeType, subtype);
break;
}
diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp
index a02a0a806d..8b9ff4c5cd 100644
--- a/src/qmltest/quicktest.cpp
+++ b/src/qmltest/quicktest.cpp
@@ -207,7 +207,11 @@ public:
TestCaseCollector(const QFileInfo &fileInfo, QQmlEngine *engine)
{
- QQmlComponent component(engine, fileInfo.absoluteFilePath());
+ QString path = fileInfo.absoluteFilePath();
+ if (path.startsWith(QLatin1String(":/")))
+ path.prepend(QLatin1String("qrc"));
+
+ QQmlComponent component(engine, path);
m_errors += component.errors();
if (component.isReady()) {
@@ -534,7 +538,7 @@ int quick_test_main_with_setup(int argc, char **argv, const char *name, const ch
QTestRootObject::instance()->init();
QString path = fi.absoluteFilePath();
if (path.startsWith(QLatin1String(":/")))
- view.setSource(QUrl(QLatin1String("qrc:") + path.midRef(2)));
+ view.setSource(QUrl(QLatin1String("qrc:") + path.midRef(1)));
else
view.setSource(QUrl::fromLocalFile(path));
diff --git a/src/quick/configure.json b/src/quick/configure.json
index b77ea863b3..ea1d49baad 100644
--- a/src/quick/configure.json
+++ b/src/quick/configure.json
@@ -120,6 +120,7 @@
"label": "Path support",
"purpose": "Provides Path elements.",
"section": "Qt Quick",
+ "condition": "features.quick-shadereffect",
"output": [
"privateFeature"
]
diff --git a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
index e70791d1c9..30aca38678 100644
--- a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
+++ b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc
@@ -29,6 +29,7 @@
\page qtquick-bestpractices.html
\title Best Practices for QML and Qt Quick
\brief Lists best practices for working with QML and Qt Quick
+\ingroup best-practices
Despite all of the benefits that QML and Qt Quick offer, they can be
challenging in certain situations. The following sections elaborate on some of
@@ -317,8 +318,8 @@ component loaded by the engine. Context properties are useful for objects that
must be available as soon as the QML is loaded and cannot be instantiated in
QML.
-\l {Integrating QML and C++} demonstrates an alternative approach where QML is
-made aware of a C++ type so that it can instantiate it itself.
+For a quick guide to choosing the correct approach to expose C++ types to QML,
+see \l {Choosing the Correct Integration Method Between C++ and QML}.
\section2 Related Information
\list
diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp
index b126b93211..d595b4c9b4 100644
--- a/src/quick/handlers/qquickmultipointhandler.cpp
+++ b/src/quick/handlers/qquickmultipointhandler.cpp
@@ -76,8 +76,10 @@ bool QQuickMultiPointHandler::wantsPointerEvent(QQuickPointerEvent *event)
if (!QQuickPointerDeviceHandler::wantsPointerEvent(event))
return false;
+#if QT_CONFIG(gestures)
if (event->asPointerNativeGestureEvent())
return true;
+#endif
if (sameAsCurrentPoints(event))
return true;
diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp
index 155822197f..fc69accffc 100644
--- a/src/quick/handlers/qquickpinchhandler.cpp
+++ b/src/quick/handlers/qquickpinchhandler.cpp
@@ -248,6 +248,7 @@ bool QQuickPinchHandler::wantsPointerEvent(QQuickPointerEvent *event)
if (!QQuickMultiPointHandler::wantsPointerEvent(event))
return false;
+#if QT_CONFIG(gestures)
if (const auto gesture = event->asPointerNativeGestureEvent()) {
if (minimumPointCount() == 2) {
switch (gesture->type()) {
@@ -263,6 +264,7 @@ bool QQuickPinchHandler::wantsPointerEvent(QQuickPointerEvent *event)
return false;
}
}
+#endif
return true;
}
@@ -319,6 +321,7 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
}
qreal dist = 0;
+#if QT_CONFIG(gestures)
if (const auto gesture = event->asPointerNativeGestureEvent()) {
switch (gesture->type()) {
case Qt::EndNativeGesture:
@@ -349,7 +352,9 @@ void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
m_centroidVelocity = QVector2D();
m_activeTranslation = QVector2D();
}
- } else {
+ } else
+#endif // QT_CONFIG(gestures)
+ {
bool containsReleasedPoints = event->isReleaseEvent();
if (!active()) {
// Verify that at least one of the points has moved beyond threshold needed to activate the handler
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index af8048f2e4..addcf9b540 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -1637,7 +1637,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(const
QV4::Scoped<QQuickContext2DStyle> gradient(scope, scope.engine->memoryManager->allocObject<QQuickContext2DStyle>());
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
- *gradient->d()->brush = QRadialGradient(QPointF(x1, y1), r0+r1, QPointF(x0, y0));
+ *gradient->d()->brush = QRadialGradient(QPointF(x1, y1), r1, QPointF(x0, y0), r0);
RETURN_RESULT(*gradient);
}
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp
index 26dfdb07a6..075c4a7d72 100644
--- a/src/quick/items/qquickanimatedimage.cpp
+++ b/src/quick/items/qquickanimatedimage.cpp
@@ -426,15 +426,18 @@ void QQuickAnimatedImage::movieRequestFinished()
}
bool pausedAtStart = d->paused;
- if (d->playing)
+ if (d->movie && d->playing)
d->movie->start();
- if (pausedAtStart)
+ if (d->movie && pausedAtStart)
d->movie->setPaused(true);
- if (d->paused || !d->playing) {
+ if (d->movie && (d->paused || !d->playing)) {
d->movie->jumpToFrame(d->presetCurrentFrame);
d->presetCurrentFrame = 0;
}
- d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this)));
+
+ QQuickPixmap *pixmap = d->infoForCurrentFrame(qmlEngine(this));
+ if (pixmap)
+ d->setPixmap(*pixmap);
if (isPlaying() != d->oldPlaying)
emit playingChanged();
@@ -512,7 +515,10 @@ void QQuickAnimatedImagePrivate::setMovie(QMovie *m)
Q_Q(QQuickAnimatedImage);
const int oldFrameCount = q->frameCount();
- delete movie;
+ if (movie) {
+ movie->disconnect();
+ movie->deleteLater();
+ }
movie = m;
if (oldFrameCount != q->frameCount())
diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp
index 190c48ac88..887c30f999 100644
--- a/src/quick/items/qquickanimatedsprite.cpp
+++ b/src/quick/items/qquickanimatedsprite.cpp
@@ -527,6 +527,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();
@@ -713,7 +715,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..d020ad7c4c 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -849,14 +849,16 @@ void QQuickEventPoint::setGrabberItem(QQuickItem *grabber)
qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
<< ": grab" << m_exclusiveGrabber << "->" << grabber;
}
+ QQuickItem *oldGrabberItem = grabberItem();
m_exclusiveGrabber = QPointer<QObject>(grabber);
m_grabberIsHandler = false;
m_sceneGrabPos = m_scenePos;
- QQuickItem *oldGrabberItem = grabberItem();
- if (oldGrabberHandler)
+ if (oldGrabberHandler) {
oldGrabberHandler->onGrabChanged(oldGrabberHandler, (grabber ? CancelGrabExclusive : UngrabExclusive), this);
- else if (oldGrabberItem && oldGrabberItem != grabber && grabber && pointerEvent()->asPointerTouchEvent())
- oldGrabberItem->touchUngrabEvent();
+ } else if (oldGrabberItem && oldGrabberItem != grabber && grabber && grabber->window()) {
+ QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(grabber->window());
+ windowPriv->sendUngrabEvent(oldGrabberItem, windowPriv->isDeliveringTouchAsMouse());
+ }
for (QPointer<QQuickPointerHandler> passiveGrabber : m_passiveGrabbers)
passiveGrabber->onGrabChanged(passiveGrabber, OverrideGrabPassive, this);
}
@@ -1388,6 +1390,7 @@ void QQuickPointerTouchEvent::localize(QQuickItem *target)
point->localizePosition(target);
}
+#if QT_CONFIG(gestures)
QQuickPointerEvent *QQuickPointerNativeGestureEvent::reset(QEvent *event)
{
auto ev = static_cast<QNativeGestureEvent*>(event);
@@ -1417,6 +1420,7 @@ void QQuickPointerNativeGestureEvent::localize(QQuickItem *target)
{
m_gesturePoint->localizePosition(target);
}
+#endif // QT_CONFIG(gestures)
QQuickEventPoint *QQuickPointerMouseEvent::point(int i) const {
if (i == 0)
@@ -1430,11 +1434,13 @@ QQuickEventPoint *QQuickPointerTouchEvent::point(int i) const {
return nullptr;
}
+#if QT_CONFIG(gestures)
QQuickEventPoint *QQuickPointerNativeGestureEvent::point(int i) const {
if (i == 0)
return m_gesturePoint;
return nullptr;
}
+#endif // QT_CONFIG(gestures)
QQuickEventPoint::QQuickEventPoint(QQuickPointerEvent *parent)
: QObject(parent), m_pointId(0), m_exclusiveGrabber(nullptr), m_timestamp(0), m_pressTimestamp(0),
@@ -1572,6 +1578,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 +1599,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
@@ -1655,6 +1668,7 @@ QMouseEvent *QQuickPointerTouchEvent::syntheticMouseEvent(int pointID, QQuickIte
return &m_synthMouseEvent;
}
+#if QT_CONFIG(gestures)
/*!
Returns the exclusive grabber of this event, if any, in a vector.
*/
@@ -1712,6 +1726,7 @@ qreal QQuickPointerNativeGestureEvent::value() const
{
return static_cast<QNativeGestureEvent *>(m_event)->value();
}
+#endif // QT_CONFIG(gestures)
/*!
\internal
@@ -1735,12 +1750,13 @@ QQuickEventPoint *QQuickPointerTouchEvent::pointById(int pointId) const {
return nullptr;
}
+#if QT_CONFIG(gestures)
QQuickEventPoint *QQuickPointerNativeGestureEvent::pointById(int pointId) const {
if (m_gesturePoint && pointId == m_gesturePoint->pointId())
return m_gesturePoint;
return nullptr;
}
-
+#endif
/*!
\internal
@@ -1859,6 +1875,7 @@ QTouchEvent *QQuickPointerTouchEvent::asTouchEvent() const
return static_cast<QTouchEvent *>(m_event);
}
+#if QT_CONFIG(gestures)
bool QQuickPointerNativeGestureEvent::allPointsAccepted() const {
return m_gesturePoint->isAccepted();
}
@@ -1871,6 +1888,7 @@ bool QQuickPointerNativeGestureEvent::allPointsGrabbed() const
{
return m_gesturePoint->exclusiveGrabber() != nullptr;
}
+#endif // QT_CONFIG(gestures)
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 2a1e9dc184..bb6726706d 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -66,7 +66,9 @@ QT_BEGIN_NAMESPACE
class QQuickPointerDevice;
class QQuickPointerEvent;
class QQuickPointerMouseEvent;
+#if QT_CONFIG(gestures)
class QQuickPointerNativeGestureEvent;
+#endif
class QQuickPointerTabletEvent;
class QQuickPointerTouchEvent;
class QQuickPointerHandler;
@@ -414,11 +416,15 @@ public: // helpers for C++ only (during event delivery)
virtual QQuickPointerMouseEvent *asPointerMouseEvent() { return nullptr; }
virtual QQuickPointerTouchEvent *asPointerTouchEvent() { return nullptr; }
virtual QQuickPointerTabletEvent *asPointerTabletEvent() { return nullptr; }
+#if QT_CONFIG(gestures)
virtual QQuickPointerNativeGestureEvent *asPointerNativeGestureEvent() { return nullptr; }
+#endif
virtual const QQuickPointerMouseEvent *asPointerMouseEvent() const { return nullptr; }
virtual const QQuickPointerTouchEvent *asPointerTouchEvent() const { return nullptr; }
virtual const QQuickPointerTabletEvent *asPointerTabletEvent() const { return nullptr; }
+#if QT_CONFIG(gestures)
virtual const QQuickPointerNativeGestureEvent *asPointerNativeGestureEvent() const { return nullptr; }
+#endif
virtual bool allPointsAccepted() const = 0;
virtual bool allUpdatedPointsAccepted() const = 0;
virtual bool allPointsGrabbed() const = 0;
@@ -510,6 +516,8 @@ public:
QTouchEvent *asTouchEvent() const;
private:
+ Qt::TouchPointStates touchPointStates() const;
+
int m_pointCount = 0;
QVector<QQuickEventTouchPoint *> m_touchPoints;
mutable QMouseEvent m_synthMouseEvent;
@@ -517,6 +525,7 @@ private:
Q_DISABLE_COPY(QQuickPointerTouchEvent)
};
+#if QT_CONFIG(gestures)
class Q_QUICK_PRIVATE_EXPORT QQuickPointerNativeGestureEvent : public QQuickPointerEvent
{
Q_OBJECT
@@ -551,6 +560,7 @@ private:
Q_DISABLE_COPY(QQuickPointerNativeGestureEvent)
};
+#endif // QT_CONFIG(gestures)
// ### Qt 6: move this to qtbase, replace QTouchDevice and the enums in QTabletEvent
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/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 3a0aea517c..70bb7db2b0 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -3134,6 +3134,9 @@ void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
*/
QTransform QQuickItemPrivate::windowToGlobalTransform() const
{
+ if (Q_UNLIKELY(window == nullptr))
+ return QTransform();
+
QPoint quickWidgetOffset;
QWindow *renderWindow = QQuickRenderControl::renderWindowFor(window, &quickWidgetOffset);
QPointF pos = (renderWindow ? renderWindow : window)->mapToGlobal(quickWidgetOffset);
@@ -3145,6 +3148,9 @@ QTransform QQuickItemPrivate::windowToGlobalTransform() const
*/
QTransform QQuickItemPrivate::globalToWindowTransform() const
{
+ if (Q_UNLIKELY(window == nullptr))
+ return QTransform();
+
QPoint quickWidgetOffset;
QWindow *renderWindow = QQuickRenderControl::renderWindowFor(window, &quickWidgetOffset);
QPointF pos = (renderWindow ? renderWindow : window)->mapToGlobal(quickWidgetOffset);
@@ -7456,11 +7462,8 @@ void QQuickItem::grabMouse()
auto point = fromTouch ?
windowPriv->pointerEventInstance(windowPriv->touchMouseDevice)->pointById(windowPriv->touchMouseId) :
windowPriv->pointerEventInstance(QQuickPointerDevice::genericMouseDevice())->point(0);
- if (point) {
- QQuickItem *oldGrabber = point->grabberItem();
+ if (point)
point->setGrabberItem(this);
- windowPriv->sendUngrabEvent(oldGrabber, fromTouch);
- }
}
/*!
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index 33becd71ec..60f7efae12 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -538,8 +538,13 @@ FxViewItem *QQuickListViewPrivate::snapItemAt(qreal pos)
qreal itemTop = item->position();
if (highlight && itemTop >= pos && item->endPosition() <= pos + highlight->size())
return item;
- if (itemTop+item->size()/2 >= pos && itemTop-prevItemSize/2 < pos)
+
+ // Middle of item and spacing (i.e. the middle of the distance between this item and the next
+ qreal halfwayToNextItem = itemTop + (item->size()+spacing) / 2;
+ qreal halfwayToPrevItem = itemTop - (prevItemSize+spacing) / 2;
+ if (halfwayToNextItem >= pos && halfwayToPrevItem < pos)
snapItem = item;
+
prevItemSize = item->size();
}
return snapItem;
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 052da9fe82..c9316c0406 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -910,7 +910,7 @@ void QQuickMouseArea::ungrabMouse()
if (d->pressed) {
// if our mouse grab has been removed (probably by Flickable), fix our
// state
- d->pressed = nullptr;
+ d->pressed = Qt::NoButton;
d->stealMouse = false;
d->doubleClick = false;
d->overThreshold = false;
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..be297bbe76 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() / img.devicePixelRatioF();
+ const int imgWidth = img.width() / img.devicePixelRatioF();
+ if (imgHeight == frameHeight && imgWidth < maxSize){ //Simple case
+ p.drawImage(QRect(0, y, state->m_frames * frameWidth, frameHeight),
+ img,
+ QRect(state->m_frameX * img.devicePixelRatioF(), 0, state->m_frames * frameWidth * img.devicePixelRatioF(), frameHeight * img.devicePixelRatioF()));
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 * img.devicePixelRatioF(), curY * img.devicePixelRatioF(), copied * img.devicePixelRatioF(), frameHeight * img.devicePixelRatioF()));
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 * img.devicePixelRatioF(), curY * img.devicePixelRatioF(), copied * img.devicePixelRatioF(), frameHeight * img.devicePixelRatioF()));
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/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index e3080dfe48..1cb12235c1 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -1304,8 +1304,12 @@ void QQuickTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
cursor.removeSelectedText();
}
+ QTextBlock block;
+
// insert commit string
if (!e->commitString().isEmpty() || e->replacementLength()) {
+ if (e->commitString().endsWith(QChar::LineFeed))
+ block = cursor.block(); // Remember the block where the preedit text is
QTextCursor c = cursor;
c.setPosition(c.position() + e->replacementStart());
c.setPosition(c.position() + e->replacementLength(), QTextCursor::KeepAnchor);
@@ -1324,7 +1328,9 @@ void QQuickTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
}
}
- QTextBlock block = cursor.block();
+ if (!block.isValid())
+ block = cursor.block();
+
QTextLayout *layout = block.layout();
if (isGettingInput) {
layout->setPreeditArea(cursor.position() - block.position(), e->preeditString());
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 02fe4809ab..fb81a835e9 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -2227,8 +2227,10 @@ QQuickPointerEvent *QQuickWindowPrivate::queryPointerEventInstance(QQuickPointer
for (QQuickPointerEvent *e : pointerEventInstances) {
// If device can generate native gestures (e.g. a trackpad), there might be two QQuickPointerEvents:
// QQuickPointerNativeGestureEvent and QQuickPointerTouchEvent. Use eventType to disambiguate.
+#if QT_CONFIG(gestures)
if (eventType == QEvent::NativeGesture && !qobject_cast<QQuickPointerNativeGestureEvent*>(e))
continue;
+#endif
// Otherwise we assume there's only one event type per device.
// More disambiguation tests might need to be added above if that changes later.
if (e->device() == device)
@@ -2252,9 +2254,11 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevic
break;
case QQuickPointerDevice::TouchPad:
case QQuickPointerDevice::TouchScreen:
+#if QT_CONFIG(gestures)
if (eventType == QEvent::NativeGesture)
ev = new QQuickPointerNativeGestureEvent(q, device);
else // assume QEvent::Type is one of TouchBegin/Update/End
+#endif
ev = new QQuickPointerTouchEvent(q, device);
break;
default:
@@ -2289,9 +2293,11 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QEvent *event) con
dev = QQuickPointerDevice::touchDevice(static_cast<QTouchEvent *>(event)->device());
break;
// TODO tablet event types
+#if QT_CONFIG(gestures)
case QEvent::NativeGesture:
dev = QQuickPointerDevice::touchDevice(static_cast<QNativeGestureEvent *>(event)->device());
break;
+#endif
default:
break;
}
@@ -2313,8 +2319,9 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event)
deliverMouseEvent(event->asPointerMouseEvent());
// failsafe: never allow any kind of grab to persist after release
if (event->isReleaseEvent() && event->buttons() == Qt::NoButton) {
+ QQuickItem *oldGrabber = q->mouseGrabberItem();
event->clearGrabbers();
- sendUngrabEvent(q->mouseGrabberItem(), false);
+ sendUngrabEvent(oldGrabber, false);
}
} else if (event->asPointerTouchEvent()) {
deliverTouchEvent(event->asPointerTouchEvent());
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
index aa83709b72..74426c5c4d 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalimagenode.cpp
@@ -68,6 +68,9 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin
QMargins sourceMargins = normalizedMargins(sourceMarginsIn);
QMargins targetMargins = normalizedMargins(targetMarginsIn);
+ const qreal sourceDpr = pixmap.devicePixelRatioF();
+ sourceMargins *= sourceDpr;
+
// source center
const int sourceCenterTop = sourceRect.top() + sourceMargins.top();
const int sourceCenterLeft = sourceRect.left() + sourceMargins.left();
@@ -89,9 +92,9 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin
int columns = 3;
int rows = 3;
if (rules.horizontal != Qt::StretchTile && sourceCenterWidth != 0)
- columns = qMax(3, 2 + qCeil(targetCenterWidth / qreal(sourceCenterWidth)));
+ columns = qMax(3, 2 + qCeil((targetCenterWidth * sourceDpr) / qreal(sourceCenterWidth)));
if (rules.vertical != Qt::StretchTile && sourceCenterHeight != 0)
- rows = qMax(3, 2 + qCeil(targetCenterHeight / qreal(sourceCenterHeight)));
+ rows = qMax(3, 2 + qCeil((targetCenterHeight * sourceDpr) / qreal(sourceCenterHeight)));
xTarget.resize(columns + 1);
yTarget.resize(rows + 1);
@@ -121,7 +124,7 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin
dx = targetCenterWidth;
break;
case Qt::RepeatTile:
- dx = sourceCenterWidth;
+ dx = sourceCenterWidth / sourceDpr;
break;
case Qt::RoundTile:
dx = targetCenterWidth / qreal(columns - 2);
@@ -136,7 +139,7 @@ void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargin
dy = targetCenterHeight;
break;
case Qt::RepeatTile:
- dy = sourceCenterHeight;
+ dy = sourceCenterHeight / sourceDpr;
break;
case Qt::RoundTile:
dy = targetCenterHeight / qreal(rows - 2);
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
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index ba71551302..afe3380494 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -775,9 +775,7 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx)
, m_currentClip(nullptr)
, m_currentClipType(NoClip)
, m_vertexUploadPool(256)
-#ifdef QSG_SEPARATE_INDEX_BUFFER
, m_indexUploadPool(64)
-#endif
, m_vao(nullptr)
, m_visualizeMode(VisualizeNothing)
{
@@ -834,12 +832,11 @@ static void qsg_wipeBuffer(Buffer *buffer, QOpenGLFunctions *funcs)
free(buffer->data);
}
-static void qsg_wipeBatch(Batch *batch, QOpenGLFunctions *funcs)
+static void qsg_wipeBatch(Batch *batch, QOpenGLFunctions *funcs, bool separateIndexBuffer)
{
qsg_wipeBuffer(&batch->vbo, funcs);
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- qsg_wipeBuffer(&batch->ibo, funcs);
-#endif
+ if (separateIndexBuffer)
+ qsg_wipeBuffer(&batch->ibo, funcs);
delete batch;
}
@@ -847,9 +844,13 @@ Renderer::~Renderer()
{
if (QOpenGLContext::currentContext()) {
// Clean up batches and buffers
- for (int i=0; i<m_opaqueBatches.size(); ++i) qsg_wipeBatch(m_opaqueBatches.at(i), this);
- for (int i=0; i<m_alphaBatches.size(); ++i) qsg_wipeBatch(m_alphaBatches.at(i), this);
- for (int i=0; i<m_batchPool.size(); ++i) qsg_wipeBatch(m_batchPool.at(i), this);
+ const bool separateIndexBuffer = m_context->separateIndexBuffer();
+ for (int i = 0; i < m_opaqueBatches.size(); ++i)
+ qsg_wipeBatch(m_opaqueBatches.at(i), this, separateIndexBuffer);
+ for (int i = 0; i < m_alphaBatches.size(); ++i)
+ qsg_wipeBatch(m_alphaBatches.at(i), this, separateIndexBuffer);
+ for (int i = 0; i < m_batchPool.size(); ++i)
+ qsg_wipeBatch(m_batchPool.at(i), this, separateIndexBuffer);
}
for (Node *n : qAsConst(m_nodes))
@@ -889,13 +890,8 @@ void Renderer::map(Buffer *buffer, int byteSize, bool isIndexBuf)
if (!m_context->hasBrokenIndexBufferObjects() && m_visualizeMode == VisualizeNothing) {
// Common case, use a shared memory pool for uploading vertex data to avoid
// excessive reevaluation
- QDataBuffer<char> &pool =
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- isIndexBuf ? m_indexUploadPool : m_vertexUploadPool;
-#else
- m_vertexUploadPool;
- Q_UNUSED(isIndexBuf);
-#endif
+ QDataBuffer<char> &pool = m_context->separateIndexBuffer() && isIndexBuf
+ ? m_indexUploadPool : m_vertexUploadPool;
if (byteSize > pool.size())
pool.resize(byteSize);
buffer->data = pool.data();
@@ -1864,11 +1860,11 @@ void Renderer::uploadBatch(Batch *b)
ibufferSize = unmergedIndexSize;
}
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- map(&b->ibo, ibufferSize, true);
-#else
- bufferSize += ibufferSize;
-#endif
+ const bool separateIndexBuffer = m_context->separateIndexBuffer();
+ if (separateIndexBuffer)
+ map(&b->ibo, ibufferSize, true);
+ else
+ bufferSize += ibufferSize;
map(&b->vbo, bufferSize);
if (Q_UNLIKELY(debug_upload())) qDebug() << " - batch" << b << " first:" << b->first << " root:"
@@ -1878,22 +1874,17 @@ void Renderer::uploadBatch(Batch *b)
if (b->merged) {
char *vertexData = b->vbo.data;
char *zData = vertexData + b->vertexCount * g->sizeOfVertex();
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- char *indexData = b->ibo.data;
-#else
- char *indexData = zData + (m_useDepthBuffer ? b->vertexCount * sizeof(float) : 0);
-#endif
+ char *indexData = separateIndexBuffer
+ ? b->ibo.data
+ : zData + (int(m_useDepthBuffer) * b->vertexCount * sizeof(float));
quint16 iOffset = 0;
e = b->first;
int verticesInSet = 0;
int indicesInSet = 0;
b->drawSets.reset();
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- int drawSetIndices = 0;
-#else
- int drawSetIndices = indexData - vertexData;
-#endif
+ int drawSetIndices = separateIndexBuffer ? 0 : indexData - vertexData;
+ const auto indexBase = separateIndexBuffer ? b->ibo.data : b->vbo.data;
b->drawSets << DrawSet(0, zData - vertexData, drawSetIndices);
while (e) {
verticesInSet += e->node->geometry()->vertexCount();
@@ -1903,11 +1894,7 @@ void Renderer::uploadBatch(Batch *b)
b->drawSets.last().indices += 1 * sizeof(quint16);
b->drawSets.last().indexCount -= 2;
}
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- drawSetIndices = indexData - b->ibo.data;
-#else
- drawSetIndices = indexData - b->vbo.data;
-#endif
+ drawSetIndices = indexData - indexBase;
b->drawSets << DrawSet(vertexData - b->vbo.data,
zData - b->vbo.data,
drawSetIndices);
@@ -1927,11 +1914,8 @@ void Renderer::uploadBatch(Batch *b)
}
} else {
char *vboData = b->vbo.data;
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- char *iboData = b->ibo.data;
-#else
- char *iboData = vboData + b->vertexCount * g->sizeOfVertex();
-#endif
+ char *iboData = separateIndexBuffer ? b->ibo.data
+ : vboData + b->vertexCount * g->sizeOfVertex();
Element *e = b->first;
while (e) {
QSGGeometry *g = e->node->geometry();
@@ -1979,12 +1963,9 @@ void Renderer::uploadBatch(Batch *b)
}
if (!b->drawSets.isEmpty()) {
- const quint16 *id =
-# ifdef QSG_SEPARATE_INDEX_BUFFER
- (const quint16 *) (b->ibo.data);
-# else
- (const quint16 *) (b->vbo.data + b->drawSets.at(0).indices);
-# endif
+ const quint16 *id = (const quint16 *)(separateIndexBuffer
+ ? b->ibo.data
+ : b->vbo.data + b->drawSets.at(0).indices);
{
QDebug iDump = qDebug();
iDump << " -- Index Data, count:" << b->indexCount;
@@ -2004,9 +1985,8 @@ void Renderer::uploadBatch(Batch *b)
#endif // QT_NO_DEBUG_OUTPUT
unmap(&b->vbo);
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- unmap(&b->ibo, true);
-#endif
+ if (separateIndexBuffer)
+ unmap(&b->ibo, true);
if (Q_UNLIKELY(debug_upload())) qDebug() << " --- vertex/index buffers unmapped, batch upload completed...";
@@ -2299,11 +2279,7 @@ void Renderer::renderMergedBatch(const Batch *batch)
glBindBuffer(GL_ARRAY_BUFFER, batch->vbo.id);
char *indexBase = nullptr;
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- const Buffer *indexBuf = &batch->ibo;
-#else
- const Buffer *indexBuf = &batch->vbo;
-#endif
+ const Buffer *indexBuf = m_context->separateIndexBuffer() ? &batch->ibo : &batch->vbo;
if (m_context->hasBrokenIndexBufferObjects()) {
indexBase = indexBuf->data;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@@ -2395,11 +2371,8 @@ void Renderer::renderUnmergedBatch(const Batch *batch)
glBindBuffer(GL_ARRAY_BUFFER, batch->vbo.id);
char *indexBase = nullptr;
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- const Buffer *indexBuf = &batch->ibo;
-#else
- const Buffer *indexBuf = &batch->vbo;
-#endif
+ const auto separateIndexBuffer = m_context->separateIndexBuffer();
+ const Buffer *indexBuf = separateIndexBuffer ? &batch->ibo : &batch->vbo;
if (batch->indexCount) {
if (m_context->hasBrokenIndexBufferObjects()) {
indexBase = indexBuf->data;
@@ -2428,11 +2401,9 @@ void Renderer::renderUnmergedBatch(const Batch *batch)
}
int vOffset = 0;
-#ifdef QSG_SEPARATE_INDEX_BUFFER
char *iOffset = indexBase;
-#else
- char *iOffset = indexBase + batch->vertexCount * gn->geometry()->sizeOfVertex();
-#endif
+ if (!separateIndexBuffer)
+ iOffset += batch->vertexCount * gn->geometry()->sizeOfVertex();
QMatrix4x4 rootMatrix = batch->root ? qsg_matrixForRoot(batch->root) : QMatrix4x4();
@@ -2735,17 +2706,13 @@ void Renderer::render()
if (Q_UNLIKELY(debug_render())) timeSorting = timer.restart();
int largestVBO = 0;
-#ifdef QSG_SEPARATE_INDEX_BUFFER
int largestIBO = 0;
-#endif
if (Q_UNLIKELY(debug_upload())) qDebug("Uploading Opaque Batches:");
for (int i=0; i<m_opaqueBatches.size(); ++i) {
Batch *b = m_opaqueBatches.at(i);
largestVBO = qMax(b->vbo.size, largestVBO);
-#ifdef QSG_SEPARATE_INDEX_BUFFER
largestIBO = qMax(b->ibo.size, largestIBO);
-#endif
uploadBatch(b);
}
if (Q_UNLIKELY(debug_render())) timeUploadOpaque = timer.restart();
@@ -2756,18 +2723,14 @@ void Renderer::render()
Batch *b = m_alphaBatches.at(i);
uploadBatch(b);
largestVBO = qMax(b->vbo.size, largestVBO);
-#ifdef QSG_SEPARATE_INDEX_BUFFER
largestIBO = qMax(b->ibo.size, largestIBO);
-#endif
}
if (Q_UNLIKELY(debug_render())) timeUploadAlpha = timer.restart();
if (largestVBO * 2 < m_vertexUploadPool.size())
m_vertexUploadPool.resize(largestVBO * 2);
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- if (largestIBO * 2 < m_indexUploadPool.size())
+ if (m_context->separateIndexBuffer() && largestIBO * 2 < m_indexUploadPool.size())
m_indexUploadPool.resize(largestIBO * 2);
-#endif
renderBatches();
@@ -2978,14 +2941,12 @@ void Renderer::visualizeBatch(Batch *b)
if (b->merged) {
shader->setUniformValue(shader->matrix, matrix);
+ const auto &dataStart = m_context->separateIndexBuffer() ? b->ibo.data : b->vbo.data;
for (int ds=0; ds<b->drawSets.size(); ++ds) {
const DrawSet &set = b->drawSets.at(ds);
glVertexAttribPointer(a.position, 2, a.type, false, g->sizeOfVertex(), (void *) (qintptr) (set.vertices));
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- glDrawElements(g->drawingMode(), set.indexCount, GL_UNSIGNED_SHORT, (void *) (qintptr) (b->ibo.data + set.indices));
-#else
- glDrawElements(g->drawingMode(), set.indexCount, GL_UNSIGNED_SHORT, (void *) (qintptr) (b->vbo.data + set.indices));
-#endif
+ glDrawElements(g->drawingMode(), set.indexCount, GL_UNSIGNED_SHORT,
+ (void *)(qintptr)(dataStart + set.indices));
}
} else {
Element *e = b->first;
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 918f3ce82c..12b48c1451 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -433,9 +433,7 @@ struct Batch
mutable uint uploadedThisFrame : 1; // solely for debugging purposes
Buffer vbo;
-#ifdef QSG_SEPARATE_INDEX_BUFFER
Buffer ibo;
-#endif
QDataBuffer<DrawSet> drawSets;
};
@@ -738,9 +736,7 @@ private:
ClipType m_currentClipType;
QDataBuffer<char> m_vertexUploadPool;
-#ifdef QSG_SEPARATE_INDEX_BUFFER
QDataBuffer<char> m_indexUploadPool;
-#endif
// For minimal OpenGL core profile support
QOpenGLVertexArrayObject *m_vao;
@@ -760,10 +756,8 @@ Batch *Renderer::newBatch()
m_batchPool.resize(size - 1);
} else {
b = new Batch();
- memset(&b->vbo, 0, sizeof(Buffer));
-#ifdef QSG_SEPARATE_INDEX_BUFFER
- memset(&b->ibo, 0, sizeof(Buffer));
-#endif
+ Q_ASSERT(offsetof(Batch, ibo) == sizeof(Buffer) + offsetof(Batch, vbo));
+ memset(&b->vbo, 0, sizeof(Buffer) * 2); // Clear VBO & IBO
}
b->init();
return b;
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index 7882496062..22e97a2dc9 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -39,6 +39,7 @@
#include "qsgdefaultrendercontext_p.h"
+#include <QtGui/QGuiApplication>
#include <QtGui/QOpenGLFramebufferObject>
#include <QtQuick/private/qsgbatchrenderer_p.h>
@@ -317,6 +318,17 @@ QSGDefaultRenderContext *QSGDefaultRenderContext::from(QOpenGLContext *context)
return qobject_cast<QSGDefaultRenderContext *>(context->property(QSG_RENDERCONTEXT_PROPERTY).value<QObject *>());
}
+bool QSGDefaultRenderContext::separateIndexBuffer() const
+{
+ // WebGL: A given WebGLBuffer object may only be bound to one of
+ // the ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER target in its
+ // lifetime. An attempt to bind a buffer object to the other
+ // target will generate an INVALID_OPERATION error, and the
+ // current binding will remain untouched.
+ static const bool isWebGL = qGuiApp->platformName().compare(QLatin1String("webgl")) == 0;
+ return isWebGL;
+}
+
QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(const QRawFont &font)
{
QString key = fontKey(font);
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index eb62586a94..57aa4b4c90 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -95,6 +95,7 @@ public:
bool hasBrokenIndexBufferObjects() const { return m_brokenIBOs; }
int maxTextureSize() const override { return m_maxTextureSize; }
+ bool separateIndexBuffer() const;
protected:
static QString fontKey(const QRawFont &font);
@@ -106,8 +107,6 @@ protected:
bool m_serializedRender;
bool m_attachToGLContext;
QSGAtlasTexture::Manager *m_atlasManager;
-
-
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index ac70c3153f..a9a71b1324 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -1,4 +1,3 @@
-# DEFINES += QSG_SEPARATE_INDEX_BUFFER
# DEFINES += QSG_DISTANCEFIELD_CACHE_DEBUG
emscripten: DEFINES += QSG_SEPARATE_INDEX_BUFFER
diff --git a/src/src.pro b/src/src.pro
index ff0e1e99bc..5177dfc743 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -8,9 +8,9 @@ SUBDIRS += \
qtHaveModule(gui):qtConfig(animation) {
SUBDIRS += \
- quick \
- qmltest
+ quick
+ qtConfig(testlib): SUBDIRS += qmltest
qtConfig(quick-particles): \
SUBDIRS += particles
qtHaveModule(widgets): SUBDIRS += quickwidgets