forked from eden-emu/eden
		
	hle: nvflinger: Move implementation for Parcel to its own header.
This commit is contained in:
		
							parent
							
								
									a454670de5
								
							
						
					
					
						commit
						d13e18a8ed
					
				
					 2 changed files with 172 additions and 0 deletions
				
			
		|  | @ -543,6 +543,7 @@ add_library(core STATIC | |||
|     hle/service/nvflinger/consumer_listener.h | ||||
|     hle/service/nvflinger/nvflinger.cpp | ||||
|     hle/service/nvflinger/nvflinger.h | ||||
|     hle/service/nvflinger/parcel.h | ||||
|     hle/service/nvflinger/pixel_format.h | ||||
|     hle/service/nvflinger/producer_listener.h | ||||
|     hle/service/nvflinger/status.h | ||||
|  |  | |||
							
								
								
									
										171
									
								
								src/core/hle/service/nvflinger/parcel.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								src/core/hle/service/nvflinger/parcel.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,171 @@ | |||
| // SPDX-License-Identifier: GPL-3.0-or-later
 | ||||
| // Copyright 2021 yuzu Emulator Project
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <memory> | ||||
| #include <vector> | ||||
| 
 | ||||
| #include "common/alignment.h" | ||||
| #include "common/assert.h" | ||||
| #include "common/common_types.h" | ||||
| 
 | ||||
| namespace android { | ||||
| 
 | ||||
| class Parcel final { | ||||
| public: | ||||
|     static constexpr std::size_t DefaultBufferSize = 0x40; | ||||
| 
 | ||||
|     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(); | ||||
|         [[maybe_unused]] const std::u16string token = ReadInterfaceToken(); | ||||
|     } | ||||
| 
 | ||||
|     template <typename T> | ||||
|     void Read(T& val) { | ||||
|         static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); | ||||
|         ASSERT(read_index + sizeof(T) <= buffer.size()); | ||||
| 
 | ||||
|         std::memcpy(&val, buffer.data() + read_index, sizeof(T)); | ||||
|         read_index += sizeof(T); | ||||
|         read_index = Common::AlignUp(read_index, 4); | ||||
|     } | ||||
| 
 | ||||
|     template <typename T> | ||||
|     T Read() { | ||||
|         T val; | ||||
|         Read(val); | ||||
|         return val; | ||||
|     } | ||||
| 
 | ||||
|     template <typename T> | ||||
|     void ReadFlattened(T& val) { | ||||
|         const auto flattened_size = Read<s64>(); | ||||
|         ASSERT(sizeof(T) == flattened_size); | ||||
|         Read(val); | ||||
|     } | ||||
| 
 | ||||
|     template <typename T> | ||||
|     T ReadFlattened() { | ||||
|         T val; | ||||
|         ReadFlattened(val); | ||||
|         return val; | ||||
|     } | ||||
| 
 | ||||
|     template <typename T> | ||||
|     T ReadUnaligned() { | ||||
|         static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); | ||||
|         ASSERT(read_index + sizeof(T) <= buffer.size()); | ||||
| 
 | ||||
|         T val; | ||||
|         std::memcpy(&val, buffer.data() + read_index, sizeof(T)); | ||||
|         read_index += sizeof(T); | ||||
|         return val; | ||||
|     } | ||||
| 
 | ||||
|     template <typename T> | ||||
|     const std::shared_ptr<T> ReadObject() { | ||||
|         static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); | ||||
| 
 | ||||
|         const auto is_valid{Read<bool>()}; | ||||
| 
 | ||||
|         if (is_valid) { | ||||
|             auto result = std::make_shared<T>(); | ||||
|             ReadFlattened(*result); | ||||
|             return result; | ||||
|         } | ||||
| 
 | ||||
|         return {}; | ||||
|     } | ||||
| 
 | ||||
|     std::u16string ReadInterfaceToken() { | ||||
|         [[maybe_unused]] const u32 unknown = Read<u32>(); | ||||
|         const u32 length = Read<u32>(); | ||||
| 
 | ||||
|         std::u16string token{}; | ||||
| 
 | ||||
|         for (u32 ch = 0; ch < length + 1; ++ch) { | ||||
|             token.push_back(ReadUnaligned<u16>()); | ||||
|         } | ||||
| 
 | ||||
|         read_index = Common::AlignUp(read_index, 4); | ||||
| 
 | ||||
|         return token; | ||||
|     } | ||||
| 
 | ||||
|     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); | ||||
|     } | ||||
| 
 | ||||
|     template <typename T> | ||||
|     void WriteObject(const T* ptr) { | ||||
|         static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); | ||||
| 
 | ||||
|         if (!ptr) { | ||||
|             Write<u32>(0); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         Write<u32>(1); | ||||
|         Write<s64>(sizeof(T)); | ||||
|         Write(*ptr); | ||||
|     } | ||||
| 
 | ||||
|     template <typename T> | ||||
|     void WriteObject(const std::shared_ptr<T> ptr) { | ||||
|         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 { | ||||
|         ASSERT(read_index == 0); | ||||
| 
 | ||||
|         Header header{}; | ||||
|         header.data_size = static_cast<u32>(write_index - sizeof(Header)); | ||||
|         header.data_offset = sizeof(Header); | ||||
|         header.objects_size = 4; | ||||
|         header.objects_offset = static_cast<u32>(sizeof(Header) + header.data_size); | ||||
|         std::memcpy(buffer.data(), &header, sizeof(Header)); | ||||
| 
 | ||||
|         return buffer; | ||||
|     } | ||||
| 
 | ||||
| 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; | ||||
|     std::size_t read_index = 0; | ||||
|     std::size_t write_index = sizeof(Header); | ||||
| }; | ||||
| 
 | ||||
| } // namespace android
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bunnei
						bunnei