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