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 DAWN_DAWNCPP_H_ 16 #define DAWN_DAWNCPP_H_ 17 18 #include "dawn/dawn.h" 19 #include "dawn/dawn_export.h" 20 #include "dawn/EnumClassBitmasks.h" 21 22 namespace dawn { 23 24 static constexpr uint64_t kWholeSize = DAWN_WHOLE_SIZE; 25 26 {% for type in by_category["enum"] %} 27 enum class {{as_cppType(type.name)}} : uint32_t { 28 {% for value in type.values %} 29 {{as_cppEnum(value.name)}} = 0x{{format(value.value, "08X")}}, 30 {% endfor %} 31 }; 32 33 {% endfor %} 34 35 {% for type in by_category["bitmask"] %} 36 enum class {{as_cppType(type.name)}} : uint32_t { 37 {% for value in type.values %} 38 {{as_cppEnum(value.name)}} = 0x{{format(value.value, "08X")}}, 39 {% endfor %} 40 }; 41 42 {% endfor %} 43 44 {% for type in by_category["bitmask"] %} 45 template<> 46 struct IsDawnBitmask<{{as_cppType(type.name)}}> { 47 static constexpr bool enable = true; 48 }; 49 50 {% endfor %} 51 52 {% for type in by_category["natively defined"] %} 53 using {{as_cppType(type.name)}} = {{as_cType(type.name)}}; 54 {% endfor %} 55 56 {% for type in by_category["object"] %} 57 class {{as_cppType(type.name)}}; 58 {% endfor %} 59 60 {% for type in by_category["structure"] %} 61 struct {{as_cppType(type.name)}}; 62 {% endfor %} 63 64 template<typename Derived, typename CType> 65 class ObjectBase { 66 public: 67 ObjectBase() = default; 68 ObjectBase(CType handle): mHandle(handle) { 69 if (mHandle) Derived::DawnReference(mHandle); 70 } 71 ~ObjectBase() { 72 if (mHandle) Derived::DawnRelease(mHandle); 73 } 74 75 ObjectBase(ObjectBase const& other) 76 : ObjectBase(other.Get()) { 77 } 78 Derived& operator=(ObjectBase const& other) { 79 if (&other != this) { 80 if (mHandle) Derived::DawnRelease(mHandle); 81 mHandle = other.mHandle; 82 if (mHandle) Derived::DawnReference(mHandle); 83 } 84 85 return static_cast<Derived&>(*this); 86 } 87 88 ObjectBase(ObjectBase&& other) { 89 mHandle = other.mHandle; 90 other.mHandle = 0; 91 } 92 Derived& operator=(ObjectBase&& other) { 93 if (&other != this) { 94 if (mHandle) Derived::DawnRelease(mHandle); 95 mHandle = other.mHandle; 96 other.mHandle = 0; 97 } 98 99 return static_cast<Derived&>(*this); 100 } 101 102 ObjectBase(std::nullptr_t) {} 103 Derived& operator=(std::nullptr_t) { 104 if (mHandle != nullptr) { 105 Derived::DawnRelease(mHandle); 106 mHandle = nullptr; 107 } 108 return static_cast<Derived&>(*this); 109 } 110 111 explicit operator bool() const { 112 return mHandle != nullptr; 113 } 114 CType Get() const { 115 return mHandle; 116 } 117 CType Release() { 118 CType result = mHandle; 119 mHandle = 0; 120 return result; 121 } 122 static Derived Acquire(CType handle) { 123 Derived result; 124 result.mHandle = handle; 125 return result; 126 } 127 128 protected: 129 CType mHandle = nullptr; 130 }; 131 132 {% macro render_cpp_default_value(member) -%} 133 {%- if member.annotation in ["*", "const*", "const*const*"] and member.optional -%} 134 {{" "}}= nullptr 135 {%- elif member.type.category in ["enum", "bitmask"] and member.default_value != None -%} 136 {{" "}}= {{as_cppType(member.type.name)}}::{{as_cppEnum(Name(member.default_value))}} 137 {%- elif member.type.category == "native" and member.default_value != None -%} 138 {{" "}}= {{member.default_value}} 139 {%- else -%} 140 {{assert(member.default_value == None)}} 141 {%- endif -%} 142 {%- endmacro %} 143 144 {% macro render_cpp_method_declaration(type, method) %} 145 {% set CppType = as_cppType(type.name) %} 146 DAWN_EXPORT {{as_cppType(method.return_type.name)}} {{method.name.CamelCase()}}( 147 {%- for arg in method.arguments -%} 148 {%- if not loop.first %}, {% endif -%} 149 {%- if arg.type.category == "object" and arg.annotation == "value" -%} 150 {{as_cppType(arg.type.name)}} const& {{as_varName(arg.name)}} 151 {%- else -%} 152 {{as_annotated_cppType(arg)}} 153 {%- endif -%} 154 {{render_cpp_default_value(arg)}} 155 {%- endfor -%} 156 ) const 157 {%- endmacro %} 158 159 {% for type in by_category["object"] %} 160 {% set CppType = as_cppType(type.name) %} 161 {% set CType = as_cType(type.name) %} 162 class {{CppType}} : public ObjectBase<{{CppType}}, {{CType}}> { 163 public: 164 using ObjectBase::ObjectBase; 165 using ObjectBase::operator=; 166 167 {% for method in native_methods(type) %} 168 {{render_cpp_method_declaration(type, method)}}; 169 {% endfor %} 170 171 private: 172 friend ObjectBase<{{CppType}}, {{CType}}>; 173 static DAWN_EXPORT void DawnReference({{CType}} handle); 174 static DAWN_EXPORT void DawnRelease({{CType}} handle); 175 }; 176 177 {% endfor %} 178 179 {% for type in by_category["structure"] %} 180 struct {{as_cppType(type.name)}} { 181 {% if type.extensible %} 182 const void* nextInChain = nullptr; 183 {% endif %} 184 {% for member in type.members %} 185 {{as_annotated_cppType(member)}}{{render_cpp_default_value(member)}}; 186 {% endfor %} 187 }; 188 189 {% endfor %} 190 191 } // namespace dawn 192 193 #endif // DAWN_DAWNCPP_H_ 194