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 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 <boost/thread.hpp>
25 #include <base/interfaces/egl-interface.h>
26 #include <internal/common/render-surface-impl.h> // needed for Dali::Internal::Adaptor::RenderSurface
43 class AdaptorInternalServices;
45 class UpdateRenderSynchronization;
46 class EglFactoryInterface;
47 class EnvironmentOptions;
50 * The render-thread is responsible for calling Core::Render() after each update.
56 * Create the render-thread; this will not do anything until Start() is called.
57 * @param[in] sync update-render synchronization object
58 * @param[in] adaptorInterfaces base adaptor interface
59 * @param[in] environmentOptions environment options
62 RenderThread( UpdateRenderSynchronization& sync,
63 AdaptorInternalServices& adaptorInterfaces,
64 const EnvironmentOptions& environmentOptions );
69 virtual ~RenderThread();
74 * Starts the render-thread
79 * Stops the render-thread
84 * Replaces the rendering surface. This method returns immediately
85 * You can call WaitForSurfaceReplaceComplete to block until the
86 * replace is completed in render thread. Note, you need to make sure
87 * that render thread is actually running!!!
89 void ReplaceSurface( RenderSurface* surface );
92 * Blocks until surface replace has been completed
94 void WaitForSurfaceReplaceComplete();
97 * Sets the EGL VSync mode synchronisation with the display.
98 * @param syncMode to use
100 void SetVSyncMode( EglInterface::SyncMode syncMode );
103 * Offscreen was posted to onscreen
107 private: // Render thread side helpers
110 * This method is used by the Render thread for rendering the Core to the screen.
111 * Called from render thread
112 * @return true, if the thread finishes properly.
118 * Called from render thread
120 void InitializeEgl();
123 * Check if display has events
124 * Called from render thread
126 void ConsumeEvents();
129 * Check if main thread posted updates
130 * Called from render thread
132 void CheckForUpdates();
135 * Changes the rendering surface
136 * Used for replacing pixmaps due to resizing
137 * Called from render thread
138 * @param newSurface to use
140 void ChangeSurface( RenderSurface* newSurface );
143 * Notify the main thread that surface has really been changed
145 void NotifySurfaceChangeCompleted();
149 * Called from render thread
154 * Called before core renders the scene
155 * Called from render thread
156 * @return true if successful and Core::Render should be called.
161 * Called after core has rendered the scene
162 * Called from render thread
163 * @param[in] timeDelta Time since PostRender was last called in microseconds
165 void PostRender( unsigned int timeDelta );
169 UpdateRenderSynchronization& mUpdateRenderSync; ///< Used to synchronize the update & render threads
170 Dali::Integration::Core& mCore; ///< Dali core reference
171 Integration::GlAbstraction& mGLES; ///< GL abstraction rerefence
172 EglFactoryInterface* mEglFactory; ///< Factory class to create EGL implementation
173 EglInterface* mEGL; ///< Interface to EGL implementation
175 boost::thread* mThread; ///< render thread
176 bool mUsingPixmap; ///< whether we're using a pixmap or a window
177 bool mSurfaceReplacing; ///< whether the surface is replacing. If true, need to notify surface changing after rendering
180 * Structure to hold values that are set by main thread and read in render thread
181 * There is two copies of this data to avoid locking and prevent concurrent access
186 * Default constructor to reset values
189 : replaceSurface( false ),
190 syncMode( EglInterface::FULL_SYNC ),
195 volatile int replaceSurface; ///< whether the surface needs replacing
196 EglInterface::SyncMode syncMode; ///< sync mode for EGL
197 RenderSurface* surface; ///< Current surface
200 RenderData mCurrent; ///< Current values, must not be used from main thread
201 RenderData mNewValues; ///< New values, sent from main thread to render thread
202 boost::mutex mThreadDataLock; ///< mutex to lock values while reading them into render thread
203 volatile int mNewDataAvailable; ///< atomic flag to notify the render thread that there's new data
206 * Helper class for sending message to render thread
208 class SendMessageGuard
212 * Constructor, sets the lock
214 SendMessageGuard( RenderThread& parent )
215 : mLock( parent.mThreadDataLock ), mFlag( &parent.mNewDataAvailable )
216 { // Nothing to do, unique lock will lock automatically and unlock when destructed
219 * Destructor, releases lock and sets flag
223 // set the flag to tell render thread there are new values, ignoring the return value here
224 (void)__sync_or_and_fetch( mFlag, 1 );
228 boost::unique_lock< boost::mutex > mLock;
232 // sync for waiting for surface change
233 boost::mutex mSurfaceChangedMutex; ///< mutex to lock during surface replacing
234 boost::condition_variable mSurfaceChangedNotify; ///< condition to notify main thread that surface has been changed
235 bool mSurfaceReplaceCompleted;///< true, while render thread is running and needs to wait for pixmap syncs
236 const EnvironmentOptions& mEnvironmentOptions; ///< Environment options
240 } // namespace Adaptor
242 } // namespace Internal
246 #endif // __DALI_INTERNAL_RENDER_THREAD_H__