From: Richard Huang Date: Tue, 7 Apr 2020 16:26:21 +0000 (+0100) Subject: Suspend window deletion while rendering X-Git-Tag: dali_1.9.7~1^2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git;a=commitdiff_plain;h=e2b1bb333f68b1a21a24f84c6c21db2f618a8f53 Suspend window deletion while rendering Change-Id: I6801f1daffa69567bad794387676e23b33051f2b --- diff --git a/dali/integration-api/adaptor-framework/scene-holder-impl.cpp b/dali/integration-api/adaptor-framework/scene-holder-impl.cpp index 17b916e..2440b35 100644 --- a/dali/integration-api/adaptor-framework/scene-holder-impl.cpp +++ b/dali/integration-api/adaptor-framework/scene-holder-impl.cpp @@ -120,6 +120,7 @@ SceneHolder::SceneHolder() mId( mSceneHolderCounter++ ), mSurface( nullptr ), mAdaptor( nullptr ), + mIsBeingDeleted( false ), mAdaptorStarted( false ), mVisible( true ) { diff --git a/dali/integration-api/adaptor-framework/scene-holder-impl.h b/dali/integration-api/adaptor-framework/scene-holder-impl.h index 10051b9..3a830f9 100644 --- a/dali/integration-api/adaptor-framework/scene-holder-impl.h +++ b/dali/integration-api/adaptor-framework/scene-holder-impl.h @@ -21,6 +21,7 @@ // EXTERNAL INCLUDES #include #include +#include #include #include #include @@ -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 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 }; diff --git a/dali/internal/adaptor/common/adaptor-impl.cpp b/dali/internal/adaptor/common/adaptor-impl.cpp index cbf467f..1e66048 100755 --- a/dali/internal/adaptor/common/adaptor-impl.cpp +++ b/dali/internal/adaptor/common/adaptor-impl.cpp @@ -1033,6 +1033,11 @@ bool Adaptor::IsMultipleWindowSupported() const return mConfigurationManager->IsMultipleWindowSupported(); } +bool Adaptor::IsRenderingWindows() const +{ + return ( mThreadController && mThreadController->IsRenderingWindows() ); +} + void Adaptor::RequestUpdateOnce() { if( mThreadController ) diff --git a/dali/internal/adaptor/common/adaptor-impl.h b/dali/internal/adaptor/common/adaptor-impl.h index 2186a15..93031ff 100755 --- a/dali/internal/adaptor/common/adaptor-impl.h +++ b/dali/internal/adaptor/common/adaptor-impl.h @@ -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 /** diff --git a/dali/internal/adaptor/common/combined-update-render-controller.cpp b/dali/internal/adaptor/common/combined-update-render-controller.cpp index 77edf45..80bc0a3 100644 --- a/dali/internal/adaptor/common/combined-update-render-controller.cpp +++ b/dali/internal/adaptor/common/combined-update-render-controller.cpp @@ -21,6 +21,7 @@ // EXTERNAL INCLUDES #include #include +#include // INTERNAL INCLUDES #include @@ -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 ); diff --git a/dali/internal/adaptor/common/combined-update-render-controller.h b/dali/internal/adaptor/common/combined-update-render-controller.h index 7f6f007..ca22517 100644 --- a/dali/internal/adaptor/common/combined-update-render-controller.h +++ b/dali/internal/adaptor/common/combined-update-render-controller.h @@ -21,6 +21,7 @@ // EXTERNAL INCLUDES #include #include +#include #include #include #include @@ -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 mIsRenderingWindows; ///< This is set only from the render thread and read only from the event thread }; } // namespace Adaptor diff --git a/dali/internal/adaptor/common/thread-controller-interface.h b/dali/internal/adaptor/common/thread-controller-interface.h index 6bf730e..94276ff 100644 --- a/dali/internal/adaptor/common/thread-controller-interface.h +++ b/dali/internal/adaptor/common/thread-controller-interface.h @@ -118,6 +118,11 @@ public: */ virtual void AddSurface( Dali::RenderSurfaceInterface* surface ) = 0; + /** + * @copydoc Dali::Adaptor::IsRenderingWindows() + */ + virtual bool IsRenderingWindows() const = 0; + protected: /** diff --git a/dali/internal/system/common/thread-controller.cpp b/dali/internal/system/common/thread-controller.cpp index e5902cb..605c76d 100644 --- a/dali/internal/system/common/thread-controller.cpp +++ b/dali/internal/system/common/thread-controller.cpp @@ -115,6 +115,11 @@ void ThreadController::AddSurface( Dali::RenderSurfaceInterface* newSurface ) mThreadControllerInterface->AddSurface( newSurface ); } +bool ThreadController::IsRenderingWindows() const +{ + return mThreadControllerInterface->IsRenderingWindows(); +} + } // namespace Adaptor } // namespace Internal diff --git a/dali/internal/system/common/thread-controller.h b/dali/internal/system/common/thread-controller.h index aeac0af..471a5f9 100644 --- a/dali/internal/system/common/thread-controller.h +++ b/dali/internal/system/common/thread-controller.h @@ -138,6 +138,11 @@ public: */ void AddSurface( Dali::RenderSurfaceInterface* surface ); + /** + * @copydoc Dali::Adaptor::IsRenderingWindows() + */ + bool IsRenderingWindows() const; + private: // Undefined copy constructor. diff --git a/dali/internal/window-system/common/window-impl.cpp b/dali/internal/window-system/common/window-impl.cpp index 9c734f5..a0fd809 100644 --- a/dali/internal/window-system/common/window-impl.cpp +++ b/dali/internal/window-system/common/window-impl.cpp @@ -19,6 +19,7 @@ #include // EXTERNAL HEADERS +#include #include #include #include @@ -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 );