From 1b23e2b8f1d7d15e40b6cc48d0a74b760722324b Mon Sep 17 00:00:00 2001 From: Maufeat Date: Sat, 19 Jul 2025 02:30:05 +0200 Subject: [PATCH] apply amichuchu patch --- src/core/CMakeLists.txt | 1 + .../hle/service/nvnflinger/buffer_history.h | 21 ++++++------- .../nvnflinger/buffer_queue_producer.cpp | 30 ++++++++++++++++--- .../nvnflinger/buffer_queue_producer.h | 4 ++- 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index d830cc381d..2f7f3b5b24 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -863,6 +863,7 @@ add_library(core STATIC hle/service/nvdrv/nvmemp.cpp hle/service/nvdrv/nvmemp.h hle/service/nvnflinger/binder.h + hle/service/nvnflinger/buffer_history.h hle/service/nvnflinger/buffer_item.h hle/service/nvnflinger/buffer_item_consumer.cpp hle/service/nvnflinger/buffer_item_consumer.h diff --git a/src/core/hle/service/nvnflinger/buffer_history.h b/src/core/hle/service/nvnflinger/buffer_history.h index 614e7fc2fe..0a1d4e89bc 100644 --- a/src/core/hle/service/nvnflinger/buffer_history.h +++ b/src/core/hle/service/nvnflinger/buffer_history.h @@ -14,24 +14,25 @@ class BufferHistoryManager { public: void PushEntry(s32 slot, s64 timestamp, s64 frame_number) { std::lock_guard lock(mutex_); - if (entries_.size() >= kMaxHistorySize) { - entries_.pop_front(); + if (history_entries.size() >= kMaxHistorySize) { + history_entries.pop_front(); } - entries_.emplace_back(BufferHistoryEntry{slot, timestamp, frame_number}); + history_entries.emplace_back(BufferHistoryEntry{slot, timestamp, frame_number}); } - s32 GetHistory(std::span out_entries) { + s32 GetHistory(s32 wantedEntries, std::span& entries) { std::lock_guard lock(mutex_); - s32 count = - std::min(static_cast(entries_.size()), static_cast(out_entries.size())); - for (s32 i = 0; i < count; ++i) { - out_entries[i] = entries_[entries_.size() - count + i]; + s32 countToCopy = std::min(wantedEntries, static_cast(history_entries.size())); + auto out_entries = std::vector(countToCopy); + for (s32 i = 0; i < countToCopy; ++i) { + out_entries[i] = history_entries[history_entries.size() - countToCopy + i]; } - return count; + entries = std::span(out_entries); + return countToCopy; } private: static constexpr size_t kMaxHistorySize = 16; - std::deque entries_; + std::deque history_entries; std::mutex mutex_; }; \ No newline at end of file diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp index e5f75e648c..e7d3e88bfc 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp @@ -27,7 +27,7 @@ BufferQueueProducer::BufferQueueProducer(Service::KernelHelpers::ServiceContext& std::shared_ptr buffer_queue_core_, Service::Nvidia::NvCore::NvMap& nvmap_) : service_context{service_context_}, core{std::move(buffer_queue_core_)}, slots(core->slots), - nvmap(nvmap_) { + buffer_history(), nvmap(nvmap_) { buffer_wait_event = service_context.CreateEvent("BufferQueue:WaitEvent"); } @@ -35,6 +35,18 @@ BufferQueueProducer::~BufferQueueProducer() { service_context.CloseEvent(buffer_wait_event); } +Status BufferQueueProducer::GetBufferHistory(s32 count, std::span& entries) { + if (count <= 0) { + LOG_ERROR(Service_Nvnflinger, "count must be positive"); + entries = std::span(); + return Status::BadValue; + + } else { + buffer_history.GetHistory(count, entries); + return Status::NoError; + } +} + Status BufferQueueProducer::RequestBuffer(s32 slot, std::shared_ptr* buf) { LOG_DEBUG(Service_Nvnflinger, "slot {}", slot); @@ -516,6 +528,7 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input, slots[slot].buffer_state = BufferState::Queued; ++core->frame_counter; slots[slot].frame_number = core->frame_counter; + buffer_history.PushEntry(slot, timestamp, static_cast(core->frame_counter)); item.acquire_called = slots[slot].acquire_called; item.graphic_buffer = slots[slot].graphic_buffer; @@ -928,9 +941,18 @@ void BufferQueueProducer::Transact(u32 code, std::span parcel_data, } case TransactionId::GetBufferHistory: { LOG_DEBUG(Service_Nvnflinger, "GetBufferHistory"); - auto out_span = parcel_in.Read>(); - s32 count = buffer_history_.GetHistory(out_span); - parcel_out.Write(s32(count)); + auto entries_wanted = parcel_in.Read(); + if (entries_wanted <= 0) { + parcel_out.Write(0); + status = Status::BadValue; + } + else { + std::span entries; + buffer_history.GetHistory(entries_wanted, entries); + parcel_out.Write(static_cast(entries.size())); + parcel_out.Write(entries); + status = Status::NoError; + } break; } default: diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.h b/src/core/hle/service/nvnflinger/buffer_queue_producer.h index 28c26ca1ed..3443c0e7f5 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.h @@ -13,6 +13,7 @@ #include #include +#include "buffer_history.h" #include "common/common_funcs.h" #include "core/hle/service/nvdrv/nvdata.h" #include "core/hle/service/nvnflinger/binder.h" @@ -59,6 +60,7 @@ public: public: Status RequestBuffer(s32 slot, std::shared_ptr* buf); Status SetBufferCount(s32 buffer_count); + Status GetBufferHistory(s32 count, std::span& entries); Status DequeueBuffer(s32* out_slot, android::Fence* out_fence, bool async, u32 width, u32 height, PixelFormat format, u32 usage); Status DetachBuffer(s32 slot); @@ -84,7 +86,7 @@ private: std::shared_ptr core; BufferQueueDefs::SlotsType& slots; - BufferHistoryManager buffer_history_; + BufferHistoryManager buffer_history; u32 sticky_transform{}; std::mutex callback_mutex; s32 next_callback_ticket{};