(FrameCallback) Ensure Update doesn't invoke removed FrameCallbacks
[platform/core/uifw/dali-core.git] / dali / internal / event / common / stage-impl.cpp
1 /*
2  * Copyright (c) 2018 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 #include <cstring> // for strcmp
25
26 // INTERNAL INCLUDES
27 #include <dali/integration-api/system-overlay.h>
28 #include <dali/internal/event/actors/layer-impl.h>
29 #include <dali/internal/event/actors/layer-list.h>
30 #include <dali/internal/event/actors/camera-actor-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/event/update/frame-callback-interface-impl.h>
36 #include <dali/internal/update/nodes/node.h>
37 #include <dali/internal/update/manager/scene-graph-frame-callback.h>
38 #include <dali/internal/event/common/object-registry-impl.h>
39 #include <dali/integration-api/platform-abstraction.h>
40 #include <dali/public-api/common/constants.h>
41 #include <dali/public-api/events/touch-data.h>
42 #include <dali/public-api/object/type-registry.h>
43 #include <dali/public-api/render-tasks/render-task-list.h>
44 #include <dali/public-api/rendering/frame-buffer.h>
45
46 using Dali::Internal::SceneGraph::Node;
47
48 namespace
49 {
50 #if defined(DEBUG_ENABLED)
51 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_DEPTH_TIMER" );
52 #endif
53 }
54
55 namespace Dali
56 {
57
58 namespace Internal
59 {
60
61 namespace
62 {
63
64 const float DEFAULT_STEREO_BASE( 65.0f );
65
66 // Signals
67
68 const char* const SIGNAL_KEY_EVENT =                 "keyEvent";
69 const char* const SIGNAL_KEY_EVENT_GENERATED =       "keyEventGenerated";
70 const char* const SIGNAL_EVENT_PROCESSING_FINISHED = "eventProcessingFinished";
71 const char* const SIGNAL_TOUCHED =                   "touched";
72 const char* const SIGNAL_TOUCH =                     "touch";
73 const char* const SIGNAL_WHEEL_EVENT =               "wheelEvent";
74 const char* const SIGNAL_CONTEXT_LOST =              "contextLost";
75 const char* const SIGNAL_CONTEXT_REGAINED =          "contextRegained";
76 const char* const SIGNAL_SCENE_CREATED =             "sceneCreated";
77
78 TypeRegistration mType( typeid(Dali::Stage), typeid(Dali::BaseHandle), NULL );
79
80 SignalConnectorType signalConnector1( mType, SIGNAL_KEY_EVENT,                 &Stage::DoConnectSignal );
81 SignalConnectorType signalConnector2( mType, SIGNAL_EVENT_PROCESSING_FINISHED, &Stage::DoConnectSignal );
82 SignalConnectorType signalConnector3( mType, SIGNAL_TOUCHED,                   &Stage::DoConnectSignal );
83 SignalConnectorType signalConnector4( mType, SIGNAL_WHEEL_EVENT,               &Stage::DoConnectSignal );
84 SignalConnectorType signalConnector5( mType, SIGNAL_CONTEXT_LOST,              &Stage::DoConnectSignal );
85 SignalConnectorType signalConnector6( mType, SIGNAL_CONTEXT_REGAINED,          &Stage::DoConnectSignal );
86 SignalConnectorType signalConnector7( mType, SIGNAL_SCENE_CREATED,             &Stage::DoConnectSignal );
87 SignalConnectorType signalConnector8( mType, SIGNAL_KEY_EVENT_GENERATED,       &Stage::DoConnectSignal );
88 SignalConnectorType signalConnector9( mType, SIGNAL_TOUCH,                     &Stage::DoConnectSignal );
89
90 } // unnamed namespace
91
92 StagePtr Stage::New( AnimationPlaylist& playlist,
93                      PropertyNotificationManager& propertyNotificationManager,
94                      SceneGraph::UpdateManager& updateManager,
95                      NotificationManager& notificationManager,
96                      Integration::RenderController& renderController )
97 {
98   return StagePtr( new Stage( playlist, propertyNotificationManager, updateManager, notificationManager, renderController ) );
99 }
100
101 void Stage::Initialize( bool renderToFbo )
102 {
103   mRenderToFbo = renderToFbo;
104   mObjectRegistry = ObjectRegistry::New();
105
106   // Create the ordered list of layers
107   mLayerList = LayerList::New( mUpdateManager, false/*not system-level*/ );
108
109   // The stage owns the default layer
110   mRootLayer = Layer::NewRoot( *mLayerList, mUpdateManager, false/*not system-level*/ );
111   mRootLayer->SetName("RootLayer");
112   // The root layer needs to have a fixed resize policy (as opposed to the default USE_NATURAL_SIZE).
113   // This stops actors parented to the stage having their relayout requests propagating
114   // up to the root layer, and down through other children unnecessarily.
115   mRootLayer->SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
116
117   // Create the default camera actor first; this is needed by the RenderTaskList
118   CreateDefaultCameraActor();
119
120   // Create the list of render-tasks
121   mRenderTaskList = RenderTaskList::New( *this, *this, false/*not system-level*/ );
122
123   // Create the default render-task
124   Dali::RenderTask defaultRenderTask = mRenderTaskList->CreateTask();
125 }
126
127 void Stage::Uninitialize()
128 {
129   // Remove actors added to SystemOverlay
130   delete mSystemOverlay;
131   mSystemOverlay = NULL;
132
133   if( mDefaultCamera )
134   {
135     // its enough to release the handle so the object is released
136     // don't need to remove it from root actor as root actor will delete the object
137     mDefaultCamera.Reset();
138   }
139
140   if( mRootLayer )
141   {
142     // we are closing down so just delete the root, no point emit disconnect
143     // signals or send messages to update
144     mRootLayer.Reset();
145   }
146 }
147
148 StagePtr Stage::GetCurrent()
149 {
150   StagePtr stage( NULL );
151   // no checking in this version
152   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
153   if( tls )
154   {
155     stage = tls->GetCurrentStage();
156   }
157   return stage;
158 }
159
160 bool Stage::IsInstalled()
161 {
162   return ThreadLocalStorage::Created();
163 }
164
165 ObjectRegistry& Stage::GetObjectRegistry()
166 {
167   return *mObjectRegistry;
168 }
169
170 void Stage::RegisterObject( Dali::BaseObject* object )
171 {
172   mObjectRegistry->RegisterObject( object );
173 }
174
175 void Stage::UnregisterObject( Dali::BaseObject* object )
176 {
177   mObjectRegistry->UnregisterObject( object );
178 }
179
180 Layer& Stage::GetRootActor()
181 {
182   return *mRootLayer;
183 }
184
185 AnimationPlaylist& Stage::GetAnimationPlaylist()
186 {
187   return mAnimationPlaylist;
188 }
189
190 PropertyNotificationManager& Stage::GetPropertyNotificationManager()
191 {
192   return mPropertyNotificationManager;
193 }
194
195 void Stage::Add( Actor& actor )
196 {
197   mRootLayer->Add( actor );
198 }
199
200 void Stage::Remove( Actor& actor )
201 {
202   mRootLayer->Remove( actor );
203 }
204
205 void Stage::SurfaceResized( float width, float height )
206 {
207   if( ( fabsf( width - mSurfaceSize.width ) > Math::MACHINE_EPSILON_1000 ) || ( fabsf( height - mSurfaceSize.height ) > Math::MACHINE_EPSILON_1000 ) )
208   {
209     mSurfaceSize.width = width;
210     mSurfaceSize.height = height;
211
212     // Internally we want to report the actual size of the stage.
213     mSize.width = width;
214     mSize.height = height - static_cast<float>( mTopMargin );
215
216     // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
217     mDefaultCamera->SetPerspectiveProjection( mSurfaceSize );
218
219     // Adjust the camera height to allow for top-margin
220     SetDefaultCameraPosition();
221
222     mRootLayer->SetSize( mSize.width, mSize.height );
223
224     // Repeat for SystemOverlay actors
225     if( mSystemOverlay )
226     {
227       // Note that the SystemOverlay has a separate camera, configured for the full surface-size.
228       // This will remain unaffected by changes in SetDefaultCameraPosition()
229       mSystemOverlay->GetImpl()->SetSize( width, height );
230     }
231
232     SetDefaultSurfaceRectMessage( mUpdateManager, Rect<int32_t>( 0, 0, static_cast<int32_t>( width ), static_cast<int32_t>( height ) ) ); // truncated
233
234     // if single render task to screen then set its viewport parameters
235     if( 1 == mRenderTaskList->GetTaskCount() )
236     {
237       Dali::RenderTask defaultRenderTask = mRenderTaskList->GetTask( 0u );
238
239       if(!defaultRenderTask.GetTargetFrameBuffer())
240       {
241         defaultRenderTask.SetViewport( Viewport( 0, 0, static_cast<int32_t>( width ), static_cast<int32_t>( height ) ) ); // truncated
242       }
243     }
244
245     if( mRenderToFbo )
246     {
247       Dali::FrameBuffer frameBuffer = Dali::FrameBuffer::New( static_cast<uint32_t>( width ), static_cast<uint32_t>( height ), Dali::FrameBuffer::Attachment::NONE );
248       Dali::Texture texture = Dali::Texture::New( Dali::TextureType::TEXTURE_2D, Dali::Pixel::RGB888, static_cast<uint32_t>( width ), static_cast<uint32_t>( height ) );
249       frameBuffer.AttachColorTexture( texture );
250
251       Dali::RenderTask defaultRenderTask = mRenderTaskList->GetTask( 0u );
252       defaultRenderTask.SetFrameBuffer( frameBuffer );
253     }
254   }
255 }
256
257 Vector2 Stage::GetSize() const
258 {
259   return mSize;
260 }
261
262 void Stage::SetTopMargin( uint32_t margin )
263 {
264   if (mTopMargin == margin)
265   {
266     return;
267   }
268   mTopMargin = margin;
269
270   mSize.width = mSurfaceSize.width;
271   mSize.height = mSurfaceSize.height - static_cast<float>( mTopMargin );
272
273   // Adjust the camera height to allow for top-margin
274   SetDefaultCameraPosition();
275
276   mRootLayer->SetSize( mSize.width, mSize.height );
277 }
278
279 RenderTaskList& Stage::GetRenderTaskList() const
280 {
281   return *mRenderTaskList;
282 }
283
284 void Stage::CreateDefaultCameraActor()
285 {
286   // The default camera attributes and position is such that
287   // children of the default layer, can be positioned at (0,0) and
288   // be at the top-left of the viewport.
289   mDefaultCamera = CameraActor::New( Size::ZERO );
290   mDefaultCamera->SetParentOrigin(ParentOrigin::CENTER);
291   Add(*(mDefaultCamera.Get()));
292 }
293
294 void Stage::SetDefaultCameraPosition()
295 {
296   mDefaultCamera->SetY( -(static_cast<float>(mTopMargin) * 0.5f) );
297 }
298
299 Actor& Stage::GetDefaultRootActor()
300 {
301   return *mRootLayer;
302 }
303
304 CameraActor& Stage::GetDefaultCameraActor()
305 {
306   return *mDefaultCamera;
307 }
308
309 uint32_t Stage::GetLayerCount() const
310 {
311   return mLayerList->GetLayerCount();
312 }
313
314 Dali::Layer Stage::GetLayer( uint32_t depth ) const
315 {
316   return Dali::Layer(mLayerList->GetLayer( depth ));
317 }
318
319 Dali::Layer Stage::GetRootLayer() const
320 {
321   return Dali::Layer( mRootLayer.Get() );
322 }
323
324 LayerList& Stage::GetLayerList()
325 {
326   return *mLayerList;
327 }
328
329 Integration::SystemOverlay& Stage::GetSystemOverlay()
330 {
331   // Lazily create system-level if requested
332   if( !mSystemOverlay )
333   {
334     mSystemOverlay = new Integration::SystemOverlay( SystemOverlay::New( *this ) );
335     DALI_ASSERT_ALWAYS( NULL != mSystemOverlay && "Failed to create system overlay" );
336
337     mSystemOverlay->GetImpl()->SetSize( mSize.width, mSize.height );
338   }
339
340   return *mSystemOverlay;
341 }
342
343 SystemOverlay* Stage::GetSystemOverlayInternal()
344 {
345   SystemOverlay* overlay( NULL );
346
347   if( mSystemOverlay )
348   {
349     overlay = mSystemOverlay->GetImpl();
350   }
351
352   return overlay;
353 }
354
355 void Stage::SetViewMode( ViewMode viewMode )
356 {
357   if( mViewMode != viewMode )
358   {
359     DALI_LOG_INFO( Debug::Filter::gActor, Debug::Concise, "View mode changed from %d to %d\n", mViewMode, viewMode);
360
361     if( mViewMode == MONO )
362     {
363       mDefaultCamera->SetOrientation( Dali::ANGLE_180, Vector3::YAXIS );
364       mRenderTaskList->GetTask(0).SetSourceActor( Dali::Actor() );
365
366       //Create camera and RenderTask for left eye
367       mLeftCamera = CameraActor::New( Size::ZERO );
368       mLeftCamera->SetParentOrigin( ParentOrigin::CENTER );
369       mDefaultCamera->Add( *mLeftCamera.Get() );
370       mLeftRenderTask = mRenderTaskList->CreateTask();
371       mLeftRenderTask.SetCameraActor( Dali::CameraActor( mLeftCamera.Get() ) );
372       mLeftCamera->SetType( Dali::Camera::FREE_LOOK );
373
374       //Create camera and RenderTask for right eye
375       mRightCamera = CameraActor::New( Size::ZERO );
376       mRightCamera->SetParentOrigin( ParentOrigin::CENTER );
377       mDefaultCamera->Add( *mRightCamera.Get() );
378       mRightRenderTask = mRenderTaskList->CreateTask();
379       mRightRenderTask.SetClearColor( Vector4( 1.0f,0.0f,0.0f,1.0f));
380
381       mRightRenderTask.SetCameraActor( Dali::CameraActor( mRightCamera.Get() ) );
382       mRightCamera->SetType( Dali::Camera::FREE_LOOK );
383     }
384
385     // save new mode
386     mViewMode = viewMode;
387
388     switch( viewMode )
389     {
390       case MONO:
391       {
392         // delete extra stereoscopic render tasks and cameras
393         mRenderTaskList->RemoveTask( mLeftRenderTask );
394         mDefaultCamera->Remove( *mLeftCamera.Get() );
395         mLeftRenderTask.Reset();
396         mLeftCamera.Reset();
397         mRenderTaskList->RemoveTask( mRightRenderTask );
398         mDefaultCamera->Remove( *mRightCamera.Get() );
399         mRightRenderTask.Reset();
400         mRightCamera.Reset();
401         mDefaultCamera->SetOrientation( Dali::ANGLE_0, Vector3::YAXIS );
402         mDefaultCamera->SetType( Dali::Camera::LOOK_AT_TARGET );
403         mRenderTaskList->GetTask(0).SetSourceActor( Dali::Layer(mRootLayer.Get()) );
404
405         break;
406       }
407       case STEREO_HORIZONTAL:
408       {
409         //Stereo mode with horizontal split is for landscape mode. That's the reason for the cameras being rotated
410         //Top camera renders the scene as seen from the right eye and bottom camera as seen from left.
411
412         //Calculate separation in pixels along vertical axis ( mStereoBase is defined in millimetres )
413         const float stereoBase( ( (mStereoBase / 25.4f) * GetDpi().y ) * 0.5f );
414
415         //Calculate aspect ratio
416         float aspect = mSize.width / (mSize.height * 0.5f);
417
418         mLeftCamera->SetPerspectiveProjection( mSize, Vector2( 0.0f,stereoBase) );
419         mLeftCamera->SetAspectRatio( aspect );
420
421         mLeftCamera->SetOrientation( -Dali::ANGLE_90, Vector3::ZAXIS );
422         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
423         mLeftRenderTask.SetViewport( Viewport(0, static_cast<int32_t>( mSize.height * 0.5f ), static_cast<int32_t>( mSize.width ), static_cast<int32_t>( mSize.height * 0.5f ) ) ); // truncated
424
425         mRightCamera->SetPerspectiveProjection( mSize, Vector2( 0.0,  -stereoBase ) );
426         mRightCamera->SetAspectRatio( aspect );
427         mRightCamera->SetOrientation( -Dali::ANGLE_90, Vector3::ZAXIS );
428         mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
429         mRightRenderTask.SetViewport( Viewport(0, 0, static_cast<int32_t>( mSize.width ), static_cast<int32_t>( mSize.height * 0.5f ) ) ); // truncated
430
431         break;
432       }
433       case STEREO_VERTICAL:
434       {
435         //Calculate separation in pixels along horizontal axis
436         const float stereoBase( ( (mStereoBase / 25.4f) * GetDpi().x ) * 0.5f );
437
438         //Recalculate fov based on viewport size
439         const float fov = 2.0f * std::atan(  mSize.y / (2.0f * std::max( mSize.x*0.5f, mSize.y )) );
440
441         mLeftCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(stereoBase,0.0f) );
442         mLeftCamera->SetFieldOfView( fov );
443         mLeftCamera->SetOrientation( Dali::ANGLE_0, Vector3::ZAXIS );
444         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
445         mLeftRenderTask.SetViewport( Viewport(0, 0, static_cast<int32_t>( mSize.width * 0.5f ), static_cast<int32_t>( mSize.height ) ) ); // truncated
446
447         mRightCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(-stereoBase,0.0f) );
448         mRightCamera->SetFieldOfView( fov );
449         mRightCamera->SetOrientation( Dali::ANGLE_0, Vector3::ZAXIS );
450         mRightCamera->SetPosition( Vector3( -stereoBase, 0.0f, 0.0f ) );
451         mRightRenderTask.SetViewport( Viewport( static_cast<int32_t>( mSize.width * 0.5f ), 0, static_cast<int32_t>( mSize.width * 0.5f ), static_cast<int32_t>( mSize.height ) ) ); // truncated
452
453         break;
454       }
455       case STEREO_INTERLACED:
456       {
457         break;
458       }
459     }
460   }
461 }
462
463 ViewMode Stage::GetViewMode() const
464 {
465   return mViewMode;
466 }
467
468 void Stage::SetStereoBase( float stereoBase )
469 {
470   if( ! Equals( mStereoBase, stereoBase ) )
471   {
472     DALI_LOG_INFO( Debug::Filter::gActor, Debug::Concise, "old( %.2f) new(%.2f)\n", mStereoBase, stereoBase );
473     mStereoBase = stereoBase;
474
475     switch( mViewMode  )
476     {
477       case STEREO_HORIZONTAL:
478       {
479         stereoBase = mStereoBase / 25.4f * GetDpi().y * 0.5f;
480         float aspect = mSize.width / (mSize.height * 0.5f);
481
482         mLeftCamera->SetPerspectiveProjection( mSize, Vector2( 0.0, stereoBase) );
483         mLeftCamera->SetAspectRatio( aspect );
484         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
485
486         mRightCamera->SetPerspectiveProjection( mSize, Vector2( 0.0, -stereoBase) );
487         mRightCamera->SetAspectRatio( aspect );
488         mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
489
490         break;
491       }
492       case STEREO_VERTICAL:
493       {
494         stereoBase = mStereoBase / 25.4f * GetDpi().x * 0.5f;
495         const float fov = 2.0f * std::atan(  mSize.y / (2.0f * std::max( mSize.x*0.5f, mSize.y )) );
496
497         mLeftCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(stereoBase,0.0f) );
498         mLeftCamera->SetFieldOfView( fov );
499         mLeftCamera->SetPosition( Vector3( stereoBase, 0.0f, 0.0f ) );
500
501         mRightCamera->SetPerspectiveProjection( Size( mSize.x * 0.5f, mSize.y ), Vector2(-stereoBase,0.0f) );
502         mRightCamera->SetFieldOfView( fov );
503         mRightCamera->SetPosition( Vector3(-stereoBase, 0.0f, 0.0f ) );
504
505         break;
506       }
507       default:
508         break;
509     }
510   }
511 }
512
513 float Stage::GetStereoBase() const
514 {
515   return mStereoBase;
516 }
517
518 void Stage::SetBackgroundColor(Vector4 color)
519 {
520   // Cache for public GetBackgroundColor()
521   mBackgroundColor = color;
522
523   // Send message to change color in next frame
524   SetBackgroundColorMessage( mUpdateManager, color );
525 }
526
527 Vector4 Stage::GetBackgroundColor() const
528 {
529   return mBackgroundColor;
530 }
531
532 Vector2 Stage::GetDpi() const
533 {
534   return mDpi;
535 }
536
537 void Stage::SetDpi(Vector2 dpi)
538 {
539   mDpi = dpi;
540 }
541
542 void Stage::KeepRendering( float durationSeconds )
543 {
544   // Send message to keep rendering
545   KeepRenderingMessage( mUpdateManager, durationSeconds );
546 }
547
548 void Stage::SetRenderingBehavior( DevelStage::Rendering renderingBehavior )
549 {
550   if( mRenderingBehavior != renderingBehavior )
551   {
552     // Send message to change the rendering behavior
553     SetRenderingBehaviorMessage( mUpdateManager, renderingBehavior );
554
555     mRenderingBehavior = renderingBehavior;
556   }
557 }
558
559 DevelStage::Rendering Stage::GetRenderingBehavior() const
560 {
561   return mRenderingBehavior;
562 }
563
564 bool Stage::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
565 {
566   bool connected( true );
567   Stage* stage = static_cast< Stage* >(object); // TypeRegistry guarantees that this is the correct type.
568
569   if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_EVENT ) )
570   {
571     stage->KeyEventSignal().Connect( tracker, functor );
572   }
573   else if( 0 == strcmp( signalName.c_str(), SIGNAL_KEY_EVENT_GENERATED ) )
574   {
575     stage->KeyEventGeneratedSignal().Connect( tracker, functor );
576   }
577   else if( 0 == strcmp( signalName.c_str(), SIGNAL_EVENT_PROCESSING_FINISHED ) )
578   {
579     stage->EventProcessingFinishedSignal().Connect( tracker, functor );
580   }
581   else if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCHED ) )
582   {
583     stage->TouchedSignal().Connect( tracker, functor );
584   }
585   else if( 0 == strcmp( signalName.c_str(), SIGNAL_TOUCH ) )
586   {
587     stage->TouchSignal().Connect( tracker, functor );
588   }
589   else if( 0 == strcmp( signalName.c_str(), SIGNAL_WHEEL_EVENT ) )
590   {
591     stage->WheelEventSignal().Connect( tracker, functor );
592   }
593   else if( 0 == strcmp( signalName.c_str(), SIGNAL_CONTEXT_LOST ) )
594   {
595     stage->ContextLostSignal().Connect( tracker, functor );
596   }
597   else if( 0 == strcmp( signalName.c_str(), SIGNAL_CONTEXT_REGAINED ) )
598   {
599     stage->ContextRegainedSignal().Connect( tracker, functor );
600   }
601   else if( 0 == strcmp( signalName.c_str(), SIGNAL_SCENE_CREATED ) )
602   {
603     stage->SceneCreatedSignal().Connect( tracker, functor );
604   }
605   else
606   {
607     // signalName does not match any signal
608     connected = false;
609   }
610
611   return connected;
612 }
613
614 void Stage::EmitKeyEventSignal(const KeyEvent& event)
615 {
616   // Emit the key event signal when no actor in the stage has gained the key input focus
617
618   mKeyEventSignal.Emit( event );
619 }
620
621 bool Stage::EmitKeyEventGeneratedSignal(const KeyEvent& event)
622 {
623   // Emit the KeyEventGenerated signal when KeyEvent is generated
624
625   return mKeyEventGeneratedSignal.Emit( event );
626 }
627
628 void Stage::EmitEventProcessingFinishedSignal()
629 {
630    mEventProcessingFinishedSignal.Emit();
631 }
632
633 void Stage::EmitTouchedSignal( const TouchEvent& touchEvent, const Dali::TouchData& touch )
634 {
635   mTouchedSignal.Emit( touchEvent );
636   mTouchSignal.Emit( touch );
637 }
638
639 void Stage::EmitWheelEventSignal(const WheelEvent& event)
640 {
641   // Emit the wheel event signal when no actor in the stage has gained the wheel input focus
642
643   mWheelEventSignal.Emit( event );
644 }
645
646 void Stage::EmitSceneCreatedSignal()
647 {
648   mSceneCreatedSignal.Emit();
649 }
650
651 Dali::Stage::KeyEventSignalType& Stage::KeyEventSignal()
652 {
653   return mKeyEventSignal;
654 }
655
656 Dali::DevelStage::KeyEventGeneratedSignalType& Stage::KeyEventGeneratedSignal()
657 {
658   return mKeyEventGeneratedSignal;
659 }
660
661 void Stage::AddFrameCallback( FrameCallbackInterface& frameCallback, Actor& rootActor )
662 {
663   DALI_ASSERT_ALWAYS( ( ! FrameCallbackInterface::Impl::Get( frameCallback ).IsConnectedToSceneGraph() )
664                       && "FrameCallbackInterface implementation already added" );
665
666   // Create scene-graph object and transfer to UpdateManager
667   OwnerPointer< SceneGraph::FrameCallback > transferOwnership( SceneGraph::FrameCallback::New( frameCallback ) );
668   AddFrameCallbackMessage( mUpdateManager, transferOwnership, rootActor.GetNode() );
669 }
670
671 void Stage::RemoveFrameCallback( FrameCallbackInterface& frameCallback )
672 {
673   FrameCallbackInterface::Impl::Get( frameCallback ).Invalidate();
674   RemoveFrameCallbackMessage( mUpdateManager, frameCallback );
675 }
676
677 Dali::Stage::EventProcessingFinishedSignalType& Stage::EventProcessingFinishedSignal()
678 {
679   return mEventProcessingFinishedSignal;
680 }
681
682 Dali::Stage::TouchedSignalType& Stage::TouchedSignal()
683 {
684   DALI_LOG_WARNING( "Deprecated. Use TouchSignal() instead.\n" );
685   return mTouchedSignal;
686 }
687
688 Dali::Stage::TouchSignalType& Stage::TouchSignal()
689 {
690   return mTouchSignal;
691 }
692
693 Dali::Stage::WheelEventSignalType& Stage::WheelEventSignal()
694 {
695   return mWheelEventSignal;
696 }
697
698 Dali::Stage::ContextStatusSignal& Stage::ContextLostSignal()
699 {
700   return mContextLostSignal;
701 }
702
703 Dali::Stage::ContextStatusSignal& Stage::ContextRegainedSignal()
704 {
705   return mContextRegainedSignal;
706 }
707
708 Dali::Stage::SceneCreatedSignalType& Stage::SceneCreatedSignal()
709 {
710   return mSceneCreatedSignal;
711 }
712
713 void Stage::NotifyContextLost()
714 {
715   mContextLostSignal.Emit();
716 }
717
718 void Stage::NotifyContextRegained()
719 {
720   mContextRegainedSignal.Emit();
721 }
722
723
724 void Stage::RequestRebuildDepthTree()
725 {
726   DALI_LOG_INFO(gLogFilter, Debug::General, "RequestRebuildDepthTree()\n");
727   mDepthTreeDirty = true;
728 }
729
730 void Stage::RebuildDepthTree()
731 {
732   // If the depth tree needs rebuilding, do it in this frame only.
733   if( mDepthTreeDirty )
734   {
735     DALI_LOG_INFO(gLogFilter, Debug::Concise, "RebuildDepthTree() dirty:T\n");
736
737     ActorPtr actor( mRootLayer.Get() );
738     actor->RebuildDepthTree();
739     mDepthTreeDirty = false;
740   }
741 }
742
743
744 Stage::Stage( AnimationPlaylist& playlist,
745               PropertyNotificationManager& propertyNotificationManager,
746               SceneGraph::UpdateManager& updateManager,
747               NotificationManager& notificationManager,
748               Integration::RenderController& renderController )
749 : mAnimationPlaylist( playlist ),
750   mPropertyNotificationManager( propertyNotificationManager ),
751   mUpdateManager( updateManager ),
752   mNotificationManager( notificationManager ),
753   mRenderController( renderController ),
754   mSize( Vector2::ZERO ),
755   mSurfaceSize( Vector2::ZERO ),
756   mBackgroundColor( Dali::Stage::DEFAULT_BACKGROUND_COLOR ),
757   mViewMode( MONO ),
758   mStereoBase( DEFAULT_STEREO_BASE ),
759   mTopMargin( 0 ),
760   mDpi( Vector2::ZERO ),
761   mRightRenderTask(),
762   mLeftRenderTask(),
763   mSystemOverlay( NULL ),
764   mKeyEventSignal(),
765   mKeyEventGeneratedSignal(),
766   mEventProcessingFinishedSignal(),
767   mTouchedSignal(),
768   mTouchSignal(),
769   mWheelEventSignal(),
770   mContextLostSignal(),
771   mContextRegainedSignal(),
772   mSceneCreatedSignal(),
773   mRenderingBehavior( DevelStage::Rendering::IF_REQUIRED ),
774   mDepthTreeDirty( false ),
775   mForceNextUpdate( false ),
776   mRenderToFbo( false )
777 {
778 }
779
780 SceneGraph::UpdateManager& Stage::GetUpdateManager()
781 {
782   return mUpdateManager;
783 }
784
785 Integration::RenderController& Stage::GetRenderController()
786 {
787   return mRenderController;
788 }
789
790 uint32_t* Stage::ReserveMessageSlot( uint32_t size, bool updateScene )
791 {
792   return mUpdateManager.ReserveMessageSlot( size, updateScene );
793 }
794
795 BufferIndex Stage::GetEventBufferIndex() const
796 {
797   return mUpdateManager.GetEventBufferIndex();
798 }
799
800 void Stage::ForceNextUpdate()
801 {
802   mForceNextUpdate = true;
803 }
804
805 bool Stage::IsNextUpdateForced()
806 {
807   bool nextUpdateForced = mForceNextUpdate;
808   mForceNextUpdate = false;
809   return nextUpdateForced;
810 }
811
812 Stage::~Stage()
813 {
814   delete mSystemOverlay;
815
816   mObjectRegistry.Reset();
817 }
818
819 } // namespace Internal
820
821 } // namespace Dali