[Tizen] Implement partial update
[platform/core/uifw/dali-core.git] / dali / internal / event / common / scene-impl.cpp
old mode 100644 (file)
new mode 100755 (executable)
index b30aa0c..82f5196
@@ -48,22 +48,22 @@ const Vector4 DEFAULT_BACKGROUND_COLOR(0.0f, 0.0f, 0.0f, 1.0f); // Default backg
 
 } //Unnamed namespace
 
-ScenePtr Scene::New( const Size& size )
+ScenePtr Scene::New( Integration::RenderSurface& surface )
 {
-  ScenePtr scene = new Scene( size );
+  ScenePtr scene = new Scene;
 
   // Second-phase construction
-  scene->Initialize();
+  scene->Initialize( surface );
 
   return scene;
 }
 
-Scene::Scene( const Size& size )
+Scene::Scene()
 : mSurface( nullptr ),
-  mSize( size ),
-  mSurfaceSize( Vector2::ZERO ),
-  mDpi( Vector2::ZERO ),
+  mSize(), // Don't set the proper value here, this will be set when the surface is set later
+  mDpi(),
   mBackgroundColor( DEFAULT_BACKGROUND_COLOR ),
+  mSurfaceOrientation( 0 ),
   mDepthTreeDirty( false ),
   mEventProcessor( *this, ThreadLocalStorage::GetInternal()->GetGestureEventProcessor() )
 {
@@ -90,11 +90,16 @@ Scene::~Scene()
     mRenderTaskList.Reset();
   }
 
-  // Discard this Scene from the Core
-  Discard();
+  if ( mFrameBuffer )
+  {
+    mFrameBuffer.Reset();
+  }
+
+  // No need to discard this Scene from Core, as Core stores an intrusive_ptr to this scene
+  // When this destructor is called, the scene has either already been removed from Core or Core has already been destroyed
 }
 
-void Scene::Initialize()
+void Scene::Initialize( Integration::RenderSurface& surface )
 {
   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
 
@@ -120,7 +125,9 @@ void Scene::Initialize()
   // Create the default camera actor first; this is needed by the RenderTaskList
   // The default camera attributes and position is such that children of the default layer,
   // can be positioned at (0,0) and be at the top-left of the viewport.
-  mDefaultCamera = CameraActor::New( mSize );
+  const PositionSize positionSize = surface.GetPositionSize();
+  const Vector2 surfaceSize( static_cast< float >( positionSize.width ), static_cast< float >( positionSize.height ) );
+  mDefaultCamera = CameraActor::New( surfaceSize );
   mDefaultCamera->SetParentOrigin(ParentOrigin::CENTER);
   Add(*(mDefaultCamera.Get()));
 
@@ -129,6 +136,9 @@ void Scene::Initialize()
 
   // Create the default render-task
   mRenderTaskList->CreateTask( mRootLayer.Get(), mDefaultCamera.Get() );
+
+  // Set the surface
+  SetSurface( surface );
 }
 
 void Scene::Add(Actor& actor)
@@ -139,6 +149,10 @@ void Scene::Add(Actor& actor)
 void Scene::Remove(Actor& actor)
 {
   mRootLayer->Remove( actor );
+  if( mSurface )
+  {
+    mRenderTaskList->GetTask( 0u )->GetFrameBuffer()->SetPartialUpdateEnabled( false );
+  }
 }
 
 Size Scene::GetSize() const
@@ -193,60 +207,67 @@ Actor& Scene::GetDefaultRootActor()
 
 void Scene::SetSurface( Integration::RenderSurface& surface )
 {
-  mSurface = &surface;
-  if ( mSurface )
+  if( mSurface != &surface )
   {
+    mSurface = &surface;
+
     RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask( 0u );
 
     mFrameBuffer = Dali::Internal::FrameBuffer::New( surface, Dali::FrameBuffer::Attachment::NONE );
     defaultRenderTask->SetFrameBuffer( mFrameBuffer );
 
-    SurfaceResized();
+    SurfaceResized( false );
   }
 }
 
