• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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