From 519084546e40118c3ee7a682339ad788ff53d56c Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Thu, 29 Sep 2022 15:25:20 -0700 Subject: [PATCH] Ensure dtor throws into catch block Explicitly destruct the GAL context to get StopDrawing throws in the proper try block Fixes https://gitlab.com/kicad/code/kicad/issues/12117 --- common/draw_panel_gal.cpp | 79 ++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index 1fc264475d..361c32cfd6 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -254,49 +254,56 @@ void EDA_DRAW_PANEL_GAL::DoRePaint() cntUpd.Stop(); - cntCtx.Start(); - KIGFX::GAL_DRAWING_CONTEXT ctx( m_gal ); - cntCtx.Stop(); - - if( m_view->IsTargetDirty( KIGFX::TARGET_OVERLAY ) - && !m_gal->HasTarget( KIGFX::TARGET_OVERLAY ) ) + // GAL_DRAWING_CONTEXT can throw in the dtor, so we need to scope + // the full lifetime inside the try block { - m_view->MarkDirty(); - } + cntCtx.Start(); + KIGFX::GAL_DRAWING_CONTEXT ctx( m_gal ); + cntCtx.Stop(); - m_gal->SetClearColor( settings->GetBackgroundColor() ); - m_gal->SetGridColor( settings->GetGridColor() ); - m_gal->SetCursorColor( settings->GetCursorColor() ); - - // TODO: find why ClearScreen() must be called here in opengl mode - // and only if m_view->IsDirty() in Cairo mode to avoid display artifacts - // when moving the mouse cursor - if( m_backend == GAL_TYPE_OPENGL ) - m_gal->ClearScreen(); - - if( m_view->IsDirty() ) - { - if( m_backend != GAL_TYPE_OPENGL // Already called in opengl - && m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) ) + if( m_view->IsTargetDirty( KIGFX::TARGET_OVERLAY ) + && !m_gal->HasTarget( KIGFX::TARGET_OVERLAY ) ) { - m_gal->ClearScreen(); + m_view->MarkDirty(); } - m_view->ClearTargets(); + m_gal->SetClearColor( settings->GetBackgroundColor() ); + m_gal->SetGridColor( settings->GetGridColor() ); + m_gal->SetCursorColor( settings->GetCursorColor() ); - // Grid has to be redrawn only when the NONCACHED target is redrawn - if( m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) ) - m_gal->DrawGrid(); + // TODO: find why ClearScreen() must be called here in opengl mode + // and only if m_view->IsDirty() in Cairo mode to avoid display artifacts + // when moving the mouse cursor + if( m_backend == GAL_TYPE_OPENGL ) + m_gal->ClearScreen(); - cntRedraw.Start(); - m_view->Redraw(); - cntRedraw.Stop(); - isDirty = true; + if( m_view->IsDirty() ) + { + if( m_backend != GAL_TYPE_OPENGL // Already called in opengl + && m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) ) + { + m_gal->ClearScreen(); + } + + m_view->ClearTargets(); + + // Grid has to be redrawn only when the NONCACHED target is redrawn + if( m_view->IsTargetDirty( KIGFX::TARGET_NONCACHED ) ) + m_gal->DrawGrid(); + + cntRedraw.Start(); + m_view->Redraw(); + cntRedraw.Stop(); + isDirty = true; + } + + m_gal->DrawCursor( m_viewControls->GetCursorPosition() ); + + cntCtxDestroy.Start(); } - m_gal->DrawCursor( m_viewControls->GetCursorPosition() ); - - cntCtxDestroy.Start(); + // ctx goes out of scope here so destructor would be called + cntCtxDestroy.Stop(); } catch( std::exception& err ) { @@ -315,10 +322,6 @@ void EDA_DRAW_PANEL_GAL::DoRePaint() } } - // ctx goes out of scope here so destructor would be called - cntCtxDestroy.Stop(); - - if( isDirty ) { KI_TRACE( traceGalProfile, "View timing: %s %s %s %s %s\n",