From: Heeyong Song Date: Wed, 13 May 2020 07:30:29 +0000 (+0900) Subject: Remove EGL surface in the update thread X-Git-Tag: dali_1.9.13~1^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F45%2F233245%2F2;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git Remove EGL surface in the update thread Change-Id: I251f2b89e02e883839964c80c2b80704a95ebf8d --- diff --git a/dali/integration-api/adaptor-framework/scene-holder-impl.cpp b/dali/integration-api/adaptor-framework/scene-holder-impl.cpp index 2440b35..7162a1c 100644 --- a/dali/integration-api/adaptor-framework/scene-holder-impl.cpp +++ b/dali/integration-api/adaptor-framework/scene-holder-impl.cpp @@ -133,6 +133,8 @@ SceneHolder::~SceneHolder() mAdaptor->RemoveObserver( *mLifeCycleObserver.get() ); mAdaptor->RemoveWindow( this ); + mAdaptor->DeleteSurface( *mSurface.get() ); + mAdaptor = nullptr; } diff --git a/dali/internal/adaptor/common/adaptor-impl.cpp b/dali/internal/adaptor/common/adaptor-impl.cpp index 2ecb543..188c64e 100755 --- a/dali/internal/adaptor/common/adaptor-impl.cpp +++ b/dali/internal/adaptor/common/adaptor-impl.cpp @@ -557,6 +557,16 @@ void Adaptor::ReplaceSurface( Dali::Integration::SceneHolder window, Dali::Rende } } +void Adaptor::DeleteSurface( Dali::RenderSurfaceInterface& surface ) +{ + // Flush the event queue to give the update-render thread chance + // to start processing messages for new camera setup etc as soon as possible + ProcessCoreEvents(); + + // This method blocks until the render thread has finished rendering the current surface. + mThreadController->DeleteSurface( &surface ); +} + Dali::RenderSurfaceInterface& Adaptor::GetSurface() const { return *mWindows.front()->GetSurface(); @@ -1041,11 +1051,6 @@ 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 c2a9ad4..d0d2379 100755 --- a/dali/internal/adaptor/common/adaptor-impl.h +++ b/dali/internal/adaptor/common/adaptor-impl.h @@ -292,6 +292,12 @@ public: // AdaptorInternalServices implementation bool RemoveWindow( Dali::Internal::Adaptor::SceneHolder* childWindow ); /** + * @brief Deletes the rendering surface + * @param[in] surface to delete + */ + void DeleteSurface( Dali::RenderSurfaceInterface& surface ); + + /** * @brief Retrieve the window that the given actor is added to. * * @param[in] actor The actor @@ -443,13 +449,6 @@ 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 80bc0a3..7343b43 100644 --- a/dali/internal/adaptor/common/combined-update-render-controller.cpp +++ b/dali/internal/adaptor/common/combined-update-render-controller.cpp @@ -115,12 +115,12 @@ CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalS mPendingRequestUpdate( FALSE ), mUseElapsedTimeAfterWait( FALSE ), mNewSurface( NULL ), + mDeletedSurface( nullptr ), mPostRendering( FALSE ), mSurfaceResized( FALSE ), mForceClear( FALSE ), mUploadWithoutRendering( FALSE ), - mFirstFrameAfterResume( FALSE ), - mIsRenderingWindows( false ) + mFirstFrameAfterResume( FALSE ) { LOG_EVENT_TRACE; @@ -324,6 +324,29 @@ void CombinedUpdateRenderController::ReplaceSurface( Dali::RenderSurfaceInterfac } } +void CombinedUpdateRenderController::DeleteSurface( Dali::RenderSurfaceInterface* surface ) +{ + LOG_EVENT_TRACE; + + if( mUpdateRenderThread ) + { + LOG_EVENT( "Starting to delete the surface, event-thread blocked" ); + + // Start replacing the surface. + { + ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); + mPostRendering = FALSE; // Clear the post-rendering flag as Update/Render thread will delete the surface now + mDeletedSurface = surface; + mUpdateRenderThreadWaitCondition.Notify( lock ); + } + + // Wait until the surface has been deleted + sem_wait( &mEventThreadSemaphore ); + + LOG_EVENT( "Surface deleted, event-thread continuing" ); + } +} + void CombinedUpdateRenderController::WaitForGraphicsInitialization() { LOG_EVENT_TRACE; @@ -663,8 +686,6 @@ void CombinedUpdateRenderController::UpdateRenderThread() AddPerformanceMarker( PerformanceInterface::RENDER_START ); - mIsRenderingWindows = true; - // Upload shared resources mCore.PreRender( renderStatus, mForceClear, mUploadWithoutRendering ); @@ -676,33 +697,42 @@ void CombinedUpdateRenderController::UpdateRenderThread() for( auto&& window : windows ) { - if ( window && !window->IsBeingDeleted() ) - { - Dali::Integration::Scene scene = window->GetScene(); - Dali::RenderSurfaceInterface* windowSurface = window->GetSurface(); + Dali::Integration::Scene scene = window->GetScene(); + Dali::RenderSurfaceInterface* windowSurface = window->GetSurface(); - if ( scene && windowSurface ) - { - windowSurface->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 - windowSurface->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 ); - windowSurface->PostRender( false, false, surfaceResized ); // Swap Buffer - } + windowSurface->PostRender( false, false, surfaceResized ); // Swap Buffer } } } mCore.PostRender( mUploadWithoutRendering ); - mIsRenderingWindows = false; + ////////////////////////////// + // DELETE SURFACE + ////////////////////////////// + + Dali::RenderSurfaceInterface* deletedSurface = ShouldSurfaceBeDeleted(); + if( DALI_UNLIKELY( deletedSurface ) ) + { + LOG_UPDATE_RENDER_TRACE_FMT( "Deleting Surface" ); + + deletedSurface->DestroySurface(); + + SurfaceDeleted(); + } AddPerformanceMarker( PerformanceInterface::RENDER_END ); @@ -788,12 +818,14 @@ bool CombinedUpdateRenderController::UpdateRenderReady( bool& useElapsedTime, bo ( mUpdateRenderThreadCanSleep && ! updateRequired && ! mPendingRequestUpdate ) ) && // Ensure we wait if we're supposed to be sleeping AND do not require another update ! mDestroyUpdateRenderThread && // Ensure we don't wait if the update-render-thread is supposed to be destroyed ! mNewSurface && // Ensure we don't wait if we need to replace the surface + ! mDeletedSurface && // Ensure we don't wait if we need to delete the surface ! mSurfaceResized ) // Ensure we don't wait if we need to resize the surface { LOG_UPDATE_RENDER( "WAIT: mUpdateRenderRunCount: %d", mUpdateRenderRunCount ); LOG_UPDATE_RENDER( " mUpdateRenderThreadCanSleep: %d, updateRequired: %d, mPendingRequestUpdate: %d", mUpdateRenderThreadCanSleep, updateRequired, mPendingRequestUpdate ); LOG_UPDATE_RENDER( " mDestroyUpdateRenderThread: %d", mDestroyUpdateRenderThread ); LOG_UPDATE_RENDER( " mNewSurface: %d", mNewSurface ); + LOG_UPDATE_RENDER( " mDeletedSurface: %d", mDeletedSurface ); LOG_UPDATE_RENDER( " mSurfaceResized: %d", mSurfaceResized ); // Reset the time when the thread is waiting, so the sleep-until time for @@ -813,6 +845,7 @@ bool CombinedUpdateRenderController::UpdateRenderReady( bool& useElapsedTime, bo LOG_COUNTER_UPDATE_RENDER( "mUpdateRenderThreadCanSleep: %d, updateRequired: %d, mPendingRequestUpdate: %d", mUpdateRenderThreadCanSleep, updateRequired, mPendingRequestUpdate ); LOG_COUNTER_UPDATE_RENDER( "mDestroyUpdateRenderThread: %d", mDestroyUpdateRenderThread ); LOG_COUNTER_UPDATE_RENDER( "mNewSurface: %d", mNewSurface ); + LOG_COUNTER_UPDATE_RENDER( "mDeletedSurface: %d", mDeletedSurface ); LOG_COUNTER_UPDATE_RENDER( "mSurfaceResized: %d", mSurfaceResized ); mUseElapsedTimeAfterWait = FALSE; @@ -846,6 +879,22 @@ void CombinedUpdateRenderController::SurfaceReplaced() sem_post( &mEventThreadSemaphore ); } +Dali::RenderSurfaceInterface* CombinedUpdateRenderController::ShouldSurfaceBeDeleted() +{ + ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); + + Dali::RenderSurfaceInterface* deletedSurface = mDeletedSurface; + mDeletedSurface = NULL; + + return deletedSurface; +} + +void CombinedUpdateRenderController::SurfaceDeleted() +{ + // Just increment the semaphore + sem_post( &mEventThreadSemaphore ); +} + bool CombinedUpdateRenderController::ShouldSurfaceBeResized() { ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); @@ -907,6 +956,7 @@ void CombinedUpdateRenderController::PostRenderWaitForCompletion() ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); while( mPostRendering && ! mNewSurface && // We should NOT wait if we're replacing the surface + ! mDeletedSurface && // We should NOT wait if we're deleting the surface ! mDestroyUpdateRenderThread ) { mUpdateRenderThreadWaitCondition.Wait( lock ); diff --git a/dali/internal/adaptor/common/combined-update-render-controller.h b/dali/internal/adaptor/common/combined-update-render-controller.h index ca22517..54cc67d 100644 --- a/dali/internal/adaptor/common/combined-update-render-controller.h +++ b/dali/internal/adaptor/common/combined-update-render-controller.h @@ -128,6 +128,11 @@ public: virtual void ReplaceSurface( Dali::RenderSurfaceInterface* surface ); /** + * @copydoc ThreadControllerInterface::DeleteSurface() + */ + virtual void DeleteSurface( Dali::RenderSurfaceInterface* surface ); + + /** * @copydoc ThreadControllerInterface::ResizeSurface() */ virtual void ResizeSurface(); @@ -152,11 +157,6 @@ public: */ virtual void AddSurface( Dali::RenderSurfaceInterface* surface ); - /** - * @copydoc ThreadControllerInterface::IsRenderingWindows() - */ - bool IsRenderingWindows() const override { return mIsRenderingWindows; } - private: // Undefined copy constructor. @@ -250,6 +250,21 @@ private: void SurfaceReplaced(); /** + * Checks to see if the surface needs to be deleted. + * This will lock the mutex in mUpdateRenderThreadWaitCondition. + * + * @return Pointer to the deleted surface, nullptr otherwise + */ + Dali::RenderSurfaceInterface* ShouldSurfaceBeDeleted(); + + /** + * Called by the Update/Render thread after a surface has been deleted. + * + * This will lock the mutex in mEventThreadWaitCondition + */ + void SurfaceDeleted(); + + /** * Checks to see if the surface needs to be resized. * This will lock the mutex in mUpdateRenderThreadWaitCondition. * @@ -365,6 +380,7 @@ private: volatile unsigned int mUseElapsedTimeAfterWait; ///< Whether we should use the elapsed time after waiting (set by the event-thread, read by the update-render-thread). Dali::RenderSurfaceInterface* volatile mNewSurface; ///< Will be set to the new-surface if requested (set by the event-thread, read & cleared by the update-render thread). + Dali::RenderSurfaceInterface* volatile mDeletedSurface; ///< Will be set to the deleted surface if requested (set by the event-thread, read & cleared by the update-render thread). volatile unsigned int mPostRendering; ///< Whether post-rendering is taking place (set by the event & render threads, read by the render-thread). volatile unsigned int mSurfaceResized; ///< Will be set to resize the surface (set by the event-thread, read & cleared by the update-render thread). @@ -373,8 +389,6 @@ 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 94276ff..6b9055b 100644 --- a/dali/internal/adaptor/common/thread-controller-interface.h +++ b/dali/internal/adaptor/common/thread-controller-interface.h @@ -93,6 +93,12 @@ public: virtual void ReplaceSurface( Dali::RenderSurfaceInterface* surface ) = 0; /** + * Deletes the surface. + * @param[in] surface The surface to be deleted + */ + virtual void DeleteSurface( Dali::RenderSurfaceInterface* surface ) = 0; + + /** * Resize the surface. */ virtual void ResizeSurface() = 0; @@ -118,11 +124,6 @@ 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 605c76d..a9054ec 100644 --- a/dali/internal/system/common/thread-controller.cpp +++ b/dali/internal/system/common/thread-controller.cpp @@ -90,6 +90,11 @@ void ThreadController::ReplaceSurface( Dali::RenderSurfaceInterface* newSurface mThreadControllerInterface->ReplaceSurface( newSurface ); } +void ThreadController::DeleteSurface( Dali::RenderSurfaceInterface* surface ) +{ + mThreadControllerInterface->DeleteSurface( surface ); +} + void ThreadController::ResizeSurface() { mThreadControllerInterface->ResizeSurface(); @@ -115,11 +120,6 @@ 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 471a5f9..c4f3961 100644 --- a/dali/internal/system/common/thread-controller.h +++ b/dali/internal/system/common/thread-controller.h @@ -112,6 +112,12 @@ public: void ReplaceSurface( Dali::RenderSurfaceInterface* surface ); /** + * Deletes the surface. + * @param surface The surface to be deleted + */ + void DeleteSurface( Dali::RenderSurfaceInterface* surface ); + + /** * Resize the surface. */ void ResizeSurface(); @@ -138,11 +144,6 @@ 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 a0fd809..5321782 100644 --- a/dali/internal/window-system/common/window-impl.cpp +++ b/dali/internal/window-system/common/window-impl.cpp @@ -99,13 +99,6 @@ 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 ); diff --git a/dali/internal/window-system/common/window-render-surface.cpp b/dali/internal/window-system/common/window-render-surface.cpp index e1a344f..c95d508 100644 --- a/dali/internal/window-system/common/window-render-surface.cpp +++ b/dali/internal/window-system/common/window-render-surface.cpp @@ -85,11 +85,6 @@ WindowRenderSurface::~WindowRenderSurface() { delete mRotationTrigger; } - - if ( mEGLSurface ) - { - DestroySurface(); - } } void WindowRenderSurface::Initialize( Any surface ) @@ -264,7 +259,13 @@ void WindowRenderSurface::DestroySurface() DALI_LOG_RELEASE_INFO("WindowRenderSurface::DestroySurface: WinId (%d)\n", mWindowBase->GetNativeWindowId() ); Internal::Adaptor::EglImplementation& eglImpl = eglGraphics->GetEglImplementation(); + eglImpl.DestroySurface( mEGLSurface ); + mEGLSurface = nullptr; + + // Destroy context also + eglImpl.DestroyContext( mEGLContext ); + mEGLContext = nullptr; mWindowBase->DestroyEglWindow(); }