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