-void Scene::SurfaceResized()
+void Scene::SurfaceResized( bool forceUpdate )
 {
   if( mSurface )
   {
-    const float fWidth = static_cast<float>( mSurface->GetPositionSize().width );
-    const float fHeight = static_cast<float>( mSurface->GetPositionSize().height );
-
-    if( ( fabsf( mSurfaceSize.width - fWidth ) > Math::MACHINE_EPSILON_1 ) || ( fabsf( mSurfaceSize.height - fHeight ) > Math::MACHINE_EPSILON_1 ) )
+    const PositionSize surfacePositionSize = mSurface->GetPositionSize();
+    const float fWidth = static_cast< float >( surfacePositionSize.width );
+    const float fHeight = static_cast< float >( surfacePositionSize.height );
+    const int orientation = mSurface->GetOrientation();
+
+    if( ( ( fabsf( mSize.width - fWidth ) > Math::MACHINE_EPSILON_1 ) || ( fabsf( mSize.height - fHeight ) > Math::MACHINE_EPSILON_1 ) )
+            || ( orientation != mSurfaceOrientation )
+            || ( forceUpdate ) )
     {
-      Rect<int32_t> newSize( 0, 0, static_cast<int32_t>( mSurface->GetPositionSize().width ), static_cast<int32_t>( mSurface->GetPositionSize().height ) );
+      Rect< int32_t > newSize( 0, 0, static_cast< int32_t >( surfacePositionSize.width ), static_cast< int32_t >( surfacePositionSize.height ) ); // truncated
 
-      mSurfaceSize.width = fWidth;
-      mSurfaceSize.height = fHeight;
-
-      mSize.width = mSurfaceSize.width;
-      mSize.height = mSurfaceSize.height;
+      mSize.width = fWidth;
+      mSize.height = fHeight;
+      mSurfaceOrientation = orientation;
 
       // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
-      mDefaultCamera->SetPerspectiveProjection( mSurfaceSize );
+      mDefaultCamera->SetPerspectiveProjection( mSize );
+      mDefaultCamera->RotateProjection( mSurfaceOrientation );
 
       mRootLayer->SetSize( mSize.width, mSize.height );
 
       ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
       SceneGraph::UpdateManager& updateManager = tls->GetUpdateManager();
-      SetDefaultSurfaceRectMessage( updateManager, newSize ); // truncated
+      SetDefaultSurfaceRectMessage( updateManager, newSize );
+      SetDefaultSurfaceOrientationMessage( updateManager, mSurfaceOrientation );
 
+      // set default render-task viewport parameters
       RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask( 0u );
-
-      // if single render task to screen then set its viewport parameters
-      if( 1 == mRenderTaskList->GetTaskCount() )
-      {
-        if( !defaultRenderTask->GetTargetFrameBuffer() )
-        {
-          defaultRenderTask->SetViewport( newSize ); // truncated
-        }
-      }
-
+      defaultRenderTask->SetViewport( newSize );
       defaultRenderTask->GetFrameBuffer()->SetSize( static_cast<uint32_t>( newSize.width ), static_cast<uint32_t>( newSize.height ) );
     }
   }
 }
 
+void Scene::SurfaceDeleted()
+{
+  mSurface = nullptr;
+  if ( mFrameBuffer )
+  {
+    // The frame buffer doesn't have a valid render surface any more.
+    mFrameBuffer->MarkSurfaceAsInvalid();
+  }
+}
+
 Integration::RenderSurface* Scene::GetSurface() const
 {
   return mSurface;
@@ -304,7 +325,11 @@ Vector4 Scene::GetBackgroundColor() const
 
 void Scene::EmitKeyEventSignal(const KeyEvent& event)
 {
-  mKeyEventSignal.Emit( event );
+  if ( !mKeyEventSignal.Empty() )
+  {
+    Dali::Integration::Scene handle( this );
+    mKeyEventSignal.Emit( event );
+  }
 }
 
 bool Scene::EmitKeyEventGeneratedSignal(const KeyEvent& event)
@@ -315,18 +340,33 @@ bool Scene::EmitKeyEventGeneratedSignal(const KeyEvent& event)
 
 void Scene::EmitEventProcessingFinishedSignal()
 {
-  mEventProcessingFinishedSignal.Emit();
+  if ( !mEventProcessingFinishedSignal.Empty() )
+  {
+    Dali::Integration::Scene handle( this );
+    mEventProcessingFinishedSignal.Emit();
+  }
 }
 
 void Scene::EmitTouchedSignal( const TouchEvent& touchEvent, const Dali::TouchData& touch )
 {
-  mTouchedSignal.Emit( touchEvent );
-  mTouchSignal.Emit( touch );
+  Dali::Integration::Scene handle( this );
+  if ( !mTouchedSignal.Empty() )
+  {
+    mTouchedSignal.Emit( touchEvent );
+  }
+  if ( !mTouchSignal.Empty() )
+  {
+    mTouchSignal.Emit( touch );
+  }
 }
 
 void Scene::EmitWheelEventSignal(const WheelEvent& event)
 {
-  mWheelEventSignal.Emit( event );
+  if ( !mWheelEventSignal.Empty() )
+  {
+    Dali::Integration::Scene handle( this );
+    mWheelEventSignal.Emit( event );
+  }
 }
 
 Integration::Scene::KeyEventSignalType& Scene::KeyEventSignal()