nvflinger: Split Parcel class into InputParcel and OutputParcel
The usages of the Parcel class were already unique to either Read or Write operations. Avoids needing a vector of the input payload for the InputParcel use-case, instead it can remain as a span.
This commit is contained in:
parent
7ffd624248
commit
32d01a39b0
|
@ -815,8 +815,8 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
|
||||||
|
|
||||||
void BufferQueueProducer::Transact(Kernel::HLERequestContext& ctx, TransactionId code, u32 flags) {
|
void BufferQueueProducer::Transact(Kernel::HLERequestContext& ctx, TransactionId code, u32 flags) {
|
||||||
Status status{Status::NoError};
|
Status status{Status::NoError};
|
||||||
Parcel parcel_in{ctx.ReadBuffer()};
|
InputParcel parcel_in{ctx.ReadBufferSpan()};
|
||||||
Parcel parcel_out{};
|
OutputParcel parcel_out{};
|
||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case TransactionId::Connect: {
|
case TransactionId::Connect: {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
namespace Service::android {
|
namespace Service::android {
|
||||||
|
|
||||||
QueueBufferInput::QueueBufferInput(Parcel& parcel) {
|
QueueBufferInput::QueueBufferInput(InputParcel& parcel) {
|
||||||
parcel.ReadFlattened(*this);
|
parcel.ReadFlattened(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,11 @@
|
||||||
|
|
||||||
namespace Service::android {
|
namespace Service::android {
|
||||||
|
|
||||||
class Parcel;
|
class InputParcel;
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct QueueBufferInput final {
|
struct QueueBufferInput final {
|
||||||
explicit QueueBufferInput(Parcel& parcel);
|
explicit QueueBufferInput(InputParcel& parcel);
|
||||||
|
|
||||||
void Deflate(s64* timestamp_, bool* is_auto_timestamp_, Common::Rectangle<s32>* crop_,
|
void Deflate(s64* timestamp_, bool* is_auto_timestamp_, Common::Rectangle<s32>* crop_,
|
||||||
NativeWindowScalingMode* scaling_mode_, NativeWindowTransform* transform_,
|
NativeWindowScalingMode* scaling_mode_, NativeWindowTransform* transform_,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <span>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
|
@ -12,18 +13,17 @@
|
||||||
|
|
||||||
namespace Service::android {
|
namespace Service::android {
|
||||||
|
|
||||||
class Parcel final {
|
struct ParcelHeader {
|
||||||
|
u32 data_size;
|
||||||
|
u32 data_offset;
|
||||||
|
u32 objects_size;
|
||||||
|
u32 objects_offset;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(ParcelHeader) == 16, "ParcelHeader has wrong size");
|
||||||
|
|
||||||
|
class InputParcel final {
|
||||||
public:
|
public:
|
||||||
static constexpr std::size_t DefaultBufferSize = 0x40;
|
explicit InputParcel(std::span<const u8> in_data) : read_buffer(std::move(in_data)) {
|
||||||
|
|
||||||
Parcel() : buffer(DefaultBufferSize) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
explicit Parcel(const T& out_data) : buffer(DefaultBufferSize) {
|
|
||||||
Write(out_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit Parcel(std::vector<u8> in_data) : buffer(std::move(in_data)) {
|
|
||||||
DeserializeHeader();
|
DeserializeHeader();
|
||||||
[[maybe_unused]] const std::u16string token = ReadInterfaceToken();
|
[[maybe_unused]] const std::u16string token = ReadInterfaceToken();
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,9 @@ public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Read(T& val) {
|
void Read(T& val) {
|
||||||
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
|
||||||
ASSERT(read_index + sizeof(T) <= buffer.size());
|
ASSERT(read_index + sizeof(T) <= read_buffer.size());
|
||||||
|
|
||||||
std::memcpy(&val, buffer.data() + read_index, sizeof(T));
|
std::memcpy(&val, read_buffer.data() + read_index, sizeof(T));
|
||||||
read_index += sizeof(T);
|
read_index += sizeof(T);
|
||||||
read_index = Common::AlignUp(read_index, 4);
|
read_index = Common::AlignUp(read_index, 4);
|
||||||
}
|
}
|
||||||
|
@ -62,10 +62,10 @@ public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T ReadUnaligned() {
|
T ReadUnaligned() {
|
||||||
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
|
||||||
ASSERT(read_index + sizeof(T) <= buffer.size());
|
ASSERT(read_index + sizeof(T) <= read_buffer.size());
|
||||||
|
|
||||||
T val;
|
T val;
|
||||||
std::memcpy(&val, buffer.data() + read_index, sizeof(T));
|
std::memcpy(&val, read_buffer.data() + read_index, sizeof(T));
|
||||||
read_index += sizeof(T);
|
read_index += sizeof(T);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,31 @@ public:
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeserializeHeader() {
|
||||||
|
ASSERT(read_buffer.size() > sizeof(ParcelHeader));
|
||||||
|
|
||||||
|
ParcelHeader header{};
|
||||||
|
std::memcpy(&header, read_buffer.data(), sizeof(ParcelHeader));
|
||||||
|
|
||||||
|
read_index = header.data_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::span<const u8> read_buffer;
|
||||||
|
std::size_t read_index = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OutputParcel final {
|
||||||
|
public:
|
||||||
|
static constexpr std::size_t DefaultBufferSize = 0x40;
|
||||||
|
|
||||||
|
OutputParcel() : buffer(DefaultBufferSize) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
explicit OutputParcel(const T& out_data) : buffer(DefaultBufferSize) {
|
||||||
|
Write(out_data);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Write(const T& val) {
|
void Write(const T& val) {
|
||||||
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
|
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
|
||||||
|
@ -133,40 +158,20 @@ public:
|
||||||
WriteObject(ptr.get());
|
WriteObject(ptr.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeserializeHeader() {
|
|
||||||
ASSERT(buffer.size() > sizeof(Header));
|
|
||||||
|
|
||||||
Header header{};
|
|
||||||
std::memcpy(&header, buffer.data(), sizeof(Header));
|
|
||||||
|
|
||||||
read_index = header.data_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<u8> Serialize() const {
|
std::vector<u8> Serialize() const {
|
||||||
ASSERT(read_index == 0);
|
ParcelHeader header{};
|
||||||
|
header.data_size = static_cast<u32>(write_index - sizeof(ParcelHeader));
|
||||||
Header header{};
|
header.data_offset = sizeof(ParcelHeader);
|
||||||
header.data_size = static_cast<u32>(write_index - sizeof(Header));
|
|
||||||
header.data_offset = sizeof(Header);
|
|
||||||
header.objects_size = 4;
|
header.objects_size = 4;
|
||||||
header.objects_offset = static_cast<u32>(sizeof(Header) + header.data_size);
|
header.objects_offset = static_cast<u32>(sizeof(ParcelHeader) + header.data_size);
|
||||||
std::memcpy(buffer.data(), &header, sizeof(Header));
|
std::memcpy(buffer.data(), &header, sizeof(ParcelHeader));
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Header {
|
|
||||||
u32 data_size;
|
|
||||||
u32 data_offset;
|
|
||||||
u32 objects_size;
|
|
||||||
u32 objects_offset;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(Header) == 16, "ParcelHeader has wrong size");
|
|
||||||
|
|
||||||
mutable std::vector<u8> buffer;
|
mutable std::vector<u8> buffer;
|
||||||
std::size_t read_index = 0;
|
std::size_t write_index = sizeof(ParcelHeader);
|
||||||
std::size_t write_index = sizeof(Header);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::android
|
} // namespace Service::android
|
||||||
|
|
|
@ -603,7 +603,7 @@ private:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto parcel = android::Parcel{NativeWindow{*buffer_queue_id}};
|
const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}};
|
||||||
const auto buffer_size = ctx.WriteBuffer(parcel.Serialize());
|
const auto buffer_size = ctx.WriteBuffer(parcel.Serialize());
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
@ -649,7 +649,7 @@ private:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto parcel = android::Parcel{NativeWindow{*buffer_queue_id}};
|
const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}};
|
||||||
const auto buffer_size = ctx.WriteBuffer(parcel.Serialize());
|
const auto buffer_size = ctx.WriteBuffer(parcel.Serialize());
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 6};
|
IPC::ResponseBuilder rb{ctx, 6};
|
||||||
|
|
Reference in New Issue