summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@qt.io>2018-08-27 15:45:45 +0200
committerFrederik Gladhorn <frederik.gladhorn@qt.io>2018-08-27 15:45:45 +0200
commitf25824e0b2154129c0c7586e708c87fe24ce63eb (patch)
treeb0a7d03a8040375381e185dccf601f7527dc6848
parent028cd30b752f296b2c9022db92961016ffb4f7fc (diff)
parent9dee534836092787d774be7face029b5cf53e546 (diff)
Merge 5.11 into 5.11.2
-rw-r--r--src/qml/jsruntime/qv4memberdata.cpp17
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp12
2 files changed, 24 insertions, 5 deletions
diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp
index 8f862d63e9..da086bd47a 100644
--- a/src/qml/jsruntime/qv4memberdata.cpp
+++ b/src/qml/jsruntime/qv4memberdata.cpp
@@ -45,12 +45,29 @@ using namespace QV4;
DEFINE_MANAGED_VTABLE(MemberData);
+static size_t nextPowerOfTwo(size_t s)
+{
+ --s;
+ s |= s >> 1;
+ s |= s >> 2;
+ s |= s >> 4;
+ s |= s >> 8;
+ s |= s >> 16;
+#if (QT_POINTER_SIZE == 8)
+ s |= s >> 32;
+#endif
+ ++s;
+ return s;
+}
+
Heap::MemberData *MemberData::allocate(ExecutionEngine *e, uint n, Heap::MemberData *old)
{
Q_ASSERT(!old || old->values.size < n);
Q_ASSERT(n);
size_t alloc = MemoryManager::align(sizeof(Heap::MemberData) + (n - 1)*sizeof(Value));
+ // round up to next power of two to avoid quadratic behaviour for very large objects
+ alloc = nextPowerOfTwo(alloc);
Heap::MemberData *m = e->memoryManager->allocManaged<MemberData>(alloc);
if (old)
// no write barrier required here
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 2eaed497ef..05f635cf1d 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -349,11 +349,16 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window)
void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
{
- QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
- if (!cd->isRenderable() || !m_windows.contains(window))
+ if (!m_windows.contains(window))
return;
WindowData &data = const_cast<WindowData &>(m_windows[window]);
+ bool alsoSwap = data.updatePending;
+ data.updatePending = false;
+
+ QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
+ if (!cd->isRenderable())
+ return;
bool current = false;
@@ -380,9 +385,6 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window)
current = gl->makeCurrent(window);
}
- bool alsoSwap = data.updatePending;
- data.updatePending = false;
-
bool lastDirtyWindow = true;
auto i = m_windows.constBegin();
while (i != m_windows.constEnd()) {