1 /* 2 * Copyright (c) 2024 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 UTIL__PROPERTY_UTIL_H 17 #define 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 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; 49 CustomPropertyPodContainer& operator=(const CustomPropertyPodContainer& other) = delete; 50 CustomPropertyPodContainer& operator=(CustomPropertyPodContainer&& other) noexcept; 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(const BASE_NS::string_view propertyName, const BASE_NS::string_view displayName, 75 const uintptr_t offset, const CORE_NS::PropertyTypeDecl& typeDecl); 76 void AddOffsetProperty(const BASE_NS::string_view propertyName, const BASE_NS::string_view displayName, 77 const uintptr_t offset, const CORE_NS::PropertyTypeDecl& typeDecl, 78 const BASE_NS::array_view<const uint8_t> data); 79 bool SetValue(const BASE_NS::string_view propertyName, const BASE_NS::array_view<uint8_t> data); 80 bool SetValue(const size_t byteOffset, const BASE_NS::array_view<uint8_t> data); 81 BASE_NS::array_view<const uint8_t> GetValue(const BASE_NS::string_view name) const; 82 // byte size of the data container 83 size_t GetByteSize() const; 84 BASE_NS::array_view<const uint8_t> GetData() const; 85 86 // Uses property handle util 87 template<typename T> SetValue(const BASE_NS::string_view propertyName, T&& propertyValue)88 bool SetValue(const BASE_NS::string_view propertyName, T&& propertyValue) 89 { 90 CORE_NS::SetPropertyValue<T>(*this, propertyName, propertyValue); 91 } 92 template<typename T> GetValue(const BASE_NS::string_view propertyName)93 T GetValue(const BASE_NS::string_view propertyName) 94 { 95 return CORE_NS::GetPropertyValue<T>(*this, propertyName); 96 } 97 98 private: 99 struct Strings { 100 BASE_NS::string name; 101 BASE_NS::string displayName; 102 }; 103 BASE_NS::vector<Strings> metaStrings_; 104 BASE_NS::vector<CORE_NS::Property> metaData_; 105 BASE_NS::vector<uint8_t> data_; 106 107 size_t reservePropertyCount_ { 0 }; 108 }; 109 110 /* 111 * CustomPropertyDataHelper 112 */ 113 class CustomPropertyPodHelper final { 114 public: 115 CustomPropertyPodHelper() = default; 116 ~CustomPropertyPodHelper() = default; 117 118 static CORE_NS::PropertyTypeDecl GetPropertyTypeDeclaration(const BASE_NS::string_view type); 119 static size_t GetPropertyTypeAlignment(const CORE_NS::PropertyTypeDecl& propertyType); 120 static void SetCustomPropertyBlobValue(const CORE_NS::PropertyTypeDecl& propertyType, 121 const CORE_NS::json::value* value, CustomPropertyPodContainer& customProperties, const size_t offset); 122 }; 123 124 /* 125 * Simple signaller class 126 */ 127 class CustomPropertyWriteSignal { 128 public: 129 CustomPropertyWriteSignal() = default; 130 virtual ~CustomPropertyWriteSignal() = default; 131 132 virtual void Signal() = 0; 133 }; 134 135 /* 136 * Implements a custom binding properties. 137 * 138 * NOTE: One must use Reserve(propertyCount) before adding properties 139 */ 140 class CustomPropertyBindingContainer final : public CORE_NS::IPropertyHandle, CORE_NS::IPropertyApi { 141 public: 142 explicit CustomPropertyBindingContainer(CustomPropertyWriteSignal& writeSignal); 143 ~CustomPropertyBindingContainer() override; 144 145 CustomPropertyBindingContainer(const CustomPropertyBindingContainer& other) = delete; 146 CustomPropertyBindingContainer(CustomPropertyBindingContainer&& other) noexcept; 147 CustomPropertyBindingContainer& operator=(const CustomPropertyBindingContainer& other) = delete; 148 CustomPropertyBindingContainer& operator=(CustomPropertyBindingContainer&& other) noexcept; 149 150 // IPropertyHandle 151 const CORE_NS::IPropertyApi* Owner() const override; 152 size_t Size() const override; 153 const void* RLock() const override; 154 void RUnlock() const override; 155 void* WLock() override; 156 void WUnlock() override; 157 158 // IPropertyApi 159 size_t PropertyCount() const override; 160 const CORE_NS::Property* MetaData(size_t index) const override; 161 BASE_NS::array_view<const CORE_NS::Property> MetaData() const override; 162 uint64_t Type() const override; 163 CORE_NS::IPropertyHandle* Create() const override; 164 CORE_NS::IPropertyHandle* Clone(const CORE_NS::IPropertyHandle* src) const override; 165 void Release(CORE_NS::IPropertyHandle* handle) const override; 166 167 // Reserve before adding any properties 168 void ReservePropertyCount(size_t propertyCount); 169 170 void AddOffsetProperty(const BASE_NS::string_view propertyName, const BASE_NS::string_view displayName, 171 const uintptr_t offset, const CORE_NS::PropertyTypeDecl& typeDecl); 172 // byte size of the data container 173 size_t GetByteSize() const; 174 175 // Uses property handle util 176 template<typename T> SetValue(const BASE_NS::string_view propertyName, T&& propertyValue)177 bool SetValue(const BASE_NS::string_view propertyName, T&& propertyValue) 178 { 179 CORE_NS::SetPropertyValue<T>(*this, propertyName, propertyValue); 180 } 181 template<typename T> GetValue(const BASE_NS::string_view propertyName)182 T GetValue(const BASE_NS::string_view propertyName) 183 { 184 return CORE_NS::GetPropertyValue<T>(*this, propertyName); 185 } 186 template<typename T> GetValue(size_t index)187 T GetValue(size_t index) 188 { 189 // the casting type needs to be known 190 if ((index < metaData_.size())) { 191 const auto& meta = metaData_[index]; 192 CORE_ASSERT(meta.offset < data_.size_in_bytes()); 193 if (void* ptr = (void*)(data_.data() + meta.offset); ptr) { 194 return *((T*)(ptr)); 195 } 196 } 197 return {}; 198 } 199 200 private: 201 // signal when value is written 202 CustomPropertyWriteSignal& writeSignal_; 203 204 struct Strings { 205 BASE_NS::string name; 206 BASE_NS::string displayName; 207 }; 208 BASE_NS::vector<Strings> metaStrings_; 209 BASE_NS::vector<CORE_NS::Property> metaData_; 210 BASE_NS::vector<uint8_t> data_; 211 size_t reservePropertyCount_ { 0 }; 212 }; 213 214 /* 215 * CustomBindingPropertyHelper 216 */ 217 class CustomPropertyBindingHelper final { 218 public: 219 CustomPropertyBindingHelper() = default; 220 ~CustomPropertyBindingHelper() = default; 221 222 static CORE_NS::PropertyTypeDecl GetPropertyTypeDeclaration(const BASE_NS::string_view type); 223 static size_t GetPropertyTypeAlignment(const CORE_NS::PropertyTypeDecl& propertyType); 224 }; 225 RENDER_END_NAMESPACE() 226 227 #endif // UTIL__PROPERTY_UTIL_H