Merge branch 'devel/tizen' into tizen
[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) 2020 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 <cstdint> // uint32_t
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-common.h>
26 #include <dali/integration-api/context-notifier.h>
27 #include <dali/integration-api/core-enumerations.h>
28
29 namespace Dali
30 {
31
32 class Layer;
33 class RenderTaskList;
34
35 namespace Internal
36 {
37 class Core;
38 }
39
40 namespace Integration
41 {
42 class Core;
43 class GlAbstraction;
44 class GlSyncAbstraction;
45 class GlContextHelperAbstraction;
46 class PlatformAbstraction;
47 class Processor;
48 class RenderController;
49 class RenderSurface;
50 struct Event;
51 struct TouchData;
52
53
54 /**
55  * The reasons why further updates are required.
56  */
57 namespace KeepUpdating
58 {
59 enum Reasons
60 {
61   NOT_REQUESTED           = 0,    ///< Zero means that no further updates are required
62   STAGE_KEEP_RENDERING    = 1<<1, ///<  - Stage::KeepRendering() is being used
63   ANIMATIONS_RUNNING      = 1<<2, ///< - Animations are ongoing
64   MONITORING_PERFORMANCE  = 1<<3, ///< - The --enable-performance-monitor option is being used
65   RENDER_TASK_SYNC        = 1<<4  ///< - A render task is waiting for render sync
66 };
67 }
68
69 /**
70  * The status of the Core::Update operation.
71  */
72 class UpdateStatus
73 {
74 public:
75
76   /**
77    * Constructor
78    */
79   UpdateStatus()
80   : keepUpdating(false),
81     needsNotification(false),
82     surfaceRectChanged(false),
83     secondsFromLastFrame( 0.0f )
84   {
85   }
86
87 public:
88
89   /**
90    * Query whether the Core has further frames to update & render e.g. when animations are ongoing.
91    * @return A bitmask of KeepUpdating values
92    */
93   uint32_t KeepUpdating() { return keepUpdating; }
94
95   /**
96    * Query whether the Core requires an Notification event.
97    * This should be sent through the same mechanism (e.g. event loop) as input events.
98    * @return True if an Notification event should be sent.
99    */
100   bool NeedsNotification() { return needsNotification; }
101
102   /**
103    * Query wheter the default surface rect is changed or not.
104    * @return true if the default surface rect is changed.
105    */
106   bool SurfaceRectChanged() { return surfaceRectChanged; }
107
108   /**
109    * This method is provided so that FPS can be easily calculated with a release version
110    * of Core.
111    * @return the seconds from last frame as float
112    */
113   float SecondsFromLastFrame() { return secondsFromLastFrame; }
114
115 public:
116
117   uint32_t keepUpdating; ///< A bitmask of KeepUpdating values
118   bool needsNotification;
119   bool surfaceRectChanged;
120   float secondsFromLastFrame;
121 };
122
123 /**
124  * The status of the Core::Render operation.
125  */
126 class RenderStatus
127 {
128 public:
129
130   /**
131    * Constructor
132    */
133   RenderStatus()
134   : needsUpdate( false ),
135     needsPostRender( false )
136   {
137   }
138
139   /**
140    * Set whether update needs to run following a render.
141    * @param[in] updateRequired Set to true if an update is required to be run
142    */
143   void SetNeedsUpdate( bool updateRequired )
144   {
145     needsUpdate = updateRequired;
146   }
147
148   /**
149    * Query the update status following rendering of a frame.
150    * @return True if update is required to be run
151    */
152   bool NeedsUpdate() const
153   {
154     return needsUpdate;
155   }
156
157   /**
158    * Sets if a post-render should be run.
159    * If nothing is rendered this frame, we can skip post-render.
160    * @param[in] postRenderRequired Set to True if post-render is required to be run
161    */
162   void SetNeedsPostRender( bool postRenderRequired )
163   {
164     needsPostRender = postRenderRequired;
165   }
166
167   /**
168    * Queries if a post-render should be run.
169    * @return True if post-render is required to be run
170    */
171   bool NeedsPostRender() const
172   {
173     return needsPostRender;
174   }
175
176 private:
177
178   bool needsUpdate      :1;  ///< True if update is required to be run
179   bool needsPostRender  :1;  ///< True if post-render is required to be run.
180 };
181
182
183 /**
184  * Integration::Core is used for integration with the native windowing system.
185  * The following integration tasks must be completed:
186  *
187  * 1) Handle GL context creation, and notify the Core when this occurs.
188  *
189  * 2) Provide suspend/resume behaviour (see below for more details).
190  *
191  * 3) Run an event loop, for passing events to the Core e.g. multi-touch input events.
192  * Notification events should be sent after a frame is updated (see UpdateStatus).
193  *
194  * 4) Run a rendering loop, instructing the Core to render each frame.
195  * A separate rendering thread is recommended; see multi-threading options below.
196  *
197  * 5) Provide an implementation of the PlatformAbstraction interface, used to access platform specific services.
198  *
199  * 6) Provide an implementation of the GlAbstraction interface, used to access OpenGL services.
200  *
201  * Multi-threading notes:
202  *
203  * The Dali API methods are not reentrant.  If you access the API from multiple threads simultaneously, then the results
204  * are undefined. This means that your application might segfault, or behave unpredictably.
205  *
206  * Rendering strategies:
207  *
208  * 1) Single-threaded. Call every Core method from the same thread. Event handling and rendering will occur in the same thread.
209  * This is not recommended, since processing input (slowly) can affect the smooth flow of animations.
210  *
211  * 2) Multi-threaded. The Core update & render operations can be processed in separate threads.
212  * See the method descriptions in Core to see which thread they should be called from.
213  * This is the recommended option, so that input processing will not affect the smoothness of animations.
214  * Note that the rendering thread must be halted, before destroying the GL context.
215  */
216 class DALI_CORE_API Core
217 {
218 public:
219
220   /**
221    * Create a new Core.
222    * This object is used for integration with the native windowing system.
223    * @param[in] renderController The interface to an object which controls rendering.
224    * @param[in] platformAbstraction The interface providing platform specific services.
225    * @param[in] glAbstraction The interface providing OpenGL services.
226    * @param[in] glSyncAbstraction The interface providing OpenGL sync objects.
227    * @param[in] glContextHelperAbstraction The interface providing OpenGL context helper objects.
228    * @param[in] renderToFboEnabled Whether rendering into the Frame Buffer Object is enabled.
229    * @param[in] depthBufferAvailable Whether the depth buffer is available
230    * @param[in] stencilBufferAvailable Whether the stencil buffer is available
231    * @param[in] partialUpdateAvailble whether the partial update is available
232    * @return A newly allocated Core.
233    */
234   static Core* New( RenderController& renderController,
235                     PlatformAbstraction& platformAbstraction,
236                     GlAbstraction& glAbstraction,
237                     GlSyncAbstraction& glSyncAbstraction,
238                     GlContextHelperAbstraction& glContextHelperAbstraction,
239                     RenderToFrameBuffer renderToFboEnabled,
240                     DepthBufferAvailable depthBufferAvailable,
241                     StencilBufferAvailable stencilBufferAvailable,
242                     PartialUpdateAvailable partialUpdateAvailable );
243
244   /**
245    * Non-virtual destructor. Core is not intended as a base class.
246    */
247   ~Core();
248
249   /**
250    * Initialize the core
251    */
252   void Initialize();
253
254   // GL Context Lifecycle
255
256   /**
257    * Get the object that will notify the application/toolkit when context is lost/regained
258    */
259   ContextNotifierInterface* GetContextNotifier();
260
261   /**
262    * Notify the Core that the GL context has been created.
263    * The context must be created before the Core can render.
264    * Multi-threading note: this method should be called from the rendering thread only
265    * @post The Core is aware of the GL context.
266    */
267   void ContextCreated();
268
269   /**
270    * Notify the Core that that GL context is about to be destroyed.
271    * The Core will free any previously allocated GL resources.
272    * Multi-threading note: this method should be called from the rendering thread only
273    * @post The Core is unaware of any GL context.
274    */
275   void ContextDestroyed();
276
277   /**
278    * Notify the Core that the GL context has been re-created, e.g. after ReplaceSurface
279    * or Context loss.
280    *
281    * In the case of ReplaceSurface, both ContextToBeDestroyed() and ContextCreated() will have
282    * been called on the render thread before this is called on the event thread.
283    *
284    * Multi-threading note: this method should be called from the main thread
285    */
286   void RecoverFromContextLoss();
287
288   /**
289    * Notify the Core that the GL surface has been deleted.
290    * Multi-threading note: this method should be called from the main thread
291    * @param[in] surface The deleted surface
292    */
293   void SurfaceDeleted( Integration::RenderSurface* surface );
294
295   // Core Lifecycle
296
297   /**
298    * Notify Core that the scene has been created.
299    */
300   void SceneCreated();
301
302   /**
303    * Queue an event with Core.
304    * 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.
305    * Multi-threading note: this method should be called from the main thread.
306    * @param[in] event The new event.
307    */
308   void QueueEvent(const Event& event);
309
310   /**
311    * Process the events queued with QueueEvent().
312    * Multi-threading note: this method should be called from the main thread.
313    * @pre ProcessEvents should not be called during ProcessEvents.
314    */
315   void ProcessEvents();
316
317   /**
318    * The Core::Update() method prepares a frame for rendering. This method determines how many frames
319    * may be prepared, ahead of the rendering.
320    * For example if the maximum update count is 2, then Core::Update() for frame N+1 may be processed
321    * whilst frame N is being rendered. However the Core::Update() for frame N+2 may not be called, until
322    * the Core::Render() method for frame N has returned.
323    * @return The maximum update count (>= 1).
324    */
325   uint32_t GetMaximumUpdateCount() const;
326
327   /**
328    * Update the scene for the next frame. This method must be called before each frame is rendered.
329    * Multi-threading notes: this method should be called from a dedicated update-thread.
330    * The update for frame N+1 may be processed whilst frame N is being rendered.
331    * However the update-thread must wait until frame N has been rendered, before processing frame N+2.
332    * After this method returns, messages may be queued internally for the main thread.
333    * In order to process these messages, a notification is sent via the main thread's event loop.
334    * @param[in] elapsedSeconds Number of seconds since the last call
335    * @param[in] lastVSyncTimeMilliseconds The last vsync time in milliseconds
336    * @param[in] nextVSyncTimeMilliseconds The time of the next predicted VSync in milliseconds
337    * @param[out] status showing whether further updates are required. This also shows
338    * whether a Notification event should be sent, regardless of whether the multi-threading is used.
339    * @param[in] renderToFboEnabled Whether rendering into the Frame Buffer Object is enabled.
340    * @param[in] isRenderingToFbo Whether this frame is being rendered into the Frame Buffer Object.
341    */
342   void Update( float elapsedSeconds,
343                uint32_t lastVSyncTimeMilliseconds,
344                uint32_t nextVSyncTimeMilliseconds,
345                UpdateStatus& status,
346                bool renderToFboEnabled,
347                bool isRenderingToFbo );
348
349   /**
350    * Render the next frame. This method should be preceded by a call up Update.
351    * Multi-threading note: this method should be called from a dedicated rendering thread.
352    * @pre The GL context must have been created, and made current.
353    * @param[out] status showing whether update is required to run.
354    * @param[in] forceClear force the Clear on the framebuffer even if nothing is rendered.
355    * @param[in] uploadOnly uploadOnly Upload the resource only without rendering.
356    */
357   void Render( RenderStatus& status, bool forceClear, bool uploadOnly );
358
359   /**
360    * @brief Register a processor
361    *
362    * Note, Core does not take ownership of this processor.
363    * @param[in] processor The process to register
364    */
365   void RegisterProcessor( Processor& processor );
366
367   /**
368    * @brief Unregister a processor
369    * @param[in] processor The process to unregister
370    */
371   void UnregisterProcessor( Processor& processor );
372
373 private:
374
375   /**
376    * Private constructor; see also Core::New()
377    */
378   Core();
379
380   /**
381    * Undefined copy-constructor.
382    * This avoids accidental calls to a default copy-constructor.
383    * @param[in] core A reference to the object to copy.
384    */
385   Core(const Core& core);
386
387   /**
388    * Undefined assignment operator.
389    * This avoids accidental calls to a default assignment operator.
390    * @param[in] rhs A reference to the object to copy.
391    */
392   Core& operator=(const Core& rhs);
393
394 private:
395
396   Internal::Core* mImpl;
397
398 };
399
400 } // namespace Integration
401
402 } // namespace Dali
403
404 #endif // DALI_INTEGRATION_CORE_H