From f4dc4d6d393026a5507be1f04a9149f6b8c2322c Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sun, 10 May 2020 19:33:11 +0200 Subject: [PATCH] When reconfiguring a PBO frame allocator, don't reuse userdata. This would cause odd stuttering, as old and new frames would share userdata briefly, causing chaos. --- nageru/pbo_frame_allocator.cpp | 16 +++++++++++++++- nageru/pbo_frame_allocator.h | 6 ++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/nageru/pbo_frame_allocator.cpp b/nageru/pbo_frame_allocator.cpp index f9b4601..70675b1 100644 --- a/nageru/pbo_frame_allocator.cpp +++ b/nageru/pbo_frame_allocator.cpp @@ -264,6 +264,14 @@ void PBOFrameAllocator::destroy_frame(Frame *frame) default: assert(false); } + + if (ud->generation != generation) { + auto it = lingering_generations.find(ud->generation); + assert(it != lingering_generations.end()); + if (--it->second.num_frames_left == 0) { + lingering_generations.erase(it); // Deallocates the userdata block. + } + } } //static int sumsum = 0; @@ -429,6 +437,8 @@ void PBOFrameAllocator::reconfigure(bmusb::PixelFormat pixel_format, return; } + size_t old_num_queued_frames = this->num_queued_frames; + this->pixel_format = pixel_format; this->frame_size = frame_size; this->width = width; @@ -441,12 +451,16 @@ void PBOFrameAllocator::reconfigure(bmusb::PixelFormat pixel_format, this->map_bits = map_bits; lock_guard lock(freelist_mutex); + lingering_generations[generation] = LingeringGeneration{ move(userdata), old_num_queued_frames }; + ++generation; + while (!freelist.empty()) { Frame frame = freelist.front(); freelist.pop(); destroy_frame(&frame); } - ++generation; + + userdata.reset(new Userdata[num_queued_frames]); for (size_t i = 0; i < num_queued_frames; ++i) { init_frame(i, frame_size, width, height, permissions, map_bits, generation); } diff --git a/nageru/pbo_frame_allocator.h b/nageru/pbo_frame_allocator.h index 5ea0ffe..eee25ce 100644 --- a/nageru/pbo_frame_allocator.h +++ b/nageru/pbo_frame_allocator.h @@ -114,6 +114,12 @@ private: GLenum permissions; GLenum map_bits; int generation = 0; // Under freelist_mutex. + + struct LingeringGeneration { + std::unique_ptr userdata; + size_t num_frames_left; + }; + std::map lingering_generations; }; #endif // !defined(_PBO_FRAME_ALLOCATOR) -- 2.39.2