Added missing newline chars to logging commands
[platform/core/uifw/dali-core.git] / dali / internal / common / core-impl.cpp
index a4e5f45..313fa72 100644 (file)
@@ -1,18 +1,19 @@
-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.0 (the License);
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://floralicense.org/license/
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an AS IS BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
+/*
+ * Copyright (c) 2015 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
 
 // CLASS HEADER
 #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/platform-abstraction.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/platform-abstraction.h>
 #include <dali/integration-api/render-controller.h>
+
 #include <dali/internal/event/actors/actor-impl.h>
-#include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/animation/animation-playlist.h>
-#include <dali/internal/event/common/property-notification-manager.h>
-#include <dali/internal/event/dynamics/dynamics-notifier.h>
 #include <dali/internal/event/common/notification-manager.h>
-#include <dali/integration-api/events/event.h>
+#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/type-registry-impl.h>
+#include <dali/internal/event/effects/shader-factory.h>
 #include <dali/internal/event/events/event-processor.h>
 #include <dali/internal/event/events/gesture-event-processor.h>
-#include <dali/internal/update/manager/update-manager.h>
-#include <dali/internal/render/common/performance-monitor.h>
-#include <dali/internal/render/common/render-manager.h>
+#include <dali/internal/event/images/image-factory.h>
+#include <dali/internal/event/render-tasks/render-task-list-impl.h>
+#include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
+
 #include <dali/internal/update/common/discard-queue.h>
-#include <dali/internal/common/event-to-update.h>
-#include <dali/internal/common/frame-time.h>
+#include <dali/internal/update/common/texture-cache-dispatcher.h>
+#include <dali/internal/update/manager/update-manager.h>
 #include <dali/internal/update/resources/resource-manager.h>
-#include <dali/internal/event/text/font-factory.h>
-#include <dali/internal/event/images/image-factory.h>
-#include <dali/internal/event/modeling/model-factory.h>
-#include <dali/internal/event/common/thread-local-storage.h>
-#include <dali/internal/event/effects/shader-factory.h>
-#include <dali/internal/update/touch/touch-resampler.h>
-#include <dali/internal/event/common/type-registry-impl.h>
 
+#include <dali/internal/render/common/performance-monitor.h>
+#include <dali/internal/render/common/render-manager.h>
 #include <dali/internal/render/gl-resources/texture-cache.h>
 #include <dali/internal/render/gl-resources/context.h>
 
@@ -55,9 +56,17 @@ using Dali::Internal::SceneGraph::RenderManager;
 using Dali::Internal::SceneGraph::DiscardQueue;
 using Dali::Internal::SceneGraph::RenderQueue;
 using Dali::Internal::SceneGraph::TextureCache;
+using Dali::Internal::SceneGraph::TextureCacheDispatcher;
 
+namespace
+{
 // The Update for frame N+1 may be processed whilst frame N is being rendered.
-static const unsigned int MAXIMUM_UPDATE_COUNT = 2u;
+const unsigned int MAXIMUM_UPDATE_COUNT = 2u;
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gCoreFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CORE");
+#endif
+}
 
 namespace Dali
 {
@@ -76,7 +85,7 @@ using Integration::RenderStatus;
 
 Core::Core( RenderController& renderController, PlatformAbstraction& platform,
             GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction,
-            GestureManager& gestureManager)
+            GestureManager& gestureManager, ResourcePolicy::DataRetention dataRetentionPolicy)
 : mRenderController( renderController ),
   mPlatform(platform),
   mGestureEventProcessor(NULL),
@@ -84,12 +93,9 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
   mUpdateManager(NULL),
   mRenderManager(NULL),
   mDiscardQueue(NULL),
-  mResourcePostProcessQueue(),
+  mTextureUploadedQueue(),
   mNotificationManager(NULL),
-  mFrameTime(NULL),
-  mFontFactory(NULL),
   mImageFactory(NULL),
-  mModelFactory(NULL),
   mShaderFactory(NULL),
   mIsActive(true),
   mProcessingEvent(false)
@@ -106,29 +112,32 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
 
   mPropertyNotificationManager = PropertyNotificationManager::New();
 
-  mDynamicsNotifier = DynamicsNotifier::New();
+  mTextureUploadedQueue = new LockedResourceQueue;
 
-  std::vector< ResourcePostProcessRequest> init;
-  mResourcePostProcessQueue = new ResourcePostProcessList(init);
-
-  mRenderManager = RenderManager::New( glAbstraction, *mResourcePostProcessQueue );
+  mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, *mTextureUploadedQueue );
 
   RenderQueue& renderQueue = mRenderManager->GetRenderQueue();
   TextureCache& textureCache = mRenderManager->GetTextureCache();
+
+  ResourcePolicy::Discardable discardPolicy = ResourcePolicy::OWNED_DISCARD;
+  if( dataRetentionPolicy == ResourcePolicy::DALI_RETAINS_ALL_DATA )
+  {
+    discardPolicy = ResourcePolicy::OWNED_RETAIN;
+  }
+  textureCache.SetDiscardBitmapsPolicy(discardPolicy);
+
+  mTextureCacheDispatcher = new SceneGraph::TextureCacheDispatcher( renderQueue, textureCache );
+
   mDiscardQueue = new DiscardQueue( renderQueue );
 
   mResourceManager = new ResourceManager(  mPlatform,
                                           *mNotificationManager,
-                                           textureCache,
-                                          *mResourcePostProcessQueue,
-                                          *mRenderManager,
+                                          *mTextureCacheDispatcher,
+                                          *mTextureUploadedQueue,
                                           *mDiscardQueue,
                                            renderQueue );
 
-  mTouchResampler = TouchResampler::New();
-
   mUpdateManager = new UpdateManager( *mNotificationManager,
-                                       glSyncAbstraction,
                                       *mAnimationPlaylist,
                                       *mPropertyNotificationManager,
                                       *mResourceManager,
@@ -136,25 +145,25 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
                                        renderController,
                                       *mRenderManager,
                                        renderQueue,
-                                       textureCache,
-                                      *mTouchResampler );
+                                      *mTextureCacheDispatcher );
+
+  mRenderManager->SetShaderSaver( *mUpdateManager );
 
-  mResourceClient = new ResourceClient( *mResourceManager, *mUpdateManager );
+  mStage = IntrusivePtr<Stage>( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager ) );
 
-  mStage = IntrusivePtr<Stage>( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mDynamicsNotifier, *mUpdateManager, *mNotificationManager ) );
+  // This must be called after stage is created but before stage initialization
+  mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) );
 
   mStage->Initialize();
 
-  mUpdateManager->SetRenderTaskList( &mStage->GetRenderTaskList() );
+  mResourceClient = new ResourceClient( *mResourceManager, *mStage );
 
   mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController);
   mEventProcessor = new EventProcessor(*mStage, *mNotificationManager, *mGestureEventProcessor);
 
-  mFrameTime = new FrameTime( mPlatform );
-  mFontFactory = new FontFactory(*mResourceClient);
   mImageFactory = new ImageFactory( *mResourceClient );
-  mModelFactory = new ModelFactory(*mResourceClient);
-  mShaderFactory = new ShaderFactory(*mResourceClient);
+  mShaderFactory = new ShaderFactory();
+  mUpdateManager->SetShaderSaver( *mShaderFactory );
   mShaderFactory->LoadDefaultShaders();
 
   GetImplementation(Dali::TypeRegistry::Get()).CallInitFunctions();
@@ -175,7 +184,14 @@ Core::~Core()
   // clear the thread local storage first
   // allows core to be created / deleted many times in the same thread (how TET cases work).
   // Do this before mStage.Reset() so Stage::IsInstalled() returns false
-  ThreadLocalStorage::Get().Remove();
+  ThreadLocalStorage* tls = ThreadLocalStorage::GetInternal();
+  if( tls )
+  {
+    tls->Remove();
+  }
+
+  // Stop relayout requests being raised on stage destruction
+  mRelayoutController.Reset();
 
   // Clean-up stage - remove default camera and root layer
   mStage->Uninitialize();
@@ -186,74 +202,68 @@ Core::~Core()
   delete mEventProcessor;
   delete mGestureEventProcessor;
   delete mNotificationManager;
-  delete mFontFactory;
   delete mImageFactory;
-  delete mModelFactory;
   delete mShaderFactory;
   delete mResourceClient;
   delete mResourceManager;
+  delete mDiscardQueue;
+  delete mTextureCacheDispatcher;
   delete mUpdateManager;
-  delete mTouchResampler;
   delete mRenderManager;
-  delete mDiscardQueue;
-  delete mResourcePostProcessQueue;
-  delete mFrameTime;
+  delete mTextureUploadedQueue;
 }
 
-void Core::ContextCreated()
+Integration::ContextNotifierInterface* Core::GetContextNotifier()
 {
-  mRenderManager->ContextCreated();
+  return mStage.Get();
 }
 
-void Core::ContextToBeDestroyed()
+void Core::RecoverFromContextLoss()
 {
-  mRenderManager->ContextToBeDestroyed();
+  DALI_LOG_INFO(gCoreFilter, Debug::Verbose, "Core::RecoverFromContextLoss()\n");
+
+  mImageFactory->RecoverFromContextLoss(); // Reload images from files
+  mStage->GetRenderTaskList().RecoverFromContextLoss(); // Re-trigger render-tasks
 }
 
-void Core::SurfaceResized(unsigned int width, unsigned int height)
+void Core::ContextCreated()
 {
-  mStage->SetSize(width, height);
+  mRenderManager->ContextCreated();
 }
 
-void Core::SetDpi(unsigned int dpiHorizontal, unsigned int dpiVertical)
+void Core::ContextDestroyed()
 {
-  mPlatform.SetDpi( dpiHorizontal, dpiVertical  );
-  mFontFactory->SetDpi( dpiHorizontal, dpiVertical);
-  mStage->SetDpi( Vector2( dpiHorizontal , dpiVertical) );
+  mRenderManager->ContextDestroyed();
 }
 
-void Core::SetMinimumFrameTimeInterval(unsigned int interval)
+void Core::SurfaceResized( unsigned int width, unsigned int height )
 {
-  mFrameTime->SetMinimumFrameTimeInterval(interval);
+  mStage->SetSize( width, height );
+  mRelayoutController->SetStageSize( width, height );
 }
 
-void Core::Update( UpdateStatus& status )
+void Core::SetDpi( unsigned int dpiHorizontal, unsigned int dpiVertical )
 {
-  // get the last delta and the predict when this update will be rendered
-  float lastFrameDelta( 0.0f );
-  unsigned int lastVSyncTime( 0 );
-  unsigned int nextVSyncTime( 0 );
-  mFrameTime->PredictNextVSyncTime( lastFrameDelta, lastVSyncTime, nextVSyncTime );
+  mStage->SetDpi( Vector2( dpiHorizontal , dpiVertical) );
+}
 
+void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, Integration::UpdateStatus& status )
+{
   // set the time delta so adaptor can easily print FPS with a release build with 0 as
   // it is cached by frametime
-  status.secondsFromLastFrame = lastFrameDelta;
+  status.secondsFromLastFrame = elapsedSeconds;
 
   // Render returns true when there are updates on the stage or one or more animations are completed.
   // Use the estimated time diff till we render as the elapsed time.
-  status.keepUpdating = mUpdateManager->Update( lastFrameDelta, lastVSyncTime, nextVSyncTime );
+  status.keepUpdating = mUpdateManager->Update( elapsedSeconds,
+                                                lastVSyncTimeMilliseconds,
+                                                nextVSyncTimeMilliseconds );
 
   // Check the Notification Manager message queue to set needsNotification
   status.needsNotification = mNotificationManager->MessagesToProcess();
 
-  // If there are notifications to process keep the update thread running as well.
-  // A notification event might add a new actor or animation to the stage which needs
-  // update thread to process it. This also prevents update thread from sleeping
-  // while actor thread is still processing events.
-  if ( status.needsNotification )
-  {
-    status.keepUpdating |= Integration::KeepUpdating::NOTIFICATIONS_PENDING;
-  }
+  // No need to keep update running if there are notifications to process.
+  // Any message to update will wake it up anyways
 
   if ( mResourceManager->ResourcesToProcess() )
   {
@@ -271,11 +281,6 @@ void Core::Render( RenderStatus& status )
 
 void Core::Suspend()
 {
-  if( mFrameTime )
-  {
-    mFrameTime->Suspend();
-  }
-
   mPlatform.Suspend();
 
   mIsActive = false;
@@ -283,11 +288,6 @@ void Core::Suspend()
 
 void Core::Resume()
 {
-  if( mFrameTime )
-  {
-    mFrameTime->Resume();
-  }
-
   mPlatform.Resume();
 
   mIsActive = true;
@@ -296,26 +296,11 @@ void Core::Resume()
   ProcessEvents();
 }
 
-void Core::Sleep()
-{
-  if( mFrameTime )
-  {
-    mFrameTime->Sleep();
-  }
-}
-
-void Core::WakeUp()
+void Core::SceneCreated()
 {
-  if( mFrameTime )
-  {
-    mFrameTime->WakeUp();
-  }
-}
+  mStage->EmitSceneCreatedSignal();
 
-void Core::VSync( unsigned int frameNumber, unsigned int seconds, unsigned int microseconds )
-{
-  // Can't use passed in time as that is not the clock the touch events use so our predicted render value will be meaningless.
-  mFrameTime->SetVSyncTime( frameNumber );
+  mRelayoutController->OnApplicationSceneCreated();
 }
 
 void Core::QueueEvent( const Integration::Event& event )
@@ -328,17 +313,16 @@ void Core::ProcessEvents()
   // Guard against calls to ProcessEvents() during ProcessEvents()
   if( mProcessingEvent )
   {
-    DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!" );
+    DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!\n" );
     mRenderController.RequestProcessEventsOnIdle();
     return;
   }
 
   mProcessingEvent = true;
-
-  EventToUpdate& eventToUpdate = mUpdateManager->GetEventToUpdate();
+  mRelayoutController->SetProcessingCoreEvents( true );
 
   // Signal that any messages received will be flushed soon
-  eventToUpdate.EventProcessingStarted();
+  mUpdateManager->EventProcessingStarted();
 
   mEventProcessor->ProcessEvents();
 
@@ -350,35 +334,31 @@ void Core::ProcessEvents()
     // Emit signal here to start size negotiation and control relayout.
     mStage->EmitEventProcessingFinishedSignal();
 
+    // Run the size negotiation after event processing finished signal
+    mRelayoutController->Relayout();
+
     // Flush discard queue for image factory
     mImageFactory->FlushReleaseQueue();
 
-    // send text requests if required
-    mFontFactory->SendTextRequests();
-
     // Flush any queued messages for the update-thread
-    const bool messagesToProcess = eventToUpdate.FlushQueue();
+    const bool messagesToProcess = mUpdateManager->FlushQueue();
 
     // Check if the touch or gestures require updates.
-    const bool touchNeedsUpdate = mTouchResampler->NeedsUpdate();
     const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
 
-    if( messagesToProcess || touchNeedsUpdate || gestureNeedsUpdate )
+    if( messagesToProcess || gestureNeedsUpdate )
     {
       // tell the render controller to keep update thread running
       mRenderController.RequestUpdate();
     }
   }
 
+  mRelayoutController->SetProcessingCoreEvents( false );
+
   // ProcessEvents() may now be called again
   mProcessingEvent = false;
 }
 
-void Core::UpdateTouchData(const Integration::TouchData& touch)
-{
-  mTouchResampler->SendTouchData( touch );
-}
-
 unsigned int Core::GetMaximumUpdateCount() const
 {
   return MAXIMUM_UPDATE_COUNT;
@@ -389,6 +369,26 @@ Integration::SystemOverlay& Core::GetSystemOverlay()
   return mStage->GetSystemOverlay();
 }
 
+void Core::SetViewMode( ViewMode viewMode )
+{
+  mStage->SetViewMode( viewMode );
+}
+
+ViewMode Core::GetViewMode() const
+{
+  return mStage->GetViewMode();
+}
+
+void Core::SetStereoBase( float stereoBase )
+{
+  mStage->SetStereoBase( stereoBase );
+}
+
+float Core::GetStereoBase() const
+{
+  return mStage->GetStereoBase();
+}
+
 StagePtr Core::GetCurrentStage()
 {
   return mStage.Get();
@@ -424,21 +424,11 @@ ResourceClient& Core::GetResourceClient()
   return *(mResourceClient);
 }
 
-FontFactory& Core::GetFontFactory()
-{
-  return *(mFontFactory);
-}
-
 ImageFactory& Core::GetImageFactory()
 {
   return *(mImageFactory);
 }
 
-ModelFactory& Core::GetModelFactory()
-{
-  return *(mModelFactory);
-}
-
 ShaderFactory& Core::GetShaderFactory()
 {
   return *(mShaderFactory);
@@ -449,6 +439,11 @@ GestureEventProcessor& Core::GetGestureEventProcessor()
   return *(mGestureEventProcessor);
 }
 
+RelayoutController& Core::GetRelayoutController()
+{
+  return *(mRelayoutController.Get());
+}
+
 void Core::CreateThreadLocalStorage()
 {
   // a pointer to the ThreadLocalStorage object will be stored in TLS