diff --git a/src/core/hle/service/nvnflinger/buffer_history.h b/src/core/hle/service/nvnflinger/buffer_history.h new file mode 100644 index 0000000000..a9bf465523 --- /dev/null +++ b/src/core/hle/service/nvnflinger/buffer_history.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once +#include +#include +#include + +struct BufferHistoryEntry { s32 slot; s64 timestamp; s64 frame_number; }; + +class BufferHistoryManager { public: void PushEntry(s32 slot, s64 timestamp, s64 frame_number) { std::lock_guardstd::mutex lock(mutex_); if (entries_.size() >= kMaxHistorySize) entries_.pop_front(); + +entries_.emplace_back(BufferHistoryEntry{slot, timestamp, frame_number}); +} + +s32 GetHistory(std::span out_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]; + + return count; +} + +private: static constexpr size_t kMaxHistorySize = 16; std::deque 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 9e5091eebd..bab004a061 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -16,6 +19,7 @@ #include "core/hle/service/nvnflinger/parcel.h" #include "core/hle/service/nvnflinger/ui/graphic_buffer.h" #include "core/hle/service/nvnflinger/window.h" +#include "core/hle/service/nvnflinger/buffer_history.h" namespace Service::android { @@ -922,11 +926,11 @@ void BufferQueueProducer::Transact(u32 code, std::span parcel_data, status = SetBufferCount(buffer_count); break; } - case TransactionId::GetBufferHistory: - LOG_WARNING(Service_Nvnflinger, "(STUBBED) called, transaction=GetBufferHistory"); - break; - default: - ASSERT_MSG(false, "Unimplemented TransactionId {}", code); + case TransactionId::GetBufferHistory: { + LOG_DEBUG(Service_Nvnflinger, "GetBufferHistory"); + auto out_span = request.PopRaw>(); + s32 count = buffer_history_.GetHistory(out_span); + response.Push(s32(count)); break; } diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.h b/src/core/hle/service/nvnflinger/buffer_queue_producer.h index 048523514c..fdc4059dbe 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.h +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2014 The Android Open Source Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -80,6 +83,8 @@ private: std::shared_ptr core; BufferQueueDefs::SlotsType& slots; + BufferHistoryManager buffer_history_; + buffer_history_.PushEntry(slot, timestamp, frame_number); u32 sticky_transform{}; std::mutex callback_mutex; s32 next_callback_ticket{};