• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
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 
16 #ifndef RENDER_UTIL_PROPERTY_UTIL_H
17 #define RENDER_UTIL_PROPERTY_UTIL_H
18 
19 #include <base/containers/string.h>
20 #include <base/containers/vector.h>
21 #include <core/json/json.h>
22 #include <core/property/intf_property_api.h>
23 #include <core/property/intf_property_handle.h>
24 #include <core/property/property_handle_util.h>
25 #include <core/property/property_types.h>
26 #include <render/namespace.h>
27 
RENDER_BEGIN_NAMESPACE()28 RENDER_BEGIN_NAMESPACE()
29 /*
30  * Implements a custom property blob for simple PODs e.g. shader custom shader properties which are stored in a single
31  * byte data.
32  * Supports float -> vec4 with u/i -variants
33  * - Single byte data blob
34  * - Multiple offsets customized properties for that data
35  * - Can only hold simple data within a single byte-blob
36  *
37  * NOTE: One must use Reserve(propertyCount) before adding properties
38  */
39 class CustomPropertyPodContainer final : public CORE_NS::IPropertyHandle, CORE_NS::IPropertyApi {
40 public:
41     CustomPropertyPodContainer() = default;
42     /* Reserve a predefined byte size to hold the property data */
43     explicit CustomPropertyPodContainer(size_t reserveByteSize);
44 
45     ~CustomPropertyPodContainer() override = default;
46 
47     CustomPropertyPodContainer(const CustomPropertyPodContainer& other) = delete;
48     CustomPropertyPodContainer(CustomPropertyPodContainer&& other) noexcept = delete;
49     CustomPropertyPodContainer& operator=(const CustomPropertyPodContainer& other) = delete;
50     CustomPropertyPodContainer& operator=(CustomPropertyPodContainer&& other) noexcept = delete;
51 
52     // IPropertyHandle
53     const CORE_NS::IPropertyApi* Owner() const override;
54     size_t Size() const override;
55     const void* RLock() const override;
56     void RUnlock() const override;
57     void* WLock() override;
58     void WUnlock() override;
59 
60     // IPropertyApi
61     size_t PropertyCount() const override;
62     const CORE_NS::Property* MetaData(size_t index) const override;
63     BASE_NS::array_view<const CORE_NS::Property> MetaData() const override;
64     uint64_t Type() const override;
65     CORE_NS::IPropertyHandle* Create() const override;
66     CORE_NS::IPropertyHandle* Clone(const CORE_NS::IPropertyHandle* src) const override;
67     void Release(CORE_NS::IPropertyHandle* handle) const override;
68 
69     // Reset, to remove old properties
70     void Reset();
71     // Reserve before adding any properties
72     void ReservePropertyCount(size_t propertyCount);
73 
74     void AddOffsetProperty(BASE_NS::string_view propertyName, BASE_NS::string_view displayName, uintptr_t offset,
75         const CORE_NS::PropertyTypeDecl& typeDecl);
76     void AddOffsetProperty(BASE_NS::string_view propertyName, BASE_NS::string_view displayName, uintptr_t offset,
77         const CORE_NS::PropertyTypeDecl& typeDecl, BASE_NS::array_view<const uint8_t> data);
78     bool SetValue(BASE_NS::string_view propertyName, BASE_NS::array_view<uint8_t> data);
79     bool SetValue(size_t byteOffset, BASE_NS::array_view<uint8_t> data);
80     BASE_NS::array_view<const uint8_t> GetValue(BASE_NS::string_view name) const;
81     // byte size of the data container
82     size_t GetByteSize() const;
83     BASE_NS::array_view<const uint8_t> GetData() const;
84 
85     // Uses property handle util
86     template<typename T>
87     bool SetValue(const BASE_NS::string_view propertyName, T&& propertyValue)
88     {
89         CORE_NS::SetPropertyValue<T>(*this, propertyName, propertyValue);
90     }
91     template<typename T>
92     T GetValue(const BASE_NS::string_view propertyName)
93     {
94         return CORE_NS::GetPropertyValue<T>(*this, propertyName);
95     }
96 
97 private:
98     struct Strings {
99         BASE_NS::string name;
100         BASE_NS::string displayName;
101     };
102     BASE_NS::vector<Strings> metaStrings_;
103     BASE_NS::vector<CORE_NS::Property> metaData_;
104     BASE_NS::vector<uint8_t> data_;
105 
106     size_t reservePropertyCount_ { 0 };
107 };
108 
109 /*
110  * CustomPropertyDataHelper
111  */
112 class CustomPropertyPodHelper final {
113 public:
114     CustomPropertyPodHelper() = default;
115     ~CustomPropertyPodHelper() = default;
116 
117     static CORE_NS::PropertyTypeDecl GetPropertyTypeDeclaration(BASE_NS::string_view type);
118     static size_t GetPropertyTypeAlignment(const CORE_NS::PropertyTypeDecl& propertyType);
119     static void SetCustomPropertyBlobValue(const CORE_NS::PropertyTypeDecl& propertyType,
120         const CORE_NS::json::value* value, CustomPropertyPodContainer& customProperties, size_t offset);
121 };
122 
123 /*
124  * Simple signaller class
125  */
126 class CustomPropertyWriteSignal {
127 public:
128     CustomPropertyWriteSignal() = default;
129     virtual ~CustomPropertyWriteSignal() = default;
130 
131     virtual void Signal() = 0;
132 };
133 
134 /*
135  * Implements a custom binding properties.
136  *
137  * NOTE: One must use Reserve(propertyCount) before adding properties
138  */
139 class CustomPropertyBindingContainer final : public CORE_NS::IPropertyHandle, CORE_NS::IPropertyApi {
140 public:
141     explicit CustomPropertyBindingContainer(CustomPropertyWriteSignal& writeSignal);
142     ~CustomPropertyBindingContainer() override;
143 
144     CustomPropertyBindingContainer(const CustomPropertyBindingContainer& other) = delete;
145     CustomPropertyBindingContainer(CustomPropertyBindingContainer&& other) noexcept = delete;
146     CustomPropertyBindingContainer& operator=(const CustomPropertyBindingContainer& other) = delete;
147     CustomPropertyBindingContainer& operator=(CustomPropertyBindingContainer&& other) noexcept = delete;
148 
149     // IPropertyHandle
150     const CORE_NS::IPropertyApi* Owner() const override;
151     size_t Size() const override;
152     const void* RLock() const override;
153     void RUnlock() const override;
154     void* WLock() override;
155     void WUnlock() override;
156 
157     // IPropertyApi
158     size_t PropertyCount() const override;
159     const CORE_NS::Property* MetaData(size_t index) const override;
160     BASE_NS::array_view<const CORE_NS::Property> MetaData() const override;
161     uint64_t Type() const override;
162     CORE_NS::IPropertyHandle* Create() const override;
163     CORE_NS::IPropertyHandle* Clone(const CORE_NS::IPropertyHandle* src) const override;
164     void Release(CORE_NS::IPropertyHandle* handle) const override;
165 
166     // Reserve before adding any properties
167     void ReservePropertyCount(size_t propertyCount);
168 
169     void AddOffsetProperty(BASE_NS::string_view propertyName, BASE_NS::string_view displayName, uintptr_t offset,
170         const CORE_NS::PropertyTypeDecl& typeDecl);
171     // byte size of the data container
172     size_t GetByteSize() const;
173 
174     // Uses property handle util
175     template<typename T>
SetValue(const BASE_NS::string_view propertyName,T && propertyValue)176     bool SetValue(const BASE_NS::string_view propertyName, T&& propertyValue)
177     {
178         CORE_NS::SetPropertyValue<T>(*this, propertyName, propertyValue);
179     }
180     template<typename T>
GetValue(const BASE_NS::string_view propertyName)181     T GetValue(const BASE_NS::string_view propertyName)
182     {
183         return CORE_NS::GetPropertyValue<T>(*this, propertyName);
184     }
185     template<typename T>
GetValue(size_t index)186     T GetValue(size_t index)
187     {
188         // the casting type needs to be known
189         if ((index < metaData_.size())) {
190             const auto& meta = metaData_[index];
191             CORE_ASSERT(meta.offset < data_.size_in_bytes());
192             if (void* ptr = (void*)(data_.data() + meta.offset); ptr) {
193                 return *((T*)(ptr));
194             }
195         }
196         return {};
197     }
198 
199 private:
200     // signal when value is written
201     CustomPropertyWriteSignal& writeSignal_;
202 
203     struct Strings {
204         BASE_NS::string name;
205         BASE_NS::string displayName;
206     };
207     BASE_NS::vector<Strings> metaStrings_;
208     BASE_NS::vector<CORE_NS::Property> metaData_;
209     BASE_NS::vector<uint8_t> data_;
210     size_t reservePropertyCount_ { 0 };
211 };
212 
213 /*
214  * CustomBindingPropertyHelper
215  */
216 class CustomPropertyBindingHelper final {
217 public:
218     CustomPropertyBindingHelper() = default;
219     ~CustomPropertyBindingHelper() = default;
220 
221     static CORE_NS::PropertyTypeDecl GetPropertyTypeDeclaration(BASE_NS::string_view type);
222     static size_t GetPropertyTypeAlignment(const CORE_NS::PropertyTypeDecl& propertyType);
223 };
224 RENDER_END_NAMESPACE()
225 
226 #endif // RENDER_UTIL_PROPERTY_UTIL_H
227