Merge "Klockwork: remove unreachable code, check iterators" 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/render-tasks/render-task-list.h>
40
41 #ifdef DYNAMICS_SUPPORT
42 #include <dali/internal/event/dynamics/dynamics-world-config-impl.h>
43 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
44 #include <dali/integration-api/dynamics/dynamics-factory-intf.h>
45 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
46 #endif
47
48 using namespace std;
49 using namespace boost;
50
51 using Dali::Internal::SceneGraph::Node;
52
53 namespace Dali
54 {
55
56 namespace Internal
57 {
58
59 namespace
60 {
61
62 const float DEFAULT_STEREO_BASE( 65.0f );
63
64 } // unnamed namespace
65
66 StagePtr Stage::New( AnimationPlaylist& playlist,
67                      PropertyNotificationManager& propertyNotificationManager,
68                      SceneGraph::UpdateManager& updateManager,
69                      NotificationManager& notificationManager )
70 {
71   return StagePtr( new Stage( playlist, propertyNotificationManager, updateManager, notificationManager ) );
72 }
73
74 void Stage::Initialize()
75 {
76   mObjectRegistry = ObjectRegistry::New();
77
78   // Create the ordered list of layers
79   mLayerList = LayerList::New( *this, false/*not system-level*/ );
80
81   // The stage owns the default layer
82   mRootLayer = Layer::NewRoot( *this, *mLayerList, mUpdateManager, false/*not system-level*/ );
83   mRootLayer->SetName("RootLayer");
84
85   // Create the default camera actor first; this is needed by the RenderTaskList
86   CreateDefaultCameraActor();
87
88   // Create the list of render-tasks
89   mRenderTaskList = RenderTaskList::New( mUpdateManager, *this, false/*not system-level*/ );
90
91   // Create the default render-task
92   Dali::RenderTask defaultRenderTask = mRenderTaskList->CreateTask();
93 }
94
95 void Stage::Uninitialize()
96 {
97   // Remove actors added to SystemOverlay
98   delete mSystemOverlay;
99   mSystemOverlay = NULL;
100
101   if( mDefaultCamera )
102   {
103     Remove(*(mDefaultCamera.Get()));
104   }
105
106   if( mRootLayer )
107   {
108     // we are closing down so just delete the root, no point emit disconnect
109     // signals or send messages to update
110     mRootLayer.Reset();
111   }
112 }
113
114 StagePtr Stage::GetCurrent()
115 {
116   return ThreadLocalStorage::Get().GetCurrentStage();
117 }
118
119 bool Stage::IsInstalled()
120 {
121   return ThreadLocalStorage::Created();
122 }
123
124 ObjectRegistry& Stage::GetObjectRegistry()
125 {
126   return *mObjectRegistry;
127 }
128
129 Layer& Stage::GetRootActor()
130 {
131   return *mRootLayer;
132 }
133
134 SceneGraph::UpdateManager& Stage::GetUpdateManager()
135 {
136   return mUpdateManager;
137 }
138
139 EventToUpdate& Stage::GetUpdateInterface()
140 {
141   return mUpdateManager.GetEventToUpdate();
142 }
143
144 AnimationPlaylist& Stage::GetAnimationPlaylist()
145 {
146   return mAnimationPlaylist;
147 }
148
149 PropertyNotificationManager& Stage::GetPropertyNotificationManager()
150 {
151   return mPropertyNotificationManager;
152 }
153
154 void Stage::Add( Actor& actor )
155 {
156   mRootLayer->Add( actor );
157 }
158
159 void Stage::Remove( Actor& actor )
160 {
161   mRootLayer->Remove( actor );
162 }
163
164 void Stage::SetSize(float width, float height)
165 {
166   // Internally we want to report the actual size of the stage.
167   mSize.width  = width;
168   mSize.height = height;
169
170   // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
171   mDefaultCamera->SetPerspectiveProjection( mSize );
172
173   // The depth of the stage gets set to the maximun of these values
174   mRootLayer->SetSize( mSize );
175
176   // Repeat for SystemOverlay actors
177   if( mSystemOverlay )
178   {
179     mSystemOverlay->GetImpl()->SetSize( mSize.width, mSize.height );
180   }
181
182   SetDefaultSurfaceRectMessage( mUpdateManager, Rect<int>( 0, 0, width, height ) );
183 }
184
185 Vector2 Stage::GetSize() const
186 {
187   return mSize;
188 }
189
190 RenderTaskList& Stage::GetRenderTaskList() const
191 {
192   return *mRenderTaskList;
193 }
194
195 void Stage::CreateDefaultCameraActor()
196 {
197   // The default camera attributes and position is such that
198   // children of the default layer, can be positioned at (0,0) and
199   // be at the top-left of the viewport.
200   mDefaultCamera = CameraActor::New( Size::ZERO );
201   mDefaultCamera->SetParentOrigin(ParentOrigin::CENTER);
202   Add(*(mDefaultCamera.Get()));
203 }
204
205 Actor& Stage::GetDefaultRootActor()
206 {
207   return *mRootLayer;
208 }
209
210 CameraActor& Stage::GetDefaultCameraActor()
211 {
212   return *mDefaultCamera;
213 }
214
215 unsigned int Stage::GetLayerCount() const
216 {
217   return mLayerList->GetLayerCount();
218 }
219
220 Dali::Layer Stage::GetLayer( unsigned int depth ) const
221 {
222   return Dali::Layer(mLayerList->GetLayer( depth ));
223 }
224
225 Dali::Layer Stage::GetRootLayer() const
226 {
227   return Dali::Layer( mRootLayer.Get() );
228 }
229
230 LayerList& Stage::GetLayerList()
231 {
232   return *mLayerList;
233 }
234
235 Integration::SystemOverlay& Stage::GetSystemOverlay()
236 {
237   // Lazily create system-level if requested
238   if( !mSystemOverlay )
239   {
240     mSystemOverlay = new Integration::SystemOverlay( SystemOverlay::New( *this ) );
241     DALI_ASSERT_ALWAYS( NULL != mSystemOverlay && "Failed to create system overlay" );
242
243     mSystemOverlay->GetImpl()->SetSize( mSize.width, mSize.height );
244   }
245
246   return *mSystemOverlay;
247 }
248
249 SystemOverlay* Stage::GetSystemOverlayInternal()
250 {
251   SystemOverlay* overlay( NULL );
252
253   if( mSystemOverlay )
254   {
255     overlay = mSystemOverlay->GetImpl();
256   }
257
258   return overlay;
259 }
260
261 void Stage::SetViewMode( ViewMode viewMode )
262 {
263   if( mViewMode != viewMode )
264   {
265     DALI_LOG_INFO( Debug::Filter::gActor, Debug::Concise, "View mode changed from %d to %d\n", mViewMode, viewMode);
266
267     if( mViewMode == MONO )
268     {
269       mDefaultCamera->SetRotation( Degree( 180.0f ), Vector3::YAXIS );
270       mRenderTaskList->GetTask(0).SetSourceActor( Dali::Actor() );
271
272       //Create camera and RenderTask for left eye
273       mLeftCamera = CameraActor::New( Size::ZERO );
274       mLeftCamera->SetParentOrigin( ParentOrigin::CENTER );
275       mDefaultCamera->Add( *mLeftCamera.Get() );
276       mLeftRenderTask = mRenderTaskList->CreateTask();
277       mLeftRenderTask.SetCameraActor( Dali::CameraActor( mLeftCamera.Get() ) );
278       mLeftCamera->SetType( Dali::Camera::FREE_LOOK );
279
280       //Create camera and RenderTask for right eye
281       mRightCamera = CameraActor::New( Size::ZERO );
282       mRightCamera->SetParentOrigin( ParentOrigin::CENTER );
283       mDefaultCamera->Add( *mRightCamera.Get() );
284       mRightRenderTask = mRenderTaskList->CreateTask();
285       mRightRenderTask.SetClearColor( Vector4( 1.0f,0.0f,0.0f,1.0f));
286
287       mRightRenderTask.SetCameraActor( Dali::CameraActor( mRightCamera.Get() ) );
288       mRightCamera->SetType( Dali::Camera::FREE_LOOK );
289     }
290
291     // save new mode
292     mViewMode = viewMode;
293
294     switch( viewMode )
295     {
296       case MONO:
297       {
298         // delete extra stereoscopic render tasks and cameras
299         mRenderTaskList->RemoveTask( mLeftRenderTask );
300         mDefaultCamera->Remove( *mLeftCamera.Get() );
301         mLeftRenderTask.Reset();
302         mLeftCamera.Reset();
303         mRenderTaskList->RemoveTask( mRightRenderTask );
304         mDefaultCamera->Remove( *mRightCamera.Get() );
305         mRightRenderTask.Reset();
306         mRightCamera.Reset();
307
308         mDefaultCamera->SetRotation( Degree( 0.0f ), Vector3::YAXIS );
309         mDefaultCamera->SetType( Dali::Camera::LOOK_AT_TARGET );
310         mRenderTaskList->GetTask(0).SetSourceActor( Dali::Layer(mRootLayer.Get()) );
311
312         break;
313       }
314       case STEREO_HORIZONTAL:
315       {
316         //Stereo mode with horizontal split is for landscape mode. That's the reason for the cameras being rotated
317         //Top camera renders the scene as seen from the right eye and bottom camera as seen from left.
318
319         //Calculate separation in pixels along vertical axis ( mStereoBase is defined in millimetres )
320         const float stereoBase( ( (mStereoBase / 25.4f) * GetDpi().y ) * 0.5f );
321
322         //Calculate aspect ratio
323         float aspect = mSize.width / (mSize.height * 0.5f);
324
325         mLeftCamera->SetPerspectiveProjection( mSize, Vector2( 0.0f,stereoBase) );
326         mLeftCamera->SetAspectRatio( aspect );
327         mLeftCamera->SetRotation( Degree(-90.0f), Vector3::ZAXIS );
328         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
329         mLeftRenderTask.SetViewport( Viewport(0, mSize.height * 0.5f, mSize.width, mSize.height * 0.5f) );
330
331         mRightCamera->SetPerspectiveProjection( mSize, Vector2( 0.0,  -stereoBase) );
332         mRightCamera->SetAspectRatio( aspect );
333         mRightCamera->SetRotation( Degree(-90.0f), Vector3::ZAXIS );
334         mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
335         mRightRenderTask.SetViewport( Viewport(0, 0, mSize.width, mSize.height * 0.5f ) );
336
337         break;
338       }
339       case STEREO_VERTICAL:
340       {
341         //Calculate separation in pixels along horizontal axis
342         const float stereoBase( ( (mStereoBase / 25.4f) * GetDpi().x ) * 0.5f );
343
344         //Recalculate fov based on viewport size
345         const float fov = 2.0f * std::atan(  mSize.y / (2.0f * std::max( mSize.x*0.5f, mSize.y )) );
346
347         mLeftCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(stereoBase,0.0f) );
348         mLeftCamera->SetFieldOfView( fov );
349         mLeftCamera->SetRotation( Degree(0.0f), Vector3::ZAXIS );
350         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
351         mLeftRenderTask.SetViewport( Viewport(0, 0, mSize.width * 0.5f, mSize.height ) );
352
353         mRightCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(-stereoBase,0.0f) );
354         mRightCamera->SetFieldOfView( fov );
355         mRightCamera->SetRotation( Degree(0.0f), Vector3::ZAXIS );
356         mRightCamera->SetPosition( Vector3( -stereoBase, 0.0f, 0.0f ) );
357         mRightRenderTask.SetViewport( Viewport(mSize.width * 0.5f, 0, mSize.width * 0.5f, mSize.height ) );
358
359         break;
360       }
361       case STEREO_INTERLACED:
362       {
363         break;
364       }
365     }
366   }
367 }
368
369 ViewMode Stage::GetViewMode() const
370 {
371   return mViewMode;
372 }
373
374 void Stage::SetStereoBase( float stereoBase )
375 {
376   if( ! Equals( mStereoBase, stereoBase ) )
377   {
378     DALI_LOG_INFO( Debug::Filter::gActor, Debug::Concise, "old( %.2f) new(%.2f)", mStereoBase, stereoBase );
379     mStereoBase = stereoBase;
380
381     switch( mViewMode  )
382     {
383       case STEREO_HORIZONTAL:
384       {
385         stereoBase = mStereoBase / 25.4f * GetDpi().y * 0.5f;
386         float aspect = mSize.width / (mSize.height * 0.5f);
387
388         mLeftCamera->SetPerspectiveProjection( mSize, Vector2( 0.0, stereoBase) );
389         mLeftCamera->SetAspectRatio( aspect );
390         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
391
392         mRightCamera->SetPerspectiveProjection( mSize, Vector2( 0.0, -stereoBase) );
393         mRightCamera->SetAspectRatio( aspect );
394         mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
395
396         break;
397       }
398       case STEREO_VERTICAL:
399       {
400         stereoBase = mStereoBase / 25.4f * GetDpi().x * 0.5f;
401         const float fov = 2.0f * std::atan(  mSize.y / (2.0f * std::max( mSize.x*0.5f, mSize.y )) );
402
403         mLeftCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(stereoBase,0.0f) );
404         mLeftCamera->SetFieldOfView( fov );
405         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
406
407         mRightCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(-stereoBase,0.0f) );
408         mRightCamera->SetFieldOfView( fov );
409         mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
410
411         break;
412       }
413       default:
414         break;
415     }
416   }
417 }
418
419 float Stage::GetStereoBase() const
420 {
421   return mStereoBase;
422 }
423
424 void Stage::SetBackgroundColor(Vector4 color)
425 {
426   // Cache for public GetBackgroundColor()
427   mBackgroundColor = color;
428
429   // Send message to change color in next frame
430   SetBackgroundColorMessage( mUpdateManager, color );
431 }
432
433 Vector4 Stage::GetBackgroundColor() const
434 {
435   return mBackgroundColor;
436 }
437
438 Vector2 Stage::GetDpi() const
439 {
440   return mDpi;
441 }
442
443 void Stage::SetDpi(Vector2 dpi)
444 {
445   mDpi = dpi;
446 }
447
448 #ifdef DYNAMICS_SUPPORT
449
450 DynamicsNotifier& Stage::GetDynamicsNotifier()
451 {
452   return mDynamicsNotifier;
453 }
454
455 DynamicsWorldPtr Stage::InitializeDynamics(DynamicsWorldConfigPtr config)
456 {
457   if( !mDynamicsFactory )
458   {
459     mDynamicsFactory = ThreadLocalStorage::Get().GetPlatformAbstraction().GetDynamicsFactory();
460   }
461
462   if( mDynamicsFactory && !mDynamicsWorld )
463   {
464     if( mDynamicsFactory->InitializeDynamics( *(config->GetSettings()) ) )
465     {
466       mDynamicsWorld = DynamicsWorld::New();
467       mDynamicsWorld->Initialize( *this, *mDynamicsFactory, config );
468     }
469   }
470   return mDynamicsWorld;
471 }
472
473 DynamicsWorldPtr Stage::GetDynamicsWorld()
474 {
475   return mDynamicsWorld;
476 }
477
478 void Stage::TerminateDynamics()
479 {
480   if( mDynamicsWorld )
481   {
482     mDynamicsWorld->Terminate(*this);
483     mDynamicsWorld = NULL;
484   }
485 }
486
487 #endif // DYNAMICS_SUPPORT
488
489 void Stage::KeepRendering( float durationSeconds )
490 {
491   // Send message to keep rendering
492   KeepRenderingMessage( mUpdateManager, durationSeconds );
493 }
494
495 void Stage::EmitKeyEventSignal(const KeyEvent& event)
496 {
497   // Emit the key event signal when no actor in the stage has gained the key input focus
498
499   mKeyEventSignalV2.Emit( event );
500 }
501
502 void Stage::EmitEventProcessingFinishedSignal()
503 {
504    mEventProcessingFinishedSignalV2.Emit();
505 }
506
507 void Stage::EmitTouchedSignal( const TouchEvent& touch )
508 {
509   mTouchedSignalV2.Emit( touch );
510 }
511
512 Dali::Stage::KeyEventSignalV2& Stage::KeyEventSignal()
513 {
514   return mKeyEventSignalV2;
515 }
516
517 Dali::Stage::EventProcessingFinishedSignalV2& Stage::EventProcessingFinishedSignal()
518 {
519   return mEventProcessingFinishedSignalV2;
520 }
521
522 Dali::Stage::TouchedSignalV2& Stage::TouchedSignal()
523 {
524   return mTouchedSignalV2;
525 }
526
527 Dali::Stage::ContextStatusSignal& Stage::ContextLostSignal()
528 {
529   return mContextLostSignal;
530 }
531
532 Dali::Stage::ContextStatusSignal& Stage::ContextRegainedSignal()
533 {
534   return mContextRegainedSignal;
535 }
536
537 void Stage::NotifyContextLost()
538 {
539   mContextLostSignal.Emit();
540 }
541
542 void Stage::NotifyContextRegained()
543 {
544   mContextRegainedSignal.Emit();
545 }
546
547 Stage::Stage( AnimationPlaylist& playlist,
548               PropertyNotificationManager& propertyNotificationManager,
549               SceneGraph::UpdateManager& updateManager,
550               NotificationManager& notificationManager )
551 : mAnimationPlaylist( playlist ),
552   mPropertyNotificationManager(propertyNotificationManager),
553   mUpdateManager(updateManager),
554   mNotificationManager(notificationManager),
555   mSize(Vector2::ZERO),
556   mBackgroundColor(Dali::Stage::DEFAULT_BACKGROUND_COLOR),
557   mViewMode( MONO ),
558   mStereoBase( DEFAULT_STEREO_BASE ),
559 #ifdef DYNAMICS_SUPPORT
560   mDynamicsFactory(NULL),
561 #endif
562   mSystemOverlay(NULL)
563 {
564 }
565
566 Stage::~Stage()
567 {
568   delete mSystemOverlay;
569
570   mObjectRegistry.Reset();
571 }
572
573 } // namespace Internal
574
575 } // namespace Dali