[dali_2.3.48] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / update / common / double-buffered.h
1 #ifndef DALI_INTERNAL_SCENE_GRAPH_DOUBLE_BUFFERED_H
2 #define DALI_INTERNAL_SCENE_GRAPH_DOUBLE_BUFFERED_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
21 // INTERNAL INCLUDES
22 #include <dali/internal/common/buffer-index.h>
23 #include <dali/internal/common/owner-pointer.h>
24
25 namespace Dali
26 {
27 namespace Internal
28 {
29 // The number of buffers per scene-graph property
30 static const unsigned int NUM_SCENE_GRAPH_BUFFERS = 2;
31
32 namespace SceneGraph
33 {
34 /**
35  * Templated class for a double-buffered value.
36  */
37 template<typename T>
38 class DoubleBuffered
39 {
40 public:
41   DoubleBuffered()
42   : mValue1(),
43     mValue2()
44   {
45   }
46
47   DoubleBuffered(const T& val)
48   : mValue1(val),
49     mValue2(val)
50   {
51   }
52
53   inline T& operator[](const BufferIndex i)
54   {
55     DALI_ASSERT_DEBUG(i < NUM_SCENE_GRAPH_BUFFERS);
56
57     return *(&mValue1 + i);
58   }
59
60   inline const T& operator[](const BufferIndex i) const
61   {
62     DALI_ASSERT_DEBUG(i < NUM_SCENE_GRAPH_BUFFERS);
63
64     return *(&mValue1 + i);
65   }
66
67 private:
68   // Undefined
69   DoubleBuffered(const DoubleBuffered&);
70
71   // Undefined
72   DoubleBuffered& operator=(const DoubleBuffered& rhs);
73
74 private:
75   T mValue1;
76   T mValue2;
77 };
78
79 /**
80  * @brief Specialization for owner-pointer
81  *
82  * This class takes ownership of the pointers and releases the memory when the pointer
83  * is no longer used by either buffer
84  */
85 template<typename T>
86 class DoubleBuffered<OwnerPointer<T> >
87 {
88 public:
89   /**
90    * Class that deals with setting a value
91    */
92   class Setter
93   {
94   public:
95     /**
96      * @brief Assignment operator to that a value that will later
97      * be set in the correct buffer index of the object referenced by the setter.
98      */
99     Setter& operator=(T* value)
100     {
101       mValue = value;
102       return *this;
103     }
104
105     ~Setter()
106     {
107       mObject.Set(mIndex, mValue);
108     }
109
110   private:
111     Setter(DoubleBuffered& object,
112            BufferIndex     i,
113            T*              value)
114     : mObject(object),
115       mIndex(i),
116       mValue(value)
117     {
118     }
119
120     Setter(const Setter& rhs)
121     : mObject(rhs.mObject),
122       mIndex(rhs.mIndex),
123       mValue(rhs.mValue)
124     {
125     }
126
127     DoubleBuffered&   mObject; ///< Double-buffered object that will be changed
128     const BufferIndex mIndex;  ///< Buffer index that will be changed
129     T*                mValue;  ///< Value of the pointer
130
131     friend class DoubleBuffered;
132   };
133
134   DoubleBuffered()
135   : mValue1(nullptr),
136     mValue2(nullptr)
137   {
138   }
139
140   DoubleBuffered(T* val)
141   : mValue1(val),
142     mValue2(val)
143   {
144   }
145
146   ~DoubleBuffered()
147   {
148     if(mValue2 != mValue1)
149     {
150       delete mValue2;
151     }
152     delete mValue1;
153   }
154
155   void Set(BufferIndex i, T* value)
156   {
157     T*& current  = *(&mValue1 + i);
158     T*& previous = *(&mValue1 + 1u - i);
159
160     if(current != value && current != previous)
161     {
162       delete current;
163     }
164     current = value;
165   }
166
167   Setter operator[](BufferIndex i)
168   {
169     return Setter(*this, i, *(&mValue1 + i));
170   }
171
172   const T* operator[](BufferIndex i) const
173   {
174     DALI_ASSERT_DEBUG(i < NUM_SCENE_GRAPH_BUFFERS);
175
176     return *(&mValue1 + i);
177   }
178
179   /**
180    * Auto-age the property: if it was set the previous frame,
181    * then copy the value into the current frame's buffer.
182    */
183   void CopyPrevious(BufferIndex i)
184   {
185     DALI_ASSERT_DEBUG(i < NUM_SCENE_GRAPH_BUFFERS);
186
187     T*& current  = *(&mValue1 + i);
188     T*& previous = *(&mValue1 + 1u - i);
189
190     if(current != previous)
191     {
192       delete current;
193     }
194
195     current = previous;
196   }
197
198 private:
199   // Undefined
200   DoubleBuffered(const DoubleBuffered&);
201
202   // Undefined
203   DoubleBuffered& operator=(const DoubleBuffered& rhs);
204
205 private:
206   T* mValue1;
207   T* mValue2;
208 };
209
210 } // namespace SceneGraph
211
212 } // namespace Internal
213
214 } // namespace Dali
215
216 #endif // DALI_INTERNAL_SCENE_GRAPH_DOUBLE_BUFFERED_H