mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #3635 from FernandoS27/buffer-free
Buffer queue: Correct behavior of free buffer.
This commit is contained in:
		
						commit
						75e39f7f88
					
				@ -28,6 +28,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer)
 | 
				
			|||||||
    buffer.slot = slot;
 | 
					    buffer.slot = slot;
 | 
				
			||||||
    buffer.igbp_buffer = igbp_buffer;
 | 
					    buffer.igbp_buffer = igbp_buffer;
 | 
				
			||||||
    buffer.status = Buffer::Status::Free;
 | 
					    buffer.status = Buffer::Status::Free;
 | 
				
			||||||
 | 
					    free_buffers.push_back(slot);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    queue.emplace_back(buffer);
 | 
					    queue.emplace_back(buffer);
 | 
				
			||||||
    buffer_wait_event.writable->Signal();
 | 
					    buffer_wait_event.writable->Signal();
 | 
				
			||||||
@ -35,16 +36,37 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width,
 | 
					std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width,
 | 
				
			||||||
                                                                                       u32 height) {
 | 
					                                                                                       u32 height) {
 | 
				
			||||||
    auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) {
 | 
					 | 
				
			||||||
        // Only consider free buffers. Buffers become free once again after they've been Acquired
 | 
					 | 
				
			||||||
        // and Released by the compositor, see the NVFlinger::Compose method.
 | 
					 | 
				
			||||||
        if (buffer.status != Buffer::Status::Free) {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Make sure that the parameters match.
 | 
					    if (free_buffers.empty()) {
 | 
				
			||||||
        return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height;
 | 
					        return {};
 | 
				
			||||||
    });
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auto f_itr = free_buffers.begin();
 | 
				
			||||||
 | 
					    auto itr = queue.end();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (f_itr != free_buffers.end()) {
 | 
				
			||||||
 | 
					        auto slot = *f_itr;
 | 
				
			||||||
 | 
					        itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) {
 | 
				
			||||||
 | 
					            // Only consider free buffers. Buffers become free once again after they've been
 | 
				
			||||||
 | 
					            // Acquired and Released by the compositor, see the NVFlinger::Compose method.
 | 
				
			||||||
 | 
					            if (buffer.status != Buffer::Status::Free) {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (buffer.slot != slot) {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Make sure that the parameters match.
 | 
				
			||||||
 | 
					            return buffer.igbp_buffer.width == width && buffer.igbp_buffer.height == height;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (itr != queue.end()) {
 | 
				
			||||||
 | 
					            free_buffers.erase(f_itr);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ++f_itr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (itr == queue.end()) {
 | 
					    if (itr == queue.end()) {
 | 
				
			||||||
        return {};
 | 
					        return {};
 | 
				
			||||||
@ -99,6 +121,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) {
 | 
				
			|||||||
    ASSERT(itr != queue.end());
 | 
					    ASSERT(itr != queue.end());
 | 
				
			||||||
    ASSERT(itr->status == Buffer::Status::Acquired);
 | 
					    ASSERT(itr->status == Buffer::Status::Acquired);
 | 
				
			||||||
    itr->status = Buffer::Status::Free;
 | 
					    itr->status = Buffer::Status::Free;
 | 
				
			||||||
 | 
					    free_buffers.push_back(slot);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    buffer_wait_event.writable->Signal();
 | 
					    buffer_wait_event.writable->Signal();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -101,6 +101,7 @@ private:
 | 
				
			|||||||
    u32 id;
 | 
					    u32 id;
 | 
				
			||||||
    u64 layer_id;
 | 
					    u64 layer_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::list<u32> free_buffers;
 | 
				
			||||||
    std::vector<Buffer> queue;
 | 
					    std::vector<Buffer> queue;
 | 
				
			||||||
    std::list<u32> queue_sequence;
 | 
					    std::list<u32> queue_sequence;
 | 
				
			||||||
    Kernel::EventPair buffer_wait_event;
 | 
					    Kernel::EventPair buffer_wait_event;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user