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 {% set API = metadata.api.upper() %} 15 {% set api = API.lower() %} 16 #ifndef {{API}}_CPP_H_ 17 #define {{API}}_CPP_H_ 18 19 #include "dawn/{{api}}.h" 20 #include "dawn/EnumClassBitmasks.h" 21 22 namespace {{metadata.namespace}} { 23 24 {% set c_prefix = metadata.c_prefix %} 25 {% for constant in by_category["constant"] %} 26 {% set type = as_cppType(constant.type.name) %} 27 {% set value = c_prefix + "_" + constant.name.SNAKE_CASE() %} 28 static constexpr {{type}} k{{as_cppType(constant.name)}} = {{ value }}; 29 {% endfor %} 30 31 {% for type in by_category["enum"] %} 32 enum class {{as_cppType(type.name)}} : uint32_t { 33 {% for value in type.values %} 34 {{as_cppEnum(value.name)}} = 0x{{format(value.value, "08X")}}, 35 {% endfor %} 36 }; 37 38 {% endfor %} 39 40 {% for type in by_category["bitmask"] %} 41 enum class {{as_cppType(type.name)}} : uint32_t { 42 {% for value in type.values %} 43 {{as_cppEnum(value.name)}} = 0x{{format(value.value, "08X")}}, 44 {% endfor %} 45 }; 46 47 {% endfor %} 48 49 {% for type in by_category["function pointer"] %} 50 using {{as_cppType(type.name)}} = {{as_cType(type.name)}}; 51 {% endfor %} 52 53 {% for type in by_category["object"] %} 54 class {{as_cppType(type.name)}}; 55 {% endfor %} 56 57 {% for type in by_category["structure"] %} 58 struct {{as_cppType(type.name)}}; 59 {% endfor %} 60 61 {% for typeDef in by_category["typedef"] %} 62 // {{as_cppType(typeDef.name)}} is deprecated. 63 // Use {{as_cppType(typeDef.type.name)}} instead. 64 using {{as_cppType(typeDef.name)}} = {{as_cppType(typeDef.type.name)}}; 65 66 {% endfor %} 67 template<typename Derived, typename CType> 68 class ObjectBase { 69 public: 70 ObjectBase() = default; 71 ObjectBase(CType handle): mHandle(handle) { 72 if (mHandle) Derived::{{c_prefix}}Reference(mHandle); 73 } 74 ~ObjectBase() { 75 if (mHandle) Derived::{{c_prefix}}Release(mHandle); 76 } 77 78 ObjectBase(ObjectBase const& other) 79 : ObjectBase(other.Get()) { 80 } 81 Derived& operator=(ObjectBase const& other) { 82 if (&other != this) { 83 if (mHandle) Derived::{{c_prefix}}Release(mHandle); 84 mHandle = other.mHandle; 85 if (mHandle) Derived::{{c_prefix}}Reference(mHandle); 86 } 87 88 return static_cast<Derived&>(*this); 89 } 90 91 ObjectBase(ObjectBase&& other) { 92 mHandle = other.mHandle; 93 other.mHandle = 0; 94 } 95 Derived& operator=(ObjectBase&& other) { 96 if (&other != this) { 97 if (mHandle) Derived::{{c_prefix}}Release(mHandle); 98 mHandle = other.mHandle; 99 other.mHandle = 0; 100 } 101 102 return static_cast<Derived&>(*this); 103 } 104 105 ObjectBase(std::nullptr_t) {} 106 Derived& operator=(std::nullptr_t) { 107 if (mHandle != nullptr) { 108 Derived::{{c_prefix}}Release(mHandle); 109 mHandle = nullptr; 110 } 111 return static_cast<Derived&>(*this); 112 } 113 114 bool operator==(std::nullptr_t) const { 115 return mHandle == nullptr; 116 } 117 bool operator!=(std::nullptr_t) const { 118 return mHandle != nullptr; 119 } 120 121 explicit operator bool() const { 122 return mHandle != nullptr; 123 } 124 CType Get() const { 125 return mHandle; 126 } 127 CType Release() { 128 CType result = mHandle; 129 mHandle = 0; 130 return result; 131 } 132 static Derived Acquire(CType handle) { 133 Derived result; 134 result.mHandle = handle; 135 return result; 136 } 137 138 protected: 139 CType mHandle = nullptr; 140 }; 141 142 {% macro render_cpp_default_value(member, is_struct=True) -%} 143 {%- if member.annotation in ["*", "const*"] and member.optional -%} 144 {{" "}}= nullptr 145 {%- elif member.type.category == "object" and member.optional and is_struct -%} 146 {{" "}}= nullptr 147 {%- elif member.type.category in ["enum", "bitmask"] and member.default_value != None -%} 148 {{" "}}= {{as_cppType(member.type.name)}}::{{as_cppEnum(Name(member.default_value))}} 149 {%- elif member.type.category == "native" and member.default_value != None -%} 150 {{" "}}= {{member.default_value}} 151 {%- else -%} 152 {{assert(member.default_value == None)}} 153 {%- endif -%} 154 {%- endmacro %} 155 156 {% macro render_cpp_method_declaration(type, method) %} 157 {% set CppType = as_cppType(type.name) %} 158 {{as_cppType(method.return_type.name)}} {{method.name.CamelCase()}}( 159 {%- for arg in method.arguments -%} 160 {%- if not loop.first %}, {% endif -%} 161 {%- if arg.type.category == "object" and arg.annotation == "value" -%} 162 {{as_cppType(arg.type.name)}} const& {{as_varName(arg.name)}} 163 {%- else -%} 164 {{as_annotated_cppType(arg)}} 165 {%- endif -%} 166 {{render_cpp_default_value(arg, False)}} 167 {%- endfor -%} 168 ) const 169 {%- endmacro %} 170 171 {% for type in by_category["object"] %} 172 {% set CppType = as_cppType(type.name) %} 173 {% set CType = as_cType(type.name) %} 174 class {{CppType}} : public ObjectBase<{{CppType}}, {{CType}}> { 175 public: 176 using ObjectBase::ObjectBase; 177 using ObjectBase::operator=; 178 179 {% for method in type.methods %} 180 {{render_cpp_method_declaration(type, method)}}; 181 {% endfor %} 182 183 private: 184 friend ObjectBase<{{CppType}}, {{CType}}>; 185 static void {{c_prefix}}Reference({{CType}} handle); 186 static void {{c_prefix}}Release({{CType}} handle); 187 }; 188 189 {% endfor %} 190 191 {% for function in by_category["function"] %} 192 {{as_cppType(function.return_type.name)}} {{as_cppType(function.name)}}( 193 {%- for arg in function.arguments -%} 194 {% if not loop.first %}, {% endif %} 195 {{as_annotated_cppType(arg)}} 196 {{render_cpp_default_value(arg, False)}} 197 {%- endfor -%} 198 ); 199 {% endfor %} 200 201 struct ChainedStruct { 202 ChainedStruct const * nextInChain = nullptr; 203 SType sType = SType::Invalid; 204 }; 205 206 struct ChainedStructOut { 207 ChainedStruct * nextInChain = nullptr; 208 SType sType = SType::Invalid; 209 }; 210 211 {% for type in by_category["structure"] %} 212 {% set Out = "Out" if type.output else "" %} 213 {% set const = "const" if not type.output else "" %} 214 {% if type.chained %} 215 struct {{as_cppType(type.name)}} : ChainedStruct{{Out}} { 216 {{as_cppType(type.name)}}() { 217 sType = SType::{{type.name.CamelCase()}}; 218 } 219 {% else %} 220 struct {{as_cppType(type.name)}} { 221 {% endif %} 222 {% if type.extensible %} 223 ChainedStruct{{Out}} {{const}} * nextInChain = nullptr; 224 {% endif %} 225 {% for member in type.members %} 226 {% set member_declaration = as_annotated_cppType(member) + render_cpp_default_value(member) %} 227 {% if type.chained and loop.first %} 228 //* Align the first member to ChainedStruct to match the C struct layout. 229 alignas(ChainedStruct{{Out}}) {{member_declaration}}; 230 {% else %} 231 {{member_declaration}}; 232 {% endif %} 233 {% endfor %} 234 }; 235 236 {% endfor %} 237 238 // The operators of EnumClassBitmmasks in the dawn:: namespace need to be imported 239 // in the {{metadata.namespace}} namespace for Argument Dependent Lookup. 240 DAWN_IMPORT_BITMASK_OPERATORS 241 } // namespace {{metadata.namespace}} 242 243 namespace dawn { 244 {% for type in by_category["bitmask"] %} 245 template<> 246 struct IsDawnBitmask<{{metadata.namespace}}::{{as_cppType(type.name)}}> { 247 static constexpr bool enable = true; 248 }; 249 250 {% endfor %} 251 } // namespace dawn 252 253 #endif // {{API}}_CPP_H_ 254