Add Overlay Layer in scene
[platform/core/uifw/dali-core.git] / dali / internal / event / common / scene-impl.cpp
index 69b0724..56ed507 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali/internal/event/common/scene-impl.h>
 
 // INTERNAL INCLUDES
+#include <dali/internal/event/actors/camera-actor-impl.h>
 #include <dali/internal/event/actors/layer-impl.h>
 #include <dali/internal/event/actors/layer-list.h>
-#include <dali/internal/event/actors/camera-actor-impl.h>
+#include <dali/internal/event/common/object-registry-impl.h>
 #include <dali/internal/event/common/thread-local-storage.h>
-#include <dali/internal/event/render-tasks/render-task-list-impl.h>
 #include <dali/internal/event/render-tasks/render-task-impl.h>
-#include <dali/internal/event/common/object-registry-impl.h>
-#include <dali/internal/update/nodes/node.h>
+#include <dali/internal/event/render-tasks/render-task-list-impl.h>
+#include <dali/internal/event/rendering/frame-buffer-impl.h>
+#include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
+#include <dali/internal/update/common/scene-graph-scene.h>
 #include <dali/internal/update/manager/update-manager.h>
+#include <dali/internal/update/nodes/node.h>
+#include <dali/public-api/common/constants.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
-#include <dali/internal/event/rendering/frame-buffer-impl.h>
-#include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
 
 using Dali::Internal::SceneGraph::Node;
 
 namespace Dali
 {
-
 namespace Internal
 {
-
-namespace
-{
-
-const Vector4 DEFAULT_BACKGROUND_COLOR(0.0f, 0.0f, 0.0f, 1.0f); // Default background color
-
-} //Unnamed namespace
-
-ScenePtr Scene::New( Integration::RenderSurface& surface )
+ScenePtr Scene::New(Size size, int32_t windowOrientation, int32_t screenOrientation)
 {
   ScenePtr scene = new Scene;
 
   // Second-phase construction
-  scene->Initialize( surface );
+  scene->Initialize(size, windowOrientation, screenOrientation);
 
   return scene;
 }
 
 Scene::Scene()
-: mSurface( nullptr ),
+: mSceneObject(nullptr),
   mSize(), // Don't set the proper value here, this will be set when the surface is set later
   mDpi(),
-  mBackgroundColor( DEFAULT_BACKGROUND_COLOR ),
-  mDepthTreeDirty( false ),
-  mEventProcessor( *this, ThreadLocalStorage::GetInternal()->GetGestureEventProcessor() )
+  mBackgroundColor(DEFAULT_BACKGROUND_COLOR),
+  mDepthTreeDirty(false),
+  mEventProcessor(*this, ThreadLocalStorage::GetInternal()->GetGestureEventProcessor()),
+  mSurfaceOrientation(0),
+  mScreenOrientation(0)
 {
 }
 
 Scene::~Scene()
 {
-  if( mDefaultCamera )
+  if(EventThreadServices::IsCoreRunning() && mSceneObject)
+  {
+    ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+    RemoveSceneMessage(tls->GetUpdateManager(), *mSceneObject);
+  }
+
+  if(mDefaultCamera)
   {
     // its enough to release the handle so the object is released
     // don't need to remove it from root actor as root actor will delete the object
     mDefaultCamera.Reset();
   }
 
-  if( mRootLayer )
+  if(mRootLayer)
   {
     // we are closing down so just delete the root, no point emit disconnect
     // signals or send messages to update
     mRootLayer.Reset();
   }
 
-  if( mRenderTaskList )
+  if(mOverlayLayer)
   {
-    mRenderTaskList.Reset();
+    mOverlayLayer.Reset();
   }
 
-  if ( mFrameBuffer )
+  if(mRenderTaskList)
   {
-    mFrameBuffer.Reset();
+    mRenderTaskList.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( Integration::RenderSurface& surface )
+void Scene::Initialize(Size size, int32_t windowOrientation, int32_t screenOrientation)
 {
   ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
 
-  DALI_ASSERT_ALWAYS( tls && "Attempt to create scene before core exists!" );
+  DALI_ASSERT_ALWAYS(tls && "Attempt to create scene before core exists!");
 
-  tls->AddScene( this );
+  tls->AddScene(this);
 
   SceneGraph::UpdateManager& updateManager = tls->GetUpdateManager();
 
   // Create the ordered list of layers
-  mLayerList = LayerList::New( updateManager );
+  mLayerList = LayerList::New(updateManager);
 
   // The scene owns the default layer
-  mRootLayer = Layer::NewRoot( *mLayerList );
+  mRootLayer = Layer::NewRoot(*mLayerList);
   mRootLayer->SetName("RootLayer");
-  mRootLayer->SetScene( *this );
+  mRootLayer->SetScene(*this);
 
   // The root layer needs to have a fixed resize policy (as opposed to the default USE_NATURAL_SIZE).
   // This stops actors parented to the stage having their relayout requests propagating
   // up to the root layer, and down through other children unnecessarily.
-  mRootLayer->SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
+  mRootLayer->SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
 
   // 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.
-  const PositionSize positionSize = surface.GetPositionSize();
-  const Vector2 surfaceSize( static_cast< float >( positionSize.width ), static_cast< float >( positionSize.height ) );
-  mDefaultCamera = CameraActor::New( surfaceSize );
+  mDefaultCamera = CameraActor::New(size);
   mDefaultCamera->SetParentOrigin(ParentOrigin::CENTER);
   Add(*(mDefaultCamera.Get()));
 
   // Create the list of render-tasks
   mRenderTaskList = RenderTaskList::New();
 
-  // Create the default render-task
-  mRenderTaskList->CreateTask( mRootLayer.Get(), mDefaultCamera.Get() );
+  // Create the default render-task and ensure clear is enabled on it to show the background color
+  RenderTaskPtr renderTask = mRenderTaskList->CreateTask(mRootLayer.Get(), mDefaultCamera.Get());
+  renderTask->SetClearEnabled(true);
 
-  // Set the surface
-  SetSurface( surface );
+  // Create scene graph object
+  mSceneObject = new SceneGraph::Scene();
+  OwnerPointer<SceneGraph::Scene> transferOwnership(const_cast<SceneGraph::Scene*>(mSceneObject));
+  AddSceneMessage(updateManager, transferOwnership);
+
+  SurfaceRotated(size.width, size.height, windowOrientation, screenOrientation);
 }
 
 void Scene::Add(Actor& actor)
 {
-  mRootLayer->Add( actor );
+  mRootLayer->Add(actor);
 }
 
 void Scene::Remove(Actor& actor)
 {
-  mRootLayer->Remove( actor );
+  mRootLayer->Remove(actor);
 }
 
 Size Scene::GetSize() const
@@ -172,7 +176,27 @@ RenderTaskList& Scene::GetRenderTaskList() const
 
 Dali::Layer Scene::GetRootLayer() const
 {
-  return Dali::Layer( mRootLayer.Get() );
+  return Dali::Layer(mRootLayer.Get());
+}
+
+Dali::Layer Scene::GetOverlayLayer()
+{
+  if(!mOverlayLayer)
+  {
+    // Creates overlay layer.
+    mOverlayLayer = Layer::New();
+    mOverlayLayer->SetName("OverlayLayer");
+    mOverlayLayer->SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+    mOverlayLayer->SetParentOrigin(Dali::ParentOrigin::TOP_LEFT);
+    mOverlayLayer->SetAnchorPoint(Dali::AnchorPoint::TOP_LEFT);
+    mRootLayer->Add(*mOverlayLayer);
+
+    // Create the overlay render-task and set exclusive to true.
+    RenderTaskPtr renderTask = mRenderTaskList->CreateOverlayTask(mOverlayLayer.Get(), mDefaultCamera.Get());
+    renderTask->SetExclusive(true);
+    renderTask->SetInputEnabled(true);
+  }
+  return Dali::Layer(mOverlayLayer.Get());
 }
 
 LayerList& Scene::GetLayerList() const
@@ -185,12 +209,12 @@ uint32_t Scene::GetLayerCount() const
   return mLayerList->GetLayerCount();
 }
 
-Dali::Layer Scene::GetLayer( uint32_t depth ) const
+Dali::Layer Scene::GetLayer(uint32_t depth) const
 {
-  return Dali::Layer(mLayerList->GetLayer( depth ));
+  return Dali::Layer(mLayerList->GetLayer(depth));
 }
 
-CameraActor& Scene::GetDefaultCameraActor()
+CameraActor& Scene::GetDefaultCameraActor() const
 {
   return *mDefaultCamera;
 }
@@ -200,74 +224,29 @@ Actor& Scene::GetDefaultRootActor()
   return *mRootLayer;
 }
 
-void Scene::SetSurface( Integration::RenderSurface& surface )
+void Scene::SurfaceResized(float width, float height)
 {
-  if( mSurface != &surface )
+  if((fabsf(mSize.width - width) > Math::MACHINE_EPSILON_1) || (fabsf(mSize.height - height) > Math::MACHINE_EPSILON_1))
   {
-    mSurface = &surface;
-
-    RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask( 0u );
-
-    mFrameBuffer = Dali::Internal::FrameBuffer::New( surface, Dali::FrameBuffer::Attachment::NONE );
-    defaultRenderTask->SetFrameBuffer( mFrameBuffer );
-
-    SurfaceResized();
-  }
-}
-
-void Scene::SurfaceResized()
-{
-  if( mSurface )
-  {
-    const PositionSize surfacePositionSize = mSurface->GetPositionSize();
-    const float fWidth = static_cast< float >( surfacePositionSize.width );
-    const float fHeight = static_cast< float >( surfacePositionSize.height );
-
-    if( ( fabsf( mSize.width - fWidth ) > Math::MACHINE_EPSILON_1 ) || ( fabsf( mSize.height - fHeight ) > Math::MACHINE_EPSILON_1 ) )
-    {
-      Rect< int32_t > newSize( 0, 0, static_cast< int32_t >( surfacePositionSize.width ), static_cast< int32_t >( surfacePositionSize.height ) ); // truncated
-
-      mSize.width = fWidth;
-      mSize.height = fHeight;
-
-      // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
-      mDefaultCamera->SetPerspectiveProjection( mSize );
-
-      mRootLayer->SetSize( mSize.width, mSize.height );
-
-      ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
-      SceneGraph::UpdateManager& updateManager = tls->GetUpdateManager();
-      SetDefaultSurfaceRectMessage( updateManager, newSize );
-
-      // set default render-task viewport parameters
-      RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask( 0u );
-      defaultRenderTask->SetViewport( newSize );
-      defaultRenderTask->GetFrameBuffer()->SetSize( static_cast<uint32_t>( newSize.width ), static_cast<uint32_t>( newSize.height ) );
-    }
+    ChangedSurface(width, height, mSurfaceOrientation, mScreenOrientation);
   }
 }
 
-void Scene::SurfaceDeleted()
+void Scene::SurfaceReplaced()
 {
-  mSurface = nullptr;
-  if ( mFrameBuffer )
+  if(mSceneObject)
   {
-    // The frame buffer doesn't have a valid render surface any more.
-    mFrameBuffer->MarkSurfaceAsInvalid();
+    ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+    SurfaceReplacedMessage(tls->GetUpdateManager(), *mSceneObject);
   }
 }
 
-Integration::RenderSurface* Scene::GetSurface() const
-{
-  return mSurface;
-}
-
 void Scene::Discard()
 {
-  if( ThreadLocalStorage::Created() )
+  if(ThreadLocalStorage::Created())
   {
     ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
-    tls->RemoveScene( this );
+    tls->RemoveScene(this);
   }
 }
 
@@ -276,9 +255,9 @@ void Scene::RequestRebuildDepthTree()
   mDepthTreeDirty = true;
 }
 
-void Scene::QueueEvent( const Integration::Event& event )
+void Scene::QueueEvent(const Integration::Event& event)
 {
-  mEventProcessor.QueueEvent( event );
+  mEventProcessor.QueueEvent(event);
 }
 
 void Scene::ProcessEvents()
@@ -289,23 +268,20 @@ void Scene::ProcessEvents()
 void Scene::RebuildDepthTree()
 {
   // If the depth tree needs rebuilding, do it in this frame only.
-  if( mDepthTreeDirty )
+  if(mDepthTreeDirty)
   {
-    ActorPtr actor( mRootLayer.Get() );
+    ActorPtr actor(mRootLayer.Get());
     actor->RebuildDepthTree();
     mDepthTreeDirty = false;
   }
 }
 
-void Scene::SetBackgroundColor( const Vector4& color )
+void Scene::SetBackgroundColor(const Vector4& color)
 {
   mBackgroundColor = color;
 
-  if( mSurface )
-  {
-    mRenderTaskList->GetTask( 0u )->SetClearColor( color );
-    mRenderTaskList->GetTask( 0u )->SetClearEnabled( true );
-  }
+  mRenderTaskList->GetTask(0u)->SetClearColor(color);
+  mRenderTaskList->GetTask(0u)->SetClearEnabled(true);
 }
 
 Vector4 Scene::GetBackgroundColor() const
@@ -313,52 +289,180 @@ Vector4 Scene::GetBackgroundColor() const
   return mBackgroundColor;
 }
 
