eb0f6f02fe0f51ad6ad900d33af8fe2ca31378be
[platform/core/uifw/dali-adaptor.git] / dali / integration-api / adaptor.h
1 #ifndef DALI_INTEGRATION_ADAPTOR_H
2 #define DALI_INTEGRATION_ADAPTOR_H
3
4 /*
5  * Copyright (c) 2019 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/signals/callback.h>
23 #include <dali/public-api/signals/dali-signal.h>
24 #include <dali/public-api/math/uint-16-pair.h>
25 #include <dali/public-api/math/rect.h>
26 #include <dali/public-api/events/touch-event.h>
27 #include <dali/public-api/common/view-mode.h>
28 #include <dali/public-api/object/any.h>
29 #include <dali/integration-api/processor-interface.h>
30
31 // INTERNAL INCLUDES
32 #include <dali/public-api/adaptor-framework/window.h>
33 #include <dali/public-api/adaptor-framework/application-configuration.h>
34 #include <dali/public-api/dali-adaptor-common.h>
35
36 #ifdef DALI_ADAPTOR_COMPILATION
37 #include <dali/integration-api/log-factory-interface.h>
38 #else
39 #include <dali/integration-api/adaptors/log-factory-interface.h>
40 #endif
41
42
43 namespace Dali
44 {
45
46 class RenderSurfaceInterface;
47
48 using WindowContainer = std::vector<Window>;
49
50 namespace Integration
51 {
52 class SceneHolder;
53 }
54
55 using SceneHolderList = std::vector<Dali::Integration::SceneHolder>;
56
57
58 namespace Internal
59 {
60 namespace Adaptor
61 {
62 class GraphicsFactory;
63 class Adaptor;
64 }
65 }
66
67 /**
68  * @brief An Adaptor object is used to initialize and control how Dali runs.
69  *
70  * It provides a lifecycle interface that allows the application
71  * writer to provide their own main loop and other platform related
72  * features.
73  *
74  * The Adaptor class provides a means for initialising the resources required by the Dali::Core.
75  *
76  * When dealing with platform events, the application writer MUST ensure that Dali is called in a
77  * thread-safe manner.
78  *
79  * As soon as the Adaptor class is created and started, the application writer can initialise their
80  * Dali::Actor objects straight away or as required by the main loop they intend to use (there is no
81  * need to wait for an initialise signal as per the Dali::Application class).
82  *
83  * The Adaptor does emit a Resize signal which informs the user when the surface is resized.
84  * Tizen and Linux Adaptors should follow the example below:
85  *
86  * @code
87  * void CreateProgram(DaliAdaptor& adaptor)
88  * {
89  *   // Create Dali components...
90  *   // Can instantiate adaptor here instead, if required
91  * }
92  *
93  * int main ()
94  * {
95  *   // Initialise platform
96  *   MyPlatform.Init();
97  *
98  *   // Create an 800 by 1280 window positioned at (0,0).
99  *   Dali::PositionSize positionSize(0, 0, 800, 1280);
100  *   Dali::Window window = Dali::Window::New( positionSize, "My Application" );
101  *
102  *   // Create an adaptor which uses that window for rendering
103  *   Dali::Adaptor adaptor = Dali::Adaptor::New( window );
104  *   adaptor.Start();
105  *
106  *   CreateProgram(adaptor);
107  *   // Or use this as a callback function depending on the platform initialisation sequence.
108  *
109  *   // Start Main Loop of your platform
110  *   MyPlatform.StartMainLoop();
111  *
112  *   return 0;
113  * }
114  * @endcode
115  *
116  * If required, you can also connect class member functions to a signal:
117  *
118  * @code
119  * MyApplication application;
120  * adaptor.ResizedSignal().Connect(&application, &MyApplication::Resize);
121  * @endcode
122  *
123  * @see RenderSurface
124  */
125 class DALI_ADAPTOR_API Adaptor
126 {
127 public:
128
129   typedef Signal< void (Adaptor&) > AdaptorSignalType; ///< Generic Type for adaptor signals
130   typedef Signal< void (Dali::Integration::SceneHolder&) > WindowCreatedSignalType;  ///< SceneHolder created signal type
131
132   using SurfaceSize = Uint16Pair; ///< Surface size type
133
134 public:
135   /**
136    * @brief Create a new adaptor using the window.
137    *
138    * @param[in] window The window to draw onto
139    * @return a reference to the adaptor handle
140    */
141   static Adaptor& New( Window window );
142
143   /**
144    * @brief Create a new adaptor using the window.
145    *
146    * @param[in] window The window to draw onto
147    * @param[in] configuration The context loss configuration.
148    * @return a reference to the adaptor handle
149    */
150   static Adaptor& New( Window window, Configuration::ContextLoss configuration );
151
152   /**
153    * @brief Create a new adaptor using render surface.
154    *
155    * @param[in] window The window to draw onto
156    * @param[in] surface The surface to draw onto
157    * @return a reference to the adaptor handle
158    */
159   static Adaptor& New( Window window, const Dali::RenderSurfaceInterface& surface );
160
161   /**
162    * @brief Create a new adaptor using render surface.
163    *
164    * @param[in] window The window to draw onto
165    * @param[in] surface The surface to draw onto
166    * @param[in] configuration The context loss configuration.
167    * @return a reference to the adaptor handle
168    */
169   static Adaptor& New( Window window, const Dali::RenderSurfaceInterface& surface, Configuration::ContextLoss configuration = Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS);
170
171   /**
172    * @brief Create a new adaptor using the SceneHolder.
173    *
174    * @param[in] sceneHolder The SceneHolder to draw onto
175    * @return a reference to the adaptor handle
176    */
177   static Adaptor& New( Dali::Integration::SceneHolder sceneHolder );
178
179   /**
180    * @brief Create a new adaptor using the SceneHolder.
181    *
182    * @param[in] sceneHolder The SceneHolder to draw onto
183    * @param[in] configuration The context loss configuration.
184    * @return a reference to the adaptor handle
185    */
186   static Adaptor& New( Dali::Integration::SceneHolder sceneHolder, Configuration::ContextLoss configuration );
187
188   /**
189    * @brief Create a new adaptor using render surface.
190    *
191    * @param[in] sceneHolder The SceneHolder to draw onto
192    * @param[in] surface The surface to draw onto
193    * @return a reference to the adaptor handle
194    */
195   static Adaptor& New( Dali::Integration::SceneHolder sceneHolder, const Dali::RenderSurfaceInterface& surface );
196
197   /**
198    * @brief Create a new adaptor using render surface.
199    *
200    * @param[in] sceneHolder The SceneHolder to draw onto
201    * @param[in] surface The surface to draw onto
202    * @param[in] configuration The context loss configuration.
203    * @return a reference to the adaptor handle
204    */
205   static Adaptor& New( Dali::Integration::SceneHolder sceneHolder, const Dali::RenderSurfaceInterface& surface, Configuration::ContextLoss configuration = Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS);
206
207   /**
208    * @brief Virtual Destructor.
209    */
210   virtual ~Adaptor();
211
212 public:
213
214   /**
215    * @brief Starts the Adaptor.
216    */
217   void Start();
218
219   /**
220    * @brief Pauses the Adaptor.
221    */
222   void Pause();
223
224   /**
225    * @brief Resumes the Adaptor, if previously paused.
226    *
227    * @note If the adaptor is not paused, this does not do anything.
228    */
229   void Resume();
230
231   /**
232    * @brief Stops the Adaptor.
233    */
234   void Stop();
235
236   /**
237    * @brief Ensures that the function passed in is called from the main loop when it is idle.
238    * @note Function must be called from the main event thread only.
239    *
240    * Callbacks of the following types may be used:
241    * @code
242    *   void MyFunction();
243    * @endcode
244    * This callback will be deleted once it is called.
245    *
246    * @code
247    *   bool MyFunction();
248    * @endcode
249    * This callback will be called repeatedly as long as it returns true. A return of 0 deletes this callback.
250    *
251    * @param[in] callback The function to call.
252    * @param[in] hasReturnValue Sould be set to true if the callback function has a return value.
253    * @return true if added successfully, false otherwise
254    *
255    * @note Ownership of the callback is passed onto this class.
256    */
257   bool AddIdle( CallbackBase* callback, bool hasReturnValue );
258
259   /**
260    * @brief Adds a new Window instance to the Adaptor
261    *
262    * @param[in]  childWindow The child window instance
263    * @param[in]  childWindowName The child window title/name
264    * @param[in]  childWindowClassName The class name that the child window belongs to
265    * @param[in]  childWindowMode The mode of the child window
266    */
267   bool AddWindow( Dali::Integration::SceneHolder childWindow,
268                   const std::string& childWindowName,
269                   const std::string& childWindowClassName,
270                   bool childWindowMode );
271
272   /**
273    * @brief Removes a previously added @p callback.
274    * @note Function must be called from the main event thread only.
275    *
276    * Does nothing if the @p callback doesn't exist.
277    *
278    * @param[in] callback The callback to be removed.
279    */
280   void RemoveIdle( CallbackBase* callback );
281
282   /**
283    * @brief Replaces the rendering surface
284    *
285    * @param[in] window The window to replace the surface for
286    * @param[in] surface to use
287    */
288   void ReplaceSurface( Window window, Dali::RenderSurfaceInterface& surface );
289
290   /**
291    * @brief Replaces the rendering surface
292    *
293    * @param[in] sceneHolder The SceneHolder to replace the surface for
294    * @param[in] surface to use
295    */
296   void ReplaceSurface( Dali::Integration::SceneHolder sceneHolder, Dali::RenderSurfaceInterface& surface );
297
298   /**
299    * @brief Get the render surface the adaptor is using to render to.
300    *
301    * @return reference to current render surface
302    */
303   Dali::RenderSurfaceInterface& GetSurface();
304
305   /**
306    * @brief Gets native window handle
307    *
308    * @return Native window handle
309    */
310   Any GetNativeWindowHandle();
311
312   /**
313    * @brief Retrieve native window handle that the given actor is added to.
314    *
315    * @param[in] actor The actor
316    * @return native window handle
317    */
318   Any GetNativeWindowHandle( Actor actor );
319
320   /**
321    * @brief Get the native display associated with the graphics backend
322    *
323    * @return A handle to the native display
324    */
325   Any GetGraphicsDisplay();
326
327   /**
328    * @brief Release any locks the surface may hold.
329    *
330    * For example, after compositing an offscreen surface, use this method to allow
331    * rendering to continue.
332    */
333   void ReleaseSurfaceLock();
334
335   /**
336    * @brief Set the number of frames per render.
337    *
338    * This enables an application to deliberately render with a reduced FPS.
339    * @param[in] numberOfVSyncsPerRender The number of vsyncs between successive renders.
340    * Suggest this is a power of two:
341    * 1 - render each vsync frame
342    * 2 - render every other vsync frame
343    * 4 - render every fourth vsync frame
344    * 8 - render every eighth vsync frame
345    */
346   void SetRenderRefreshRate( unsigned int numberOfVSyncsPerRender );
347
348   /**
349    * @brief The callback is called from the Update/Render thread prior to rendering.
350    *
351    * @param[in] callback The function to call
352    *
353    * @note The function is called from the Update thread, so should do as little processing as possible.
354    * It is not possible to call any DALi event side APIs from within the callback; doing so will cause
355    * instability. Only 1 callback is supported. Setting the callback to NULL will remove the current callback.
356    *
357    * A callback of the following type should be used:
358    * @code
359    *   bool MyFunction();
360    * @endcode
361    * This callback will be called repeatedly as long as it returns true. A return of 0 deletes this callback.
362    */
363   void SetPreRenderCallback( CallbackBase* callback );
364
365   /**
366    * @brief Returns a reference to the instance of the adaptor used by the current thread.
367    *
368    * @return A reference to the adaptor.
369    * @pre The adaptor has been initialised.
370    * @note This is only valid in the main thread.
371    */
372   static Adaptor& Get();
373
374   /**
375    * @brief Checks whether the adaptor is available.
376    *
377    * @return true, if it is available, false otherwise.
378    */
379   static bool IsAvailable();
380
381   /**
382    * @brief Call this method to notify Dali when scene is created and initialized.
383    *
384    * Notify Adaptor that the scene has been created.
385    */
386   void NotifySceneCreated();
387
388   /**
389    * @brief Call this method to notify Dali when the system language changes.
390    *
391    * Use this only when NOT using Dali::Application, As Application created using
392    * Dali::Application will automatically receive notification of language change.
393    * When Dali::Application is not used, the application developer should
394    * use app-core to receive language change notifications and should update Dali
395    * by calling this method.
396    */
397   void NotifyLanguageChanged();
398
399   /**
400    * @brief Feed a touch point to the adaptor.
401    *
402    * @param[in] point touch point
403    * @param[in] timeStamp time value of event
404    */
405   void FeedTouchPoint( TouchPoint& point, int timeStamp );
406
407   /**
408    * @brief Feed a wheel event to the adaptor.
409    *
410    * @param[in]  wheelEvent wheel event
411    */
412   void FeedWheelEvent( WheelEvent& wheelEvent );
413
414   /**
415    * @brief Feed a key event to the adaptor.
416    *
417    * @param[in] keyEvent The key event holding the key information.
418    */
419   void FeedKeyEvent( KeyEvent& keyEvent );
420
421   /**
422    * @copydoc Dali::Core::SceneCreated();
423    */
424   void SceneCreated();
425
426   /**
427    * @brief Informs core the surface size has changed.
428    *
429    * @param[in] surface The current render surface
430    * @param[in] surfaceSize The new surface size
431    */
432   void SurfaceResizePrepare( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize );
433
434   /**
435    * @brief Informs ThreadController the surface size has changed.
436    *
437    * @param[in] surface The current render surface
438    * @param[in] surfaceSize The new surface size
439    */
440   void SurfaceResizeComplete( Dali::RenderSurfaceInterface* surface, SurfaceSize surfaceSize );
441
442   /**
443    * @brief Renders once more even if we're paused
444    * @note Will not work if the window is hidden.
445    */
446   void RenderOnce();
447
448   /**
449    * @brief The log factory allows installation of a logger function in worker threads.
450    * @return An interface to a logging factory
451    */
452   const LogFactoryInterface& GetLogFactory();
453
454   /**
455    * @brief Register a processor implementing the Integration::Processor interface with dali-core.
456    * @param[in] processor the Processor to register
457    * @note using this api does not maintain the processor's lifecycle, must be done elsewhere.
458    */
459   void RegisterProcessor( Integration::Processor& processor );
460
461   /**
462    * @brief Unregister a previously registered processor from dali-core.
463    * @param[in] processor the Processor to unregister
464    */
465   void UnregisterProcessor( Integration::Processor& processor );
466
467   /**
468    * @brief Get the list of windows created.
469    * @return The list of windows
470    */
471   Dali::WindowContainer GetWindows() const;
472
473   /**
474    * @brief Get the list of scene holders.
475    * @return The list of scene holers
476    */
477   SceneHolderList GetSceneHolders() const;
478
479   /**
480    * @brief Called when the window becomes fully or partially visible.
481    */
482   void OnWindowShown();
483
484   /**
485    * @brief Called when the window is fully hidden.
486    */
487   void OnWindowHidden();
488
489 public:  // Signals
490
491   /**
492    * @brief The user should connect to this signal if they need to perform any
493    * special activities when the surface Dali is being rendered on is resized.
494    *
495    * @return The signal to connect to
496    */
497   AdaptorSignalType& ResizedSignal();
498
499   /**
500    * @brief This signal is emitted when the language is changed on the device.
501    *
502    * @return The signal to connect to
503    */
504   AdaptorSignalType& LanguageChangedSignal();
505
506   /**
507    * @brief This signal is emitted when a new window (scene holder) is created
508    *
509    * @return The signal to connect to
510    */
511   WindowCreatedSignalType& WindowCreatedSignal();
512
513 private:
514
515   // Undefined
516   Adaptor(const Adaptor&);
517   Adaptor& operator=(Adaptor&);
518
519 private:
520
521   /**
522    * @brief Create an uninitialized Adaptor.
523    */
524   Adaptor();
525
526   Internal::Adaptor::Adaptor* mImpl; ///< Implementation object
527   friend class Internal::Adaptor::Adaptor;
528 };
529
530 } // namespace Dali
531
532 #endif // DALI_INTEGRATION_ADAPTOR_H