1 //* Copyright 2017 The Dawn Authors 2 //* 3 //* Licensed under the Apache License, Version 2.0 (the "License"); 4 //* you may not use this file except in compliance with the License. 5 //* You may obtain a copy of the License at 6 //* 7 //* http://www.apache.org/licenses/LICENSE-2.0 8 //* 9 //* Unless required by applicable law or agreed to in writing, software 10 //* distributed under the License is distributed on an "AS IS" BASIS, 11 //* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 //* See the License for the specific language governing permissions and 13 //* limitations under the License. 14 15 #ifndef DAWNWIRE_WIRECMD_AUTOGEN_H_ 16 #define DAWNWIRE_WIRECMD_AUTOGEN_H_ 17 18 #include <dawn/webgpu.h> 19 20 #include "dawn_wire/BufferConsumer.h" 21 #include "dawn_wire/ObjectType_autogen.h" 22 #include "dawn_wire/WireResult.h" 23 24 namespace dawn_wire { 25 26 using ObjectId = uint32_t; 27 using ObjectGeneration = uint32_t; 28 struct ObjectHandle { 29 ObjectId id; 30 ObjectGeneration generation; 31 32 ObjectHandle(); 33 ObjectHandle(ObjectId id, ObjectGeneration generation); 34 35 ObjectHandle(const volatile ObjectHandle& rhs); 36 ObjectHandle& operator=(const volatile ObjectHandle& rhs); 37 38 // MSVC has a bug where it thinks the volatile copy assignment is a duplicate. 39 // Workaround this by forwarding to a different function AssignFrom. 40 template <typename T> 41 ObjectHandle& operator=(const T& rhs) { 42 return AssignFrom(rhs); 43 } 44 ObjectHandle& AssignFrom(const ObjectHandle& rhs); 45 ObjectHandle& AssignFrom(const volatile ObjectHandle& rhs); 46 }; 47 48 // Interface to allocate more space to deserialize pointed-to data. 49 // nullptr is treated as an error. 50 class DeserializeAllocator { 51 public: 52 virtual void* GetSpace(size_t size) = 0; 53 }; 54 55 // Interface to convert an ID to a server object, if possible. 56 // Methods return FatalError if the ID is for a non-existent object and Success otherwise. 57 class ObjectIdResolver { 58 public: 59 {% for type in by_category["object"] %} 60 virtual WireResult GetFromId(ObjectId id, {{as_cType(type.name)}}* out) const = 0; 61 virtual WireResult GetOptionalFromId(ObjectId id, {{as_cType(type.name)}}* out) const = 0; 62 {% endfor %} 63 }; 64 65 // Interface to convert a client object to its ID for the wiring. 66 class ObjectIdProvider { 67 public: 68 {% for type in by_category["object"] %} 69 virtual WireResult GetId({{as_cType(type.name)}} object, ObjectId* out) const = 0; 70 virtual WireResult GetOptionalId({{as_cType(type.name)}} object, ObjectId* out) const = 0; 71 {% endfor %} 72 }; 73 74 //* Enum used as a prefix to each command on the wire format. 75 enum class WireCmd : uint32_t { 76 {% for command in cmd_records["command"] %} 77 {{command.name.CamelCase()}}, 78 {% endfor %} 79 }; 80 81 //* Enum used as a prefix to each command on the return wire format. 82 enum class ReturnWireCmd : uint32_t { 83 {% for command in cmd_records["return command"] %} 84 {{command.name.CamelCase()}}, 85 {% endfor %} 86 }; 87 88 struct CmdHeader { 89 uint64_t commandSize; 90 }; 91 92 {% macro write_command_struct(command, is_return_command) %} 93 {% set Return = "Return" if is_return_command else "" %} 94 {% set Cmd = command.name.CamelCase() + "Cmd" %} 95 struct {{Return}}{{Cmd}} { 96 //* From a filled structure, compute how much size will be used in the serialization buffer. 97 size_t GetRequiredSize() const; 98 99 //* Serialize the structure and everything it points to into serializeBuffer which must be 100 //* big enough to contain all the data (as queried from GetRequiredSize). 101 WireResult Serialize(size_t commandSize, SerializeBuffer* serializeBuffer, const ObjectIdProvider& objectIdProvider) const; 102 // Override which produces a FatalError if any object is used. 103 WireResult Serialize(size_t commandSize, SerializeBuffer* serializeBuffer) const; 104 105 //* Deserializes the structure from a buffer, consuming a maximum of *size bytes. When this 106 //* function returns, buffer and size will be updated by the number of bytes consumed to 107 //* deserialize the structure. Structures containing pointers will use allocator to get 108 //* scratch space to deserialize the pointed-to data. 109 //* Deserialize returns: 110 //* - Success if everything went well (yay!) 111 //* - FatalError is something bad happened (buffer too small for example) 112 WireResult Deserialize(DeserializeBuffer* deserializeBuffer, DeserializeAllocator* allocator, const ObjectIdResolver& resolver); 113 // Override which produces a FatalError if any object is used. 114 WireResult Deserialize(DeserializeBuffer* deserializeBuffer, DeserializeAllocator* allocator); 115 116 {% if command.derived_method %} 117 //* Command handlers want to know the object ID in addition to the backing object. 118 //* Doesn't need to be filled before Serialize, or GetRequiredSize. 119 ObjectId selfId; 120 {% endif %} 121 122 {% for member in command.members %} 123 {{as_annotated_cType(member)}}; 124 {% endfor %} 125 }; 126 {% endmacro %} 127 128 {% for command in cmd_records["command"] %} 129 {{write_command_struct(command, False)}} 130 {% endfor %} 131 132 {% for command in cmd_records["return command"] %} 133 {{write_command_struct(command, True)}} 134 {% endfor %} 135 136 } // namespace dawn_wire 137 138 #endif // DAWNWIRE_WIRECMD_AUTOGEN_H_ 139