diff options
| author | bunnei <bunneidev@gmail.com> | 2023-05-12 16:07:35 -0700 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-12 16:07:35 -0700 | 
| commit | 1805de030159219808ed9d6f519b60a6ee8c7931 (patch) | |
| tree | 6d19b6192706f9350df1f09cabd1ccbbf933b027 /src/core | |
| parent | 182221b9ffdee68c0f8c3749868918799f5b3d0f (diff) | |
| parent | bb94beed15a4b95a896dfd68160e386c0be7b063 (diff) | |
Merge pull request #10236 from liamwhite/thats-not-an-ibinder
nvnflinger: fix Parcel serialization
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/service/nvnflinger/buffer_queue_producer.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/service/nvnflinger/parcel.h | 72 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 12 | 
3 files changed, 50 insertions, 39 deletions
| diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp index cd0a13094..b16f9933f 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp @@ -793,6 +793,7 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,      std::scoped_lock lock{core->mutex};      slots[slot] = {}; +    slots[slot].fence = Fence::NoFence();      slots[slot].graphic_buffer = buffer;      slots[slot].frame_number = 0; @@ -854,7 +855,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u          status = DequeueBuffer(&slot, &fence, is_async, width, height, pixel_format, usage);          parcel_out.Write(slot); -        parcel_out.WriteObject(&fence); +        parcel_out.WriteFlattenedObject(&fence);          break;      }      case TransactionId::RequestBuffer: { @@ -864,7 +865,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u          status = RequestBuffer(slot, &buf); -        parcel_out.WriteObject(buf); +        parcel_out.WriteFlattenedObject(buf);          break;      }      case TransactionId::QueueBuffer: { diff --git a/src/core/hle/service/nvnflinger/parcel.h b/src/core/hle/service/nvnflinger/parcel.h index d1b6201e0..fb56d75d7 100644 --- a/src/core/hle/service/nvnflinger/parcel.h +++ b/src/core/hle/service/nvnflinger/parcel.h @@ -117,61 +117,67 @@ private:  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); -    } +    OutputParcel() = default;      template <typename T>      void Write(const T& val) { -        static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); - -        if (buffer.size() < write_index + sizeof(T)) { -            buffer.resize(buffer.size() + sizeof(T) + DefaultBufferSize); -        } - -        std::memcpy(buffer.data() + write_index, &val, sizeof(T)); -        write_index += sizeof(T); -        write_index = Common::AlignUp(write_index, 4); +        this->WriteImpl(val, m_data_buffer);      }      template <typename T> -    void WriteObject(const T* ptr) { -        static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); - +    void WriteFlattenedObject(const T* ptr) {          if (!ptr) { -            Write<u32>(0); +            this->Write<u32>(0);              return;          } -        Write<u32>(1); -        Write<s64>(sizeof(T)); -        Write(*ptr); +        this->Write<u32>(1); +        this->Write<s64>(sizeof(T)); +        this->Write(*ptr);      }      template <typename T> -    void WriteObject(const std::shared_ptr<T> ptr) { -        WriteObject(ptr.get()); +    void WriteFlattenedObject(const std::shared_ptr<T> ptr) { +        this->WriteFlattenedObject(ptr.get()); +    } + +    template <typename T> +    void WriteInterface(const T& val) { +        this->WriteImpl(val, m_data_buffer); +        this->WriteImpl(0U, m_object_buffer);      }      std::vector<u8> Serialize() const { +        std::vector<u8> output_buffer(sizeof(ParcelHeader) + m_data_buffer.size() + +                                      m_object_buffer.size()); +          ParcelHeader header{}; -        header.data_size = static_cast<u32>(write_index - sizeof(ParcelHeader)); +        header.data_size = static_cast<u32>(m_data_buffer.size());          header.data_offset = sizeof(ParcelHeader); -        header.objects_size = 4; -        header.objects_offset = static_cast<u32>(sizeof(ParcelHeader) + header.data_size); -        std::memcpy(buffer.data(), &header, sizeof(ParcelHeader)); +        header.objects_size = static_cast<u32>(m_object_buffer.size()); +        header.objects_offset = header.data_offset + header.data_size; + +        std::memcpy(output_buffer.data(), &header, sizeof(header)); +        std::ranges::copy(m_data_buffer, output_buffer.data() + header.data_offset); +        std::ranges::copy(m_object_buffer, output_buffer.data() + header.objects_offset); + +        return output_buffer; +    } + +private: +    template <typename T> +        requires(std::is_trivially_copyable_v<T>) +    void WriteImpl(const T& val, std::vector<u8>& buffer) { +        const size_t aligned_size = Common::AlignUp(sizeof(T), 4); +        const size_t old_size = buffer.size(); +        buffer.resize(old_size + aligned_size); -        return buffer; +        std::memcpy(buffer.data() + old_size, &val, sizeof(T));      }  private: -    mutable std::vector<u8> buffer; -    std::size_t write_index = sizeof(ParcelHeader); +    std::vector<u8> m_data_buffer; +    std::vector<u8> m_object_buffer;  };  } // namespace Service::android diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 68eab5133..1b193f00c 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -64,8 +64,8 @@ public:  private:      const u32 magic = 2;      const u32 process_id = 1; -    const u32 id; -    INSERT_PADDING_WORDS(3); +    const u64 id; +    INSERT_PADDING_WORDS(2);      std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'};      INSERT_PADDING_WORDS(2);  }; @@ -608,7 +608,9 @@ private:              return;          } -        const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}}; +        android::OutputParcel parcel; +        parcel.WriteInterface(NativeWindow{*buffer_queue_id}); +          const auto buffer_size = ctx.WriteBuffer(parcel.Serialize());          IPC::ResponseBuilder rb{ctx, 4}; @@ -654,7 +656,9 @@ private:              return;          } -        const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}}; +        android::OutputParcel parcel; +        parcel.WriteInterface(NativeWindow{*buffer_queue_id}); +          const auto buffer_size = ctx.WriteBuffer(parcel.Serialize());          IPC::ResponseBuilder rb{ctx, 6}; | 
