Uses TextArray new type definition.
[platform/core/uifw/dali-adaptor.git] / adaptors / base / update-render-synchronization.h
1 #ifndef __DALI_INTERNAL_UPDATE_RENDER_SYNCHRONIZATION_H__
2 #define __DALI_INTERNAL_UPDATE_RENDER_SYNCHRONIZATION_H__
3
4 /*
5  * Copyright (c) 2014 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 <base/interfaces/performance-interface.h>
23
24 // EXTERNAL INCLUDES
25 #include <stdint.h>
26 #include <boost/thread.hpp>
27 #include <boost/thread/condition_variable.hpp>
28
29 namespace Dali
30 {
31
32 namespace Integration
33 {
34
35 class Core;
36 class PlatformAbstraction;
37
38 } // namespace Integration
39
40 namespace Internal
41 {
42
43 namespace Adaptor
44 {
45
46 class AdaptorInternalServices;
47
48 /**
49  * This object is used to synchronize the update, render and vsync threads.
50  * The Core::GetMaximumUpdateCount() method determines how many frames may be prepared, ahead of the rendering.
51  * 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.
52  * However the Core::Update() for frame N+2 may not be called, until the Core::Render() method for frame N has returned.
53  */
54 class UpdateRenderSynchronization
55 {
56 public:
57
58   /**
59    * Create an update/render synchronization object.
60    * @param[in] adaptorInterfaces base adaptor interface
61   */
62   UpdateRenderSynchronization( AdaptorInternalServices& adaptorInterfaces );
63
64   /**
65    * Non virtual destructor. Not inteded as base class.
66    */
67   ~UpdateRenderSynchronization();
68
69   /**
70    * Start the threads
71    */
72   void Start();
73
74   /**
75    * Stop the threads
76    */
77   void Stop();
78
79   /**
80    * Pause the controller (and threads)
81    */
82   void Pause();
83
84   /**
85    * Resume the controller (and threads)
86    */
87   void Resume();
88
89   /**
90    * Wake update thread if sleeping. If the update thread is not sleeping
91    * this becomes a noop.
92    * Called when an update is requested by Core.
93    * i.e. when a batch of messages have been queued for the next update.
94    */
95   void UpdateRequested();
96
97   /**
98    * Update once (even if paused)
99    */
100   void UpdateWhilePaused();
101
102   /**
103    * Called by Update thread before it runs the update. This is the point where we can pause
104    */
105   void UpdateReadyToRun();
106
107   /**
108    * Called after an update has completed, to inform render-thread a buffer is ready to render.
109    * The function also waits for a free buffer to become available before returning.
110    * @pre Called by update thread only.
111    * @param[out] renderNeedsUpdate Whether the render task requires another update.
112    * @return True if updating should continue, false if the update-thread should quit.
113    */
114   bool UpdateSyncWithRender( bool& renderNeedsUpdate );
115
116   /**
117    * Called by update thread to wait for all rendering to finish.
118    * Used by update to check the status of the final render before pausing.
119    * @pre Called by update thread only.
120    */
121   void UpdateWaitForAllRenderingToFinish();
122
123   /**
124    * Try block the update-thread when there's nothing to update.
125    * @return True if updating should continue, false if the update-thread should quit.
126    */
127   bool UpdateTryToSleep();
128
129   /**
130    * Called by the render thread after it renders a frame.
131    * Used to notify the update-thread that a frame has been rendered.
132    * @pre Called by render thread only.
133    * @param updateRequired Whether a further update is required.
134    */
135   void RenderFinished( bool updateRequired );
136
137   /**
138    * Called by the render-thread to wait for a buffer to read from and then render.
139    * @pre Called by render thread only.
140    * @return True if rendering should continue, false if the render-thread should quit.
141    */
142   bool RenderSyncWithUpdate();
143
144   /**
145    * Called by the render/update threads to wait for a VSync.
146    */
147   void WaitVSync();
148
149   /**
150    * Called by the VSync notifier thread so it can sleep if Update/Render threads are sleeping/paused
151    * @return true if VSync monitoring/notifications should continue.
152    */
153   bool VSyncNotifierSyncWithUpdateAndRender( unsigned int frameNumber, unsigned int seconds, unsigned int microseconds );
154
155   /**
156    * Retrieves the last VSync frame number
157    * @return The VSync frame number.
158    */
159   unsigned int GetFrameNumber() const;
160
161   /**
162    * Retrieves the time (in microseconds) at the last VSync
163    * @return The VSync timestamp in microseconds.
164    */
165   uint64_t GetTimeMicroseconds();
166
167 private:
168
169   // Undefined copy constructor.
170   UpdateRenderSynchronization( const UpdateRenderSynchronization& );
171
172   // Undefined assignment operator.
173   UpdateRenderSynchronization& operator=( const UpdateRenderSynchronization& );
174
175   /**
176    * Helper to add a performance marker to the performance server (if its active)
177    * @param type performance marker type
178    */
179   void AddPerformanceMarker( PerformanceMarker::MarkerType type );
180
181 private:
182
183   const unsigned int mMaximumUpdateCount;             ///< How many frames may be prepared, ahead of the rendering.
184   volatile unsigned int mUpdateReadyCount;            ///< Incremented after each update, decremented after each render (protected by mMutex)
185   // ARM CPUs perform aligned 32 bit read/writes atomically, so the following variables do not require mutex protection on modification
186   volatile int mRunning;                              ///< Used during UpdateThread::Stop() to exit the update & render loops
187   volatile int mUpdateRequired;                       ///< Used to inform the update thread, that render requires another update
188   volatile int mPaused;                               ///< The paused flag
189   volatile int mUpdateRequested;                      ///< An update has been requested
190   volatile int mAllowUpdateWhilePaused;               ///< whether to allow (one) update while paused
191   volatile int mVSyncSleep;                           ///< Set true when the VSync thread should sleep
192   volatile unsigned int mVSyncFrameNumber;            ///< Frame number of latest VSync
193   volatile unsigned int mVSyncSeconds;                ///< Timestamp (seconds) of latest VSync
194   volatile unsigned int mVSyncMicroseconds;           ///< Timestamp (microseconds) of latest VSync
195
196   boost::mutex mMutex;                                ///< This mutex must be locked before reading/writing mUpdateReadyCount
197   boost::condition_variable mUpdateFinishedCondition; ///< The render thread waits for this condition
198   boost::condition_variable mUpdateSleepCondition;    ///< The update thread waits for this condition when sleeping
199   boost::condition_variable mRenderFinishedCondition; ///< The update thread waits for this condition
200   boost::condition_variable mVSyncReceivedCondition;  ///< The render thread waits on this condition
201   boost::condition_variable mVSyncSleepCondition;     ///< The vsync thread waits for this condition
202   boost::condition_variable mPausedCondition;         ///< The controller waits for this condition while paused
203
204   Dali::Integration::Core&            mCore;                ///< Dali core reference
205   PerformanceInterface*               mPerformanceInterface;///< The performance logging interface
206
207 }; // class UpdateRenderSynchronization
208
209 } // namespace Adaptor
210
211 } // namespace Internal
212
213 } // namespace Dali
214
215 #endif // __DALI_INTERNAL_UPDATE_RENDER_SYNCHRONIZATION_H__