1 #ifndef __DALI_INTERNAL_UPDATE_RENDER_SYNCHRONIZATION_H__
2 #define __DALI_INTERNAL_UPDATE_RENDER_SYNCHRONIZATION_H__
5 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <base/interfaces/performance-interface.h>
23 #include <base/frame-time.h>
27 #include <boost/thread.hpp>
28 #include <boost/thread/condition_variable.hpp>
37 class PlatformAbstraction;
39 } // namespace Integration
47 class AdaptorInternalServices;
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.
56 class UpdateRenderSynchronization
61 * Create an update/render synchronization object.
62 * @param[in] adaptorInterfaces base adaptor interface
63 * @param[in] numberOfVSyncsPerRender The number of frames per render
65 UpdateRenderSynchronization( AdaptorInternalServices& adaptorInterfaces, unsigned int numberOfVSyncsPerRender );
68 * Non virtual destructor. Not intended as base class.
70 ~UpdateRenderSynchronization();
83 * Pause the controller (and threads)
88 * Resume the controller (and threads)
93 * Resume the frame time predictor
95 void ResumeFrameTime();
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.
103 void UpdateRequested();
106 * Update once (even if paused)
108 void UpdateWhilePaused();
111 * Called by Update thread before it runs the update. This is the point where we can pause
113 void UpdateReadyToRun();
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.
122 bool UpdateSyncWithRender( bool& renderNeedsUpdate );
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.
129 void UpdateWaitForAllRenderingToFinish();
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.
135 bool UpdateTryToSleep();
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.
143 void RenderFinished( bool updateRequired );
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.
150 bool RenderSyncWithUpdate();
153 * Called by the render/update threads to wait for a Synchronization
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.
166 bool VSyncNotifierSyncWithUpdateAndRender( bool validSync, unsigned int frameNumber, unsigned int seconds, unsigned int microseconds, unsigned int& numberOfVSyncsPerRender );
169 * Sets the expected minimum frame time interval.
170 * @param[in] interval The interval in microseconds.
172 void SetMinimumFrameTimeInterval( unsigned int timeInterval );
175 * Predicts when the next render time will occur.
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.
181 * @note Should only be called once per tick, from the update thread.
183 void PredictNextSyncTime( float& lastFrameDeltaSeconds,
184 unsigned int& lastSyncTimeMilliseconds,
185 unsigned int& nextSyncTimeMilliseconds );
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.
192 * @return The sync frame number.
194 unsigned int GetFrameNumber() const;
197 * Retrieves the time (in microseconds) at the last VSync
198 * @return The VSync timestamp in microseconds.
200 uint64_t GetTimeMicroseconds();
203 * Set the refresh rate for rendering
204 * @param[in] numberOfVSyncsPerRender The number of vsync frames per render
206 void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender );
210 // Undefined copy constructor.
211 UpdateRenderSynchronization( const UpdateRenderSynchronization& );
213 // Undefined assignment operator.
214 UpdateRenderSynchronization& operator=( const UpdateRenderSynchronization& );
217 * Helper to add a performance marker to the performance server (if its active)
218 * @param type performance marker type
220 void AddPerformanceMarker( PerformanceMarker::MarkerType type );
224 const unsigned int mMaximumUpdateCount; ///< How many frames may be prepared, ahead of the rendering.
226 unsigned int mNumberOfVSyncsPerRender; ///< How many frames for each update/render cycle.
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
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
248 FrameTime mFrameTime; ///< Frame timer predicts next vsync time
249 PerformanceInterface* mPerformanceInterface; ///< The performance logging interface
251 }; // class UpdateRenderSynchronization
253 } // namespace Adaptor
255 } // namespace Internal
259 #endif // __DALI_INTERNAL_UPDATE_RENDER_SYNCHRONIZATION_H__