make frametime state flags properly atomic read/write
[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 #include <base/frame-time.h>
24
25 // EXTERNAL INCLUDES
26 #include <stdint.h>
27 #include <boost/thread.hpp>
28 #include <boost/thread/condition_variable.hpp>
29
30 namespace Dali
31 {
32
33 namespace Integration
34 {
35
36 class Core;
37 class PlatformAbstraction;
38
39 } // namespace Integration
40
41 namespace Internal
42 {
43
44 namespace Adaptor
45 {
46
47 class AdaptorInternalServices;
48
49 /**
50  * This object is used to synchronize the update, render and vsync threads.
51  * The Core::GetMaximumUpdateCount() method determines how many frames may be prepared, ahead of the rendering.
52  * 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.
53  * However the Core::Update() for frame N+2 may not be called, until the Core::Render() method for frame N has returned.
54  *
55  */
56 class UpdateRenderSynchronization
57 {
58 public:
59
60   /**
61    * Create an update/render synchronization object.
62    * @param[in] adaptorInterfaces base adaptor interface
63    * @param[in] numberOfVSyncsPerRender The number of frames per render
64   */
65   UpdateRenderSynchronization( AdaptorInternalServices& adaptorInterfaces, unsigned int numberOfVSyncsPerRender );
66
67   /**
68    * Non virtual destructor. Not intended as base class.
69    */
70   ~UpdateRenderSynchronization();
71
72   /**
73    * Start the threads
74    */
75   void Start();
76
77   /**
78    * Stop the threads
79    */
80   void Stop();
81
82   /**
83    * Pause the controller (and threads)
84    */
85   void Pause();
86
87   /**
88    * Resume the controller (and threads)
89    */
90   void Resume();
91
92   /**
93    * Resume the frame time predictor
94    */
95   void ResumeFrameTime();
96
97   /**
98    * Wake update thread if sleeping. If the update thread is not sleeping
99    * this becomes a noop.
100    * Called when an update is requested by Core.
101    * i.e. when a batch of messages have been queued for the next update.
102    */
103   void UpdateRequested();
104
105   /**
106    * Update once (even if paused)
107    */
108   void UpdateWhilePaused();
109
110   /**
111    * Called by Update thread before it runs the update. This is the point where we can pause
112    */
113   void UpdateReadyToRun();
114
115   /**
116    * Called after an update has completed, to inform render-thread a buffer is ready to render.
117    * The function also waits for a free buffer to become available before returning.
118    * @pre Called by update thread only.
119    * @param[out] renderNeedsUpdate Whether the render task requires another update.
120    * @return True if updating should continue, false if the update-thread should quit.
121    */
122   bool UpdateSyncWithRender( bool& renderNeedsUpdate );
123
124   /**
125    * Called by update thread to wait for all rendering to finish.
126    * Used by update to check the status of the final render before pausing.
127    * @pre Called by update thread only.
128    */
129   void UpdateWaitForAllRenderingToFinish();
130
131   /**
132    * Try block the update-thread when there's nothing to update.
133    * @return True if updating should continue, false if the update-thread should quit.
134    */
135   bool UpdateTryToSleep();
136
137   /**
138    * Called by the render thread after it renders a frame.
139    * Used to notify the update-thread that a frame has been rendered.
140    * @pre Called by render thread only.
141    * @param updateRequired Whether a further update is required.
142    */
143   void RenderFinished( bool updateRequired );
144
145   /**
146    * Called by the render-thread to wait for a buffer to read from and then render.
147    * @pre Called by render thread only.
148    * @return True if rendering should continue, false if the render-thread should quit.
149    */
150   bool RenderSyncWithUpdate();
151
152   /**
153    * Called by the render/update threads to wait for a Synchronization
154    */
155   void WaitSync();
156
157   /**
158    * Called by the VSync notifier thread so it can sleep if Update/Render threads are sleeping/paused
159    * @param[in] validSync True if the sync was valid (@see VSyncMonitor::DoSync)
160    * @param[in] frameNumber The current frame number
161    * @param[in] seconds The current time
162    * @param[in] microseconds The current time
163    * @param[out] numberOfVSyncsPerRender The number of frames per render.
164    * @return true if VSync monitoring/notifications should continue.
165    */
166   bool VSyncNotifierSyncWithUpdateAndRender( bool validSync, unsigned int frameNumber, unsigned int seconds, unsigned int microseconds, unsigned int& numberOfVSyncsPerRender );
167
168   /**
169    * Sets the expected minimum frame time interval.
170    * @param[in]  interval  The interval in microseconds.
171    */
172   void SetMinimumFrameTimeInterval( unsigned int timeInterval );
173
174   /**
175    * Predicts when the next render time will occur.
176    *
177    * @param[out]  lastFrameDeltaSeconds      The delta, in seconds (with float precision), between the last two renders.
178    * @param[out]  lastSyncTimeMilliseconds  The time, in milliseconds, of the last Sync.
179    * @param[out]  nextSyncTimeMilliseconds  The estimated time, in milliseconds, at the next Sync.
180    *
181    * @note Should only be called once per tick, from the update thread.
182    */
183   void PredictNextSyncTime( float& lastFrameDeltaSeconds,
184                             unsigned int& lastSyncTimeMilliseconds,
185                             unsigned int& nextSyncTimeMilliseconds );
186
187   /**
188    * Retrieves the last sync frame number.
189    * This is a count of the number of synchronised update/render
190    * frames, not a count of hardware VSync frames.
191    *
192    * @return The sync frame number.
193    */
194   unsigned int GetFrameNumber() const;
195
196   /**
197    * Retrieves the time (in microseconds) at the last VSync
198    * @return The VSync timestamp in microseconds.
199    */
200   uint64_t GetTimeMicroseconds();
201
202   /**
203    * Set the refresh rate for rendering
204    * @param[in] numberOfVSyncsPerRender The number of vsync frames per render
205    */
206   void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender );
207
208 private:
209
210   // Undefined copy constructor.
211   UpdateRenderSynchronization( const UpdateRenderSynchronization& );
212
213   // Undefined assignment operator.
214   UpdateRenderSynchronization& operator=( const UpdateRenderSynchronization& );
215
216   /**
217    * Helper to add a performance marker to the performance server (if its active)
218    * @param type performance marker type
219    */
220   void AddPerformanceMarker( PerformanceMarker::MarkerType type );
221
222 private:
223
224   const unsigned int mMaximumUpdateCount;             ///< How many frames may be prepared, ahead of the rendering.
225
226   unsigned int mNumberOfVSyncsPerRender;              ///< How many frames for each update/render cycle.
227
228   volatile unsigned int mUpdateReadyCount;            ///< Incremented after each update, decremented after each render (protected by mMutex)
229   // ARM CPUs perform aligned 32 bit read/writes atomically, so the following variables do not require mutex protection on modification
230   volatile int mRunning;                              ///< Used during UpdateThread::Stop() to exit the update & render loops
231   volatile int mUpdateRequired;                       ///< Used to inform the update thread, that render requires another update
232   volatile int mPaused;                               ///< The paused flag
233   volatile int mUpdateRequested;                      ///< An update has been requested
234   volatile int mAllowUpdateWhilePaused;               ///< whether to allow (one) update while paused
235   volatile int mVSyncSleep;                           ///< Set true when the VSync thread should sleep
236   volatile unsigned int mSyncFrameNumber;            ///< Frame number of latest Sync
237   volatile unsigned int mSyncSeconds;                ///< Timestamp (seconds) of latest Sync
238   volatile unsigned int mSyncMicroseconds;           ///< Timestamp (microseconds) of latest Sync
239
240   boost::mutex mMutex;                                ///< This mutex must be locked before reading/writing mUpdateReadyCount
241   boost::condition_variable mUpdateFinishedCondition; ///< The render thread waits for this condition
242   boost::condition_variable mUpdateSleepCondition;    ///< The update thread waits for this condition when sleeping
243   boost::condition_variable mRenderFinishedCondition; ///< The update thread waits for this condition
244   boost::condition_variable mVSyncReceivedCondition;  ///< The render thread waits on this condition
245   boost::condition_variable mVSyncSleepCondition;     ///< The vsync thread waits for this condition
246   boost::condition_variable mPausedCondition;         ///< The controller waits for this condition while paused
247
248   FrameTime mFrameTime;                               ///< Frame timer predicts next vsync time
249   PerformanceInterface* mPerformanceInterface;        ///< The performance logging interface
250
251 }; // class UpdateRenderSynchronization
252
253 } // namespace Adaptor
254
255 } // namespace Internal
256
257 } // namespace Dali
258
259 #endif // __DALI_INTERNAL_UPDATE_RENDER_SYNCHRONIZATION_H__