Merge "Don't do AABB culling if the clipping mode of the node is enabled" into devel...
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-proxy-impl.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/update/manager/update-proxy-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/update/manager/update-proxy-property-modifier.h>
23
24 namespace Dali
25 {
26 namespace Internal
27 {
28 namespace
29 {
30 SceneGraph::Node* FindNodeInSceneGraph(uint32_t id, SceneGraph::Node& node)
31 {
32   SceneGraph::Node* matchingNode = nullptr;
33
34   if(node.mId == id)
35   {
36     matchingNode = &node;
37   }
38   else
39   {
40     for(auto&& i : node.GetChildren())
41     {
42       matchingNode = FindNodeInSceneGraph(id, *i);
43       if(matchingNode)
44       {
45         break;
46       }
47     }
48   }
49
50   return matchingNode;
51 }
52
53 } // unnamed namespace
54
55 UpdateProxy::UpdateProxy(SceneGraph::UpdateManager& updateManager, SceneGraph::TransformManager& transformManager, SceneGraph::Node& rootNode)
56 : mNodeContainer(),
57   mLastCachedIdNodePair({0u, nullptr}),
58   mCurrentBufferIndex(0u),
59   mUpdateManager(updateManager),
60   mTransformManager(transformManager),
61   mRootNode(rootNode),
62   mPropertyModifier(nullptr)
63 {
64 }
65
66 UpdateProxy::~UpdateProxy() = default;
67
68 bool UpdateProxy::GetPosition(uint32_t id, Vector3& position) const
69 {
70   bool                    success = false;
71   const SceneGraph::Node* node    = GetNodeWithId(id);
72   if(node)
73   {
74     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
75     position                                             = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION);
76     success                                              = true;
77   }
78   return success;
79 }
80
81 bool UpdateProxy::SetPosition(uint32_t id, const Vector3& position)
82 {
83   bool              success = false;
84   SceneGraph::Node* node    = GetNodeWithId(id);
85   if(node)
86   {
87     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION, position);
88     success = true;
89   }
90   return success;
91 }
92
93 bool UpdateProxy::BakePosition(uint32_t id, const Vector3& position)
94 {
95   bool              success = false;
96   SceneGraph::Node* node    = GetNodeWithId(id);
97   if(node)
98   {
99     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION, position);
100     success = true;
101   }
102   return success;
103 }
104
105 bool UpdateProxy::GetSize(uint32_t id, Vector3& size) const
106 {
107   bool                    success = false;
108   const SceneGraph::Node* node    = GetNodeWithId(id);
109   if(node)
110   {
111     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
112     size                                                 = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
113     success                                              = true;
114   }
115   return success;
116 }
117
118 bool UpdateProxy::SetSize(uint32_t id, const Vector3& size)
119 {
120   bool              success = false;
121   SceneGraph::Node* node    = GetNodeWithId(id);
122   if(node)
123   {
124     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE, size);
125     success = true;
126   }
127   return success;
128 }
129
130 bool UpdateProxy::BakeSize(uint32_t id, const Vector3& size)
131 {
132   bool              success = false;
133   SceneGraph::Node* node    = GetNodeWithId(id);
134   if(node)
135   {
136     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE, size);
137     success = true;
138   }
139   return success;
140 }
141
142 bool UpdateProxy::GetPositionAndSize(uint32_t id, Vector3& position, Vector3& size) const
143 {
144   bool                    success = false;
145   const SceneGraph::Node* node    = GetNodeWithId(id);
146   if(node)
147   {
148     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
149     position                                             = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION);
150     size                                                 = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
151     success                                              = true;
152   }
153   return success;
154 }
155
156 bool UpdateProxy::GetScale(uint32_t id, Vector3& scale) const
157 {
158   bool                    success = false;
159   const SceneGraph::Node* node    = GetNodeWithId(id);
160   if(node)
161   {
162     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
163     scale                                                = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE);
164     success                                              = true;
165   }
166
167   return success;
168 }
169
170 bool UpdateProxy::SetScale(uint32_t id, const Vector3& scale)
171 {
172   bool              success = false;
173   SceneGraph::Node* node    = GetNodeWithId(id);
174   if(node)
175   {
176     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE, scale);
177     success = true;
178   }
179   return success;
180 }
181
182 bool UpdateProxy::BakeScale(uint32_t id, const Vector3& scale)
183 {
184   bool              success = false;
185   SceneGraph::Node* node    = GetNodeWithId(id);
186   if(node)
187   {
188     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE, scale);
189     success = true;
190   }
191   return success;
192 }
193
194 bool UpdateProxy::GetColor(uint32_t id, Vector4& color) const
195 {
196   bool                    success = false;
197   const SceneGraph::Node* node    = GetNodeWithId(id);
198   if(node)
199   {
200     color   = node->mColor.Get(mCurrentBufferIndex);
201     success = true;
202   }
203
204   return success;
205 }
206
207 bool UpdateProxy::SetColor(uint32_t id, const Vector4& color)
208 {
209   bool              success = false;
210   SceneGraph::Node* node    = GetNodeWithId(id);
211   if(node)
212   {
213     node->mColor.Set(mCurrentBufferIndex, color);
214     node->SetDirtyFlag(SceneGraph::NodePropertyFlags::COLOR);
215     AddResetter(*node, node->mColor);
216     success = true;
217   }
218   return success;
219 }
220
221 bool UpdateProxy::BakeColor(uint32_t id, const Vector4& color)
222 {
223   bool              success = false;
224   SceneGraph::Node* node    = GetNodeWithId(id);
225   if(node)
226   {
227     node->mColor.Bake(mCurrentBufferIndex, color);
228     success = true;
229   }
230   return success;
231 }
232
233 void UpdateProxy::NodeHierarchyChanged()
234 {
235   mLastCachedIdNodePair = {0u, nullptr};
236   mNodeContainer.clear();
237   mPropertyModifier.reset();
238 }
239
240 SceneGraph::Node* UpdateProxy::GetNodeWithId(uint32_t id) const
241 {
242   SceneGraph::Node* node = nullptr;
243
244   // Cache the last accessed node so we don't have to traverse
245   if(mLastCachedIdNodePair.node && mLastCachedIdNodePair.id == id)
246   {
247     node = mLastCachedIdNodePair.node;
248   }
249   else
250   {
251     // Find node in vector
252     for(auto&& pair : mNodeContainer)
253     {
254       if(pair.id == id)
255       {
256         node                  = pair.node;
257         mLastCachedIdNodePair = pair;
258         break;
259       }
260     }
261
262     if(!node)
263     {
264       // Node not in vector, find in scene-graph
265       node = FindNodeInSceneGraph(id, mRootNode);
266       if(node)
267       {
268         mNodeContainer.push_back({id, node});
269         mLastCachedIdNodePair = *mNodeContainer.rbegin();
270       }
271     }
272   }
273
274   return node;
275 }
276
277 void UpdateProxy::AddResetter(SceneGraph::Node& node, SceneGraph::PropertyBase& propertyBase)
278 {
279   if(!mPropertyModifier)
280   {
281     mPropertyModifier = PropertyModifierPtr(new PropertyModifier(mUpdateManager));
282   }
283   mPropertyModifier->AddResetter(node, propertyBase);
284 }
285
286 } // namespace Internal
287
288 } // namespace Dali