Add a thread mode 69/232069/6
authorHeeyong Song <heeyong.song@samsung.com>
Tue, 28 Apr 2020 05:34:50 +0000 (14:34 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Mon, 1 Jun 2020 08:09:40 +0000 (08:09 +0000)
In case of ThreadMode::RUN_IF_REQUESTED, the update thread runs when the application requests rendering.

Change-Id: I8aac3fcd7fb802b0b8d5259fe40ecf14f7b905c3

dali/internal/adaptor/common/adaptor-impl.cpp
dali/internal/adaptor/common/adaptor-impl.h
dali/internal/adaptor/common/combined-update-render-controller.cpp
dali/internal/adaptor/common/combined-update-render-controller.h
dali/internal/adaptor/common/thread-controller-interface.h
dali/internal/system/common/thread-controller.cpp
dali/internal/system/common/thread-controller.h

index 737845d..a48eb5f 100755 (executable)
@@ -199,7 +199,7 @@ void Adaptor::Initialize( GraphicsFactory& graphicsFactory, Dali::Configuration:
 
   mDisplayConnection = Dali::DisplayConnection::New( *mGraphics, defaultWindow->GetSurface()->GetSurfaceType() );
 
-  mThreadController = new ThreadController( *this, *mEnvironmentOptions );
+  mThreadController = new ThreadController( *this, *mEnvironmentOptions, mThreadMode );
 
   // Should be called after Core creation
   if( mEnvironmentOptions->GetPanGestureLoggingLevel() )
@@ -1030,7 +1030,21 @@ void Adaptor::NotifyLanguageChanged()
 
 void Adaptor::RenderOnce()
 {
-  RequestUpdateOnce();
+  if( mThreadController )
+  {
+    UpdateMode updateMode;
+    if( mThreadMode == ThreadMode::NORMAL )
+    {
+      updateMode = UpdateMode::NORMAL;
+    }
+    else
+    {
+      updateMode = UpdateMode::FORCE_RENDER;
+
+      ProcessCoreEvents();
+    }
+    mThreadController->RequestUpdateOnce( updateMode );
+  }
 }
 
 const LogFactoryInterface& Adaptor::GetLogFactory()
@@ -1141,6 +1155,7 @@ Adaptor::Adaptor(Dali::Integration::SceneHolder window, Dali::Adaptor& adaptor,
   mSystemTracer(),
   mObjectProfiler( nullptr ),
   mSocketFactory(),
+  mThreadMode( ThreadMode::NORMAL ),
   mEnvironmentOptionsOwned( environmentOptions ? false : true /* If not provided then we own the object */ ),
   mUseRemoteSurface( false )
 {
index 9e4c079..31fd83a 100755 (executable)
@@ -76,6 +76,7 @@ class LifeCycleObserver;
 class ObjectProfiler;
 class SceneHolder;
 class ConfigurationManager;
+enum class ThreadMode;
 
 /**
  * Implementation of the Adaptor class.
@@ -685,6 +686,7 @@ private: // Data
   SystemTrace                           mSystemTracer;                ///< System tracer
   ObjectProfiler*                       mObjectProfiler;              ///< Tracks object lifetime for profiling
   SocketFactory                         mSocketFactory;               ///< Socket factory
+  ThreadMode                            mThreadMode;                  ///< The thread mode
   const bool                            mEnvironmentOptionsOwned:1;   ///< Whether we own the EnvironmentOptions (and thus, need to delete it)
   bool                                  mUseRemoteSurface:1;          ///< whether the remoteSurface is used or not
 
index 75d469c..0e20903 100644 (file)
@@ -89,7 +89,7 @@ const unsigned int MAXIMUM_UPDATE_REQUESTS = 2;
 // EVENT THREAD
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions )
+CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions, ThreadMode threadMode )
 : mFpsTracker( environmentOptions ),
   mUpdateStatusLogger( environmentOptions ),
   mEventThreadSemaphore(),
@@ -109,6 +109,7 @@ CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalS
   mDefaultHalfFrameNanoseconds( 0u ),
   mUpdateRequestCount( 0u ),
   mRunning( FALSE ),
+  mThreadMode( threadMode ),
   mUpdateRenderRunCount( 0 ),
   mDestroyUpdateRenderThread( FALSE ),
   mUpdateRenderThreadCanSleep( FALSE ),
@@ -289,7 +290,7 @@ void CombinedUpdateRenderController::RequestUpdateOnce( UpdateMode updateMode )
     ++mUpdateRequestCount;
   }
 
-  if( IsUpdateRenderThreadPaused() )
+  if( IsUpdateRenderThreadPaused() || updateMode == UpdateMode::FORCE_RENDER )
   {
     LOG_EVENT_TRACE;
 
@@ -418,9 +419,31 @@ void CombinedUpdateRenderController::AddSurface( Dali::RenderSurfaceInterface* s
 void CombinedUpdateRenderController::RunUpdateRenderThread( int numberOfCycles, AnimationProgression animationProgression, UpdateMode updateMode )
 {
   ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition );
-  mUpdateRenderRunCount = numberOfCycles;
+
+  switch( mThreadMode )
+  {
+    case ThreadMode::NORMAL:
+    {
+      mUpdateRenderRunCount = numberOfCycles;
+      mUseElapsedTimeAfterWait = ( animationProgression == AnimationProgression::USE_ELAPSED_TIME );
+      break;
+    }
+    case ThreadMode::RUN_IF_REQUESTED:
+    {
+      if( updateMode != UpdateMode::FORCE_RENDER )
+      {
+        // Render only if the update mode is FORCE_RENDER which means the application requests it.
+        // We don't want to awake the update thread.
+        return;
+      }
+
+      mUpdateRenderRunCount++;          // Increase the update request count
+      mUseElapsedTimeAfterWait = TRUE;  // The elapsed time should be used. We want animations to proceed.
+      break;
+    }
+  }
+
   mUpdateRenderThreadCanSleep = FALSE;
-  mUseElapsedTimeAfterWait = ( animationProgression == AnimationProgression::USE_ELAPSED_TIME );
   mUploadWithoutRendering = ( updateMode == UpdateMode::SKIP_RENDER );
   LOG_COUNTER_EVENT( "mUpdateRenderRunCount: %d, mUseElapsedTimeAfterWait: %d", mUpdateRenderRunCount, mUseElapsedTimeAfterWait );
   mUpdateRenderThreadWaitCondition.Notify( lock );
@@ -442,6 +465,12 @@ void CombinedUpdateRenderController::StopUpdateRenderThread()
 bool CombinedUpdateRenderController::IsUpdateRenderThreadPaused()
 {
   ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition );
+
+  if( mThreadMode == ThreadMode::RUN_IF_REQUESTED )
+  {
+    return !mRunning || mUpdateRenderThreadCanSleep;
+  }
+
   return ( mUpdateRenderRunCount != CONTINUOUS ) || // Report paused if NOT continuously running
          mUpdateRenderThreadCanSleep;               // Report paused if sleeping
 }
@@ -562,7 +591,7 @@ void CombinedUpdateRenderController::UpdateRenderThread()
     uint64_t currentFrameStartTime = 0;
     TimeService::GetNanoseconds( currentFrameStartTime );
 
-    const uint64_t timeSinceLastFrame = currentFrameStartTime - lastFrameTime;
+    uint64_t timeSinceLastFrame = currentFrameStartTime - lastFrameTime;
 
     // Optional FPS Tracking when continuously rendering
     if( useElapsedTime && mFpsTracker.Enabled() )
@@ -609,6 +638,16 @@ void CombinedUpdateRenderController::UpdateRenderThread()
     float frameDelta = 0.0f;
     if( useElapsedTime )
     {
+      if( mThreadMode == ThreadMode::RUN_IF_REQUESTED )
+      {
+        extraFramesDropped = 0;
+        while( timeSinceLastFrame >= mDefaultFrameDurationNanoseconds )
+        {
+           timeSinceLastFrame -= mDefaultFrameDurationNanoseconds;
+           extraFramesDropped++;
+        }
+      }
+
       // If using the elapsed time, then calculate frameDelta as a multiple of mDefaultFrameDelta
       noOfFramesSinceLastUpdate += extraFramesDropped;
 
index 54cc67d..965479e 100644 (file)
@@ -80,7 +80,7 @@ public:
   /**
    * Constructor
    */
-  CombinedUpdateRenderController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions );
+  CombinedUpdateRenderController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions, ThreadMode threadMode );
 
   /**
    * Non virtual destructor. Not intended as base class.
@@ -367,6 +367,8 @@ private:
   unsigned int                      mUpdateRequestCount;               ///< Count of update-requests we have received to ensure we do not go to sleep too early.
   unsigned int                      mRunning;                          ///< Read and set on the event-thread only to state whether we are running.
 
+  ThreadMode                        mThreadMode;                       ///< Whether the thread runs continuously or runs when it is requested.
+
   //
   // NOTE: cannot use booleans as these are used from multiple threads, must use variable with machine word size for atomic read/write
   //
index 6b9055b..efeb819 100644 (file)
@@ -34,7 +34,14 @@ namespace Adaptor
 enum class UpdateMode
 {
   NORMAL,                     ///< Update and render
-  SKIP_RENDER                 ///< Update and resource upload but no rendering
+  SKIP_RENDER,                ///< Update and resource upload but no rendering
+  FORCE_RENDER                ///< Force update and render
+};
+
+enum class ThreadMode
+{
+  NORMAL,                     ///< The thread runs continuously
+  RUN_IF_REQUESTED            ///< The threads runs when it is requested
 };
 
 /**
index a9054ec..31a5a24 100644 (file)
@@ -32,14 +32,14 @@ namespace Internal
 namespace Adaptor
 {
 
-ThreadController::ThreadController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions )
+ThreadController::ThreadController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions, ThreadMode threadMode )
 : mThreadControllerInterface( NULL )
 {
   switch( environmentOptions.GetThreadingMode() )
   {
     case ThreadingMode::COMBINED_UPDATE_RENDER:
     {
-      mThreadControllerInterface = new CombinedUpdateRenderController( adaptorInterfaces, environmentOptions );
+      mThreadControllerInterface = new CombinedUpdateRenderController( adaptorInterfaces, environmentOptions, threadMode );
       break;
     }
   }
index c4f3961..d51e57d 100644 (file)
@@ -34,6 +34,7 @@ namespace Adaptor
 {
 
 enum class UpdateMode;
+enum class ThreadMode;
 
 class AdaptorInternalServices;
 class EnvironmentOptions;
@@ -49,7 +50,7 @@ public:
   /**
    * Constructor
    */
-  ThreadController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions );
+  ThreadController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions, ThreadMode threadMode );
 
   /**
    * Non virtual destructor. Not intended as base class.