diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2019-10-30 15:13:18 +0100 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2019-10-30 15:25:38 +0100 |
commit | db9f0721c4406843766aab66d1cae170e76a237d (patch) | |
tree | ed737b1fb0f95e58244ef22f41210dac9e17cf1d | |
parent | e5b5505569b409798e382d60b71fbf436952bab9 (diff) |
Buffer: make sure we force allocate before doing partial updates
Change-Id: I229f9bcd21a10c0a4cff5c4f559cd285a3e50276
Reviewed-by: Mike Krus <mike.krus@kdab.com>
-rw-r--r-- | src/render/geometry/buffer.cpp | 29 | ||||
-rw-r--r-- | tests/auto/render/buffer/tst_buffer.cpp | 55 |
2 files changed, 75 insertions, 9 deletions
diff --git a/src/render/geometry/buffer.cpp b/src/render/geometry/buffer.cpp index 0d634c911..6db3bab44 100644 --- a/src/render/geometry/buffer.cpp +++ b/src/render/geometry/buffer.cpp @@ -137,20 +137,31 @@ void Buffer::syncFromFrontEnd(const QNode *frontEnd, bool firstTime) m_manager->addDirtyBuffer(peerId()); } { - QVariant v = node->property("QT3D_updateData"); - if (v.isValid()) { + const QVariant v = node->property("QT3D_updateData"); + + // Make sure we record data if it's the first time we are called + // or if we have no partial updates + if (firstTime || !v.isValid()){ + const QByteArray newData = node->data(); + const bool dirty = m_data != newData; + m_bufferDirty |= dirty; + m_data = newData; + + // Since frontend applies partial updates to its m_data + // if we enter this code block, there's no problem in actually + // ignoring the partial updates + if (v.isValid()) + const_cast<QBuffer *>(node)->setProperty("QT3D_updateData", {}); + + if (dirty && !m_data.isEmpty()) + forceDataUpload(); + } else if (v.isValid()) { + // Apply partial updates and record them to allow partial upload to the GPU Qt3DRender::QBufferUpdate updateData = v.value<Qt3DRender::QBufferUpdate>(); m_data.replace(updateData.offset, updateData.data.size(), updateData.data); m_bufferUpdates.push_back(updateData); m_bufferDirty = true; const_cast<QBuffer *>(node)->setProperty("QT3D_updateData", {}); - } else { - QByteArray newData = node->data(); - bool dirty = m_data != newData; - m_bufferDirty |= dirty; - m_data = newData; - if (dirty && !m_data.isEmpty()) - forceDataUpload(); } } markDirty(AbstractRenderer::BuffersDirty); diff --git a/tests/auto/render/buffer/tst_buffer.cpp b/tests/auto/render/buffer/tst_buffer.cpp index 1b53efd33..fa1491914 100644 --- a/tests/auto/render/buffer/tst_buffer.cpp +++ b/tests/auto/render/buffer/tst_buffer.cpp @@ -157,6 +157,61 @@ private Q_SLOTS: QVERIFY(backendBuffer.pendingBufferUpdates().empty()); } + + void checkForceFullUploadOnFirstTime() + { + // GIVEN + Qt3DRender::Render::Buffer backendBuffer; + Qt3DRender::Render::BufferManager bufferManager; + TestRenderer renderer; + Qt3DRender::QBuffer frontendBuffer; + + QByteArray data("111456789\0"); + + frontendBuffer.setData(data); + frontendBuffer.updateData(1, QByteArray("23\0")); + + // THEN + QCOMPARE(frontendBuffer.data(), QByteArray("123456789\0")); + + // WHEN + backendBuffer.setManager(&bufferManager); + backendBuffer.setRenderer(&renderer); + simulateInitializationSync(&frontendBuffer, &backendBuffer); + + // THEN + QCOMPARE(backendBuffer.pendingBufferUpdates().size(), 1); + Qt3DRender::QBufferUpdate fullUpdate = backendBuffer.pendingBufferUpdates().first(); + QCOMPARE(fullUpdate.offset, -1); + QVERIFY(fullUpdate.data.isEmpty()); + QCOMPARE(frontendBuffer.data(), backendBuffer.data()); + + backendBuffer.pendingBufferUpdates().clear(); + + // WHEN + frontendBuffer.updateData(1, QByteArray("00\0")); + backendBuffer.syncFromFrontEnd(&frontendBuffer, false); + + // THEN + QCOMPARE(frontendBuffer.data(), QByteArray("100456789\0")); + QCOMPARE(backendBuffer.pendingBufferUpdates().size(), 1); + fullUpdate = backendBuffer.pendingBufferUpdates().first(); + QCOMPARE(fullUpdate.offset, 1); + QCOMPARE(fullUpdate.data, QByteArray("00\0")); + QCOMPARE(frontendBuffer.data(), backendBuffer.data()); + + // WHEN + frontendBuffer.updateData(1, QByteArray("22\0")); + backendBuffer.syncFromFrontEnd(&frontendBuffer, true); + + // THEN + QCOMPARE(frontendBuffer.data(), QByteArray("122456789\0")); + fullUpdate = backendBuffer.pendingBufferUpdates().first(); + QCOMPARE(fullUpdate.offset, -1); + QVERIFY(fullUpdate.data.isEmpty()); + QCOMPARE(frontendBuffer.data(), backendBuffer.data()); + } + void checkPropertyChanges() { // GIVEN |