Disable certain GL calls when depth and/or stencil buffers are not available
[platform/core/uifw/dali-core.git] / dali / internal / common / core-impl.cpp
index ddc8537..7637a27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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/integration-api/system-overlay.h>
 #include <dali/integration-api/core.h>
 #include <dali/integration-api/debug.h>
-#include <dali/integration-api/platform-abstraction.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/common/notification-manager.h>
-#include <dali/integration-api/events/event.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/update/common/discard-queue.h>
-#include <dali/internal/update/resources/resource-manager.h>
-#include <dali/internal/event/images/image-factory.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/effects/shader-factory.h>
-#include <dali/internal/update/touch/touch-resampler.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/event/render-tasks/render-task-list-impl.h>
 #include <dali/internal/event/size-negotiation/relayout-controller-impl.h>
 
-#include <dali/internal/render/gl-resources/texture-cache.h>
+#include <dali/internal/update/common/discard-queue.h>
+#include <dali/internal/update/manager/update-manager.h>
+#include <dali/internal/update/manager/render-task-processor.h>
+
+#include <dali/internal/render/common/performance-monitor.h>
+#include <dali/internal/render/common/render-manager.h>
 #include <dali/internal/render/gl-resources/context.h>
 
 using Dali::Internal::SceneGraph::UpdateManager;
 using Dali::Internal::SceneGraph::RenderManager;
 using Dali::Internal::SceneGraph::DiscardQueue;
 using Dali::Internal::SceneGraph::RenderQueue;
-using Dali::Internal::SceneGraph::TextureCache;
 
 namespace
 {
@@ -80,21 +78,17 @@ 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,
+            GestureManager& gestureManager,
+            ResourcePolicy::DataRetention dataRetentionPolicy,
+            Integration::RenderToFrameBuffer renderToFboEnabled,
+            Integration::DepthBufferAvailable depthBufferAvailable,
+            Integration::StencilBufferAvailable stencilBufferAvailable )
 : mRenderController( renderController ),
   mPlatform(platform),
-  mGestureEventProcessor(NULL),
-  mEventProcessor(NULL),
-  mUpdateManager(NULL),
-  mRenderManager(NULL),
-  mDiscardQueue(NULL),
-  mResourcePostProcessQueue(),
-  mNotificationManager(NULL),
-  mImageFactory(NULL),
-  mShaderFactory(NULL),
-  mIsActive(true),
   mProcessingEvent(false)
 {
   // Create the thread local storage
@@ -109,72 +103,43 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
 
   mPropertyNotificationManager = PropertyNotificationManager::New();
 
-  std::vector< ResourcePostProcessRequest> init;
-  mResourcePostProcessQueue = new ResourcePostProcessList(init);
+  mRenderTaskProcessor = new SceneGraph::RenderTaskProcessor();
 
-  mRenderManager = RenderManager::New( glAbstraction, *mResourcePostProcessQueue );
+  mRenderManager = RenderManager::New( glAbstraction, glSyncAbstraction, depthBufferAvailable, stencilBufferAvailable );
 
   RenderQueue& renderQueue = mRenderManager->GetRenderQueue();
-  TextureCache& textureCache = mRenderManager->GetTextureCache();
-
-  ResourcePolicy::Discardable discardPolicy = ResourcePolicy::DISCARD;
-  if( dataRetentionPolicy == ResourcePolicy::DALI_RETAINS_ALL_DATA )
-  {
-    discardPolicy = ResourcePolicy::RETAIN;
-  }
-  textureCache.SetDiscardBitmapsPolicy(discardPolicy);
 
   mDiscardQueue = new DiscardQueue( renderQueue );
 
-  mResourceManager = new ResourceManager(  mPlatform,
-                                          *mNotificationManager,
-                                           textureCache,
-                                          *mResourcePostProcessQueue,
-                                          *mRenderManager,
-                                          *mDiscardQueue,
-                                           renderQueue );
-
-  mTouchResampler = TouchResampler::New();
-
   mUpdateManager = new UpdateManager( *mNotificationManager,
-                                       glSyncAbstraction,
                                       *mAnimationPlaylist,
                                       *mPropertyNotificationManager,
-                                      *mResourceManager,
                                       *mDiscardQueue,
                                        renderController,
                                       *mRenderManager,
                                        renderQueue,
-                                       textureCache,
-                                      *mTouchResampler );
+                                      *mRenderTaskProcessor );
 
