[Tizen] Implement partial update
[platform/core/uifw/dali-core.git] / dali / internal / common / core-impl.cpp
old mode 100644 (file)
new mode 100755 (executable)
index ab522eb..863c7e5
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 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/common/core-impl.h>
 
 // INTERNAL INCLUDES
-#include <dali/integration-api/system-overlay.h>
 #include <dali/integration-api/core.h>
 #include <dali/integration-api/debug.h>
 #include <dali/integration-api/events/event.h>
 #include <dali/integration-api/gl-sync-abstraction.h>
+#include <dali/integration-api/gl-context-helper-abstraction.h>
 #include <dali/integration-api/platform-abstraction.h>
+#include <dali/integration-api/processor-interface.h>
 #include <dali/integration-api/render-controller.h>
+#include <dali/integration-api/render-surface.h>
 
 #include <dali/internal/event/actors/actor-impl.h>
 #include <dali/internal/event/animation/animation-playlist.h>
@@ -33,6 +35,7 @@
 #include <dali/internal/event/common/property-notification-manager.h>
 #include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/common/thread-local-storage.h>
+#include <dali/internal/event/common/event-thread-services.h>
 #include <dali/internal/event/common/type-registry-impl.h>
 #include <dali/internal/event/effects/shader-factory.h>
 #include <dali/internal/event/events/event-processor.h>
@@ -56,7 +59,7 @@ using Dali::Internal::SceneGraph::RenderQueue;
 namespace
 {
 // The Update for frame N+1 may be processed whilst frame N is being rendered.
-const unsigned int MAXIMUM_UPDATE_COUNT = 2u;
+const uint32_t MAXIMUM_UPDATE_COUNT = 2u;
 
 #if defined(DEBUG_ENABLED)
 Debug::Filter* gCoreFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CORE");
@@ -72,19 +75,26 @@ namespace Internal
 using Integration::RenderController;
 using Integration::PlatformAbstraction;
 using Integration::GlSyncAbstraction;
-using Integration::GestureManager;
 using Integration::GlAbstraction;
+using Integration::GlContextHelperAbstraction;
 using Integration::Event;
 using Integration::UpdateStatus;
 using Integration::RenderStatus;
 
-Core::Core( RenderController& renderController, PlatformAbstraction& platform,
-            GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction,
-            GestureManager& gestureManager, ResourcePolicy::DataRetention dataRetentionPolicy)
+Core::Core( RenderController& renderController,
+            PlatformAbstraction& platform,
+            GlAbstraction& glAbstraction,
+            GlSyncAbstraction& glSyncAbstraction,
+            GlContextHelperAbstraction& glContextHelperAbstraction,
+            ResourcePolicy::DataRetention dataRetentionPolicy,
+            Integration::RenderToFrameBuffer renderToFboEnabled,
+            Integration::DepthBufferAvailable depthBufferAvailable,
+            Integration::StencilBufferAvailable stencilBufferAvailable,
+            Integration::PartialUpdateAvailable partialUpdateAvailable )
 : mRenderController( renderController ),
   mPlatform(platform),
-  mIsActive(true),
-  mProcessingEvent(false)
+  mProcessingEvent(false),
+  mForceNextUpdate( false )
 {
   // Create the thread local storage
   CreateThreadLocalStorage();
@@ -100,7 +110,7 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
 
   mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor();
 
-  mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction );
+  mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, glContextHelperAbstraction, depthBufferAvailable, stencilBufferAvailable, partialUpdateAvailable );
 
   RenderQueue& renderQueue = mRenderManager->GetRenderQueue();
 
@@ -117,15 +127,14 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
 
   mRenderManager->SetShaderSaver( *mUpdateManager );
 
-  mStage = IntrusivePtr<Stage>( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager ) );
+  mObjectRegistry = ObjectRegistry::New();
+
+  mStage = IntrusivePtr<Stage>( Stage::New( *mUpdateManager ) );
 
   // This must be called after stage is created but before stage initialization
   mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) );
 
-  mStage->Initialize();
-
-  mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController);
-  mEventProcessor = new EventProcessor(*mStage, *mNotificationManager, *mGestureEventProcessor);
+  mGestureEventProcessor = new GestureEventProcessor( *mUpdateManager, mRenderController );
 
   mShaderFactory = new ShaderFactory();
   mUpdateManager->SetShaderSaver( *mShaderFactory );
@@ -149,17 +158,21 @@ Core::~Core()
     delete tls;
   }
 
+  mObjectRegistry.Reset();
+
   // Stop relayout requests being raised on stage destruction
   mRelayoutController.Reset();
 
-  // Clean-up stage - remove default camera and root layer
-  mStage->Uninitialize();
-
   // remove (last?) reference to stage
   mStage.Reset();
 
 }
 
+void Core::Initialize()
+{
+  mStage->Initialize( *mScenes[0] );
+}
+
 Integration::ContextNotifierInterface* Core::GetContextNotifier()
 {
   return mStage.Get();
@@ -182,30 +195,19 @@ void Core::ContextDestroyed()
   mRenderManager->ContextDestroyed();
 }
 
