2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/event/common/stage-impl.h>
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>
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>
48 using namespace boost;
50 using Dali::Internal::SceneGraph::Node;
61 const float DEFAULT_STEREO_BASE( 65.0f );
63 } // unnamed namespace
65 StagePtr Stage::New( AnimationPlaylist& playlist,
66 PropertyNotificationManager& propertyNotificationManager,
67 SceneGraph::UpdateManager& updateManager,
68 NotificationManager& notificationManager )
70 return StagePtr( new Stage( playlist, propertyNotificationManager, updateManager, notificationManager ) );
73 void Stage::Initialize()
75 mObjectRegistry = ObjectRegistry::New();
77 // Create the ordered list of layers
78 mLayerList = LayerList::New( *this, false/*not system-level*/ );
80 // The stage owns the default layer
81 mRootLayer = Layer::NewRoot( *this, *mLayerList, mUpdateManager, false/*not system-level*/ );
82 mRootLayer->SetName("RootLayer");
84 // Create the default camera actor first; this is needed by the RenderTaskList
85 CreateDefaultCameraActor();
87 // Create the list of render-tasks
88 mRenderTaskList = RenderTaskList::New( mUpdateManager, *this, false/*not system-level*/ );
90 // Create the default render-task
91 Dali::RenderTask defaultRenderTask = mRenderTaskList->CreateTask();
94 void Stage::Uninitialize()
96 // Remove actors added to SystemOverlay
97 delete mSystemOverlay;
98 mSystemOverlay = NULL;
102 Remove(*(mDefaultCamera.Get()));
107 // we are closing down so just delete the root, no point emit disconnect
108 // signals or send messages to update
113 StagePtr Stage::GetCurrent()
115 return ThreadLocalStorage::Get().GetCurrentStage();
118 bool Stage::IsInstalled()
120 return ThreadLocalStorage::Created();
123 ObjectRegistry& Stage::GetObjectRegistry()
125 return *mObjectRegistry;
128 Layer& Stage::GetRootActor()
133 SceneGraph::UpdateManager& Stage::GetUpdateManager()
135 return mUpdateManager;
138 EventToUpdate& Stage::GetUpdateInterface()
140 return mUpdateManager.GetEventToUpdate();
143 AnimationPlaylist& Stage::GetAnimationPlaylist()
145 return mAnimationPlaylist;
148 PropertyNotificationManager& Stage::GetPropertyNotificationManager()
150 return mPropertyNotificationManager;
153 void Stage::Add( Actor& actor )
155 mRootLayer->Add( actor );
158 void Stage::Remove( Actor& actor )
160 mRootLayer->Remove( actor );
163 void Stage::SetSize(float width, float height)
165 // Internally we want to report the actual size of the stage.
167 mSize.height = height;
169 // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
170 mDefaultCamera->SetPerspectiveProjection( mSize );
172 // The depth of the stage gets set to the maximun of these values
173 mRootLayer->SetSize( mSize );
175 // Repeat for SystemOverlay actors
178 mSystemOverlay->GetImpl()->SetSize( mSize.width, mSize.height );
181 SetDefaultSurfaceRectMessage( mUpdateManager, Rect<int>( 0, 0, width, height ) );
184 Vector2 Stage::GetSize() const
189 RenderTaskList& Stage::GetRenderTaskList() const
191 return *mRenderTaskList;
194 void Stage::CreateDefaultCameraActor()
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()));
204 Actor& Stage::GetDefaultRootActor()
209 CameraActor& Stage::GetDefaultCameraActor()
211 return *mDefaultCamera;
214 unsigned int Stage::GetLayerCount() const
216 return mLayerList->GetLayerCount();
219 Dali::Layer Stage::GetLayer( unsigned int depth ) const
221 return Dali::Layer(mLayerList->GetLayer( depth ));
224 Dali::Layer Stage::GetRootLayer() const
226 return Dali::Layer( mRootLayer.Get() );
229 LayerList& Stage::GetLayerList()
234 Integration::SystemOverlay& Stage::GetSystemOverlay()
236 // Lazily create system-level if requested
237 if( !mSystemOverlay )
239 mSystemOverlay = new Integration::SystemOverlay( SystemOverlay::New( *this ) );
240 DALI_ASSERT_ALWAYS( NULL != mSystemOverlay && "Failed to create system overlay" );
242 mSystemOverlay->GetImpl()->SetSize( mSize.width, mSize.height );
245 return *mSystemOverlay;
248 SystemOverlay* Stage::GetSystemOverlayInternal()
250 SystemOverlay* overlay( NULL );
254 overlay = mSystemOverlay->GetImpl();
260 void Stage::SetViewMode( ViewMode viewMode )
262 if( mViewMode != viewMode )
264 DALI_LOG_INFO( Debug::Filter::gActor, Debug::Concise, "View mode changed from %d to %d\n", mViewMode, viewMode);
266 const float stereoBase( ( (mStereoBase / 25.4f) * GetDpi().x ) * 0.5f );
268 if( mViewMode == MONO )
270 mDefaultCamera->SetRotation( Degree( 180.0f ), Vector3::YAXIS );
271 mRenderTaskList->GetTask(0).SetSourceActor( Dali::Actor() );
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 );
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 );
293 mViewMode = viewMode;
299 // delete extra stereoscopic render tasks and cameras
300 mRenderTaskList->RemoveTask( mLeftRenderTask );
301 mDefaultCamera->Remove( *mLeftCamera.Get() );
302 mLeftRenderTask.Reset();
304 mRenderTaskList->RemoveTask( mRightRenderTask );
305 mDefaultCamera->Remove( *mRightCamera.Get() );
306 mRightRenderTask.Reset();
307 mRightCamera.Reset();
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()) );
314 case STEREO_HORIZONTAL:
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) );
320 case STEREO_VERTICAL:
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 ) );
326 case STEREO_INTERLACED:
334 ViewMode Stage::GetViewMode() const
339 void Stage::SetStereoBase( float stereoBase )
341 if( ! Equals( mStereoBase, stereoBase ) )
343 DALI_LOG_INFO( Debug::Filter::gActor, Debug::Concise, "old( %.2f) new(%.2f)", mStereoBase, stereoBase );
344 mStereoBase = stereoBase;
346 if( mViewMode != MONO )
349 mLeftCamera->SetX( stereoBase );
350 mLeftCamera->SetPerspectiveProjection( mSize, stereoBase );
351 mRightCamera->SetX( -stereoBase );
352 mRightCamera->SetPerspectiveProjection( mSize, -stereoBase );
357 float Stage::GetStereoBase() const
362 void Stage::SetBackgroundColor(Vector4 color)
364 // Cache for public GetBackgroundColor()
365 mBackgroundColor = color;
367 // Send message to change color in next frame
368 SetBackgroundColorMessage( mUpdateManager, color );
371 Vector4 Stage::GetBackgroundColor() const
373 return mBackgroundColor;
376 Vector2 Stage::GetDpi() const
381 void Stage::SetDpi(Vector2 dpi)
386 #ifdef DYNAMICS_SUPPORT
388 DynamicsNotifier& Stage::GetDynamicsNotifier()
390 return mDynamicsNotifier;
393 DynamicsWorldPtr Stage::InitializeDynamics(DynamicsWorldConfigPtr config)
395 if( !mDynamicsFactory )
397 mDynamicsFactory = ThreadLocalStorage::Get().GetPlatformAbstraction().GetDynamicsFactory();
400 if( mDynamicsFactory && !mDynamicsWorld )
402 if( mDynamicsFactory->InitializeDynamics( *(config->GetSettings()) ) )
404 mDynamicsWorld = DynamicsWorld::New();
405 mDynamicsWorld->Initialize( *this, *mDynamicsFactory, config );
408 return mDynamicsWorld;
411 DynamicsWorldPtr Stage::GetDynamicsWorld()
413 return mDynamicsWorld;
416 void Stage::TerminateDynamics()
420 mDynamicsWorld->Terminate(*this);
421 mDynamicsWorld = NULL;
425 #endif // DYNAMICS_SUPPORT
427 void Stage::KeepRendering( float durationSeconds )
429 // Send message to keep rendering
430 KeepRenderingMessage( mUpdateManager, durationSeconds );
433 void Stage::EmitKeyEventSignal(const KeyEvent& event)
435 // Emit the key event signal when no actor in the stage has gained the key input focus
437 mKeyEventSignalV2.Emit( event );
440 void Stage::EmitEventProcessingFinishedSignal()
442 mEventProcessingFinishedSignalV2.Emit();
445 void Stage::EmitTouchedSignal( const TouchEvent& touch )
447 mTouchedSignalV2.Emit( touch );
450 Dali::Stage::KeyEventSignalV2& Stage::KeyEventSignal()
452 return mKeyEventSignalV2;
455 Dali::Stage::EventProcessingFinishedSignalV2& Stage::EventProcessingFinishedSignal()
457 return mEventProcessingFinishedSignalV2;
460 Dali::Stage::TouchedSignalV2& Stage::TouchedSignal()
462 return mTouchedSignalV2;
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),
476 mStereoBase( DEFAULT_STEREO_BASE ),
477 #ifdef DYNAMICS_SUPPORT
478 mDynamicsFactory(NULL),
486 delete mSystemOverlay;
488 mObjectRegistry.Reset();
491 } // namespace Internal