Suspend window deletion while rendering 69/230069/2
authorRichard Huang <r.huang@samsung.com>
Tue, 7 Apr 2020 16:26:21 +0000 (17:26 +0100)
committerRichard Huang <r.huang@samsung.com>
Wed, 8 Apr 2020 13:40:46 +0000 (14:40 +0100)
Change-Id: I6801f1daffa69567bad794387676e23b33051f2b

dali/integration-api/adaptor-framework/scene-holder-impl.cpp
dali/integration-api/adaptor-framework/scene-holder-impl.h
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
dali/internal/window-system/common/window-impl.cpp

index 17b916e..2440b35 100644 (file)
@@ -120,6 +120,7 @@ SceneHolder::SceneHolder()
   mId( mSceneHolderCounter++ ),
   mSurface( nullptr ),
   mAdaptor( nullptr ),
+  mIsBeingDeleted( false ),
   mAdaptorStarted( false ),
   mVisible( true )
 {
index 10051b9..3a830f9 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <memory>
 #include <vector>
+#include <atomic>
 #include <dali/public-api/object/base-object.h>
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/integration-api/scene.h>
@@ -148,6 +149,13 @@ public:
   void Resume();
 
   /**
+   * @brief Checks whether this scene holder is being deleted in the event thread.
+   *
+   * @return true if this scene holder is being deleted in the event thread, or false if not.
+   */
+  bool IsBeingDeleted() const { return mIsBeingDeleted; }
+
+  /**
    * @copydoc Dali::Integration::SceneHolder::FeedTouchPoint
    */
   void FeedTouchPoint( Dali::Integration::Point& point, int timeStamp );
@@ -273,6 +281,8 @@ protected:
 
   Dali::Integration::TouchEventCombiner           mCombiner;           ///< Combines multi-touch events.
 
+  std::atomic<bool>                               mIsBeingDeleted;     ///< This is set only from the event thread and read only from the render thread
+
   bool                                            mAdaptorStarted:1;   ///< Whether the adaptor has started or not
   bool                                            mVisible:1;          ///< Whether the scene is visible or not
 };
index cbf467f..1e66048 100755 (executable)
@@ -1033,6 +1033,11 @@ bool Adaptor::IsMultipleWindowSupported() const
   return mConfigurationManager->IsMultipleWindowSupported();
 }
 