-void Scene::EmitKeyEventSignal(const KeyEvent& event)
+SceneGraph::Scene* Scene::GetSceneObject() const
+{
+  return mSceneObject;
+}
+
+void Scene::EmitKeyEventSignal(const Dali::KeyEvent& event)
+{
+  if(!mKeyEventSignal.Empty())
+  {
+    Dali::Integration::Scene handle(this);
+    mKeyEventSignal.Emit(event);
+  }
+}
+
+void Scene::SurfaceRotated(float width, float height, int32_t windowOrientation, int32_t screenOrientation)
+{
+  ChangedSurface(width, height, windowOrientation, screenOrientation);
+}
+
+int32_t Scene::GetCurrentSurfaceOrientation() const
+{
+  return mSceneObject->GetSurfaceOrientation();
+}
+
+int32_t Scene::GetCurrentScreenOrientation() const
+{
+  return mSceneObject->GetScreenOrientation();
+}
+
+const Rect<int32_t>& Scene::GetCurrentSurfaceRect() const
 {
-  if ( !mKeyEventSignal.Empty() )
+  return mSceneObject->GetSurfaceRect();
+}
+
+void Scene::ChangedSurface(float width, float height, int32_t windowOrientation, int32_t screenOrientation)
+{
+  bool changedOrientation = false;
+  Rect<int32_t> newSize(0, 0, static_cast<int32_t>(width), static_cast<int32_t>(height)); // truncated
+  mSize.width  = width;
+  mSize.height = height;
+
+  if(mSurfaceOrientation != windowOrientation || mScreenOrientation != screenOrientation)
+  {
+    changedOrientation = true;
+  }
+
+  mSurfaceOrientation = windowOrientation;
+  mScreenOrientation = screenOrientation;
+
+  // Calculates the aspect ratio, near and far clipping planes, field of view and camera Z position.
+  mDefaultCamera->SetPerspectiveProjection(mSize);
+  // Set the surface orientation to Default camera for window/screen rotation
+  if(changedOrientation)
+  {
+    int32_t orientation = (windowOrientation + screenOrientation) % 360;
+    mDefaultCamera->RotateProjection(orientation);
+  }
+
+  mRootLayer->SetSize(width, height);
+
+  // Send the surface rectangle/orientation to SceneGraph::Scene for calculating glViewport/Scissor
+  ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+  DALI_LOG_RELEASE_INFO("Send Surface Rect Message, width[%d], height[%d]\n", newSize.width, newSize.height);
+  SetSurfaceRectMessage(tls->GetEventThreadServices(), *mSceneObject, newSize);
+  if(changedOrientation)
+  {
+    DALI_LOG_RELEASE_INFO("Send Surface Orientation Message, surface orientation[%d], screen orientation[%d]\n", mSurfaceOrientation, mScreenOrientation);
+    SetSurfaceOrientationsMessage(tls->GetEventThreadServices(), *mSceneObject, mSurfaceOrientation, mScreenOrientation);
+  }
+
+  // set default render-task viewport parameters
+  RenderTaskPtr defaultRenderTask = mRenderTaskList->GetTask(0u);
+  defaultRenderTask->SetViewport(newSize);
+  // set overlay render-task viewport parameters
+  RenderTaskPtr overlayRenderTask = mRenderTaskList->GetOverlayTask();
+  if(overlayRenderTask)
   {
-    Dali::Integration::Scene handle( this );
-    mKeyEventSignal.Emit( event );
+    overlayRenderTask->SetViewport(newSize);
   }
 }
 
