Added rotation support to frame-callback
[platform/core/uifw/dali-core.git] / dali / internal / update / manager / update-proxy-impl.cpp
1 /*
2  * Copyright (c) 2023 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   mDirtyNodes(),
59   mCurrentBufferIndex(0u),
60   mUpdateManager(updateManager),
61   mTransformManager(transformManager),
62   mRootNode(rootNode),
63   mPropertyModifier(nullptr)
64 {
65 }
66
67 UpdateProxy::~UpdateProxy() = default;
68
69 bool UpdateProxy::GetPosition(uint32_t id, Vector3& position) const
70 {
71   bool                    success = false;
72   const SceneGraph::Node* node    = GetNodeWithId(id);
73   if(node)
74   {
75     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
76     position                                             = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION);
77     success                                              = true;
78   }
79   return success;
80 }
81
82 bool UpdateProxy::SetPosition(uint32_t id, const Vector3& position)
83 {
84   bool              success = false;
85   SceneGraph::Node* node    = GetNodeWithId(id);
86   if(node)
87   {
88     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION, position);
89     success = true;
90   }
91   return success;
92 }
93
94 bool UpdateProxy::BakePosition(uint32_t id, const Vector3& position)
95 {
96   bool              success = false;
97   SceneGraph::Node* node    = GetNodeWithId(id);
98   if(node)
99   {
100     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION, position);
101     success = true;
102   }
103   return success;
104 }
105
106 bool UpdateProxy::GetOrientation(uint32_t id, Quaternion& orientation) const
107 {
108   bool                    success = false;
109   const SceneGraph::Node* node    = GetNodeWithId(id);
110   if(node)
111   {
112     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
113
114     orientation = transformManager.GetQuaternionPropertyValue(node->GetTransformId());
115     success     = true;
116   }
117   return success;
118 }
119
120 bool UpdateProxy::SetOrientation(uint32_t id, const Quaternion& orientation)
121 {
122   bool              success = false;
123   SceneGraph::Node* node    = GetNodeWithId(id);
124   if(node)
125   {
126     mTransformManager.SetQuaternionPropertyValue(node->GetTransformId(), orientation);
127     success = true;
128   }
129   return success;
130 }
131
132 bool UpdateProxy::BakeOrientation(uint32_t id, const Quaternion& orientation)
133 {
134   bool              success = false;
135   SceneGraph::Node* node    = GetNodeWithId(id);
136   if(node)
137   {
138     mTransformManager.BakeQuaternionPropertyValue(node->GetTransformId(), orientation);
139     success = true;
140   }
141   return success;
142 }
143
144 bool UpdateProxy::GetSize(uint32_t id, Vector3& size) const
145 {
146   bool                    success = false;
147   const SceneGraph::Node* node    = GetNodeWithId(id);
148   if(node)
149   {
150     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
151     size                                                 = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
152     success                                              = true;
153   }
154   return success;
155 }
156
157 bool UpdateProxy::SetSize(uint32_t id, const Vector3& size)
158 {
159   bool              success = false;
160   SceneGraph::Node* node    = GetNodeWithId(id);
161   if(node)
162   {
163     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE, size);
164     success = true;
165   }
166   return success;
167 }
168
169 bool UpdateProxy::BakeSize(uint32_t id, const Vector3& size)
170 {
171   bool              success = false;
172   SceneGraph::Node* node    = GetNodeWithId(id);
173   if(node)
174   {
175     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE, size);
176     success = true;
177   }
178   return success;
179 }
180
181 bool UpdateProxy::GetPositionAndSize(uint32_t id, Vector3& position, Vector3& size) const
182 {
183   bool                    success = false;
184   const SceneGraph::Node* node    = GetNodeWithId(id);
185   if(node)
186   {
187     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
188     position                                             = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_POSITION);
189     size                                                 = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
190     success                                              = true;
191   }
192   return success;
193 }
194
195 bool UpdateProxy::GetWorldPositionScaleAndSize(uint32_t id, Vector3& position, Vector3& scale, Vector3& size) const
196 {
197   bool                    success = false;
198   const SceneGraph::Node* node    = GetNodeWithId(id);
199   if(node)
200   {
201     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
202     const Matrix&                       worldMatrix      = transformManager.GetWorldMatrix(node->GetTransformId());
203
204     Quaternion orientation;
205     worldMatrix.GetTransformComponents(position, orientation, scale);
206
207     size    = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
208     success = true;
209   }
210   return success;
211 }
212
213 bool UpdateProxy::GetWorldTransformAndSize(uint32_t id, Vector3& position, Vector3& scale, Quaternion& orientation, Vector3& size) const
214 {
215   bool                    success = false;
216   const SceneGraph::Node* node    = GetNodeWithId(id);
217   if(node)
218   {
219     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
220     const Matrix&                       worldMatrix      = transformManager.GetWorldMatrix(node->GetTransformId());
221
222     worldMatrix.GetTransformComponents(position, orientation, scale);
223     size    = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SIZE);
224     success = true;
225   }
226   return success;
227 }
228
229 bool UpdateProxy::GetScale(uint32_t id, Vector3& scale) const
230 {
231   bool                    success = false;
232   const SceneGraph::Node* node    = GetNodeWithId(id);
233   if(node)
234   {
235     const SceneGraph::TransformManager& transformManager = mTransformManager; // To ensure we call the const getter
236     scale                                                = transformManager.GetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE);
237     success                                              = true;
238   }
239
240   return success;
241 }
242
243 bool UpdateProxy::SetScale(uint32_t id, const Vector3& scale)
244 {
245   bool              success = false;
246   SceneGraph::Node* node    = GetNodeWithId(id);
247   if(node)
248   {
249     mTransformManager.SetVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE, scale);
250     success = true;
251   }
252   return success;
253 }
254
255 bool UpdateProxy::BakeScale(uint32_t id, const Vector3& scale)
256 {
257   bool              success = false;
258   SceneGraph::Node* node    = GetNodeWithId(id);
259   if(node)
260   {
261     mTransformManager.BakeVector3PropertyValue(node->GetTransformId(), SceneGraph::TRANSFORM_PROPERTY_SCALE, scale);
262     success = true;
263   }
264   return success;
265 }
266
267 bool UpdateProxy::GetColor(uint32_t id, Vector4& color) const
268 {
269   bool                    success = false;
270   const SceneGraph::Node* node    = GetNodeWithId(id);
271   if(node)
272   {
273     color   = node->mColor.Get(mCurrentBufferIndex);
274     success = true;
275   }
276
277   return success;
278 }
279
280 bool UpdateProxy::SetColor(uint32_t id, const Vector4& color)
281 {
282   bool              success = false;
283   SceneGraph::Node* node    = GetNodeWithId(id);
284   if(node)
285   {
286     node->mColor.Set(mCurrentBufferIndex, color);
287     node->SetDirtyFlag(SceneGraph::NodePropertyFlags::COLOR);
288     mDirtyNodes.push_back(id);
289     AddResetter(*node, node->mColor);
290     success = true;
291   }
292   return success;
293 }
294
295 bool UpdateProxy::BakeColor(uint32_t id, const Vector4& color)
296 {
297   bool              success = false;
298   SceneGraph::Node* node    = GetNodeWithId(id);
299   if(node)
300   {
301     node->mColor.Bake(mCurrentBufferIndex, color);
302     success = true;
303   }
304   return success;
305 }
306
307 void UpdateProxy::NodeHierarchyChanged()
308 {
309   mLastCachedIdNodePair = {0u, nullptr};
310   mNodeContainer.clear();
311   mPropertyModifier.reset();
312 }
313
314 SceneGraph::Node* UpdateProxy::GetNodeWithId(uint32_t id) const
315 {
316   SceneGraph::Node* node = nullptr;
317
318   // Cache the last accessed node so we don't have to traverse
319   if(mLastCachedIdNodePair.node && mLastCachedIdNodePair.id == id)
320   {
321     node = mLastCachedIdNodePair.node;
322   }
323   else
324   {
325     // Find node in vector
326     for(auto&& pair : mNodeContainer)
327     {
328       if(pair.id == id)
329       {
330         node                  = pair.node;
331         mLastCachedIdNodePair = pair;
332         break;
333       }
334     }
335
336     if(!node)
337     {
338       // Node not in vector, find in scene-graph
339       node = FindNodeInSceneGraph(id, mRootNode);
340       if(node)
341       {
342         mNodeContainer.push_back({id, node});
343         mLastCachedIdNodePair = *mNodeContainer.rbegin();
344       }
345     }
346   }
347
348   return node;
349 }
350
351 void UpdateProxy::AddResetter(SceneGraph::Node& node, SceneGraph::PropertyBase& propertyBase)
352 {
353   if(!mPropertyModifier)
354   {
355     mPropertyModifier = PropertyModifierPtr(new PropertyModifier(mUpdateManager));
356   }
357   mPropertyModifier->AddResetter(node, propertyBase);
358 }
359
360 void UpdateProxy::AddNodeResetters()
361 {
362   for(auto&& id : mDirtyNodes)
363   {
364     SceneGraph::Node* node = FindNodeInSceneGraph(id, mRootNode);
365     if(node)
366     {
367       mUpdateManager.AddNodeResetter(*node);
368     }
369   }
370 }
371
372 } // namespace Internal
373
374 } // namespace Dali