Merge "Refactored EventToUpdate into EventThreadServices" into tizen
[platform/core/uifw/dali-core.git] / dali / internal / event / common / stage-impl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/common/stage-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <cmath>
24
25 // INTERNAL INCLUDES
26 #include <dali/integration-api/system-overlay.h>
27 #include <dali/internal/event/actors/layer-impl.h>
28 #include <dali/internal/event/actors/layer-list.h>
29 #include <dali/internal/event/actors/camera-actor-impl.h>
30 #include <dali/internal/event/actor-attachments/camera-attachment-impl.h>
31 #include <dali/internal/event/common/system-overlay-impl.h>
32 #include <dali/internal/event/common/thread-local-storage.h>
33 #include <dali/internal/event/common/property-notification-manager.h>
34 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
35 #include <dali/internal/update/nodes/node.h>
36 #include <dali/internal/event/common/object-registry-impl.h>
37 #include <dali/integration-api/platform-abstraction.h>
38 #include <dali/public-api/common/constants.h>
39 #include <dali/public-api/object/type-registry.h>
40 #include <dali/public-api/render-tasks/render-task-list.h>
41
42 #ifdef DYNAMICS_SUPPORT
43 #include <dali/internal/event/dynamics/dynamics-world-config-impl.h>
44 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
45 #include <dali/integration-api/dynamics/dynamics-factory-intf.h>
46 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
47 #endif
48
49 using Dali::Internal::SceneGraph::Node;
50
51 namespace Dali
52 {
53
54 namespace Internal
55 {
56
57 namespace
58 {
59
60 const float DEFAULT_STEREO_BASE( 65.0f );
61
62 // Signals
63
64 const char* const SIGNAL_KEY_EVENT =                 "key-event";
65 const char* const SIGNAL_EVENT_PROCESSING_FINISHED = "event-processing-finished";
66 const char* const SIGNAL_TOUCHED =                   "touched";
67 const char* const SIGNAL_CONTEXT_LOST =              "context-lost";
68 const char* const SIGNAL_CONTEXT_REGAINED =          "context-regained";
69 const char* const SIGNAL_SCENE_CREATED =             "scene-created";
70
71 TypeRegistration mType( typeid(Dali::Stage), typeid(Dali::BaseHandle), NULL );
72
73 SignalConnectorType signalConnector1( mType, SIGNAL_KEY_EVENT,                 &Stage::DoConnectSignal );
74 SignalConnectorType signalConnector2( mType, SIGNAL_EVENT_PROCESSING_FINISHED, &Stage::DoConnectSignal );
75 SignalConnectorType signalConnector3( mType, SIGNAL_TOUCHED,                   &Stage::DoConnectSignal );
76 SignalConnectorType signalConnector4( mType, SIGNAL_CONTEXT_LOST,              &Stage::DoConnectSignal );
77 SignalConnectorType signalConnector5( mType, SIGNAL_CONTEXT_REGAINED,          &Stage::DoConnectSignal );
78 SignalConnectorType signalConnector6( mType, SIGNAL_SCENE_CREATED,             &Stage::DoConnectSignal );
79
80 } // unnamed namespace
81
82 StagePtr Stage::New( AnimationPlaylist& playlist,
83                      PropertyNotificationManager& propertyNotificationManager,
84                      SceneGraph::UpdateManager& updateManager,
85                      NotificationManager& notificationManager )
86 {
87   return StagePtr( new Stage( playlist, propertyNotificationManager, updateManager, notificationManager ) );
88 }
89
90 void Stage::Initialize()
91 {
92   mObjectRegistry = ObjectRegistry::New();
93
94   // Create the ordered list of layers
95   mLayerList = LayerList::New( mUpdateManager, false/*not system-level*/ );
96
97   // The stage owns the default layer
98   mRootLayer = Layer::NewRoot( *mLayerList, mUpdateManager, false/*not system-level*/ );
99   mRootLayer->SetName("RootLayer");
100
101   // Create the default camera actor first; this is needed by the RenderTaskList
102   CreateDefaultCameraActor();
103
104   // Create the list of render-tasks
105   mRenderTaskList = RenderTaskList::New( *this, *this, false/*not system-level*/ );
106
107   // Create the default render-task
108   Dali::RenderTask defaultRenderTask = mRenderTaskList->CreateTask();
109 }
110
111 void Stage::Uninitialize()
112 {
113   // Remove actors added to SystemOverlay
114   delete mSystemOverlay;
115   mSystemOverlay = NULL;
116
117   if( mDefaultCamera )
118   {
119     Remove(*(mDefaultCamera.Get()));
120   }
121
122   if( mRootLayer )
123   {
124     // we are closing down so just delete the root, no point emit disconnect
125     // signals or send messages to update
126     mRootLayer.Reset();
127   }
128 }
129
130 StagePtr Stage::GetCurrent()
131 {
132   StagePtr stage( NULL );
133   // no checking in this version
134   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
135   if( tls )
136   {
137     stage = tls->GetCurrentStage();
138   }
139   return stage;
140 }
141
142 bool Stage::IsInstalled()
143 {
144   return ThreadLocalStorage::Created();
145 }
146
147 ObjectRegistry& Stage::GetObjectRegistry()
148 {
149   return *mObjectRegistry;
150 }
151
152 void Stage::RegisterObject( Dali::BaseObject* object )
153 {
154   mObjectRegistry->RegisterObject( object );
155 }
156
157 void Stage::UnregisterObject( Dali::BaseObject* object )
158 {
159   mObjectRegistry->UnregisterObject( object );
160 }
161
162 Layer& Stage::GetRootActor()
163 {
164   return *mRootLayer;
165 }
166
167 AnimationPlaylist& Stage::GetAnimationPlaylist()
168 {
169   return mAnimationPlaylist;
170 }
171
172 PropertyNotificationManager& Stage::GetPropertyNotificationManager()
173 {
174   return mPropertyNotificationManager;
175 }
176
177 void Stage::Add( Actor& actor )
178 {
179   mRootLayer->Add( actor );
180 }
181
182 void Stage::Remove( Actor& actor )
183 {
184   mRootLayer->Remove( actor );
185 }
186
187 void Stage::SetSize(float width, float height)
188 {
189   // Internally we want to report the actual size of the stage.
190   mSize.width  = width;
191   mSize.height = height;
192
193   // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
194   mDefaultCamera->SetPerspectiveProjection( mSize );
195
196   // The depth of the stage gets set to the maximun of these values
197   mRootLayer->SetSize( mSize );
198
199   // Repeat for SystemOverlay actors
200   if( mSystemOverlay )
201   {
202     mSystemOverlay->GetImpl()->SetSize( mSize.width, mSize.height );
203   }
204
205   SetDefaultSurfaceRectMessage( mUpdateManager, Rect<int>( 0, 0, width, height ) );
206 }
207
208 Vector2 Stage::GetSize() const
209 {
210   return mSize;
211 }
212
213 RenderTaskList& Stage::GetRenderTaskList() const
214 {
215   return *mRenderTaskList;
216 }
217
218 void Stage::CreateDefaultCameraActor()
219 {
220   // The default camera attributes and position is such that
221   // children of the default layer, can be positioned at (0,0) and
222   // be at the top-left of the viewport.
223   mDefaultCamera = CameraActor::New( Size::ZERO );
224   mDefaultCamera->SetParentOrigin(ParentOrigin::CENTER);
225   Add(*(mDefaultCamera.Get()));
226 }
227
228 Actor& Stage::GetDefaultRootActor()
229 {
230   return *mRootLayer;
231 }
232
233 CameraActor& Stage::GetDefaultCameraActor()
234 {
235   return *mDefaultCamera;
236 }
237
238 unsigned int Stage::GetLayerCount() const
239 {
240   return mLayerList->GetLayerCount();
241 }
242
243 Dali::Layer Stage::GetLayer( unsigned int depth ) const
244 {
245   return Dali::Layer(mLayerList->GetLayer( depth ));
246 }
247
248 Dali::Layer Stage::GetRootLayer() const
249 {
250   return Dali::Layer( mRootLayer.Get() );
251 }
252
253 LayerList& Stage::GetLayerList()
254 {
255   return *mLayerList;
256 }
257
258 Integration::SystemOverlay& Stage::GetSystemOverlay()
259 {
260   // Lazily create system-level if requested
261   if( !mSystemOverlay )
262   {
263     mSystemOverlay = new Integration::SystemOverlay( SystemOverlay::New( *this ) );
264     DALI_ASSERT_ALWAYS( NULL != mSystemOverlay && "Failed to create system overlay" );
265
266     mSystemOverlay->GetImpl()->SetSize( mSize.width, mSize.height );
267   }
268
269   return *mSystemOverlay;
270 }
271
272 SystemOverlay* Stage::GetSystemOverlayInternal()
273 {
274   SystemOverlay* overlay( NULL );
275
276   if( mSystemOverlay )
277   {
278     overlay = mSystemOverlay->GetImpl();
279   }
280
281   return overlay;
282 }
283
284 void Stage::SetViewMode( ViewMode viewMode )
285 {
286   if( mViewMode != viewMode )
287   {
288     DALI_LOG_INFO( Debug::Filter::gActor, Debug::Concise, "View mode changed from %d to %d\n", mViewMode, viewMode);
289
290     if( mViewMode == MONO )
291     {
292       mDefaultCamera->SetOrientation( Degree( 180.0f ), Vector3::YAXIS );
293       mRenderTaskList->GetTask(0).SetSourceActor( Dali::Actor() );
294
295       //Create camera and RenderTask for left eye
296       mLeftCamera = CameraActor::New( Size::ZERO );
297       mLeftCamera->SetParentOrigin( ParentOrigin::CENTER );
298       mDefaultCamera->Add( *mLeftCamera.Get() );
299       mLeftRenderTask = mRenderTaskList->CreateTask();
300       mLeftRenderTask.SetCameraActor( Dali::CameraActor( mLeftCamera.Get() ) );
301       mLeftCamera->SetType( Dali::Camera::FREE_LOOK );
302
303       //Create camera and RenderTask for right eye
304       mRightCamera = CameraActor::New( Size::ZERO );
305       mRightCamera->SetParentOrigin( ParentOrigin::CENTER );
306       mDefaultCamera->Add( *mRightCamera.Get() );
307       mRightRenderTask = mRenderTaskList->CreateTask();
308       mRightRenderTask.SetClearColor( Vector4( 1.0f,0.0f,0.0f,1.0f));
309
310       mRightRenderTask.SetCameraActor( Dali::CameraActor( mRightCamera.Get() ) );
311       mRightCamera->SetType( Dali::Camera::FREE_LOOK );
312     }
313
314     // save new mode
315     mViewMode = viewMode;
316
317     switch( viewMode )
318     {
319       case MONO:
320       {
321         // delete extra stereoscopic render tasks and cameras
322         mRenderTaskList->RemoveTask( mLeftRenderTask );
323         mDefaultCamera->Remove( *mLeftCamera.Get() );
324         mLeftRenderTask.Reset();
325         mLeftCamera.Reset();
326         mRenderTaskList->RemoveTask( mRightRenderTask );
327         mDefaultCamera->Remove( *mRightCamera.Get() );
328         mRightRenderTask.Reset();
329         mRightCamera.Reset();
330
331         mDefaultCamera->SetOrientation( Degree( 0.0f ), Vector3::YAXIS );
332         mDefaultCamera->SetType( Dali::Camera::LOOK_AT_TARGET );
333         mRenderTaskList->GetTask(0).SetSourceActor( Dali::Layer(mRootLayer.Get()) );
334
335         break;
336       }
337       case STEREO_HORIZONTAL:
338       {
339         //Stereo mode with horizontal split is for landscape mode. That's the reason for the cameras being rotated
340         //Top camera renders the scene as seen from the right eye and bottom camera as seen from left.
341
342         //Calculate separation in pixels along vertical axis ( mStereoBase is defined in millimetres )
343         const float stereoBase( ( (mStereoBase / 25.4f) * GetDpi().y ) * 0.5f );
344
345         //Calculate aspect ratio
346         float aspect = mSize.width / (mSize.height * 0.5f);
347
348         mLeftCamera->SetPerspectiveProjection( mSize, Vector2( 0.0f,stereoBase) );
349         mLeftCamera->SetAspectRatio( aspect );
350         mLeftCamera->SetOrientation( Degree(-90.0f), Vector3::ZAXIS );
351         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
352         mLeftRenderTask.SetViewport( Viewport(0, mSize.height * 0.5f, mSize.width, mSize.height * 0.5f) );
353
354         mRightCamera->SetPerspectiveProjection( mSize, Vector2( 0.0,  -stereoBase) );
355         mRightCamera->SetAspectRatio( aspect );
356         mRightCamera->SetOrientation( Degree(-90.0f), Vector3::ZAXIS );
357         mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
358         mRightRenderTask.SetViewport( Viewport(0, 0, mSize.width, mSize.height * 0.5f ) );
359
360         break;
361       }
362       case STEREO_VERTICAL:
363       {
364         //Calculate separation in pixels along horizontal axis
365         const float stereoBase( ( (mStereoBase / 25.4f) * GetDpi().x ) * 0.5f );
366
367         //Recalculate fov based on viewport size
368         const float fov = 2.0f * std::atan(  mSize.y / (2.0f * std::max( mSize.x*0.5f, mSize.y )) );
369
370         mLeftCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(stereoBase,0.0f) );
371         mLeftCamera->SetFieldOfView( fov );
372         mLeftCamera->SetOrientation( Degree(0.0f), Vector3::ZAXIS );
373         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
374         mLeftRenderTask.SetViewport( Viewport(0, 0, mSize.width * 0.5f, mSize.height ) );
375
376         mRightCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(-stereoBase,0.0f) );
377         mRightCamera->SetFieldOfView( fov );
378         mRightCamera->SetOrientation( Degree(0.0f), Vector3::ZAXIS );
379         mRightCamera->SetPosition( Vector3( -stereoBase, 0.0f, 0.0f ) );
380         mRightRenderTask.SetViewport( Viewport(mSize.width * 0.5f, 0, mSize.width * 0.5f, mSize.height ) );
381
382         break;
383       }
384       case STEREO_INTERLACED:
385       {
386         break;
387       }
388     }
389   }
390 }
391
392 ViewMode Stage::GetViewMode() const
393 {
394   return mViewMode;
395 }
396
397 void Stage::SetStereoBase( float stereoBase )
398 {
399   if( ! Equals( mStereoBase, stereoBase ) )
400   {
401     DALI_LOG_INFO( Debug::Filter::gActor, Debug::Concise, "old( %.2f) new(%.2f)", mStereoBase, stereoBase );
402     mStereoBase = stereoBase;
403
404     switch( mViewMode  )
405     {
406       case STEREO_HORIZONTAL:
407       {
408         stereoBase = mStereoBase / 25.4f * GetDpi().y * 0.5f;
409         float aspect = mSize.width / (mSize.height * 0.5f);
410
411         mLeftCamera->SetPerspectiveProjection( mSize, Vector2( 0.0, stereoBase) );
412         mLeftCamera->SetAspectRatio( aspect );
413         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
414
415         mRightCamera->SetPerspectiveProjection( mSize, Vector2( 0.0, -stereoBase) );
416         mRightCamera->SetAspectRatio( aspect );
417         mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
418
419         break;
420       }
421       case STEREO_VERTICAL:
422       {
423         stereoBase = mStereoBase / 25.4f * GetDpi().x * 0.5f;
424         const float fov = 2.0f * std::atan(  mSize.y / (2.0f * std::max( mSize.x*0.5f, mSize.y )) );
425
426         mLeftCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(stereoBase,0.0f) );
427         mLeftCamera->SetFieldOfView( fov );
428         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
429
430         mRightCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(-stereoBase,0.0f) );
431         mRightCamera->SetFieldOfView( fov );
432         mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
433
434         break;
435       }
436       default:
437         break;
438     }
439   }
440 }
441
442 float Stage::GetStereoBase() const
443 {
444   return mStereoBase;
445 }
446
447 void Stage::SetBackgroundColor(Vector4 color)
448 {
449   // Cache for public GetBackgroundColor()
450   mBackgroundColor = color;
451
452   // Send message to change color in next frame
453   SetBackgroundColorMessage( mUpdateManager, color );
454 }
455
456 Vector4 Stage::GetBackgroundColor() const
457 {
458   return mBackgroundColor;
459 }
460
461 Vector2 Stage::GetDpi() const
462 {
463   return mDpi;
464 }
465
466 void Stage::SetDpi(Vector2 dpi)
467 {
468   mDpi = dpi;
469 }
470
471 #ifdef DYNAMICS_SUPPORT
472
473 DynamicsNotifier& Stage::GetDynamicsNotifier()
474 {
475   return mDynamicsNotifier;
476 }
477
478 DynamicsWorldPtr Stage::InitializeDynamics(DynamicsWorldConfigPtr config)
479 {
480   if( !mDynamicsFactory )
481   {
482     mDynamicsFactory = ThreadLocalStorage::Get().GetPlatformAbstraction().GetDynamicsFactory();
483   }
484
485   if( mDynamicsFactory && !mDynamicsWorld )
486   {
487     if( mDynamicsFactory->InitializeDynamics( *(config->GetSettings()) ) )
488     {
489       mDynamicsWorld = DynamicsWorld::New();
490       mDynamicsWorld->Initialize( *this, *mDynamicsFactory, config );
491     }
492   }
493   return mDynamicsWorld;
494 }
495
496 DynamicsWorldPtr Stage::GetDynamicsWorld()
497 {
498   return mDynamicsWorld;
499 }
500
501 void Stage::TerminateDynamics()
502 {
503   if( mDynamicsWorld )
504   {
505     mDynamicsWorld->Terminate(*this);
506     mDynamicsWorld = NULL;
507   }
508 }
509
510 #endif // DYNAMICS_SUPPORT
511
512 void Stage::KeepRendering( float durationSeconds )
513 {
514   // Send message to keep rendering
515   KeepRenderingMessage( mUpdateManager, durationSeconds );
516 }
517
518 bool Stage::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
519 {
520   bool connected( true );
521   Stage* stage = dynamic_cast<Stage*>(object);
522
523   if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_EVENT ) )
524   {
525     stage->KeyEventSignal().Connect( tracker, functor );
526   }
527   else if( 0 == strcmp( signalName.c_str(), SIGNAL_EVENT_PROCESSING_FINISHED ) )
528   {
529     stage->EventProcessingFinishedSignal().Connect( tracker, functor );
530   }
531   else if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCHED ) )
532   {
533     stage->TouchedSignal().Connect( tracker, functor );
534   }
535   else if( 0 == strcmp( signalName.c_str(), SIGNAL_CONTEXT_LOST ) )
536   {
537     stage->ContextLostSignal().Connect( tracker, functor );
538   }
539   else if( 0 == strcmp( signalName.c_str(), SIGNAL_CONTEXT_REGAINED ) )
540   {
541     stage->ContextRegainedSignal().Connect( tracker, functor );
542   }
543   else if( 0 == strcmp( signalName.c_str(), SIGNAL_SCENE_CREATED ) )
544   {
545     stage->SceneCreatedSignal().Connect( tracker, functor );
546   }
547   else
548   {
549     // signalName does not match any signal
550     connected = false;
551   }
552
553   return connected;
554 }
555
556 void Stage::EmitKeyEventSignal(const KeyEvent& event)
557 {
558   // Emit the key event signal when no actor in the stage has gained the key input focus
559
560   mKeyEventSignal.Emit( event );
561 }
562
563 void Stage::EmitEventProcessingFinishedSignal()
564 {
565    mEventProcessingFinishedSignal.Emit();
566 }
567
568 void Stage::EmitTouchedSignal( const TouchEvent& touch )
569 {
570   mTouchedSignal.Emit( touch );
571 }
572
573
574 void Stage::EmitSceneCreatedSignal()
575 {
576   mSceneCreatedSignal.Emit();
577 }
578
579 Dali::Stage::KeyEventSignalType& Stage::KeyEventSignal()
580 {
581   return mKeyEventSignal;
582 }
583
584 Dali::Stage::EventProcessingFinishedSignalType& Stage::EventProcessingFinishedSignal()
585 {
586   return mEventProcessingFinishedSignal;
587 }
588
589 Dali::Stage::TouchedSignalType& Stage::TouchedSignal()
590 {
591   return mTouchedSignal;
592 }
593
594 Dali::Stage::ContextStatusSignal& Stage::ContextLostSignal()
595 {
596   return mContextLostSignal;
597 }
598
599 Dali::Stage::ContextStatusSignal& Stage::ContextRegainedSignal()
600 {
601   return mContextRegainedSignal;
602 }
603
604 Dali::Stage::SceneCreatedSignalType& Stage::SceneCreatedSignal()
605 {
606   return mSceneCreatedSignal;
607 }
608
609 void Stage::NotifyContextLost()
610 {
611   mContextLostSignal.Emit();
612 }
613
614 void Stage::NotifyContextRegained()
615 {
616   mContextRegainedSignal.Emit();
617 }
618
619 Stage::Stage( AnimationPlaylist& playlist,
620               PropertyNotificationManager& propertyNotificationManager,
621               SceneGraph::UpdateManager& updateManager,
622               NotificationManager& notificationManager )
623 : mAnimationPlaylist( playlist ),
624   mPropertyNotificationManager(propertyNotificationManager),
625   mUpdateManager(updateManager),
626   mNotificationManager(notificationManager),
627   mSize(Vector2::ZERO),
628   mBackgroundColor(Dali::Stage::DEFAULT_BACKGROUND_COLOR),
629   mViewMode( MONO ),
630   mStereoBase( DEFAULT_STEREO_BASE ),
631 #ifdef DYNAMICS_SUPPORT
632   mDynamicsFactory(NULL),
633 #endif
634   mSystemOverlay(NULL)
635 {
636 }
637
638 SceneGraph::UpdateManager& Stage::GetUpdateManager()
639 {
640   return mUpdateManager;
641 }
642
643 unsigned int* Stage::ReserveMessageSlot( std::size_t size, bool updateScene )
644 {
645   return mUpdateManager.ReserveMessageSlot( size, updateScene );
646 }
647
648 BufferIndex Stage::GetEventBufferIndex() const
649 {
650   return mUpdateManager.GetEventBufferIndex();
651 }
652
653 Stage::~Stage()
654 {
655   delete mSystemOverlay;
656
657   mObjectRegistry.Reset();
658 }
659
660 } // namespace Internal
661
662 } // namespace Dali