summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp41
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.h1
2 files changed, 33 insertions, 9 deletions
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index 32b6f4b27..9bcafa5fc 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -28,6 +28,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer)
28 buffer.slot = slot; 28 buffer.slot = slot;
29 buffer.igbp_buffer = igbp_buffer; 29 buffer.igbp_buffer = igbp_buffer;
30 buffer.status = Buffer::Status::Free; 30 buffer.status = Buffer::Status::Free;
31 free_buffers.push_back(slot);
31 32
32 queue.emplace_back(buffer); 33 queue.emplace_back(buffer);
33 buffer_wait_event.writable->Signal(); 34 buffer_wait_event.writable->Signal();
@@ -35,16 +36,37 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer)
35 36
36std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width, 37std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width,
37 u32 height) { 38 u32 height) {
38 auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) {
39 // Only consider free buffers. Buffers become free once again after they've been Acquired
40 // and Released by the compositor, see the NVFlinger::Compose method.
41 if (buffer.status != Buffer::Status::Free) {
42 return false;
43 }
44 39
45 // Make sure that the parameters match. 40 if (free_buffers.empty()) {
46 return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height; 41 return {};
47 }); 42 }
43
44 auto f_itr = free_buffers.begin();
45 auto itr = queue.end();
46
47 while (f_itr != free_buffers.end()) {
48 auto slot = *f_itr;
49 itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) {
50 // Only consider free buffers. Buffers become free once again after they've been
51 // Acquired and Released by the compositor, see the NVFlinger::Compose method.
52 if (buffer.status != Buffer::Status::Free) {
53 return false;
54 }
55
56 if (buffer.slot != slot) {
57 return false;
58 }
59
60 // Make sure that the parameters match.
61 return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height;
62 });
63
64 if (itr != queue.end()) {
65 free_buffers.erase(f_itr);
66 break;
67 }
68 ++f_itr;
69 }
48 70
49 if (itr == queue.end()) { 71 if (itr == queue.end()) {
50 return {}; 72 return {};
@@ -99,6 +121,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) {
99 ASSERT(itr != queue.end()); 121 ASSERT(itr != queue.end());
100 ASSERT(itr->status == Buffer::Status::Acquired); 122 ASSERT(itr->status == Buffer::Status::Acquired);
101 itr->status = Buffer::Status::Free; 123 itr->status = Buffer::Status::Free;
124 free_buffers.push_back(slot);
102 125
103 buffer_wait_event.writable->Signal(); 126 buffer_wait_event.writable->Signal();
104} 127}
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h
index f4bbfd945..f674823b0 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.h
+++ b/src/core/hle/service/nvflinger/buffer_queue.h
@@ -101,6 +101,7 @@ private:
101 u32 id; 101 u32 id;
102 u64 layer_id; 102 u64 layer_id;
103 103
104 std::list<u32> free_buffers;
104 std::vector<Buffer> queue; 105 std::vector<Buffer> queue;
105 std::list<u32> queue_sequence; 106 std::list<u32> queue_sequence;
106 Kernel::EventPair buffer_wait_event; 107 Kernel::EventPair buffer_wait_event;