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