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 CORE3D_UTIL_PROPERTY_UTIL_H 17 #define CORE3D_UTIL_PROPERTY_UTIL_H 18 19 #include <3d/namespace.h> 20 #include <base/containers/string.h> 21 #include <base/containers/vector.h> 22 #include <core/json/json.h> 23 #include <core/property/intf_property_api.h> 24 #include <core/property/intf_property_handle.h> 25 #include <core/property/property_handle_util.h> 26 #include <core/property/property_types.h> 27 28 CORE3D_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) = delete; 49 CustomPropertyPodContainer& operator=(const CustomPropertyPodContainer& other) = delete; 50 CustomPropertyPodContainer& operator=(CustomPropertyPodContainer&& other) = 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<const uint8_t> data); 79 bool SetValue(size_t byteOffset, BASE_NS::array_view<const 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 84 void CopyValues(const CustomPropertyPodContainer& other); 85 86 // Uses property handle util 87 template<typename T> SetValue(BASE_NS::string_view propertyName, T&& propertyValue)88 bool SetValue(BASE_NS::string_view propertyName, T&& propertyValue) 89 { 90 return CORE_NS::SetPropertyValue(*this, propertyName, BASE_NS::forward<T>(propertyValue)); 91 } 92 template<typename T> GetValue(BASE_NS::string_view propertyName)93 T GetValue(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 CORE3D_END_NAMESPACE() 124 125 #endif // CORE3D_UTIL_PROPERTY_UTIL_H 126