Added network build option. Disabled by default.
[platform/core/uifw/dali-adaptor.git] / adaptors / base / thread-synchronization.h
1 #ifndef __DALI_INTERNAL_THREAD_SYNCHRONIZATION_H__
2 #define __DALI_INTERNAL_THREAD_SYNCHRONIZATION_H__
3
4 /*
5  * Copyright (c) 2015 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 // EXTERNAL INCLUDES
22
23 // INTERNAL INCLUDES
24 #include <base/interfaces/performance-interface.h>
25 #include <base/conditional-wait.h>
26 #include <trigger-event-interface.h>
27 #include <base/frame-time.h>
28 #include <base/render-thread.h>
29
30 namespace Dali
31 {
32
33 class RenderSurface;
34
35 namespace Internal
36 {
37
38 namespace Adaptor
39 {
40
41 class AdaptorInternalServices;
42
43 /**
44  * This object is used to synchronize the update, render and vsync threads.
45  * The Core::GetMaximumUpdateCount() method determines how many frames may be prepared, ahead of the rendering.
46  * For example if the maximum update count is 2, then Core::Update() for frame N+1 may be processed whilst frame N is being rendered.
47  * However the Core::Update() for frame N+2 may not be called, until the Core::Render() method for frame N has returned.
48  *
49  */
50 class ThreadSynchronization
51 {
52 public:
53
54   /**
55    * Create an update/render synchronization object.
56    * @param[in] adaptorInterfaces base adaptor interface
57    * @param[in] numberOfVSyncsPerRender The number of frames per render
58   */
59   ThreadSynchronization( AdaptorInternalServices& adaptorInterfaces, unsigned int numberOfVSyncsPerRender );
60
61   /**
62    * Non virtual destructor. Not intended as base class.
63    */
64   ~ThreadSynchronization();
65
66   /////////////////////////////////////////////////////////////////////////////////////////////////
67   // Called by the Event Thread
68   /////////////////////////////////////////////////////////////////////////////////////////////////
69
70   /**
71    * Initialises the ThreadSynchronisation class. The expectation is that this function will be
72    * called when all threads are about to be set up and that Start will be called when
73    * the the scene is actually prepared and ready to be displayed. This way our first update
74    * will have the actual scene we require.
75    *
76    * @note Should only be called by the Event Thread.
77    */
78   void Initialise();
79
80   /**
81    * Starts running all threads. This waits until all threads are up and running.
82    *
83    * @pre A call to Initialise has been made.
84    *
85    * @note Should only be called by the Event Thread.
86    */
87   void Start();
88
89   /**
90    * Stop the threads.
91    *
92    * @note Should only be called by the Event Thread.
93    */
94   void Stop();
95
96   /**
97    * Pause the controller (and threads).
98    *
99    * @note Should only be called by the Event Thread.
100    */
101   void Pause();
102
103   /**
104    * Resume the controller (and threads).
105    *
106    * @note Should only be called by the Event Thread.
107    */
108   void Resume();
109
110   /**
111    * Wake update thread if sleeping. If the update thread is not sleeping
112    * this becomes a no-op.
113    * Called when an update is requested by Core.
114    * i.e. when a batch of messages have been queued for the next update.
115    *
116    * @note Should only be called by the Event Thread.
117    */
118   void UpdateRequest();
119
120   /**
121    * Update once (even if paused)
122    *
123    * @note Should only be called by the Event Thread.
124    */
125   void UpdateOnce();
126
127   /**
128    * Inform the render thread that there is a new surface, and that
129    * it should replace the current surface.
130    *
131    * @param[in] newSurface The new surface for rendering.
132    *
133    * @note Should only be called by the Event Thread.
134    */
135   void ReplaceSurface( RenderSurface* newSurface );
136
137   /**
138    * Set the refresh rate for rendering
139    *
140    * @param[in] numberOfVSyncsPerRender The number of vsync frames per render
141    *
142    * @note Should only be called by the Event Thread.
143    */
144   void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender );
145
146   /////////////////////////////////////////////////////////////////////////////////////////////////
147   // Called by the Update Thread
148   /////////////////////////////////////////////////////////////////////////////////////////////////
149
150   /**
151    * Called by Update thread when it is ready to run the update.
152    *
153    * @param[in] notifyEvent Whether the event thread should be woken up.
154    * @param[in] runUpdate Whether to run another update. If false, then the update-thread will attempt to sleep.
155    * @param[out] lastFrameDeltaSeconds The delta, in seconds (with float precision), between the last two renders.
156    * @param[out] lastSyncTimeMilliseconds The time, in milliseconds, of the last Sync.
157    * @param[out] nextSyncTimeMilliseconds The estimated time, in milliseconds, at the next Sync.
158    * @return true if updating should continue, false if the update-thread should quit.
159    *
160    * @note Should only be called by the Update thread.
161    */
162   bool UpdateReady( bool notifyEvent, bool runUpdate, float& lastFrameDeltaSeconds, unsigned int& lastSyncTimeMilliseconds, unsigned int& nextSyncTimeMilliseconds );
163
164   /////////////////////////////////////////////////////////////////////////////////////////////////
165   // Called by the Render Thread
166   /////////////////////////////////////////////////////////////////////////////////////////////////
167
168   /**
169    * Called by the Render thread when it is ready to render.
170    *
171    * @param[in] request Pointer to set if there are any requests. This does not need to be freed by the caller.
172    *
173    * @note Should only be called by the Render thread.
174    * @note If there is a request, then the Render thread should NOT perform a Render and only process the request
175    */
176   bool RenderReady( RenderRequest*& request );
177
178   /**
179    * Called by the Render thread to inform the synchronization class that the surface has been replaced.
180    *
181    * @note Should only be called by the Render thread.
182    */
183   void RenderInformSurfaceReplaced();
184
185   /////////////////////////////////////////////////////////////////////////////////////////////////
186   // Called by the V-Sync Thread
187   /////////////////////////////////////////////////////////////////////////////////////////////////
188
189   /**
190    * Called by the VSync notifier thread so it can sleep if Update/Render threads are sleeping/paused
191    *
192    * @param[in] validSync True if the sync was valid (@see VSyncMonitor::DoSync)
193    * @param[in] frameNumber The current frame number
194    * @param[in] seconds The current time
195    * @param[in] microseconds The current time
196    * @param[out] numberOfVSyncsPerRender The number of frames per render.
197    * @return true if VSync monitoring/notifications should continue.
198    *
199    * @note Should only be called by the VSync thread.
200    * @note The first call to this method should be BEFORE the actual VSync so a thread-sync point can be established (and startup time is not delayed).
201    */
202   bool VSyncReady( bool validSync, unsigned int frameNumber, unsigned int seconds, unsigned int microseconds, unsigned int& numberOfVSyncsPerRender );
203
204   /////////////////////////////////////////////////////////////////////////////////////////////////
205   // Called by ALL Threads
206   /////////////////////////////////////////////////////////////////////////////////////////////////
207
208   /**
209    * Helper to add a performance marker to the performance server (if it's active)
210    * @param type performance marker type
211    */
212   void AddPerformanceMarker( PerformanceInterface::MarkerType type );
213
214 private:
215
216   // Undefined copy constructor.
217   ThreadSynchronization( const ThreadSynchronization& );
218
219   // Undefined assignment operator.
220   ThreadSynchronization& operator=( const ThreadSynchronization& );
221
222   /////////////////////////////////////////////////////////////////////////////////////////////////
223   // Called by ALL Threads
224   /////////////////////////////////////////////////////////////////////////////////////////////////
225
226   /**
227    * Called by the update, render & v-sync thread when they up and running.
228    * This will lock the mutex in mEventThreadWaitCondition.
229    */
230   inline void NotifyThreadInitialised();
231
232   /////////////////////////////////////////////////////////////////////////////////////////////////
233   // Called by Update Thread
234   /////////////////////////////////////////////////////////////////////////////////////////////////
235
236   /**
237    * Called by the update-thread when the state is State::INITIALISING.
238    * Calls methods that lock and locks itself so should NOT be called while a scoped-lock is held.
239    */
240   void UpdateInitialising();
241
242   /**
243    * Called by the update thread to attempt to sleep.
244    * @param[in] runUpdate Whether to run another update. If false, then the update-thread will attempt to sleep.
245    */
246   void UpdateTryToSleep( bool runUpdate );
247
248   /**
249    * Called by the update thread to wait while the render-surface is being replaced.
250    * Calls methods that lock and locks itself so should NOT be called while a scoped-lock is held.
251    */
252   void UpdateWaitIfReplacingSurface();
253
254   /**
255    * Called by the update thread to check if we're just resuming.
256    * This will lock the mutex in mUpdateThreadWaitCondition.
257    */
258   inline bool IsUpdateThreadResuming();
259
260   /**
261    * Called by the update thread to check if the update thread should be running.
262    * This will lock the mutex in mUpdateThreadWaitCondition.
263    *
264    * @return True if we're stopping, false otherwise.
265    */
266   inline bool IsUpdateThreadStopping();
267
268   /**
269    * Called by the update thread to check if we've filled all update buffers.
270    * This will lock the mutex in mRenderThreadWaitCondition.
271    *
272    * @return True if all update buffers are full.
273    */
274   inline bool MaximumUpdateAheadOfRenderReached();
275
276   /**
277    * Called by the update thread when we are about to stop.
278    * This will call other functions which lock various conditional wait mutexes.
279    */
280   inline void StopAllThreads();
281
282   /**
283    * Runs the V-Sync Thread.
284    * This will lock the mutex in mVSyncThreadWaitCondition.
285    */
286   inline void RunVSyncThread();
287
288   /**
289    * Pauses the V-Sync Thread.
290    * This will lock the mutex in mVSyncThreadWaitCondition.
291    */
292   inline void PauseVSyncThread();
293
294   /**
295    * Stops the V-Sync Thread.
296    * This will lock the mutex in mVSyncThreadWaitCondition.
297    */
298   inline void StopVSyncThread();
299
300   /**
301    * Stops the Render Thread.
302    * This will lock the mutex in mRenderThreadWaitCondition.
303    */
304   inline void StopRenderThread();
305
306   /////////////////////////////////////////////////////////////////////////////////////////////////
307   // Called by V-Sync Thread
308   /////////////////////////////////////////////////////////////////////////////////////////////////
309
310   /**
311    * Checks if the V-Sync thread should be running.
312    * This will lock the mutex in mVSyncThreadWaitCondition.
313    *
314    * @return true if running, false otherwise.
315    */
316   inline bool IsVSyncThreadRunning();
317
318   /////////////////////////////////////////////////////////////////////////////////////////////////
319   // Called by Render Thread
320   /////////////////////////////////////////////////////////////////////////////////////////////////
321
322   /**
323    * Checks if the Render thread should be running.
324    * This will lock the mutex in mRenderThreadWaitCondition.
325    *
326    * @return true if running, false otherwise.
327    */
328   inline bool IsRenderThreadRunning();
329
330   /**
331    * Checks if the render thread should be replacing the surface
332    * This will lock the mutex in mRenderThreadWaitCondition.
333    *
334    * @return true if the render thread should be replacing the surface, false otherwise.
335    */
336   inline bool IsRenderThreadReplacingSurface();
337
338 private:
339
340   struct State
341   {
342     enum Type
343     {
344       STOPPED,
345       INITIALISING,
346       RUNNING,
347       PAUSED,
348       SLEEPING,
349       REPLACING_SURFACE
350     };
351   };
352
353   FrameTime mFrameTime;                               ///< Frame timer predicts next vsync time
354   TriggerEventInterface& mNotificationTrigger;        ///< Reference to notification event trigger
355   PerformanceInterface* mPerformanceInterface;        ///< The performance logging interface
356   ReplaceSurfaceRequest mReplaceSurfaceRequest;       ///< Holder for a replace surface request
357
358   ConditionalWait mUpdateThreadWaitCondition;         ///< The wait condition for the update-thread.
359   ConditionalWait mRenderThreadWaitCondition;         ///< The wait condition for the render-thread.
360   ConditionalWait mVSyncThreadWaitCondition;          ///< The wait condition for the v-sync-thread.
361   ConditionalWait mEventThreadWaitCondition;          ///< The wait condition for the event-thread.
362
363   const int mMaximumUpdateCount;                      ///< How many frames may be prepared, ahead of the rendering.
364   unsigned int mNumberOfVSyncsPerRender;              ///< How many frames for each update/render cycle.
365
366   unsigned int mTryToSleepCount;                      ///< Count to ensure we don't go to sleep too early
367
368   volatile State::Type mState;                        ///< The current state of synchronisation (set & read by both the event & update threads).
369
370   volatile int mVSyncAheadOfUpdate;                   ///< The number of frames vsync is ahead of update (set & read by both the v-sync & update threads).
371   volatile int mUpdateAheadOfRender;                  ///< The number of frames update is ahead of render (set & read by both the update & render threads).
372   volatile int mNumberOfThreadsStarted;               ///< The number of threads that are initialised and running (set by update, v-sync & render threads, read by event-thread).
373
374   //
375   // NOTE: cannot use booleans as these are used from multiple threads, must use variable with machine word size for atomic read/write
376   //
377
378   volatile unsigned int mUpdateThreadResuming;        ///< Whether the update-thread is resuming.
379
380   volatile unsigned int mVSyncThreadRunning;          ///< Whether the V-Sync thread is running (set by the update-thread, read by v-sync-thread).
381   volatile unsigned int mVSyncThreadStop;             ///< Whether the V-Sync thread should be stopped (set by the update-thread, read by the v-sync-thread).
382
383   volatile unsigned int mRenderThreadStop;            ///< Whether the render-thread should be stopped (set by the update-thread, read by the render-thread).
384   volatile unsigned int mRenderThreadReplacingSurface;///< Whether the render-thread should replace the surface (set by the event & render threads, read by the render-thread).
385
386   volatile unsigned int mEventThreadSurfaceReplaced;  ///< Checked by the event-thread & set by the render-thread when the surface has been replaced (set by the event & render threads, read by the event-thread).
387
388   unsigned int mVSyncThreadInitialised;               ///< Whether the V-Sync thread has been initialised (only used by v-sync-thread).
389   unsigned int mRenderThreadInitialised;              ///< Whether the render-thread has been initialised (only used by the render-thread).
390   unsigned int mRenderThreadSurfaceReplaced;          ///< Whether the render-thread has replaced the surface (only used by render-thread).
391 }; // class ThreadSynchronization
392
393 } // namespace Adaptor
394
395 } // namespace Internal
396
397 } // namespace Dali
398
399 #endif // __DALI_INTERNAL_THREAD_SYNCHRONIZATION_H__