Removing shader uniform map observers
[platform/core/uifw/dali-core.git] / dali / internal / update / common / uniform-map.h
1 #ifndef DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_H
2 #define DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 // EXTERNAL INCLUDES
21 #include <cstdint> // uint32_t
22 #include <string>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-vector.h>
26
27 #include <dali/devel-api/common/hash.h>
28
29 #include <dali/internal/common/const-string.h>
30
31 namespace Dali
32 {
33 namespace Internal
34 {
35 class PropertyInputImpl;
36
37 namespace SceneGraph
38 {
39 /**
40  * The uniform map is used to map a uniform name to a property value.
41  */
42 class UniformPropertyMapping
43 {
44 public:
45   using Hash = unsigned long;
46
47   /**
48    * Constructor
49    */
50   UniformPropertyMapping(ConstString theUniformName, const PropertyInputImpl* thePropertyPtr)
51   : propertyPtr(thePropertyPtr),
52     uniformName(theUniformName),
53     uniformNameHash(0u),
54     uniformNameHashNoArray(0u),
55     arrayIndex(0u)
56   {
57     // Look for array index closing bracket
58     auto nameStringView = theUniformName.GetStringView();
59     auto pos            = nameStringView.rfind("]");
60
61     // If found, extract the array index and store it, if it's an element in an array of basic types.
62     if(pos != std::string::npos)
63     {
64       auto pos0 = theUniformName.GetStringView().rfind("[", pos);
65       if(pos == nameStringView.length() - 1) // if element is in struct, don't set array index.
66       {
67         arrayIndex = atoi(theUniformName.GetCString() + pos0 + 1);
68       }
69       // Calculate hash from name without array index
70       uniformNameHashNoArray = Dali::CalculateHash(theUniformName.GetStringView().substr(0, pos0).data(), '[');
71     }
72     uniformName     = theUniformName;
73     uniformNameHash = Dali::CalculateHash(theUniformName.GetCString());
74   }
75
76   UniformPropertyMapping() = default;
77
78   const PropertyInputImpl* propertyPtr{nullptr};
79   ConstString              uniformName{};
80   Hash                     uniformNameHash{0u};
81   Hash                     uniformNameHashNoArray{0u};
82   int32_t                  arrayIndex{0u};
83 };
84
85 /**
86  * The UniformMap class is used to map uniform names to property values. It is available
87  * in the following rendering classes: Node, Renderer, Shader.
88  *
89  * They can test the ChangeCounter to see if the mapping has been updated.
90  */
91 class UniformMap
92 {
93 public:
94   using SizeType = uint32_t;
95
96   /**
97    * Add a map to the mappings table.
98    */
99   void Add(UniformPropertyMapping map);
100
101   /**
102    * Remove a map from the mappings table
103    */
104   void Remove(ConstString uniformName);
105
106   /**
107    * Find a property given the uniform name.
108    * @return The address of the property if it's in the map, or NULL otherwise.
109    */
110   const PropertyInputImpl* Find(ConstString uniformName);
111
112   /**
113    * Get the count of uniforms in the map
114    * @return The number of uniform mappings
115    */
116   SizeType Count() const;
117
118   /**
119    * @pre index must be in the range 0 :: Count()-1
120    * @param[in] index The index of the element to fetch
121    * @return reference to the element in the map
122    */
123   const UniformPropertyMapping& operator[](SizeType index) const;
124
125   /**
126    * Return the change counter
127    */
128   inline std::size_t GetChangeCounter() const
129   {
130     return mChangeCounter;
131   }
132
133 private:
134   /**
135    * Helper to call the observers when the mappings have changed
136    */
137   void MappingChanged();
138
139 private:
140   using UniformMapContainer = Dali::Vector<UniformPropertyMapping>;
141   using UniformMapIter      = UniformMapContainer::Iterator;
142
143   UniformMapContainer mUniformMaps;       ///< container of uniform maps
144   std::size_t         mChangeCounter{0u}; ///< Counter that is incremented when the map changes
145 };
146
147 } // namespace SceneGraph
148 } // namespace Internal
149 } // namespace Dali
150
151 #endif // DALI_INTERNAL_SCENE_GRAPH_UNIFORM_MAP_H