From 76138fee6da9364f4f1a9e3d377689a89c86751e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 5 Apr 2018 17:47:08 +0200 Subject: [PATCH] Move pushbuffer deletion to the render manager. --- ext/native/thin3d/GLRenderManager.cpp | 10 +++++++++- ext/native/thin3d/GLRenderManager.h | 13 +++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index f7cc21e87d..2ba1057031 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -13,7 +13,12 @@ #define VLOG(...) #endif +// Runs on the GPU thread. void GLDeleter::Perform() { + for (auto pushBuffer : pushBuffers) { + delete pushBuffer; + } + pushBuffers.clear(); for (auto shader : shaders) { delete shader; } @@ -638,10 +643,13 @@ bool GLPushBuffer::AddBuffer() { return true; } +// Executed on the render thread! void GLPushBuffer::Destroy() { for (BufInfo &info : buffers_) { // This will automatically unmap device memory, if needed. - render_->DeleteBuffer(info.buffer); + // NOTE: We immediately delete the buffer, don't go through the deleter, since we're on the render thread. + // render_->DeleteBuffer(info.buffer); + delete info.buffer; FreeAlignedMemory(info.localMemory); } buffers_.clear(); diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index 7bfd0fab4a..ad8de14584 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -184,8 +184,12 @@ class GLRenderManager; // faster than the hundreds of buffer uploads or memory array buffers we used before. // On modern GL we could avoid the copy using glBufferStorage but not sure it's worth the // trouble. +// We need to manage the lifetime of this together with the other resources so its destructor +// runs on the render thread. class GLPushBuffer { public: + friend class GLRenderManager; + struct BufInfo { GLRBuffer *buffer = nullptr; uint8_t *localMemory = nullptr; @@ -198,6 +202,7 @@ public: void Reset() { offset_ = 0; } +private: // Needs context in case of defragment. void Begin() { buf_ = 0; @@ -216,6 +221,7 @@ public: Unmap(); } +public: void Map(); void Unmap(); @@ -306,7 +312,7 @@ public: void Perform(); bool IsEmpty() const { - return shaders.empty() && programs.empty() && buffers.empty() && textures.empty() && inputLayouts.empty() && framebuffers.empty(); + return shaders.empty() && programs.empty() && buffers.empty() && textures.empty() && inputLayouts.empty() && framebuffers.empty() && pushBuffers.empty(); } void Take(GLDeleter &other) { _assert_msg_(G3D, IsEmpty(), "Deleter already has stuff"); @@ -316,12 +322,14 @@ public: textures = std::move(other.textures); inputLayouts = std::move(other.inputLayouts); framebuffers = std::move(other.framebuffers); + pushBuffers = std::move(other.pushBuffers); other.shaders.clear(); other.programs.clear(); other.buffers.clear(); other.textures.clear(); other.inputLayouts.clear(); other.framebuffers.clear(); + other.pushBuffers.clear(); } std::vector shaders; @@ -330,6 +338,7 @@ public: std::vector textures; std::vector inputLayouts; std::vector framebuffers; + std::vector pushBuffers; }; class GLRInputLayout { @@ -469,7 +478,7 @@ public: deleter_.framebuffers.push_back(framebuffer); } void DeletePushBuffer(GLPushBuffer *pushbuffer) { - delete pushbuffer; + deleter_.pushBuffers.push_back(pushbuffer); } void BeginPushBuffer(GLPushBuffer *pushbuffer) {