// Copyright 2019 The Dawn Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef INCLUDE_DAWN_WIRE_WIRECLIENT_H_ #define INCLUDE_DAWN_WIRE_WIRECLIENT_H_ #include <memory> #include <vector> #include "dawn/dawn_proc_table.h" #include "dawn/wire/Wire.h" namespace dawn::wire { namespace client { class Client; class MemoryTransferService; DAWN_WIRE_EXPORT const DawnProcTable& GetProcs(); } // namespace client struct ReservedTexture { WGPUTexture texture; uint32_t id; uint32_t generation; uint32_t deviceId; uint32_t deviceGeneration; }; struct ReservedSwapChain { WGPUSwapChain swapchain; uint32_t id; uint32_t generation; uint32_t deviceId; uint32_t deviceGeneration; }; struct ReservedDevice { WGPUDevice device; uint32_t id; uint32_t generation; }; struct ReservedInstance { WGPUInstance instance; uint32_t id; uint32_t generation; }; struct DAWN_WIRE_EXPORT WireClientDescriptor { CommandSerializer* serializer; client::MemoryTransferService* memoryTransferService = nullptr; }; class DAWN_WIRE_EXPORT WireClient : public CommandHandler { public: explicit WireClient(const WireClientDescriptor& descriptor); ~WireClient() override; const volatile char* HandleCommands(const volatile char* commands, size_t size) final; ReservedTexture ReserveTexture(WGPUDevice device); ReservedSwapChain ReserveSwapChain(WGPUDevice device); ReservedDevice ReserveDevice(); ReservedInstance ReserveInstance(); void ReclaimTextureReservation(const ReservedTexture& reservation); void ReclaimSwapChainReservation(const ReservedSwapChain& reservation); void ReclaimDeviceReservation(const ReservedDevice& reservation); void ReclaimInstanceReservation(const ReservedInstance& reservation); // Disconnects the client. // Commands allocated after this point will not be sent. void Disconnect(); private: std::unique_ptr<client::Client> mImpl; }; namespace client { class DAWN_WIRE_EXPORT MemoryTransferService { public: MemoryTransferService(); virtual ~MemoryTransferService(); class ReadHandle; class WriteHandle; // Create a handle for reading server data. // This may fail and return nullptr. virtual ReadHandle* CreateReadHandle(size_t) = 0; // Create a handle for writing server data. // This may fail and return nullptr. virtual WriteHandle* CreateWriteHandle(size_t) = 0; class DAWN_WIRE_EXPORT ReadHandle { public: ReadHandle(); virtual ~ReadHandle(); // Get the required serialization size for SerializeCreate virtual size_t SerializeCreateSize() = 0; // Serialize the handle into |serializePointer| so it can be received by the server. virtual void SerializeCreate(void* serializePointer) = 0; // Simply return the base address of the allocation (without applying any offset) // Returns nullptr if the allocation failed. // The data must live at least until the ReadHandle is destructued virtual const void* GetData() = 0; // Gets called when a MapReadCallback resolves. // deserialize the data update and apply // it to the range (offset, offset + size) of allocation // There could be nothing to be deserialized (if using shared memory) // Needs to check potential offset/size OOB and overflow virtual bool DeserializeDataUpdate(const void* deserializePointer, size_t deserializeSize, size_t offset, size_t size) = 0; private: ReadHandle(const ReadHandle&) = delete; ReadHandle& operator=(const ReadHandle&) = delete; }; class DAWN_WIRE_EXPORT WriteHandle { public: WriteHandle(); virtual ~WriteHandle(); // Get the required serialization size for SerializeCreate virtual size_t SerializeCreateSize() = 0; // Serialize the handle into |serializePointer| so it can be received by the server. virtual void SerializeCreate(void* serializePointer) = 0; // Simply return the base address of the allocation (without applying any offset) // The data returned should be zero-initialized. // The data returned must live at least until the WriteHandle is destructed. // On failure, the pointer returned should be null. virtual void* GetData() = 0; // Get the required serialization size for SerializeDataUpdate virtual size_t SizeOfSerializeDataUpdate(size_t offset, size_t size) = 0; // Serialize a command to send the modified contents of // the subrange (offset, offset + size) of the allocation at buffer unmap // This subrange is always the whole mapped region for now // There could be nothing to be serialized (if using shared memory) virtual void SerializeDataUpdate(void* serializePointer, size_t offset, size_t size) = 0; private: WriteHandle(const WriteHandle&) = delete; WriteHandle& operator=(const WriteHandle&) = delete; }; private: MemoryTransferService(const MemoryTransferService&) = delete; MemoryTransferService& operator=(const MemoryTransferService&) = delete; }; // Backdoor to get the order of the ProcMap for testing DAWN_WIRE_EXPORT std::vector<const char*> GetProcMapNamesForTesting(); } // namespace client } // namespace dawn::wire #endif // INCLUDE_DAWN_WIRE_WIRECLIENT_H_