+bool Adaptor::IsRenderingWindows() const
+{
+  return ( mThreadController && mThreadController->IsRenderingWindows() );
+}
+
 void Adaptor::RequestUpdateOnce()
 {
   if( mThreadController )
index 2186a15..93031ff 100755 (executable)
@@ -438,6 +438,13 @@ public:
    */
   bool IsMultipleWindowSupported() const;
 
+  /**
+   * @brief Checks whether the windows are being rendered in the render thread.
+   *
+   * @return true if the windows are being rendered in the render thread, or false if not.
+   */
+  bool IsRenderingWindows() const;
+
 public:  //AdaptorInternalServices
 
   /**
index 77edf45..80bc0a3 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <errno.h>
 #include <dali/integration-api/platform-abstraction.h>
+#include <unistd.h>
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/adaptor-framework/trigger-event-factory.h>
@@ -118,7 +119,8 @@ CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalS
   mSurfaceResized( FALSE ),
   mForceClear( FALSE ),
   mUploadWithoutRendering( FALSE ),
-  mFirstFrameAfterResume( FALSE )
+  mFirstFrameAfterResume( FALSE ),
+  mIsRenderingWindows( false )
 {
   LOG_EVENT_TRACE;
 
@@ -661,6 +663,8 @@ void CombinedUpdateRenderController::UpdateRenderThread()
 
     AddPerformanceMarker( PerformanceInterface::RENDER_START );
 
+    mIsRenderingWindows = true;
+
     // Upload shared resources
     mCore.PreRender( renderStatus, mForceClear, mUploadWithoutRendering );
 
@@ -670,30 +674,35 @@ void CombinedUpdateRenderController::UpdateRenderThread()
       WindowContainer windows;
       mAdaptorInterfaces.GetWindowContainerInterface( windows );
 
-      for ( auto&& iter = windows.begin(); iter != windows.end(); ++iter )
+      for( auto&& window : windows )
       {
-        if (*iter)
+        if ( window && !window->IsBeingDeleted() )
         {
-          Dali::Integration::Scene scene = (*iter)->GetScene();
+          Dali::Integration::Scene scene = window->GetScene();
+          Dali::RenderSurfaceInterface* windowSurface = window->GetSurface();
 
-          (*iter)->GetSurface()->InitializeGraphics();
+          if ( scene && windowSurface )
+          {
+            windowSurface->InitializeGraphics();
 
-          // Render off-screen frame buffers first if any
-          mCore.RenderScene( scene, true );
+            // Render off-screen frame buffers first if any
+            mCore.RenderScene( scene, true );
 
-          // Switch to the EGL context of the surface
-          (*iter)->GetSurface()->PreRender( surfaceResized ); // Switch GL context
+            // Switch to the EGL context of the surface
+            windowSurface->PreRender( surfaceResized ); // Switch GL context
 
-          // Render the surface
-          mCore.RenderScene( scene, false );
+            // Render the surface
+            mCore.RenderScene( scene, false );
 
-          (*iter)->GetSurface()->PostRender( false, false, surfaceResized ); // Swap Buffer
+            windowSurface->PostRender( false, false, surfaceResized ); // Swap Buffer
+          }
         }
       }
     }
 
     mCore.PostRender( mUploadWithoutRendering );
 
+    mIsRenderingWindows = false;
 
     AddPerformanceMarker( PerformanceInterface::RENDER_END );
 
index 7f6f007..ca22517 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <pthread.h>
 #include <semaphore.h>
+#include <atomic>
 #include <stdint.h>
 #include <dali/devel-api/threading/conditional-wait.h>
 #include <dali/integration-api/core.h>
@@ -151,6 +152,11 @@ public:
    */
   virtual void AddSurface( Dali::RenderSurfaceInterface* surface );
 
+  /**
+   * @copydoc ThreadControllerInterface::IsRenderingWindows()
+   */
+  bool IsRenderingWindows() const override { return mIsRenderingWindows; }
+
 private:
 
   // Undefined copy constructor.
@@ -367,6 +373,8 @@ private:
   volatile unsigned int             mUploadWithoutRendering;           ///< Will be set to upload the resource only (with no rendering)
 
   volatile unsigned int             mFirstFrameAfterResume;            ///< Will be set to check the first frame after resume (for log)
+
+  std::atomic<bool>                 mIsRenderingWindows;               ///< This is set only from the render thread and read only from the event thread
 };
 
 } // namespace Adaptor
index 6bf730e..94276ff 100644 (file)
@@ -118,6 +118,11 @@ public:
    */
   virtual void AddSurface( Dali::RenderSurfaceInterface* surface ) = 0;
 
+  /**
+   * @copydoc Dali::Adaptor::IsRenderingWindows()
+   */
+  virtual bool IsRenderingWindows() const = 0;
+
 protected:
 
   /**
index e5902cb..605c76d 100644 (file)
@@ -115,6 +115,11 @@ void ThreadController::AddSurface( Dali::RenderSurfaceInterface* newSurface )
   mThreadControllerInterface->AddSurface( newSurface );
 }
 
+bool ThreadController::IsRenderingWindows() const
+{
+  return mThreadControllerInterface->IsRenderingWindows();
+}
+
 } // namespace Adaptor
 
 } // namespace Internal
index aeac0af..471a5f9 100644 (file)
@@ -138,6 +138,11 @@ public:
    */
   void AddSurface( Dali::RenderSurfaceInterface* surface );
 
+  /**
+   * @copydoc Dali::Adaptor::IsRenderingWindows()
+   */
+  bool IsRenderingWindows() const;
+
 private:
 
   // Undefined copy constructor.
index 9c734f5..a0fd809 100644 (file)
@@ -19,6 +19,7 @@
 #include <dali/internal/window-system/common/window-impl.h>
 
 // EXTERNAL HEADERS
+#include <thread>
 #include <dali/integration-api/core.h>
 #include <dali/public-api/actors/actor.h>
 #include <dali/public-api/actors/layer.h>
@@ -98,6 +99,13 @@ Window::Window()
 
 Window::~Window()
 {
+  mIsBeingDeleted = true;
+
+  while ( mAdaptor && mAdaptor->IsRenderingWindows() )
+  {
+    std::this_thread::yield(); // to allow other threads to run
+  }
+
   if ( mEventHandler )
   {
     mEventHandler->RemoveObserver( *this );