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