-bool Scene::EmitKeyEventGeneratedSignal(const KeyEvent& event)
+bool Scene::IsSurfaceRectChanged() const
+{
+  return mSceneObject->IsSurfaceRectChanged();
+}
+
+bool Scene::IsRotationCompletedAcknowledgementSet() const
+{
+  return mSceneObject->IsRotationCompletedAcknowledgementSet();
+}
+
+void Scene::SetRotationCompletedAcknowledgement()
+{
+  ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+  SetRotationCompletedAcknowledgementMessage(tls->GetEventThreadServices(), *mSceneObject);
+}
+
+void Scene::SetSurfaceRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo)
+{
+  // Send the surface render target to SceneGraph::Scene
+  ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+  SetSurfaceRenderTargetCreateInfoMessage(tls->GetEventThreadServices(), *mSceneObject, renderTargetCreateInfo);
+}
+
+bool Scene::EmitKeyEventGeneratedSignal(const Dali::KeyEvent& event)
 {
   // Emit the KeyEventGenerated signal when KeyEvent is generated
-  return mKeyEventGeneratedSignal.Emit( event );
+  Dali::Integration::Scene handle(this);
+  return mKeyEventGeneratedSignal.Emit(event);
+}
+
+bool Scene::EmitInterceptKeyEventSignal(const Dali::KeyEvent& event)
+{
+  // Emit the InterceptKeyEvent signal
+  Dali::Integration::Scene handle(this);
+  return mInterceptKeyEventSignal.Emit(event);
 }
 
 void Scene::EmitEventProcessingFinishedSignal()
 {
-  if ( !mEventProcessingFinishedSignal.Empty() )
+  if(!mEventProcessingFinishedSignal.Empty())
   {
-    Dali::Integration::Scene handle( this );
+    Dali::Integration::Scene handle(this);
     mEventProcessingFinishedSignal.Emit();
   }
 }
 
