blob: 12ce3405e775ed5e6c4466dc3871b203afcc814a [file] [log] [blame]
Corentin Wallez4a9ef4e2018-07-18 11:40:26 +02001//* Copyright 2017 The Dawn Authors
Corentin Wallezf07e3bd2017-04-20 14:38:20 -04002//*
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.
fujunweic7d4f2c2021-12-07 00:46:35 +000014{% set API = metadata.api.upper() %}
15{% set api = API.lower() %}
Loko Kung14ed5332023-05-16 04:50:32 +000016{% if 'dawn' in enabled_tags %}
Shrek Shao71a363b2022-02-09 19:42:51 +000017 #ifdef __EMSCRIPTEN__
18 #error "Do not include this header. Emscripten already provides headers needed for {{metadata.api}}."
19 #endif
20{% endif %}
fujunweic7d4f2c2021-12-07 00:46:35 +000021#ifndef {{API}}_CPP_H_
22#define {{API}}_CPP_H_
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040023
fujunweic7d4f2c2021-12-07 00:46:35 +000024#include "dawn/{{api}}.h"
Loko Kung14ed5332023-05-16 04:50:32 +000025#include "dawn/{{api}}_cpp_chained_struct.h"
Corentin Wallez3e371b12018-07-18 14:32:45 +020026#include "dawn/EnumClassBitmasks.h"
Brandon Jones6e8c4732022-02-19 00:44:12 +000027#include <cmath>
Loko Kung6f5515a2023-05-25 23:19:48 +000028#include <cstddef>
29#include <cstdint>
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040030
fujunweic7d4f2c2021-12-07 00:46:35 +000031namespace {{metadata.namespace}} {
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040032
fujunwei4e876902021-11-25 08:44:01 +000033 {% set c_prefix = metadata.c_prefix %}
34 {% for constant in by_category["constant"] %}
35 {% set type = as_cppType(constant.type.name) %}
36 {% set value = c_prefix + "_" + constant.name.SNAKE_CASE() %}
37 static constexpr {{type}} k{{as_cppType(constant.name)}} = {{ value }};
38 {% endfor %}
François Beaufort0326b802019-07-17 08:54:19 +000039
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040040 {% for type in by_category["enum"] %}
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["bitmask"] %}
50 enum class {{as_cppType(type.name)}} : uint32_t {
51 {% for value in type.values %}
52 {{as_cppEnum(value.name)}} = 0x{{format(value.value, "08X")}},
53 {% endfor %}
54 };
55
56 {% endfor %}
57
fujunwei23f71622021-12-02 07:41:21 +000058 {% for type in by_category["function pointer"] %}
Corentin Wallez4b410a32017-04-20 14:42:36 -040059 using {{as_cppType(type.name)}} = {{as_cType(type.name)}};
60 {% endfor %}
61
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040062 {% for type in by_category["object"] %}
63 class {{as_cppType(type.name)}};
64 {% endfor %}
65
Corentin Walleza6416542018-05-17 16:55:53 -040066 {% for type in by_category["structure"] %}
Corentin Wallez8e335a52018-08-27 23:12:56 +020067 struct {{as_cppType(type.name)}};
Corentin Walleza6416542018-05-17 16:55:53 -040068 {% endfor %}
69
Brandon Jones58a471a2021-02-08 19:48:06 +000070 {% for typeDef in by_category["typedef"] %}
71 // {{as_cppType(typeDef.name)}} is deprecated.
72 // Use {{as_cppType(typeDef.type.name)}} instead.
73 using {{as_cppType(typeDef.name)}} = {{as_cppType(typeDef.type.name)}};
74
75 {% endfor %}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040076 template<typename Derived, typename CType>
77 class ObjectBase {
Corentin Wallez8f938712019-07-08 19:20:22 +000078 public:
79 ObjectBase() = default;
80 ObjectBase(CType handle): mHandle(handle) {
fujunweic7d4f2c2021-12-07 00:46:35 +000081 if (mHandle) Derived::{{c_prefix}}Reference(mHandle);
Corentin Wallez8f938712019-07-08 19:20:22 +000082 }
83 ~ObjectBase() {
fujunweic7d4f2c2021-12-07 00:46:35 +000084 if (mHandle) Derived::{{c_prefix}}Release(mHandle);
Corentin Wallez8f938712019-07-08 19:20:22 +000085 }
86
87 ObjectBase(ObjectBase const& other)
88 : ObjectBase(other.Get()) {
89 }
90 Derived& operator=(ObjectBase const& other) {
91 if (&other != this) {
fujunweic7d4f2c2021-12-07 00:46:35 +000092 if (mHandle) Derived::{{c_prefix}}Release(mHandle);
Corentin Wallez8f938712019-07-08 19:20:22 +000093 mHandle = other.mHandle;
fujunweic7d4f2c2021-12-07 00:46:35 +000094 if (mHandle) Derived::{{c_prefix}}Reference(mHandle);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -040095 }
Corentin Wallez8f938712019-07-08 19:20:22 +000096
97 return static_cast<Derived&>(*this);
98 }
99
100 ObjectBase(ObjectBase&& other) {
101 mHandle = other.mHandle;
102 other.mHandle = 0;
103 }
104 Derived& operator=(ObjectBase&& other) {
105 if (&other != this) {
fujunweic7d4f2c2021-12-07 00:46:35 +0000106 if (mHandle) Derived::{{c_prefix}}Release(mHandle);
Corentin Wallez42dbde12017-11-23 16:04:26 -0500107 mHandle = other.mHandle;
108 other.mHandle = 0;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400109 }
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400110
Corentin Wallez8f938712019-07-08 19:20:22 +0000111 return static_cast<Derived&>(*this);
112 }
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400113
Corentin Wallez8f938712019-07-08 19:20:22 +0000114 ObjectBase(std::nullptr_t) {}
115 Derived& operator=(std::nullptr_t) {
116 if (mHandle != nullptr) {
fujunweic7d4f2c2021-12-07 00:46:35 +0000117 Derived::{{c_prefix}}Release(mHandle);
Corentin Wallez8f938712019-07-08 19:20:22 +0000118 mHandle = nullptr;
Corentin Wallezf48e6b72018-12-04 12:13:03 +0000119 }
Corentin Wallez8f938712019-07-08 19:20:22 +0000120 return static_cast<Derived&>(*this);
121 }
Corentin Wallezf48e6b72018-12-04 12:13:03 +0000122
Austin Engf6eb8902019-11-22 17:02:22 +0000123 bool operator==(std::nullptr_t) const {
124 return mHandle == nullptr;
125 }
126 bool operator!=(std::nullptr_t) const {
127 return mHandle != nullptr;
128 }
129
Corentin Wallez8f938712019-07-08 19:20:22 +0000130 explicit operator bool() const {
131 return mHandle != nullptr;
132 }
133 CType Get() const {
134 return mHandle;
135 }
Loko Kung0214a302023-05-10 23:48:22 +0000136 // TODO(dawn:1639) Deprecate Release after uses have been removed.
Corentin Wallez8f938712019-07-08 19:20:22 +0000137 CType Release() {
138 CType result = mHandle;
139 mHandle = 0;
140 return result;
141 }
Loko Kung0214a302023-05-10 23:48:22 +0000142 CType MoveToCHandle() {
143 CType result = mHandle;
144 mHandle = 0;
145 return result;
146 }
Corentin Wallez8f938712019-07-08 19:20:22 +0000147 static Derived Acquire(CType handle) {
148 Derived result;
149 result.mHandle = handle;
150 return result;
151 }
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400152
Corentin Wallez8f938712019-07-08 19:20:22 +0000153 protected:
154 CType mHandle = nullptr;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400155 };
156
Corentin Wallez9d6265b2020-11-04 10:04:17 +0000157{% macro render_cpp_default_value(member, is_struct=True) -%}
Corentin Wallez1260a532022-07-26 17:36:44 +0000158 {%- if member.json_data.get("no_default", false) -%}
159 {%- elif member.annotation in ["*", "const*"] and member.optional or member.default_value == "nullptr" -%}
Corentin Wallez8f938712019-07-08 19:20:22 +0000160 {{" "}}= nullptr
Corentin Wallez9d6265b2020-11-04 10:04:17 +0000161 {%- elif member.type.category == "object" and member.optional and is_struct -%}
Corentin Wallezb0789fd2020-10-29 13:09:12 +0000162 {{" "}}= nullptr
Corentin Wallez8f938712019-07-08 19:20:22 +0000163 {%- elif member.type.category in ["enum", "bitmask"] and member.default_value != None -%}
164 {{" "}}= {{as_cppType(member.type.name)}}::{{as_cppEnum(Name(member.default_value))}}
165 {%- elif member.type.category == "native" and member.default_value != None -%}
166 {{" "}}= {{member.default_value}}
Brandon Jones6e8c4732022-02-19 00:44:12 +0000167 {%- elif member.default_value != None -%}
168 {{" "}}= {{member.default_value}}
Corentin Wallez8f938712019-07-08 19:20:22 +0000169 {%- else -%}
170 {{assert(member.default_value == None)}}
171 {%- endif -%}
172{%- endmacro %}
173
174{% macro render_cpp_method_declaration(type, method) %}
175 {% set CppType = as_cppType(type.name) %}
Corentin Wallez96496822019-10-15 11:44:38 +0000176 {{as_cppType(method.return_type.name)}} {{method.name.CamelCase()}}(
Corentin Wallez8f938712019-07-08 19:20:22 +0000177 {%- for arg in method.arguments -%}
178 {%- if not loop.first %}, {% endif -%}
179 {%- if arg.type.category == "object" and arg.annotation == "value" -%}
180 {{as_cppType(arg.type.name)}} const& {{as_varName(arg.name)}}
181 {%- else -%}
182 {{as_annotated_cppType(arg)}}
183 {%- endif -%}
Corentin Wallez9d6265b2020-11-04 10:04:17 +0000184 {{render_cpp_default_value(arg, False)}}
Corentin Wallez8f938712019-07-08 19:20:22 +0000185 {%- endfor -%}
186 ) const
187{%- endmacro %}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400188
189 {% for type in by_category["object"] %}
190 {% set CppType = as_cppType(type.name) %}
191 {% set CType = as_cType(type.name) %}
Corentin Wallezbd483852019-01-09 09:05:18 +0000192 class {{CppType}} : public ObjectBase<{{CppType}}, {{CType}}> {
Corentin Wallez8f938712019-07-08 19:20:22 +0000193 public:
194 using ObjectBase::ObjectBase;
195 using ObjectBase::operator=;
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400196
Corentin Wallezaca8c4a2019-11-22 14:02:52 +0000197 {% for method in type.methods %}
Corentin Wallez8f938712019-07-08 19:20:22 +0000198 {{render_cpp_method_declaration(type, method)}};
199 {% endfor %}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400200
Corentin Wallez8f938712019-07-08 19:20:22 +0000201 private:
202 friend ObjectBase<{{CppType}}, {{CType}}>;
fujunweic7d4f2c2021-12-07 00:46:35 +0000203 static void {{c_prefix}}Reference({{CType}} handle);
204 static void {{c_prefix}}Release({{CType}} handle);
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400205 };
206
207 {% endfor %}
208
fujunweic7d4f2c2021-12-07 00:46:35 +0000209 {% for function in by_category["function"] %}
fujunweid3cac112021-12-14 02:20:15 +0000210 {{as_cppType(function.return_type.name)}} {{as_cppType(function.name)}}(
fujunweic7d4f2c2021-12-07 00:46:35 +0000211 {%- for arg in function.arguments -%}
fujunweid3cac112021-12-14 02:20:15 +0000212 {%- if not loop.first %}, {% endif -%}
213 {{as_annotated_cppType(arg)}}{{render_cpp_default_value(arg, False)}}
fujunweic7d4f2c2021-12-07 00:46:35 +0000214 {%- endfor -%}
215 );
216 {% endfor %}
Corentin Wallezc57b1802019-10-15 12:08:48 +0000217
Corentin Wallez8e335a52018-08-27 23:12:56 +0200218 {% for type in by_category["structure"] %}
Austin Engbffc9662021-09-17 15:36:00 +0000219 {% set Out = "Out" if type.output else "" %}
220 {% set const = "const" if not type.output else "" %}
Corentin Wallez2b24c3d2020-01-15 09:54:42 +0000221 {% if type.chained %}
Corentin Walleza45561b2022-07-14 12:58:25 +0000222 {% for root in type.chain_roots %}
223 // Can be chained in {{as_cppType(root.name)}}
224 {% endfor %}
Austin Engbffc9662021-09-17 15:36:00 +0000225 struct {{as_cppType(type.name)}} : ChainedStruct{{Out}} {
Corentin Wallez2b24c3d2020-01-15 09:54:42 +0000226 {{as_cppType(type.name)}}() {
227 sType = SType::{{type.name.CamelCase()}};
228 }
229 {% else %}
230 struct {{as_cppType(type.name)}} {
231 {% endif %}
Corentin Wallez8e335a52018-08-27 23:12:56 +0200232 {% if type.extensible %}
Austin Engbffc9662021-09-17 15:36:00 +0000233 ChainedStruct{{Out}} {{const}} * nextInChain = nullptr;
Corentin Wallez8e335a52018-08-27 23:12:56 +0200234 {% endif %}
235 {% for member in type.members %}
Austin Eng76a8d0b2020-04-03 17:37:48 +0000236 {% set member_declaration = as_annotated_cppType(member) + render_cpp_default_value(member) %}
237 {% if type.chained and loop.first %}
Corentin Wallez7a641272022-06-29 17:37:41 +0000238 //* Align the first member after ChainedStruct to match the C struct layout.
239 //* It has to be aligned both to its natural and ChainedStruct's alignment.
240 static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct{{out}}), alignof({{decorate("", as_cppType(member.type.name), member)}}));
241 alignas(kFirstMemberAlignment) {{member_declaration}};
Austin Eng76a8d0b2020-04-03 17:37:48 +0000242 {% else %}
243 {{member_declaration}};
244 {% endif %}
Corentin Wallez8e335a52018-08-27 23:12:56 +0200245 {% endfor %}
246 };
247
248 {% endfor %}
fujunweied33e052021-12-08 05:46:17 +0000249
250 // The operators of EnumClassBitmmasks in the dawn:: namespace need to be imported
251 // in the {{metadata.namespace}} namespace for Argument Dependent Lookup.
252 DAWN_IMPORT_BITMASK_OPERATORS
fujunweic7d4f2c2021-12-07 00:46:35 +0000253} // namespace {{metadata.namespace}}
Corentin Wallezf07e3bd2017-04-20 14:38:20 -0400254
fujunweied33e052021-12-08 05:46:17 +0000255namespace dawn {
256 {% for type in by_category["bitmask"] %}
257 template<>
258 struct IsDawnBitmask<{{metadata.namespace}}::{{as_cppType(type.name)}}> {
259 static constexpr bool enable = true;
260 };
261
262 {% endfor %}
263} // namespace dawn
264
fujunweic7d4f2c2021-12-07 00:46:35 +0000265#endif // {{API}}_CPP_H_