1 #ifndef __DALI_INTERNAL_RENDER_THREAD_H__
2 #define __DALI_INTERNAL_RENDER_THREAD_H__
5 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
7 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
21 #include <boost/thread.hpp>
24 #include <base/interfaces/egl-interface.h>
25 #include <internal/common/render-surface-impl.h> // needed for Dali::Internal::Adaptor::RenderSurface
42 class AdaptorInternalServices;
44 class UpdateRenderSynchronization;
45 class EglFactoryInterface;
49 * The render-thread is responsible for calling Core::Render() after each update.
55 * Create the render-thread; this will not do anything until Start() is called.
56 * @param[in] sync update-render synchronization object
57 * @param[in] adaptorInterfaces base adaptor interface
58 * @param[in] logOptions log options
61 RenderThread( UpdateRenderSynchronization& sync,
62 AdaptorInternalServices& adaptorInterfaces,
63 const LogOptions& logOptions );
68 virtual ~RenderThread();
73 * Starts the render-thread
78 * Stops the render-thread
83 * Replaces the rendering surface. This method returns immediately
84 * You can call WaitForSurfaceReplaceComplete to block until the
85 * replace is completed in render thread. Note, you need to make sure
86 * that render thread is actually running!!!
88 void ReplaceSurface( RenderSurface* surface );
91 * Blocks until surface replace has been completed
93 void WaitForSurfaceReplaceComplete();
96 * Sets the EGL VSync mode synchronisation with the display.
97 * @param syncMode to use
99 void SetVSyncMode( EglInterface::SyncMode syncMode );
102 * Offscreen was posted to onscreen
106 private: // Render thread side helpers
109 * This method is used by the Render thread for rendering the Core to the screen.
110 * Called from render thread
111 * @return true, if the thread finishes properly.
117 * Called from render thread
119 void InitializeEgl();
122 * Check if display has events
123 * Called from render thread
125 void ConsumeEvents();
128 * Check if main thread posted updates
129 * Called from render thread
131 void CheckForUpdates();
134 * Changes the rendering surface
135 * Used for replacing pixmaps due to resizing
136 * Called from render thread
137 * @param newSurface to use
139 void ChangeSurface( RenderSurface* newSurface );
142 * Notify the main thread that surface has really been changed
144 void NotifySurfaceChangeCompleted();
148 * Called from render thread
153 * Called before core renders the scene
154 * Called from render thread
155 * @return true if successful and Core::Render should be called.
160 * Called after core has rendered the scene
161 * Called from render thread
162 * @param[in] timeDelta Time since PostRender was last called in microseconds
164 void PostRender( unsigned int timeDelta );
168 UpdateRenderSynchronization& mUpdateRenderSync; ///< Used to synchronize the update & render threads
169 Dali::Integration::Core& mCore; ///< Dali core reference
170 Integration::GlAbstraction& mGLES; ///< GL abstraction rerefence
171 EglFactoryInterface* mEglFactory; ///< Factory class to create EGL implementation
172 EglInterface* mEGL; ///< Interface to EGL implementation
174 boost::thread* mThread; ///< render thread
175 bool mUsingPixmap; ///< whether we're using a pixmap or a window
176 bool mSurfaceReplacing; ///< whether the surface is replacing. If true, need to notify surface changing after rendering
179 * Structure to hold values that are set by main thread and read in render thread
180 * There is two copies of this data to avoid locking and prevent concurrent access
185 * Default constructor to reset values
188 : replaceSurface( false ),
189 syncMode( EglInterface::FULL_SYNC ),
194 volatile int replaceSurface; ///< whether the surface needs replacing
195 EglInterface::SyncMode syncMode; ///< sync mode for EGL
196 RenderSurface* surface; ///< Current surface
199 RenderData mCurrent; ///< Current values, must not be used from main thread
200 RenderData mNewValues; ///< New values, sent from main thread to render thread
201 boost::mutex mThreadDataLock; ///< mutex to lock values while reading them into render thread
202 volatile int mNewDataAvailable; ///< atomic flag to notify the render thread that there's new data
205 * Helper class for sending message to render thread
207 class SendMessageGuard
211 * Constructor, sets the lock
213 SendMessageGuard( RenderThread& parent )
214 : mLock( parent.mThreadDataLock ), mFlag( &parent.mNewDataAvailable )
215 { // Nothing to do, unique lock will lock automatically and unlock when destructed
218 * Destructor, releases lock and sets flag
222 // set the flag to tell render thread there are new values, ignoring the return value here
223 (void)__sync_or_and_fetch( mFlag, 1 );
227 boost::unique_lock< boost::mutex > mLock;
231 // sync for waiting offscreen flushed to onscreen
232 boost::mutex mPixmapSyncMutex; ///< mutex to lock during waiting sync
233 boost::condition_variable mPixmapSyncNotify; ///< condition to notify main thread that pixmap was flushed to onscreen
234 bool mPixmapSyncReceived; ///< true, when a pixmap sync has occurred, (cleared after reading)
235 bool mPixmapSyncRunning; ///< true, while render thread is running and needs to wait for pixmap syncs
236 unsigned long mCurrentMicroSec;
238 // sync for waiting for surface change
239 boost::mutex mSurfaceChangedMutex; ///< mutex to lock during surface replacing
240 boost::condition_variable mSurfaceChangedNotify; ///< condition to notify main thread that surface has been changed
241 bool mSurfaceReplaceCompleted;///< true, while render thread is running and needs to wait for pixmap syncs
242 const LogOptions& mLogOptions; ///< Log options
246 } // namespace Adaptor
248 } // namespace Internal
252 #endif // __DALI_INTERNAL_RENDER_THREAD_H__