-void Scene::EmitTouchedSignal( const TouchEvent& touchEvent, const Dali::TouchData& touch )
+void Scene::EmitTouchedSignal(const Dali::TouchEvent& touch)
 {
-  Dali::Integration::Scene handle( this );
-  if ( !mTouchedSignal.Empty() )
-  {
-    mTouchedSignal.Emit( touchEvent );
-  }
-  if ( !mTouchSignal.Empty() )
+  Dali::Integration::Scene handle(this);
+  if(!mTouchedSignal.Empty())
   {
-    mTouchSignal.Emit( touch );
+    mTouchedSignal.Emit(touch);
   }
 }
 
-void Scene::EmitWheelEventSignal(const WheelEvent& event)
+void Scene::EmitWheelEventSignal(const Dali::WheelEvent& event)
 {
-  if ( !mWheelEventSignal.Empty() )
+  if(!mWheelEventSignal.Empty())
   {
-    Dali::Integration::Scene handle( this );
-    mWheelEventSignal.Emit( event );
+    Dali::Integration::Scene handle(this);
+    mWheelEventSignal.Emit(event);
   }
 }
 
+bool Scene::EmitWheelEventGeneratedSignal(const Dali::WheelEvent& event)
+{
+  // Emit the WheelEventGenerated signal when WheelEvent is generated
+  Dali::Integration::Scene handle(this);
+  return mWheelEventGeneratedSignal.Emit(event);
+}
+
+void Scene::AddFrameRenderedCallback(std::unique_ptr<CallbackBase> callback, int32_t frameId)
+{
+  ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+  AddFrameRenderedCallbackMessage(tls->GetEventThreadServices(), *mSceneObject, callback.release(), frameId);
+}
+
+void Scene::AddFramePresentedCallback(std::unique_ptr<CallbackBase> callback, int32_t frameId)
+{
+  ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+  AddFramePresentedCallbackMessage(tls->GetEventThreadServices(), *mSceneObject, callback.release(), frameId);
+}
+
+void Scene::GetFrameRenderedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks)
+{
+  mSceneObject->GetFrameRenderedCallback(callbacks);
+}
+
+void Scene::GetFramePresentedCallback(Dali::Integration::Scene::FrameCallbackContainer& callbacks)
+{
+  mSceneObject->GetFramePresentedCallback(callbacks);
+}
+
 Integration::Scene::KeyEventSignalType& Scene::KeyEventSignal()
 {
   return mKeyEventSignal;
@@ -369,26 +473,31 @@ Integration::Scene::KeyEventGeneratedSignalType& Scene::KeyEventGeneratedSignal(
   return mKeyEventGeneratedSignal;
 }
 
+Integration::Scene::KeyEventGeneratedSignalType& Scene::InterceptKeyEventSignal()
+{
+  return mInterceptKeyEventSignal;
+}
+
 Integration::Scene::EventProcessingFinishedSignalType& Scene::EventProcessingFinishedSignal()
 {
   return mEventProcessingFinishedSignal;
 }
 
-Scene::TouchedSignalType& Scene::TouchedSignal()
+Integration::Scene::TouchEventSignalType& Scene::TouchedSignal()
 {
   return mTouchedSignal;
 }
 
-Integration::Scene::TouchSignalType& Scene::TouchSignal()
+Integration::Scene::WheelEventSignalType& Scene::WheelEventSignal()
 {
-  return mTouchSignal;
+  return mWheelEventSignal;
 }
 
-Integration::Scene::WheelEventSignalType& Scene::WheelEventSignal()
+Integration::Scene::WheelEventGeneratedSignalType& Scene::WheelEventGeneratedSignal()
 {
-  return mWheelEventSignal;
+  return mWheelEventGeneratedSignal;
 }
 
-} // Internal
+} // namespace Internal
 
-} // Dali
+} // namespace Dali