-void Core::SurfaceResized( unsigned int width, unsigned int height )
-{
-  mStage->SurfaceResized( width, height );
-
-  // The stage-size may be less than surface-size (reduced by top-margin)
-  Vector2 size = mStage->GetSize();
-  mRelayoutController->SetStageSize( size.width, size.height );
-}
-
-void Core::SetTopMargin( unsigned int margin )
-{
-  mStage->SetTopMargin( margin );
-
-  // The stage-size may be less than surface-size (reduced by top-margin)
-  Vector2 size = mStage->GetSize();
-  mRelayoutController->SetStageSize( size.width, size.height );
-}
-
-void Core::SetDpi( unsigned int dpiHorizontal, unsigned int dpiVertical )
+void Core::SurfaceDeleted( Integration::RenderSurface* surface )
 {
-  mStage->SetDpi( Vector2( dpiHorizontal , dpiVertical) );
+  for( auto scene : mScenes )
+  {
+    if( scene->GetSurface() == surface )
+    {
+      scene->SurfaceDeleted();
+      break;
+    }
+  }
 }
 
-void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, Integration::UpdateStatus& status )
+void Core::Update( float elapsedSeconds, uint32_t lastVSyncTimeMilliseconds, uint32_t nextVSyncTimeMilliseconds, Integration::UpdateStatus& status, bool renderToFboEnabled, bool isRenderingToFbo )
 {
   // set the time delta so adaptor can easily print FPS with a release build with 0 as
   // it is cached by frametime
@@ -215,31 +217,23 @@ void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds,
   // Use the estimated time diff till we render as the elapsed time.
   status.keepUpdating = mUpdateManager->Update( elapsedSeconds,
                                                 lastVSyncTimeMilliseconds,
-                                                nextVSyncTimeMilliseconds );
+                                                nextVSyncTimeMilliseconds,
+                                                renderToFboEnabled,
+                                                isRenderingToFbo );
 
   // Check the Notification Manager message queue to set needsNotification
   status.needsNotification = mNotificationManager->MessagesToProcess();
 
+  // Check if the default surface is changed
+  status.surfaceRectChanged = mUpdateManager->IsDefaultSurfaceRectChanged();
+
   // No need to keep update running if there are notifications to process.
   // Any message to update will wake it up anyways
 }
 
-void Core::Render( RenderStatus& status )
-{
-  mRenderManager->Render( status );
-}
-
-void Core::Suspend()
-{
-  mIsActive = false;
-}
-
-void Core::Resume()
+void Core::Render( RenderStatus& status, bool forceClear )
 {
-  mIsActive = true;
-
-  // trigger processing of events queued up while paused
-  ProcessEvents();
+  mRenderManager->Render( status, forceClear );
 }
 
 void Core::SceneCreated()
@@ -247,11 +241,20 @@ void Core::SceneCreated()
   mStage->EmitSceneCreatedSignal();
 
   mRelayoutController->OnApplicationSceneCreated();
+
+  for( auto iter = mScenes.begin(); iter != mScenes.end(); ++iter )
+  {
+    Dali::Actor sceneRootLayer = (*iter)->GetRootLayer();
+    mRelayoutController->RequestRelayoutTree( sceneRootLayer );
+  }
 }
 
 void Core::QueueEvent( const Integration::Event& event )
 {
-  mEventProcessor->QueueEvent( event );
+  if (mScenes.size() != 0)
+  {
+    mScenes.front()->QueueEvent( event );
+  }
 }
 
 void Core::ProcessEvents()
@@ -260,7 +263,7 @@ void Core::ProcessEvents()
   if( mProcessingEvent )
   {
     DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!\n" );
-    mRenderController.RequestProcessEventsOnIdle();
+    mRenderController.RequestProcessEventsOnIdle( false );
     return;
   }
 
@@ -270,30 +273,48 @@ void Core::ProcessEvents()
   // Signal that any messages received will be flushed soon
   mUpdateManager->EventProcessingStarted();
 
-  mEventProcessor->ProcessEvents();
+  // Scene could be added or removed while processing the events
+  // Copy the Scene container locally to avoid possibly invalid iterator
+  SceneContainer scenes = mScenes;
+
+  // process events in all scenes
+  for( auto scene : scenes )
+  {
+    scene->ProcessEvents();
+  }
 
   mNotificationManager->ProcessMessages();
 
-  // Avoid allocating MessageBuffers, triggering size-negotiation or sending any other spam whilst paused
-  if( mIsActive )
+  // Emit signal here to inform listeners that event processing has finished.
+  for( auto scene : scenes )
   {
-    // Emit signal here to inform listeners that event processing has finished.
-    mStage->EmitEventProcessingFinishedSignal();
+    scene->EmitEventProcessingFinishedSignal();
+  }
 
-    // Run the size negotiation after event processing finished signal
-    mRelayoutController->Relayout();
+  // Run any registered processors
+  RunProcessors();
 
-    // Flush any queued messages for the update-thread
-    const bool messagesToProcess = mUpdateManager->FlushQueue();
+  // Run the size negotiation after event processing finished signal
+  mRelayoutController->Relayout();
 
