d9d533251695ecde27384f5d1e62046a9678b11d
[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 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 // EXTERNAL INCLUDES
22 #include <dali/public-api/common/dali-common.h>
23 #include <dali/public-api/common/view-mode.h>
24
25 namespace Dali
26 {
27
28 namespace Internal
29 {
30 class Core;
31 }
32
33 namespace Integration
34 {
35
36 class Core;
37 class GestureManager;
38 class GlAbstraction;
39 class GlSyncAbstraction;
40 class PlatformAbstraction;
41 class RenderController;
42 class SystemOverlay;
43 struct Event;
44 struct TouchData;
45
46 /**
47  * The reasons why further updates are required.
48  */
49 namespace KeepUpdating DALI_IMPORT_API
50 {
51   extern const unsigned int NOT_REQUESTED; ///< Zero means that no further updates are required
52
53   // Bit-field values
54   extern const unsigned int STAGE_KEEP_RENDERING;   ///< 0x01 - Stage::KeepRendering() is being used
55   extern const unsigned int INCOMING_MESSAGES;      ///< 0x02 - Event-thread is sending messages to update-thread
56   extern const unsigned int ANIMATIONS_RUNNING;     ///< 0x04 - Animations are ongoing
57   extern const unsigned int DYNAMICS_CHANGED;       ///< 0x08 - A dynamics simulation is running
58   extern const unsigned int LOADING_RESOURCES;      ///< 0x10 - Resources are being loaded
59   extern const unsigned int MONITORING_PERFORMANCE; ///< 0x20 - The --enable-performance-monitor option is being used
60   extern const unsigned int RENDER_TASK_SYNC;       ///< 0x40 - A render task is waiting for render sync
61 };
62
63 /**
64  * The status of the Core::Update operation.
65  */
66 class 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 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   // Core Lifecycle
262
263   /**
264    * Put Core into the suspended state.
265    * Any ongoing event processing will be cancelled, for example multi-touch sequences.
266    * The core expects the system has suspended us. Animation time will continue during the suspended
267    * state.
268    * Multi-threading note: this method should be called from the main thread
269    * @post The Core is in the suspended state.
270    */
271   void Suspend();
272
273   /**
274    * Resume the Core from the suspended state.
275    * At the first update, the elapsed time passed to the animations will be equal to the time spent
276    * suspended.
277    * Multi-threading note: this method should be called from the main thread
278    * @post The Core is not in the suspended state.
279    */
280   void Resume();
281
282   /**
283    * Queue an event with Core.
284    * Pre-processing of events may be beneficial e.g. a series of motion events could be throttled, so that only the last event is queued.
285    * Multi-threading note: this method should be called from the main thread.
286    * @param[in] event The new event.
287    */
288   void QueueEvent(const Event& event);
289
290   /**
291    * Process the events queued with QueueEvent().
292    * Multi-threading note: this method should be called from the main thread.
293    * @pre ProcessEvents should not be called during ProcessEvents.
294    */
295   void ProcessEvents();
296
297   /**
298    * Update external raw touch data in core.
299    * The core will use the touch data to generate Dali Touch/Gesture events for applications to use
300    * in the update thread.
301    * @param[in] touch The raw touch data.
302    * @note This can be called from either the event thread OR a dedicated touch thread.
303    */
304   void UpdateTouchData(const TouchData& touch);
305
306   /**
307    * The Core::Update() method prepares a frame for rendering. This method determines how many frames
308    * may be prepared, ahead of the rendering.
309    * For example if the maximum update count is 2, then Core::Update() for frame N+1 may be processed
310    * whilst frame N is being rendered. However the Core::Update() for frame N+2 may not be called, until
311    * the Core::Render() method for frame N has returned.
312    * @return The maximum update count (>= 1).
313    */
314   unsigned int GetMaximumUpdateCount() const;
315
316   /**
317    * Update the scene for the next frame. This method must be called before each frame is rendered.
318    * Multi-threading notes: this method should be called from a dedicated update-thread.
319    * The update for frame N+1 may be processed whilst frame N is being rendered.
320    * However the update-thread must wait until frame N has been rendered, before processing frame N+2.
321    * After this method returns, messages may be queued internally for the main thread.
322    * In order to process these messages, a notification is sent via the main thread's event loop.
323    * @param[in] elapsedSeconds Number of seconds since the last call
324    * @param[in] lastVSyncTimeMilliseconds The last vsync time in milliseconds
325    * @param[in] nextVSyncTimeMilliseconds The time of the next predicted VSync in milliseconds
326    * @param[out] status showing whether further updates are required. This also shows
327    * whether a Notification event should be sent, regardless of whether the multi-threading is used.
328    */
329   void Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, UpdateStatus& status );
330
331   /**
332    * Render the next frame. This method should be preceded by a call up Update.
333    * Multi-threading note: this method should be called from a dedicated rendering thread.
334    * @pre The GL context must have been created, and made current.
335    * @param[out] status showing whether update is required to run.
336    */
337   void Render( RenderStatus& status );
338
339   // System-level overlay
340
341   /**
342    * Use the SystemOverlay to draw content for system-level indicators, dialogs etc.
343    * @return The SystemOverlay.
344    */
345   SystemOverlay& GetSystemOverlay();
346
347   /**
348    * Set the stereoscopic 3D view mode
349    * @param[in] viewMode The new view mode
350    */
351   void SetViewMode( ViewMode viewMode );
352
353   /**
354    * Get the current view mode
355    * @return The current view mode
356    * @see SetViewMode.
357    */
358   ViewMode GetViewMode() const;
359
360   /**
361    * Set the stereo base (eye seperation) for stereoscopic 3D
362    * @param[in] stereoBase The stereo base (eye seperation) for stereoscopic 3D (mm)
363    */
364   void SetStereoBase( float stereoBase );
365
366   /**
367    * Get the stereo base (eye seperation) for stereoscopic 3D
368    * @return The stereo base (eye seperation) for stereoscopic 3D (mm)
369    */
370   float GetStereoBase() const;
371
372 private:
373
374   /**
375    * Private constructor; see also Core::New()
376    */
377   Core();
378
379   /**
380    * Undefined copy-constructor.
381    * This avoids accidental calls to a default copy-constructor.
382    * @param[in] core A reference to the object to copy.
383    */
384   Core(const Core& core);
385
386   /**
387    * Undefined assignment operator.
388    * This avoids accidental calls to a default assignment operator.
389    * @param[in] rhs A reference to the object to copy.
390    */
391   Core& operator=(const Core& rhs);
392
393 private:
394
395   Internal::Core* mImpl;
396
397 };
398
399 } // namespace Integration
400
401 } // namespace Dali
402
403 #endif // __DALI_INTEGRATION_CORE_H__