-  mStage = IntrusivePtr<Stage>( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager ) );
+  mRenderManager->SetShaderSaver( *mUpdateManager );
 
-  // This must be called after stage is created but before stage initialization
-  mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController() );
+  mStage = IntrusivePtr<Stage>( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager, mRenderController ) );
 
-  mStage->Initialize();
+  // This must be called after stage is created but before stage initialization
+  mRelayoutController = IntrusivePtr< RelayoutController >( new RelayoutController( mRenderController ) );
 
-  mResourceClient = new ResourceClient( *mResourceManager, *mStage, dataRetentionPolicy );
+  mStage->Initialize( renderToFboEnabled == Integration::RenderToFrameBuffer::TRUE );
 
-  mGestureEventProcessor = new GestureEventProcessor(*mStage, gestureManager, mRenderController);
-  mEventProcessor = new EventProcessor(*mStage, *mNotificationManager, *mGestureEventProcessor);
+  mGestureEventProcessor = new GestureEventProcessor( *mStage, *mUpdateManager, gestureManager, mRenderController );
+  mEventProcessor = new EventProcessor( *mStage, *mNotificationManager, *mGestureEventProcessor );
 
-  mImageFactory = new ImageFactory( *mResourceClient );
-  mShaderFactory = new ShaderFactory(*mResourceClient);
-  mShaderFactory->LoadDefaultShaders();
+  mShaderFactory = new ShaderFactory();
+  mUpdateManager->SetShaderSaver( *mShaderFactory );
 
   GetImplementation(Dali::TypeRegistry::Get()).CallInitFunctions();
 }
 
 Core::~Core()
 {
-  /**
-   * TODO this should be done by Adaptor, Core does not know about threading
-   * First stop the resource loading thread(s)
-   */
-  mPlatform.JoinLoaderThreads();
-
   /*
    * The order of destructing these singletons is important!!!
    */
@@ -186,6 +151,7 @@ Core::~Core()
   if( tls )
   {
     tls->Remove();
+    delete tls;
   }
 
   // Stop relayout requests being raised on stage destruction
@@ -197,18 +163,6 @@ Core::~Core()
   // remove (last?) reference to stage
   mStage.Reset();
 
-  delete mEventProcessor;
-  delete mGestureEventProcessor;
-  delete mNotificationManager;
-  delete mImageFactory;
-  delete mShaderFactory;
-  delete mResourceClient;
-  delete mResourceManager;
-  delete mUpdateManager;
-  delete mTouchResampler;
-  delete mRenderManager;
-  delete mDiscardQueue;
-  delete mResourcePostProcessQueue;
 }
 
 Integration::ContextNotifierInterface* Core::GetContextNotifier()
@@ -220,7 +174,6 @@ void Core::RecoverFromContextLoss()
 {
   DALI_LOG_INFO(gCoreFilter, Debug::Verbose, "Core::RecoverFromContextLoss()\n");
 
-  mImageFactory->RecoverFromContextLoss(); // Reload images from files
   mStage->GetRenderTaskList().RecoverFromContextLoss(); // Re-trigger render-tasks
 }
 
@@ -234,18 +187,30 @@ void Core::ContextDestroyed()
   mRenderManager->ContextDestroyed();
 }
 
