Reducing message spam for baked properties
[platform/core/uifw/dali-core.git] / dali / internal / update / common / animatable-property-messages.h
1 #ifndef DALI_INTERNAL_COMMON_ANIMATABLE_PROPERTY_MESSAGES_H
2 #define DALI_INTERNAL_COMMON_ANIMATABLE_PROPERTY_MESSAGES_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 #include <dali/internal/common/message.h>
21 #include <dali/internal/event/common/event-thread-services.h>
22 #include <dali/internal/update/common/animatable-property.h>
23 #include <dali/internal/update/common/property-owner.h>
24 #include <dali/internal/update/common/property-resetter.h>
25 #include <dali/internal/update/manager/update-manager.h>
26
27 namespace Dali::Internal
28 {
29
30 /**
31  * Special message to first bake a property, then create a resetter for the
32  * property in the update thread to reduce load on event thread.
33  * @tparam T The type of the property
34  * @tparam P2 The type of the parameter to the second object method
35  */
36 template<class T, typename P>
37 class MessageBakeReset : public MessageBase
38 {
39 public:
40   using MemberFunction = void (T::*)(BufferIndex, typename ParameterType<P>::PassingType);
41
42   /**
43    * Create a message.
44    * @note The object is expected to be const in the thread which sends this message.
45    * However it can be modified when Process() is called in a different thread.
46    * @param[in] updateManager
47    * @param[in] propertyOwner The owner of the property
48    * @param[in] property The property to update
49    * @param[in] member The member function of the property object (bake/set)
50    * @param[in] p The value to update the property to
51    */
52   MessageBakeReset(SceneGraph::UpdateManager&             updateManager,
53                    const SceneGraph::PropertyOwner&       propertyOwner,
54                    const T*                               property,
55                    MemberFunction                         member,
56                    typename ParameterType<P>::PassingType p)
57   : MessageBase(),
58     mUpdateManager(updateManager),
59     mPropertyOwner(propertyOwner),
60     object(const_cast<T*>(property)),
61     memberFunction(member),
62     param(p)
63   {
64     DALI_ASSERT_DEBUG(property && "nullptr passed into message as property");
65   }
66
67   /**
68    * Virtual destructor
69    */
70   ~MessageBakeReset() override = default;
71
72   /**
73    * @copydoc MessageBase::Process
74    */
75   void Process(BufferIndex bufferIndex) override
76   {
77     // Bake/set the property
78     (object->*memberFunction)(bufferIndex, param);
79
80     // Create the resetter in the Update thread.
81     OwnerPointer<SceneGraph::PropertyResetterBase> resetter(
82       new SceneGraph::BakerResetter(const_cast<SceneGraph::PropertyOwner*>(&mPropertyOwner),
83                                     object,
84                                     SceneGraph::BakerResetter::Lifetime::BAKE));
85     mUpdateManager.AddPropertyResetter(resetter);
86   }
87
88 private:
89   SceneGraph::UpdateManager&            mUpdateManager;
90   const SceneGraph::PropertyOwner&      mPropertyOwner;
91   T*                                    object;
92   MemberFunction                        memberFunction;
93   typename ParameterType<P>::HolderType param;
94 };
95
96 template<typename T>
97 void BakeMessage(EventThreadServices&                     eventThreadServices,
98                  const SceneGraph::PropertyOwner&         propertyOwner,
99                  const SceneGraph::AnimatableProperty<T>& property,
100                  typename ParameterType<T>::PassingType   newValue)
101 {
102   using LocalType = MessageBakeReset<SceneGraph::AnimatableProperty<T>, T>;
103
104   // Reserve some memory inside the message queue
105   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
106
107   // Construct message in the message queue memory; note that delete should not be called on the return value
108   new(slot) LocalType(eventThreadServices.GetUpdateManager(),
109                       propertyOwner,
110                       &property,
111                       &SceneGraph::AnimatableProperty<T>::Bake,
112                       newValue);
113 }
114
115 template<class T>
116 void BakeRelativeMessage(EventThreadServices&                     eventThreadServices,
117                          const SceneGraph::PropertyOwner&         propertyOwner,
118                          const SceneGraph::AnimatableProperty<T>& property,
119                          const T&                                 delta)
120 {
121   using LocalType = MessageBakeReset<SceneGraph::AnimatableProperty<T>, T>;
122
123   // Reserve some memory inside the message queue
124   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
125
126   // Construct message in the message queue memory; note that delete should not be called on the return value
127   new(slot) LocalType(eventThreadServices.GetUpdateManager(),
128                       propertyOwner,
129                       &property,
130                       &SceneGraph::AnimatableProperty<T>::BakeRelative,
131                       delta);
132 }
133
134 template<class T>
135 void SetXComponentMessage(EventThreadServices&                       eventThreadServices,
136                           const SceneGraph::PropertyOwner&           propertyOwner,
137                           const SceneGraph::AnimatableProperty<T>&   property,
138                           typename ParameterType<float>::PassingType newValue)
139 {
140   using LocalType = MessageBakeReset<SceneGraph::AnimatableProperty<T>, float>;
141
142   // Reserve some memory inside the message queue
143   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
144
145   // Construct message in the message queue memory; note that delete should not be called on the return value
146   new(slot) LocalType(eventThreadServices.GetUpdateManager(),
147                       propertyOwner,
148                       &property,
149                       &SceneGraph::AnimatableProperty<T>::BakeX,
150                       newValue);
151 }
152
153 template<class T>
154 void SetYComponentMessage(EventThreadServices&                       eventThreadServices,
155                           const SceneGraph::PropertyOwner&           propertyOwner,
156                           const SceneGraph::AnimatableProperty<T>&   property,
157                           typename ParameterType<float>::PassingType newValue)
158 {
159   using LocalType = MessageBakeReset<SceneGraph::AnimatableProperty<T>, float>;
160
161   // Reserve some memory inside the message queue
162   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
163
164   // Construct message in the message queue memory; note that delete should not be called on the return value
165   new(slot) LocalType(eventThreadServices.GetUpdateManager(),
166                       propertyOwner,
167                       &property,
168                       &SceneGraph::AnimatableProperty<T>::BakeY,
169                       newValue);
170 }
171
172 template<class T>
173 void SetZComponentMessage(EventThreadServices&                       eventThreadServices,
174                           const SceneGraph::PropertyOwner&           propertyOwner,
175                           const SceneGraph::AnimatableProperty<T>&   property,
176                           typename ParameterType<float>::PassingType newValue)
177 {
178   using LocalType = MessageBakeReset<SceneGraph::AnimatableProperty<T>, float>;
179
180   // Reserve some memory inside the message queue
181   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
182
183   // Construct message in the message queue memory; note that delete should not be called on the return value
184   new(slot) LocalType(eventThreadServices.GetUpdateManager(),
185                       propertyOwner,
186                       &property,
187                       &SceneGraph::AnimatableProperty<T>::BakeZ,
188                       newValue);
189 }
190
191 template<class T>
192 void SetWComponentMessage(EventThreadServices&                       eventThreadServices,
193                           const SceneGraph::PropertyOwner&           propertyOwner,
194                           const SceneGraph::AnimatableProperty<T>&   property,
195                           typename ParameterType<float>::PassingType newValue)
196 {
197   using LocalType = MessageBakeReset<SceneGraph::AnimatableProperty<T>, float>;
198
199   // Reserve some memory inside the message queue
200   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
201
202   // Construct message in the message queue memory; note that delete should not be called on the return value
203   new(slot) LocalType(eventThreadServices.GetUpdateManager(),
204                       propertyOwner,
205                       &property,
206                       &SceneGraph::AnimatableProperty<T>::BakeW,
207                       newValue);
208 }
209
210 } // namespace Dali::Internal
211
212 #endif // DALI_INTERNAL_COMMON_ANIMATABLE_PROPERTY_MESSAGES_H