From 7f1e82898c0bc8741cbdf4db47215fca327ebd98 Mon Sep 17 00:00:00 2001 From: Maufeat Date: Sun, 4 Jan 2026 07:05:09 +0100 Subject: [PATCH] add WriteUnmanagedSpan --- .../nvnflinger/buffer_queue_producer.cpp | 4 +--- src/core/hle/service/nvnflinger/parcel.h | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp index 5081933fee..0723592716 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp @@ -984,9 +984,7 @@ void BufferQueueProducer::Transact(u32 code, std::span parcel_data, parcel_out.Write(status); parcel_out.Write(static_cast(history.size())); - for (const auto& rec : history) { - parcel_out.Write(rec); - } + parcel_out.WriteUnmanagedSpan(history); break; } default: diff --git a/src/core/hle/service/nvnflinger/parcel.h b/src/core/hle/service/nvnflinger/parcel.h index 4567942016..14feb0387e 100644 --- a/src/core/hle/service/nvnflinger/parcel.h +++ b/src/core/hle/service/nvnflinger/parcel.h @@ -129,6 +129,23 @@ public: this->WriteImpl(val, m_data_buffer); } + template + void WriteUnmanagedSpan(std::span values) { + static_assert(std::is_trivially_copyable_v, "T must be trivially copyable."); + if (values.empty()) { + return; + } + + const size_t bytes = values.size_bytes(); + const size_t old_size = m_data_buffer.size(); + m_data_buffer.resize(old_size + bytes); + std::memcpy(m_data_buffer.data() + old_size, values.data(), bytes); + + // Align the parcel stream once after the whole span. + const size_t aligned = Common::AlignUp(m_data_buffer.size(), 4); + m_data_buffer.resize(aligned); + } + template void WriteFlattenedObject(const T* ptr) { if (!ptr) {