Changes to support stereoscopic 3D
[platform/core/uifw/dali-core.git] / dali / integration-api / core.h
1 #ifndef __DALI_INTEGRATION_CORE_H__
2 #define __DALI_INTEGRATION_CORE_H__
3
4 //
5 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
6 //
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
10 //
11 //     http://floralicense.org/license/
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 // EXTERNAL INCLUDES
21 #include <dali/public-api/common/dali-common.h>
22 #include <dali/public-api/common/view-mode.h>
23
24 namespace Dali
25 {
26
27 namespace Internal
28 {
29 class Core;
30 }
31
32 namespace Integration
33 {
34
35 class Core;
36 class GestureManager;
37 class GlAbstraction;
38 class GlSyncAbstraction;
39 class PlatformAbstraction;
40 class RenderController;
41 class SystemOverlay;
42 struct Event;
43 struct TouchData;
44
45 /**
46  * The reasons why further updates are required.
47  */
48 namespace KeepUpdating DALI_IMPORT_API
49 {
50   extern const unsigned int NOT_REQUESTED; ///< Zero means that no further updates are required
51
52   // Bit-field values
53   extern const unsigned int STAGE_KEEP_RENDERING;   ///< 0x01 - Stage::KeepRendering() is being used
54   extern const unsigned int INCOMING_MESSAGES;      ///< 0x02 - Event-thread is sending messages to update-thread
55   extern const unsigned int ANIMATIONS_RUNNING;     ///< 0x04 - Animations are ongoing
56   extern const unsigned int DYNAMICS_CHANGED;       ///< 0x08 - A dynamics simulation is running
57   extern const unsigned int LOADING_RESOURCES;      ///< 0x10 - Resources are being loaded
58   extern const unsigned int NOTIFICATIONS_PENDING;  ///< 0x20 - Notifications are pending for the event-thread
59   extern const unsigned int MONITORING_PERFORMANCE; ///< 0x40 - The --enable-performance-monitor option is being used
60   extern const unsigned int RENDER_TASK_SYNC;       ///< 0x80 - A render task is waiting for render sync
61 };
62
63 /**
64  * The status of the Core::Update operation.
65  */
66 class DALI_IMPORT_API UpdateStatus
67 {
68 public:
69
70   /**
71    * Constructor
72    */
73   UpdateStatus()
74   : keepUpdating(false),
75     needsNotification(false),
76     secondsFromLastFrame( 0.0f )
77   {
78   }
79
80 public:
81
82   /**
83    * Query whether the Core has further frames to update & render e.g. when animations are ongoing.
84    * @return A bitmask of KeepUpdating values
85    */
86   unsigned int KeepUpdating() { return keepUpdating; }
87
88   /**
89    * Query whether the Core requires an Notification event.
90    * This should be sent through the same mechanism (e.g. event loop) as input events.
91    * @return True if an Notification event should be sent.
92    */
93   bool NeedsNotification() { return needsNotification; }
94
95   /**
96    * This method is provided so that FPS can be easily calculated with a release version
97    * of Core.
98    * @return the seconds from last frame as float
99    */
100   float SecondsFromLastFrame() { return secondsFromLastFrame; }
101
102 public:
103
104   unsigned int keepUpdating; ///< A bitmask of KeepUpdating values
105   bool needsNotification;
106   float secondsFromLastFrame;
107 };
108
109 /**
110  * The status of the Core::Render operation.
111  */
112 class DALI_IMPORT_API RenderStatus
113 {
114 public:
115
116   /**
117    * Constructor
118    */
119   RenderStatus()
120   : needsUpdate(false),
121     hasRendered(false)
122   {
123   }
124
125   /**
126    * Set whether update needs to run following a render.
127    * This might be because render has sent messages to update, or it has
128    * some textures to upload over several frames.
129    */
130   void SetNeedsUpdate(bool updateRequired) { needsUpdate = updateRequired; }
131
132   /**
133    * Query the update status following rendering of a frame.
134    * @return true if update should run.
135    */
136   bool NeedsUpdate() { return needsUpdate; }
137
138   /**
139    * Set whether there were new render instructions.
140    */
141   void SetHasRendered(bool rendered) { hasRendered = rendered; }
142
143   /**
144    * Query whether there were new render instructions.
145    * @return true if there were render instructions
146    */
147   bool HasRendered() { return hasRendered; }
148
149 private:
150
151   bool needsUpdate;
152   bool hasRendered;
153 };
154
155 /**
156  * Integration::Core is used for integration with the native windowing system.
157  * The following integration tasks must be completed:
158  *
159  * 1) Handle GL context creation, and notify the Core when this occurs.
160  *
161  * 2) Provide suspend/resume behaviour (see below for more details).
162  *
163  * 3) Run an event loop, for passing events to the Core e.g. multi-touch input events.
164  * Notification events should be sent after a frame is updated (see UpdateStatus).
165  *
166  * 4) Run a rendering loop, instructing the Core to render each frame.
167  * A separate rendering thread is recommended; see multi-threading options below.
168  *
169  * 5) Provide an implementation of the PlatformAbstraction interface, used to access platform specific services.
170  *
171  * 6) Provide an implementation of the GlAbstraction interface, used to access OpenGL services.
172  *
173  * 7) Provide an implementation of the GestureManager interface, used to register gestures provided by the platform.
174  *
175  * Suspend/Resume behaviour:
176  *
177  * The Core has no knowledge of the application lifecycle, but can be suspended.
178  * In the suspended state, input events will not be processed, and animations will not progress any further.
179  * The Core can still render in the suspended state; the same frame will be produced each time.
180  *
181  * Multi-threading notes:
182  *
183  * The Dali API methods are not reentrant.  If you access the API from multiple threads simultaneously, then the results
184  * are undefined. This means that your application might segfault, or behave unpredictably.
185  *
186  * Rendering strategies:
187  *
188  * 1) Single-threaded. Call every Core method from the same thread. Event handling and rendering will occur in the same thread.
189  * This is not recommended, since processing input (slowly) can affect the smooth flow of animations.
190  *
191  * 2) Multi-threaded. The Core update & render operations can be processed in separate threads.
192  * See the method descriptions in Core to see which thread they should be called from.
193  * This is the recommended option, so that input processing will not affect the smoothness of animations.
194  * Note that the rendering thread must be halted, before destroying the GL context.
195  */
196 class DALI_IMPORT_API Core
197 {
198 public:
199
200   /**
201    * Create a new Core.
202    * This object is used for integration with the native windowing system.
203    * @param[in] renderController The interface to an object which controls rendering.
204    * @param[in] platformAbstraction The interface providing platform specific services.
205    * @param[in] glAbstraction The interface providing OpenGL services.
206    * @param[in] glSyncAbstraction The interface providing OpenGL sync objects.
207    * @param[in] gestureManager The interface providing gesture manager services.
208    * @return A newly allocated Core.
209    */
210   static Core* New(RenderController& renderController,
211                    PlatformAbstraction& platformAbstraction,
212                    GlAbstraction& glAbstraction,
213                    GlSyncAbstraction& glSyncAbstraction,
214                    GestureManager& gestureManager);
215
216   /**
217    * Non-virtual destructor. Core is not intended as a base class.
218    */
219   ~Core();
220
221   // GL Context Lifecycle
222
223   /**
224    * Notify the Core that the GL context has been created.
225    * The context must be created before the Core can render.
226    * Multi-threading note: this method should be called from the rendering thread only
227    * @post The Core is aware of the GL context.
228    */
229   void ContextCreated();
230
231   /**
232    * Notify the Core that that GL context is about to be destroyed.
233    * The Core will free any previously allocated GL resources.
234    * Multi-threading note: this method should be called from the rendering thread only
235    * @post The Core is unaware of any GL context.
236    */
237   void ContextToBeDestroyed();
238
239   /**
240    * Notify the Core that the GL surface has been resized.
241    * This should be done at least once i.e. after the first call to ContextCreated().
242    * The Core will use the surface size for camera calculations, and to set the GL viewport.
243    * Multi-threading note: this method should be called from the main thread
244    * @param[in] width The new surface width.
245    * @param[in] height The new surface height.
246    */
247   void SurfaceResized(unsigned int width, unsigned int height);
248
249   // Core setters
250
251   /**
252    * Notify the Core about the display's DPI values.
253    * This should be done after the display is initialized and a Core instance is created.
254    * The Core will use the DPI values for font rendering.
255    * Multi-threading note: this method should be called from the main thread
256    * @param[in] dpiHorizontal Horizontal DPI value.
257    * @param[in] dpiVertical   Vertical DPI value.
258    */
259   void SetDpi(unsigned int dpiHorizontal, unsigned int dpiVertical);
260
261   /**
262    * Sets the expected interval between frames used to predict future intervals and the time when the
263    * next render will take place.
264    *
265    * This is the minimum interval that Core should expect. Core will adapt the predicted interval
266    * accordingly if the expected interval is constantly not met (but will not drop it below this
267    * amount).
268    *
269    * The value provided should be in microseconds.
270    *
271    * @param[in]  interval  The minimum interval between frames (in microseconds).
272    *
273    * Multi-threading note: this method should be called from the render thread
274    */
275   void SetMinimumFrameTimeInterval(unsigned int interval);
276
277   // Core Lifecycle
278
279   /**
280    * Put Core into the suspended state.
281    * Any ongoing event processing will be cancelled, for example multi-touch sequences.
282    * The core expects the system has suspended us. Animation time will continue during the suspended
283    * state.
284    * Multi-threading note: this method should be called from the main thread
285    * @post The Core is in the suspended state.
286    */
287   void Suspend();
288
289   /**
290    * Resume the Core from the suspended state.
291    * At the first update, the elapsed time passed to the animations will be equal to the time spent
292    * suspended.
293    * Multi-threading note: this method should be called from the main thread
294    * @post The Core is not in the suspended state.
295    */
296   void Resume();
297
298   /**
299    * Queue an event with Core.
300    * Pre-processing of events may be benificial e.g. a series of motion events could be throttled, so that only the last event is queued.
301    * Multi-threading note: this method should be called from the main thread.
302    * @param[in] event The new event.
303    */
304   void QueueEvent(const Event& event);
305
306   /**
307    * Process the events queued with QueueEvent().
308    * Multi-threading note: this method should be called from the main thread.
309    * @pre ProcessEvents should not be called during ProcessEvents.
310    */
311   void ProcessEvents();
312
313   /**
314    * Update external raw touch data in core.
315    * The core will use the touch data to generate Dali Touch/Gesture events for applications to use
316    * in the update thread.
317    * @param[in] touch The raw touch data.
318    * @note This can be called from either the event thread OR a dedicated touch thread.
319    */
320   void UpdateTouchData(const TouchData& touch);
321
322   /**
323    * The Core::Update() method prepares a frame for rendering. This method determines how many frames
324    * may be prepared, ahead of the rendering.
325    * For example if the maximum update count is 2, then Core::Update() for frame N+1 may be processed
326    * whilst frame N is being rendered. However the Core::Update() for frame N+2 may not be called, until
327    * the Core::Render() method for frame N has returned.
328    * @return The maximum update count (>= 1).
329    */
330   unsigned int GetMaximumUpdateCount() const;
331
332   /**
333    * Update the scene for the next frame. This method must be called before each frame is rendered.
334    * Multi-threading notes: this method should be called from a dedicated update-thread.
335    * The update for frame N+1 may be processed whilst frame N is being rendered.
336    * However the update-thread must wait until frame N has been rendered, before processing frame N+2.
337    * After this method returns, messages may be queued internally for the main thread.
338    * In order to process these messages, a notification is sent via the main thread's event loop.
339    * @param[out] status showing whether further updates are required. This also shows
340    * whether a Notification event should be sent, regardless of whether the multi-threading is used.
341    */
342   void Update( UpdateStatus& status );
343
344   /**
345    * Render the next frame. This method should be preceded by a call up Update.
346    * Multi-threading note: this method should be called from a dedicated rendering thread.
347    * @pre The GL context must have been created, and made current.
348    * @param[out] status showing whether update is required to run.
349    */
350   void Render( RenderStatus& status );
351
352   /**
353    * Tells core that it is about to sleep.
354    * Application is running as normal, but no updates are taking place i.e. no ongoing animations.
355    * This should be called when we choose to stop updating and rendering when there are no screen
356    * updates required.
357    * Multi-threading note: this method should be called from the update-thread.
358    */
359   void Sleep();
360
361   /**
362    * Wakes up core from a sleep state.
363    * At the first update the elapsed time passed to the animations is zero.
364    * Multi-threading note: this method should be called from the update-thread.
365    */
366   void WakeUp();
367
368   /**
369    * Notification of a vertical blank sync
370    * @param[in] frameNumber  The frame number of this vsync. This number will not update
371    *                         while paused.
372    * @param[in] seconds      The timestamp seconds
373    * @param[in] microseconds The timestamp microseconds
374    */
375   void VSync( unsigned int frameNumber, unsigned int seconds, unsigned int microseconds );
376
377   // System-level overlay
378
379   /**
380    * Use the SystemOverlay to draw content for system-level indicators, dialogs etc.
381    * @return The SystemOverlay.
382    */
383   SystemOverlay& GetSystemOverlay();
384
385   /**
386    * Set the stereoscopic 3D view mode
387    * @param[in] viewMode The new view mode
388    */
389   void SetViewMode( ViewMode viewMode );
390
391   /**
392    * Get the current view mode
393    * @return The current view mode
394    * @see SetViewMode.
395    */
396   ViewMode GetViewMode() const;
397
398   /**
399    * Set the stereo base (eye seperation) for stereoscopic 3D
400    * @param[in] stereoBase The stereo base (eye seperation) for stereoscopic 3D (mm)
401    */
402   void SetStereoBase( float stereoBase );
403
404   /**
405    * Get the stereo base (eye seperation) for stereoscopic 3D
406    * @return The stereo base (eye seperation) for stereoscopic 3D (mm)
407    */
408   float GetStereoBase() const;
409
410 private:
411
412   /**
413    * Private constructor; see also Core::New()
414    */
415   Core();
416
417   /**
418    * Undefined copy-constructor.
419    * This avoids accidental calls to a default copy-constructor.
420    * @param[in] core A reference to the object to copy.
421    */
422   Core(const Core& core);
423
424   /**
425    * Undefined assignment operator.
426    * This avoids accidental calls to a default assignment operator.
427    * @param[in] rhs A reference to the object to copy.
428    */
429   Core& operator=(const Core& rhs);
430
431 private:
432
433   Internal::Core* mImpl;
434
435 };
436
437 } // namespace Integration
438
439 } // namespace Dali
440
441 #endif // __DALI_INTEGRATION_CORE_H__