2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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
8 // http://floralicense.org/license/
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.
18 #include <dali/internal/event/common/stage-impl.h>
24 #include <dali/integration-api/system-overlay.h>
25 #include <dali/internal/event/actors/layer-impl.h>
26 #include <dali/internal/event/actors/layer-list.h>
27 #include <dali/internal/event/actors/camera-actor-impl.h>
28 #include <dali/internal/event/actor-attachments/camera-attachment-impl.h>
29 #include <dali/internal/event/common/system-overlay-impl.h>
30 #include <dali/internal/event/common/thread-local-storage.h>
31 #include <dali/internal/event/common/property-notification-manager.h>
32 #include <dali/internal/event/render-tasks/render-task-list-impl.h>
33 #include <dali/internal/update/nodes/node.h>
34 #include <dali/internal/event/common/object-registry-impl.h>
35 #include <dali/integration-api/platform-abstraction.h>
36 #include <dali/public-api/common/constants.h>
37 #include <dali/public-api/render-tasks/render-task-list.h>
39 #ifdef DYNAMICS_SUPPORT
40 #include <dali/internal/event/dynamics/dynamics-world-config-impl.h>
41 #include <dali/internal/event/dynamics/dynamics-world-impl.h>
42 #include <dali/integration-api/dynamics/dynamics-factory-intf.h>
43 #include <dali/integration-api/dynamics/dynamics-world-settings.h>
47 using namespace boost;
49 using Dali::Internal::SceneGraph::Node;
60 const float DEFAULT_STEREO_BASE( 65.0f );
62 } // unnamed namespace
64 StagePtr Stage::New( AnimationPlaylist& playlist,
65 PropertyNotificationManager& propertyNotificationManager,
66 SceneGraph::UpdateManager& updateManager,
67 NotificationManager& notificationManager )
69 return StagePtr( new Stage( playlist, propertyNotificationManager, updateManager, notificationManager ) );
72 void Stage::Initialize()
74 mObjectRegistry = ObjectRegistry::New();
76 // Create the ordered list of layers
77 mLayerList = LayerList::New( *this, false/*not system-level*/ );
79 // The stage owns the default layer
80 mRootLayer = Layer::NewRoot( *this, *mLayerList, mUpdateManager, false/*not system-level*/ );
81 mRootLayer->SetName("RootLayer");
83 // Create the default camera actor first; this is needed by the RenderTaskList
84 CreateDefaultCameraActor();
86 // Create the list of render-tasks
87 mRenderTaskList = RenderTaskList::New( mUpdateManager, *this, false/*not system-level*/ );
89 // Create the default render-task
90 Dali::RenderTask defaultRenderTask = mRenderTaskList->CreateTask();
93 void Stage::Uninitialize()
95 // Remove actors added to SystemOverlay
96 delete mSystemOverlay;
97 mSystemOverlay = NULL;
101 Remove(*(mDefaultCamera.Get()));
106 // we are closing down so just delete the root, no point emit disconnect
107 // signals or send messages to update
112 StagePtr Stage::GetCurrent()
114 return ThreadLocalStorage::Get().GetCurrentStage();
117 bool Stage::IsInstalled()
119 return ThreadLocalStorage::Created();
122 ObjectRegistry& Stage::GetObjectRegistry()
124 return *mObjectRegistry;
127 Layer& Stage::GetRootActor()
132 SceneGraph::UpdateManager& Stage::GetUpdateManager()
134 return mUpdateManager;
137 EventToUpdate& Stage::GetUpdateInterface()
139 return mUpdateManager.GetEventToUpdate();
142 AnimationPlaylist& Stage::GetAnimationPlaylist()
144 return mAnimationPlaylist;
147 PropertyNotificationManager& Stage::GetPropertyNotificationManager()
149 return mPropertyNotificationManager;
152 void Stage::Add( Actor& actor )
154 mRootLayer->Add( actor );
157 void Stage::Remove( Actor& actor )
159 mRootLayer->Remove( actor );
162 void Stage::SetSize(float width, float height)
164 // Internally we want to report the actual size of the stage.
166 mSize.height = height;
168 // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
169 mDefaultCamera->SetPerspectiveProjection( mSize );
171 // The depth of the stage gets set to the maximun of these values
172 mRootLayer->SetSize( mSize );
174 // Repeat for SystemOverlay actors
177 mSystemOverlay->GetImpl()->SetSize( mSize.width, mSize.height );
180 SetDefaultSurfaceRectMessage( mUpdateManager, Rect<int>( 0, 0, width, height ) );
183 Vector2 Stage::GetSize() const
188 RenderTaskList& Stage::GetRenderTaskList() const
190 return *mRenderTaskList;
193 void Stage::CreateDefaultCameraActor()
195 // The default camera attributes and position is such that
196 // children of the default layer, can be positioned at (0,0) and
197 // be at the top-left of the viewport.
198 mDefaultCamera = CameraActor::New( Size::ZERO );
199 mDefaultCamera->SetParentOrigin(ParentOrigin::CENTER);
200 Add(*(mDefaultCamera.Get()));
203 Actor& Stage::GetDefaultRootActor()
208 CameraActor& Stage::GetDefaultCameraActor()
210 return *mDefaultCamera;
213 unsigned int Stage::GetLayerCount() const
215 return mLayerList->GetLayerCount();
218 Dali::Layer Stage::GetLayer( unsigned int depth ) const
220 return Dali::Layer(mLayerList->GetLayer( depth ));
223 Dali::Layer Stage::GetRootLayer() const
225 return Dali::Layer( mRootLayer.Get() );
228 LayerList& Stage::GetLayerList()
233 Integration::SystemOverlay& Stage::GetSystemOverlay()
235 // Lazily create system-level if requested
236 if( !mSystemOverlay )
238 mSystemOverlay = new Integration::SystemOverlay( SystemOverlay::New( *this ) );
239 DALI_ASSERT_ALWAYS( NULL != mSystemOverlay && "Failed to create system overlay" );
241 mSystemOverlay->GetImpl()->SetSize( mSize.width, mSize.height );
244 return *mSystemOverlay;
247 SystemOverlay* Stage::GetSystemOverlayInternal()
249 SystemOverlay* overlay( NULL );
253 overlay = mSystemOverlay->GetImpl();
259 void Stage::SetViewMode( ViewMode viewMode )
261 if( mViewMode != viewMode )
263 DALI_LOG_INFO( Debug::Filter::gActor, Debug::Concise, "View mode changed from %d to %d\n", mViewMode, viewMode);
265 const float stereoBase( ( (mStereoBase / 25.4f) * GetDpi().x ) * 0.5f );
267 if( mViewMode == MONO )
269 mDefaultCamera->SetRotation( Degree( 180.0f ), Vector3::YAXIS );
270 mRenderTaskList->GetTask(0).SetSourceActor( Dali::Actor() );
272 mLeftCamera = CameraActor::New( Size::ZERO );
273 mLeftCamera->SetParentOrigin( ParentOrigin::CENTER );
274 mLeftCamera->SetPerspectiveProjection( mSize, stereoBase );
275 mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
276 mDefaultCamera->Add( *mLeftCamera.Get() );
277 mLeftRenderTask = mRenderTaskList->CreateTask();
278 mLeftRenderTask.SetCameraActor( Dali::CameraActor( mLeftCamera.Get() ) );
279 mLeftCamera->SetType( Dali::Camera::FREE_LOOK );
281 mRightCamera = CameraActor::New( Size::ZERO );
282 mRightCamera->SetParentOrigin( ParentOrigin::CENTER );
283 mRightCamera->SetPerspectiveProjection( mSize, -stereoBase );
284 mRightCamera->SetPosition( Vector3( -stereoBase, 0.0f, 0.0f ) );
285 mDefaultCamera->Add( *mRightCamera.Get() );
286 mRightRenderTask = mRenderTaskList->CreateTask();
287 mRightRenderTask.SetCameraActor( Dali::CameraActor( mRightCamera.Get() ) );
288 mRightCamera->SetType( Dali::Camera::FREE_LOOK );
292 mViewMode = viewMode;
298 // delete extra stereoscopic render tasks and cameras
299 mRenderTaskList->RemoveTask( mLeftRenderTask );
300 mDefaultCamera->Remove( *mLeftCamera.Get() );
301 mLeftRenderTask.Reset();
303 mRenderTaskList->RemoveTask( mRightRenderTask );
304 mDefaultCamera->Remove( *mRightCamera.Get() );
305 mRightRenderTask.Reset();
306 mRightCamera.Reset();
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()) );
313 case STEREO_HORIZONTAL:
315 mLeftRenderTask.SetViewport( Viewport(0, 0, mSize.width, mSize.height * 0.5f ) );
316 mRightRenderTask.SetViewport( Viewport(0, mSize.height * 0.5f, mSize.width, mSize.height * 0.5f) );
319 case STEREO_VERTICAL:
321 mLeftRenderTask.SetViewport( Viewport(0, 0, mSize.width * 0.5f, mSize.height ) );
322 mRightRenderTask.SetViewport( Viewport(mSize.width * 0.5f, 0, mSize.width * 0.5f, mSize.height ) );
325 case STEREO_INTERLACED:
333 ViewMode Stage::GetViewMode() const
338 void Stage::SetStereoBase( float stereoBase )
340 if( ! Equals( mStereoBase, stereoBase ) )
342 DALI_LOG_INFO( Debug::Filter::gActor, Debug::Concise, "old( %.2f) new(%.2f)", mStereoBase, stereoBase );
343 mStereoBase = stereoBase;
345 if( mViewMode != MONO )
348 mLeftCamera->SetX( stereoBase );
349 mLeftCamera->SetPerspectiveProjection( mSize, stereoBase );
350 mRightCamera->SetX( -stereoBase );
351 mRightCamera->SetPerspectiveProjection( mSize, -stereoBase );
356 float Stage::GetStereoBase() const
361 void Stage::SetBackgroundColor(Vector4 color)
363 // Cache for public GetBackgroundColor()
364 mBackgroundColor = color;
366 // Send message to change color in next frame
367 SetBackgroundColorMessage( mUpdateManager, color );
370 Vector4 Stage::GetBackgroundColor() const
372 return mBackgroundColor;
375 Vector2 Stage::GetDpi() const
380 void Stage::SetDpi(Vector2 dpi)
385 #ifdef DYNAMICS_SUPPORT
387 DynamicsNotifier& Stage::GetDynamicsNotifier()
389 return mDynamicsNotifier;
392 DynamicsWorldPtr Stage::InitializeDynamics(DynamicsWorldConfigPtr config)
394 if( !mDynamicsFactory )
396 mDynamicsFactory = ThreadLocalStorage::Get().GetPlatformAbstraction().GetDynamicsFactory();
399 if( mDynamicsFactory && !mDynamicsWorld )
401 if( mDynamicsFactory->InitializeDynamics( *(config->GetSettings()) ) )
403 mDynamicsWorld = DynamicsWorld::New();
404 mDynamicsWorld->Initialize( *this, *mDynamicsFactory, config );
407 return mDynamicsWorld;
410 DynamicsWorldPtr Stage::GetDynamicsWorld()
412 return mDynamicsWorld;
415 void Stage::TerminateDynamics()
419 mDynamicsWorld->Terminate(*this);
420 mDynamicsWorld = NULL;
424 #endif // DYNAMICS_SUPPORT
426 void Stage::KeepRendering( float durationSeconds )
428 // Send message to keep rendering
429 KeepRenderingMessage( mUpdateManager, durationSeconds );
432 void Stage::EmitKeyEventSignal(const KeyEvent& event)
434 // Emit the key event signal when no actor in the stage has gained the key input focus
436 mKeyEventSignalV2.Emit( event );
439 void Stage::EmitEventProcessingFinishedSignal()
441 mEventProcessingFinishedSignalV2.Emit();
444 void Stage::EmitTouchedSignal( const TouchEvent& touch )
446 mTouchedSignalV2.Emit( touch );
449 Dali::Stage::KeyEventSignalV2& Stage::KeyEventSignal()
451 return mKeyEventSignalV2;
454 Dali::Stage::EventProcessingFinishedSignalV2& Stage::EventProcessingFinishedSignal()
456 return mEventProcessingFinishedSignalV2;
459 Dali::Stage::TouchedSignalV2& Stage::TouchedSignal()
461 return mTouchedSignalV2;
464 Stage::Stage( AnimationPlaylist& playlist,
465 PropertyNotificationManager& propertyNotificationManager,
466 SceneGraph::UpdateManager& updateManager,
467 NotificationManager& notificationManager )
468 : mAnimationPlaylist( playlist ),
469 mPropertyNotificationManager(propertyNotificationManager),
470 mUpdateManager(updateManager),
471 mNotificationManager(notificationManager),
472 mSize(Vector2::ZERO),
473 mBackgroundColor(Dali::Stage::DEFAULT_BACKGROUND_COLOR),
475 mStereoBase( DEFAULT_STEREO_BASE ),
476 #ifdef DYNAMICS_SUPPORT
477 mDynamicsFactory(NULL),
485 delete mSystemOverlay;
487 mObjectRegistry.Reset();
490 } // namespace Internal