-void Core::SurfaceResized(unsigned int width, unsigned int height)
+void Core::SurfaceResized( unsigned int width, unsigned int height )
 {
-  mStage->SetSize(width, 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::SetDpi( unsigned int dpiHorizontal, unsigned int dpiVertical )
 {
-  mPlatform.SetDpi( dpiHorizontal, dpiVertical );
   mStage->SetDpi( Vector2( dpiHorizontal , dpiVertical) );
 }
 
-void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int nextVSyncTimeMilliseconds, Integration::UpdateStatus& status )
+void Core::Update( float elapsedSeconds, unsigned int lastVSyncTimeMilliseconds, unsigned int 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
@@ -255,43 +220,20 @@ 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();
 
   // No need to keep update running if there are notifications to process.
   // Any message to update will wake it up anyways
-
-  if ( mResourceManager->ResourcesToProcess() )
-  {
-    // If we are still processing resources, then we have to continue the update
-    status.keepUpdating |= Integration::KeepUpdating::LOADING_RESOURCES;
-  }
 }
 
 void Core::Render( RenderStatus& status )
 {
-  bool updateRequired = mRenderManager->Render( status );
-
-  status.SetNeedsUpdate( updateRequired );
-}
-
-void Core::Suspend()
-{
-  mPlatform.Suspend();
-
-  mIsActive = false;
-}
-
-void Core::Resume()
-{
-  mPlatform.Resume();
-
-  mIsActive = true;
-
-  // trigger processing of events queued up while paused
-  ProcessEvents();
+  mRenderManager->Render( status );
 }
 
 void Core::SceneCreated()
@@ -311,12 +253,13 @@ void Core::ProcessEvents()
   // Guard against calls to ProcessEvents() during ProcessEvents()
   if( mProcessingEvent )
   {
-    DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!" );
-    mRenderController.RequestProcessEventsOnIdle();
+    DALI_LOG_ERROR( "ProcessEvents should not be called from within ProcessEvents!\n" );
+    mRenderController.RequestProcessEventsOnIdle( false );
     return;
   }
 
   mProcessingEvent = true;
+  mRelayoutController->SetProcessingCoreEvents( true );
 
   // Signal that any messages received will be flushed soon
   mUpdateManager->EventProcessingStarted();
@@ -325,41 +268,35 @@ void Core::ProcessEvents()
 
   mNotificationManager->ProcessMessages();
 
-  // Avoid allocating MessageBuffers, triggering size-negotiation or sending any other spam whilst paused
-  if( mIsActive )
-  {
-    // Emit signal here to start size negotiation and control relayout.
-    mStage->EmitEventProcessingFinishedSignal();
+  // Emit signal here to inform listeners that event processing has finished.
+  mStage->EmitEventProcessingFinishedSignal();
 
-    // Run the size negotiation after event processing finished signal
-    mRelayoutController->Relayout();
+  // Run the size negotiation after event processing finished signal
+  mRelayoutController->Relayout();
 
-    // Flush discard queue for image factory
-    mImageFactory->FlushReleaseQueue();
+  // Rebuild depth tree after event processing has finished
+  mStage->RebuildDepthTree();
 
-    // Flush any queued messages for the update-thread
-    const bool messagesToProcess = mUpdateManager->FlushQueue();
+  // Flush any queued messages for the update-thread
+  const bool messagesToProcess = mUpdateManager->FlushQueue();
 
-    // Check if the touch or gestures require updates.
-    const bool touchNeedsUpdate = mTouchResampler->NeedsUpdate();
-    const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
+  // Check if the touch or gestures require updates.
+  const bool gestureNeedsUpdate = mGestureEventProcessor->NeedsUpdate();
+  // Check if the next update is forced.
+  const bool forceUpdate = mStage->IsNextUpdateForced();
 
-    if( messagesToProcess || touchNeedsUpdate || gestureNeedsUpdate )
-    {
-      // tell the render controller to keep update thread running
-      mRenderController.RequestUpdate();
-    }
+  if( messagesToProcess || gestureNeedsUpdate || forceUpdate )
+  {
+    // tell the render controller to keep update thread running
+    mRenderController.RequestUpdate( forceUpdate );
   }
 
+  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;
@@ -415,21 +352,6 @@ NotificationManager& Core::GetNotificationManager()
   return *(mNotificationManager);
 }
 
-ResourceManager& Core::GetResourceManager()
-{
-  return *(mResourceManager);
-}
-
-ResourceClient& Core::GetResourceClient()
-{
-  return *(mResourceClient);
-}
-
-ImageFactory& Core::GetImageFactory()
-{
-  return *(mImageFactory);
-}
-
 ShaderFactory& Core::GetShaderFactory()
 {
   return *(mShaderFactory);
@@ -448,7 +370,7 @@ RelayoutController& Core::GetRelayoutController()
 void Core::CreateThreadLocalStorage()
 {
   // a pointer to the ThreadLocalStorage object will be stored in TLS
-  // and automatically deleted when the thread is killed
+  // The ThreadLocalStorage object should be deleted by the Core destructor
   new ThreadLocalStorage(this);
 }