diff options
author | Mauro Persano <mauro.persano@kdab.com> | 2017-05-29 08:58:29 -0300 |
---|---|---|
committer | Mauro Persano <mauro.persano@kdab.com> | 2017-05-30 13:20:50 +0000 |
commit | 4c9303aa377e45681377997586f0985d5c282bbe (patch) | |
tree | d37475fc7ea49096c72f60207f8f4b3f77f17c29 /tests | |
parent | 95d6847cec8a8c0d5c0013fece507d56c4aee7e6 (diff) |
Add reference count for backend buffers
In the main rendering loop, first dirty GL resources are uploaded, then
render views are submitted, and then unused GL resources are released.
Consider the following piece of code:
entity->setParent(nullptr);
entity->setParent(root);
If this is executed inside a single frame, entity's children buffers
will be marked for release when they are removed from the scene, and
marked as dirty when they're added again. In the following frame, the
render thread will upload them at the beginning of the frame, and
incorrectly release them at the end of the frame.
This patch adds a reference count for buffers in BufferManager to
prevent this kind of race. The reference is incremented when a buffer is
added to the scene (in Buffer::initializeFromPeer) and decremented when
it's removed from the scene (in BufferFunctor::destroy).
Task-number: QTBUG-60726
Change-Id: I8eed7b4c2d8262ba846e73bf4299edae7bc16b3e
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/render/buffer/tst_buffer.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/tests/auto/render/buffer/tst_buffer.cpp b/tests/auto/render/buffer/tst_buffer.cpp index 8049aaf37..19c12a317 100644 --- a/tests/auto/render/buffer/tst_buffer.cpp +++ b/tests/auto/render/buffer/tst_buffer.cpp @@ -261,6 +261,30 @@ private Q_SLOTS: renderBuffer.unsetDirty(); QVERIFY(!renderBuffer.isDirty()); } + + void checkBufferManagerReferenceCount() + { + // GIVEN + Qt3DRender::Render::Buffer renderBuffer; + Qt3DRender::QBuffer buffer(Qt3DRender::QBuffer::IndexBuffer); + Qt3DRender::Render::BufferManager bufferManager; + + // WHEN + renderBuffer.setManager(&bufferManager); + simulateInitialization(&buffer, &renderBuffer); + + // THEN + QVERIFY(bufferManager.takeBuffersToRelease().empty()); + + // WHEN + bufferManager.removeBufferReference(renderBuffer.peerId()); + auto buffers = bufferManager.takeBuffersToRelease(); + + // THEN + QVERIFY(buffers.size() == 1); + QVERIFY(buffers.first() == renderBuffer.peerId()); + QVERIFY(bufferManager.takeBuffersToRelease().empty()); + } }; |