From 28f08e43f12f58ec91d0b4434d67ba4c30a633bf Mon Sep 17 00:00:00 2001 From: John Date: Mon, 29 Dec 2025 20:42:10 +0100 Subject: [PATCH] [core/nvnflinger] Revert GetBufferHistory #84 and #528 (#3218) This will fix 1 of 2 performance regression to LM3 introduced between 0.0.2 and 0.0.3rc1. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3218 Reviewed-by: Maufeat Reviewed-by: Lizzie Reviewed-by: DraVee Co-authored-by: John Co-committed-by: John --- .../nvnflinger/buffer_queue_consumer.cpp | 8 --- .../service/nvnflinger/buffer_queue_core.cpp | 11 +--- .../service/nvnflinger/buffer_queue_core.h | 22 ------- .../nvnflinger/buffer_queue_producer.cpp | 63 ++----------------- .../nvnflinger/buffer_queue_producer.h | 2 - src/core/hle/service/nvnflinger/buffer_slot.h | 1 - 6 files changed, 6 insertions(+), 101 deletions(-) diff --git a/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp index 2913d25819..298ec4b811 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_consumer.cpp @@ -100,14 +100,6 @@ Status BufferQueueConsumer::AcquireBuffer(BufferItem* out_buffer, slots[slot].needs_cleanup_on_release = false; slots[slot].buffer_state = BufferState::Acquired; - // Mark tracked buffer history records as acquired - for (auto& buffer_history_record : core->buffer_history) { - if (buffer_history_record.frame_number == core->frame_counter) { - buffer_history_record.state = BufferState::Acquired; - break; - } - } - // TODO: for now, avoid resetting the fence, so that when we next return this // slot to the producer, it will wait for the fence to pass. We should fix this // by properly waiting for the fence in the BufferItemConsumer. diff --git a/src/core/hle/service/nvnflinger/buffer_queue_core.cpp b/src/core/hle/service/nvnflinger/buffer_queue_core.cpp index 6120d8eae1..63e69ac124 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_core.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_core.cpp @@ -14,17 +14,8 @@ namespace Service::android { BufferQueueCore::BufferQueueCore() = default; -BufferQueueCore::~BufferQueueCore() = default; -void BufferQueueCore::PushHistory(u64 frame_number, s64 queue_time, s64 presentation_time, BufferState state) { - buffer_history_pos = (buffer_history_pos + 1) % BUFFER_HISTORY_SIZE; - buffer_history[buffer_history_pos] = BufferHistoryInfo{ - .frame_number = frame_number, - .queue_time = queue_time, - .presentation_time = presentation_time, - .state = state, - }; -} +BufferQueueCore::~BufferQueueCore() = default; void BufferQueueCore::SignalDequeueCondition() { dequeue_possible.store(true); diff --git a/src/core/hle/service/nvnflinger/buffer_queue_core.h b/src/core/hle/service/nvnflinger/buffer_queue_core.h index ed7d4b4069..305c54b1b1 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_core.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_core.h @@ -18,29 +18,12 @@ #include "core/hle/service/nvnflinger/buffer_item.h" #include "core/hle/service/nvnflinger/buffer_queue_defs.h" -#include "core/hle/service/nvnflinger/buffer_slot.h" #include "core/hle/service/nvnflinger/pixel_format.h" #include "core/hle/service/nvnflinger/status.h" #include "core/hle/service/nvnflinger/window.h" namespace Service::android { -#ifdef _MSC_VER -#pragma pack(push, 1) -struct BufferHistoryInfo { -#elif defined(__GNUC__) || defined(__clang__) -struct __attribute__((packed)) BufferHistoryInfo { -#endif - u64 frame_number; - s64 queue_time; - s64 presentation_time; - BufferState state; -}; -#ifdef _MSC_VER -#pragma pack(pop) -#endif -static_assert(sizeof(BufferHistoryInfo) == 0x1C, "BufferHistoryInfo must be 28 bytes"); - class IConsumerListener; class IProducerListener; @@ -50,13 +33,10 @@ class BufferQueueCore final { public: static constexpr s32 INVALID_BUFFER_SLOT = BufferItem::INVALID_BUFFER_SLOT; - static constexpr u32 BUFFER_HISTORY_SIZE = 8; BufferQueueCore(); ~BufferQueueCore(); - void PushHistory(u64 frame_number, s64 queue_time, s64 presentation_time, BufferState state); - private: void SignalDequeueCondition(); bool WaitForDequeueCondition(std::unique_lock& lk); @@ -92,8 +72,6 @@ private: const s32 max_acquired_buffer_count{}; // This is always zero on HOS bool buffer_has_been_queued{}; u64 frame_counter{}; - std::array buffer_history{}; - u32 buffer_history_pos{BUFFER_HISTORY_SIZE-1}; u32 transform_hint{}; bool is_allocating{}; mutable std::condition_variable_any is_allocating_condition; diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp index bc3076d20b..4f6cdd6945 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp @@ -515,8 +515,6 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input, slots[slot].buffer_state = BufferState::Queued; ++core->frame_counter; slots[slot].frame_number = core->frame_counter; - slots[slot].queue_time = timestamp; - slots[slot].presentation_time = 0; item.acquire_called = slots[slot].acquire_called; item.graphic_buffer = slots[slot].graphic_buffer; @@ -549,15 +547,6 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input, // mark it as freed if (core->StillTracking(*front)) { slots[front->slot].buffer_state = BufferState::Free; - - // Mark tracked buffer history records as free - for (auto& buffer_history_record : core->buffer_history) { - if (buffer_history_record.frame_number == front->frame_number) { - buffer_history_record.state = BufferState::Free; - break; - } - } - // Reset the frame number of the freed buffer so that it is the first in line to // be dequeued again slots[front->slot].frame_number = 0; @@ -571,7 +560,6 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input, } } - core->PushHistory(core->frame_counter, slots[slot].queue_time, slots[slot].presentation_time, BufferState::Queued); core->buffer_has_been_queued = true; core->SignalDequeueCondition(); output->Inflate(core->default_width, core->default_height, core->transform_hint, @@ -822,10 +810,6 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot, return Status::NoError; } -Kernel::KReadableEvent* BufferQueueProducer::GetNativeHandle(u32 type_id) { - return &buffer_wait_event->GetReadableEvent(); -} - void BufferQueueProducer::Transact(u32 code, std::span parcel_data, std::span parcel_reply, u32 flags) { // Values used by BnGraphicBufferProducer onTransact @@ -945,49 +929,9 @@ void BufferQueueProducer::Transact(u32 code, std::span parcel_data, status = SetBufferCount(buffer_count); break; } - case TransactionId::GetBufferHistory: { - LOG_DEBUG(Service_Nvnflinger, "called, transaction=GetBufferHistory"); - - const s32 request = parcel_in.Read(); - if (request <= 0) { - parcel_out.Write(Status::BadValue); - parcel_out.Write(0); - break; - } - - constexpr u32 history_max = BufferQueueCore::BUFFER_HISTORY_SIZE; - std::array buffer_history_snapshot{}; - s32 valid_index{}; - { - std::scoped_lock lk(core->mutex); - - const u32 current_history_pos = core->buffer_history_pos; - u32 index_reversed{}; - for (u32 i = 0; i < history_max; ++i) { - // Wrap values backwards e.g. 7, 6, 5, etc. in the range of 0-7 - index_reversed = (current_history_pos + history_max - i) % history_max; - const auto& current_history_buffer = core->buffer_history[index_reversed]; - - // Here we use the frame number as a terminator. - // Because a buffer without frame_number is not considered complete - if (current_history_buffer.frame_number == 0) { - break; - } - - buffer_history_snapshot[valid_index] = current_history_buffer; - ++valid_index; - } - } - - const s32 limit = std::min(request, valid_index); - parcel_out.Write(Status::NoError); - parcel_out.Write(limit); - for (s32 i = 0; i < limit; ++i) { - parcel_out.Write(buffer_history_snapshot[i]); - } - + case TransactionId::GetBufferHistory: + LOG_WARNING(Service_Nvnflinger, "(STUBBED) called, transaction=GetBufferHistory"); break; - } default: ASSERT_MSG(false, "Unimplemented TransactionId {}", code); break; @@ -1000,5 +944,8 @@ void BufferQueueProducer::Transact(u32 code, std::span parcel_data, (std::min)(parcel_reply.size(), serialized.size())); } +Kernel::KReadableEvent* BufferQueueProducer::GetNativeHandle(u32 type_id) { + return &buffer_wait_event->GetReadableEvent(); +} } // namespace Service::android diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.h b/src/core/hle/service/nvnflinger/buffer_queue_producer.h index 6610e0853a..55e95b2ac9 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.h @@ -89,8 +89,6 @@ private: s32 current_callback_ticket{}; std::condition_variable_any callback_condition; - u64 position; - Service::Nvidia::NvCore::NvMap& nvmap; }; diff --git a/src/core/hle/service/nvnflinger/buffer_slot.h b/src/core/hle/service/nvnflinger/buffer_slot.h index d348b331cb..b33eac35e0 100644 --- a/src/core/hle/service/nvnflinger/buffer_slot.h +++ b/src/core/hle/service/nvnflinger/buffer_slot.h @@ -37,7 +37,6 @@ struct BufferSlot final { bool needs_cleanup_on_release{}; bool attached_by_consumer{}; bool is_preallocated{}; - s64 queue_time{}, presentation_time{}; }; } // namespace Service::android