From b9bf5e457c6acf67b7412088a46ce4dba15aa168 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Tue, 18 Aug 2020 17:17:54 +0900 Subject: [PATCH] Fix WindowRenderSurface crash Prevent accessing the mFrameCallbackInfoContainer in 2 thread at the same time Change-Id: I6cdf6cea5a39747adf8f764abb58613263038752 --- .../window-system/common/window-render-surface.cpp | 61 ++++++++++++++-------- .../window-system/common/window-render-surface.h | 2 + 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/dali/internal/window-system/common/window-render-surface.cpp b/dali/internal/window-system/common/window-render-surface.cpp index 509c174..7326047 100644 --- a/dali/internal/window-system/common/window-render-surface.cpp +++ b/dali/internal/window-system/common/window-render-surface.cpp @@ -67,6 +67,7 @@ WindowRenderSurface::WindowRenderSurface( Dali::PositionSize positionSize, Any s mColorDepth( isTransparent ? COLOR_DEPTH_32 : COLOR_DEPTH_24 ), mOutputTransformedSignal(), mFrameCallbackInfoContainer(), + mMutex(), mRotationAngle( 0 ), mScreenRotationAngle( 0 ), mOwnSurface( false ), @@ -361,22 +362,21 @@ bool WindowRenderSurface::PreRender( bool resizingSurface, const std::vectorCreateFrameRenderedSyncFence(); if( frameRenderedSync != -1 ) { + Dali::Mutex::ScopedLock lock( mMutex ); + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: CreateFrameRenderedSyncFence [%d]\n", frameRenderedSync ); mFrameCallbackInfoContainer.push_back( std::unique_ptr< FrameCallbackInfo >( new FrameCallbackInfo( callbacks, frameRenderedSync ) ) ); - if( !mFrameRenderedTrigger ) - { - mFrameRenderedTrigger = std::unique_ptr< TriggerEventInterface >( TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &WindowRenderSurface::ProcessFrameCallback ), - TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) ); - } - mFrameRenderedTrigger->Trigger(); + needFrameRenderedTrigger = true; } else { @@ -393,16 +393,13 @@ bool WindowRenderSurface::PreRender( bool resizingSurface, const std::vectorCreateFramePresentedSyncFence(); if( framePresentedSync != -1 ) { + Dali::Mutex::ScopedLock lock( mMutex ); + DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::PreRender: CreateFramePresentedSyncFence [%d]\n", framePresentedSync ); mFrameCallbackInfoContainer.push_back( std::unique_ptr< FrameCallbackInfo >( new FrameCallbackInfo( callbacks, framePresentedSync ) ) ); - if( !mFrameRenderedTrigger ) - { - mFrameRenderedTrigger = std::unique_ptr< TriggerEventInterface >( TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &WindowRenderSurface::ProcessFrameCallback ), - TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) ); - } - mFrameRenderedTrigger->Trigger(); + needFrameRenderedTrigger = true; } else { @@ -412,6 +409,16 @@ bool WindowRenderSurface::PreRender( bool resizingSurface, const std::vector( TriggerEventFactory::CreateTriggerEvent( MakeCallback( this, &WindowRenderSurface::ProcessFrameCallback ), + TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) ); + } + mFrameRenderedTrigger->Trigger(); + } } MakeContextCurrent(); @@ -588,6 +595,8 @@ void WindowRenderSurface::ProcessRotationRequest() void WindowRenderSurface::ProcessFrameCallback() { + Dali::Mutex::ScopedLock lock( mMutex ); + for( auto&& iter : mFrameCallbackInfoContainer ) { if( !iter->fileDescriptorMonitor ) @@ -611,19 +620,29 @@ void WindowRenderSurface::OnFileDescriptorEventDispatched( FileDescriptorMonitor DALI_LOG_INFO( gWindowRenderSurfaceLogFilter, Debug::Verbose, "WindowRenderSurface::OnFileDescriptorEventDispatched: Frame rendered [%d]\n", fileDescriptor ); - auto frameCallbackInfo = std::find_if( mFrameCallbackInfoContainer.begin(), mFrameCallbackInfoContainer.end(), - [fileDescriptor]( std::unique_ptr< FrameCallbackInfo >& callbackInfo ) - { - return callbackInfo->fileDescriptor == fileDescriptor; - } ); - if( frameCallbackInfo != mFrameCallbackInfoContainer.end() ) + std::unique_ptr< FrameCallbackInfo > callbackInfo; + { + Dali::Mutex::ScopedLock lock( mMutex ); + auto frameCallbackInfo = std::find_if( mFrameCallbackInfoContainer.begin(), mFrameCallbackInfoContainer.end(), + [fileDescriptor]( std::unique_ptr< FrameCallbackInfo >& callbackInfo ) + { + return callbackInfo->fileDescriptor == fileDescriptor; + } ); + if( frameCallbackInfo != mFrameCallbackInfoContainer.end() ) + { + callbackInfo = std::move( *frameCallbackInfo ); + + mFrameCallbackInfoContainer.erase( frameCallbackInfo ); + } + } + + // Call the connected callback + if( callbackInfo ) { - // Call the connected callback - for( auto&& iter : ( *frameCallbackInfo )->callbacks ) + for( auto&& iter : ( callbackInfo )->callbacks ) { CallbackBase::Execute( *( iter.first ), iter.second ); } - mFrameCallbackInfoContainer.erase( frameCallbackInfo ); } } diff --git a/dali/internal/window-system/common/window-render-surface.h b/dali/internal/window-system/common/window-render-surface.h index 6f982e4..6b72a55 100644 --- a/dali/internal/window-system/common/window-render-surface.h +++ b/dali/internal/window-system/common/window-render-surface.h @@ -21,6 +21,7 @@ // EXTERNAL INCLUDES #include #include +#include #include #include @@ -284,6 +285,7 @@ private: // Data ColorDepth mColorDepth; ///< Color depth of surface (32 bit or 24 bit) OutputSignalType mOutputTransformedSignal; FrameCallbackInfoContainer mFrameCallbackInfoContainer; + Dali::Mutex mMutex; int mRotationAngle; int mScreenRotationAngle; bool mOwnSurface; ///< Whether we own the surface (responsible for deleting it) -- 2.7.4