-    // Check if the touch or gestures require updates.
-    const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
+  // Rebuild depth tree after event processing has finished
+  for( auto scene : scenes )
+  {
+    scene->RebuildDepthTree();
+  }
 
-    if( messagesToProcess || gestureNeedsUpdate )
-    {
-      // tell the render controller to keep update thread running
-      mRenderController.RequestUpdate();
-    }
+  // Flush any queued messages for the update-thread
+  const bool messagesToProcess = mUpdateManager->FlushQueue();
+
+  // Check if the touch or gestures require updates.
+  const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
+  // Check if the next update is forced.
+  const bool forceUpdate = IsNextUpdateForced();
+
+  if( messagesToProcess || gestureNeedsUpdate || forceUpdate )
+  {
+    // tell the render controller to keep update thread running
+    mRenderController.RequestUpdate( forceUpdate );
   }
 
   mRelayoutController->SetProcessingCoreEvents( false );
@@ -302,34 +323,37 @@ void Core::ProcessEvents()
   mProcessingEvent = false;
 }
 
-unsigned int Core::GetMaximumUpdateCount() const
+uint32_t Core::GetMaximumUpdateCount() const
 {
   return MAXIMUM_UPDATE_COUNT;
 }
 
-Integration::SystemOverlay& Core::GetSystemOverlay()
+void Core::RegisterProcessor( Integration::Processor& processor )
 {
-  return mStage->GetSystemOverlay();
+  mProcessors.PushBack(&processor);
 }
 
-void Core::SetViewMode( ViewMode viewMode )
+void Core::UnregisterProcessor( Integration::Processor& processor )
 {
-  mStage->SetViewMode( viewMode );
+  auto iter = std::find( mProcessors.Begin(), mProcessors.End(), &processor );
+  if( iter != mProcessors.End() )
+  {
+    mProcessors.Erase( iter );
+  }
 }
 
-ViewMode Core::GetViewMode() const
+void Core::RunProcessors()
 {
-  return mStage->GetViewMode();
-}
+  // Copy processor pointers to prevent changes to vector affecting loop iterator.
+  Dali::Vector<Integration::Processor*> processors( mProcessors );
 
-void Core::SetStereoBase( float stereoBase )
-{
-  mStage->SetStereoBase( stereoBase );
-}
-
-float Core::GetStereoBase() const
-{
-  return mStage->GetStereoBase();
+  for( auto processor : processors )
+  {
+    if( processor )
+    {
+      processor->Process();
+    }
+  }
 }
 
 StagePtr Core::GetCurrentStage()
@@ -372,6 +396,40 @@ RelayoutController& Core::GetRelayoutController()
   return *(mRelayoutController.Get());
 }
 
+ObjectRegistry& Core::GetObjectRegistry() const
+{
+  return *(mObjectRegistry.Get());
+}
+
+EventThreadServices& Core::GetEventThreadServices()
+{
+  return *this;
+}
+
+PropertyNotificationManager& Core::GetPropertyNotificationManager() const
+{
+  return *(mPropertyNotificationManager);
+}
+
+AnimationPlaylist& Core::GetAnimationPlaylist() const
+{
+  return *(mAnimationPlaylist);
+}
+
+void Core::AddScene( Scene* scene )
+{
+  mScenes.push_back( scene );
+}
+
+void Core::RemoveScene( Scene* scene )
+{
+  auto iter = std::find( mScenes.begin(), mScenes.end(), scene );
+  if( iter != mScenes.end() )
+  {
+    mScenes.erase( iter );
+  }
+}
+
 void Core::CreateThreadLocalStorage()
 {
   // a pointer to the ThreadLocalStorage object will be stored in TLS
@@ -379,6 +437,45 @@ void Core::CreateThreadLocalStorage()
   new ThreadLocalStorage(this);
 }
 
+void Core::RegisterObject( Dali::BaseObject* object )
+{
+  mObjectRegistry = &ThreadLocalStorage::Get().GetObjectRegistry();
+  mObjectRegistry->RegisterObject( object );
+}
+
+void Core::UnregisterObject( Dali::BaseObject* object )
+{
+  mObjectRegistry = &ThreadLocalStorage::Get().GetObjectRegistry();
+  mObjectRegistry->UnregisterObject( object );
+}
+
+Integration::RenderController& Core::GetRenderController()
+{
+  return mRenderController;
+}
+
+uint32_t* Core::ReserveMessageSlot( uint32_t size, bool updateScene )
+{
+  return mUpdateManager->ReserveMessageSlot( size, updateScene );
+}
+
+BufferIndex Core::GetEventBufferIndex() const
+{
+  return mUpdateManager->GetEventBufferIndex();
+}
+
+void Core::ForceNextUpdate()
+{
+  mForceNextUpdate = true;
+}
+
+bool Core::IsNextUpdateForced()
+{
+  bool nextUpdateForced = mForceNextUpdate;
+  mForceNextUpdate = false;
+  return nextUpdateForced;
+}
+
 } // namespace Internal
 
 } // namespace Dali