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