From 3e51b2c647e44bb313345bf978dee40c4c39b525 Mon Sep 17 00:00:00 2001
From: jean-pierre charras <jp.charras@wanadoo.fr>
Date: Wed, 26 Mar 2025 13:18:22 +0100
Subject: [PATCH] Pcbnew, performance fix: rebuild the pad view only when
 mandatory.

The LAYER_PAD_HOLEWALLS shape needs a rebuild only when the zoom level changes.
So keep trace of the last GAL zoom level to rebuild the shape, and only rebuild
the view when needed
---
 pcbnew/pad.cpp | 14 ++++++++++++--
 pcbnew/pad.h   |  3 +++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp
index fa23c29a54..f8c7d4a44c 100644
--- a/pcbnew/pad.cpp
+++ b/pcbnew/pad.cpp
@@ -65,6 +65,7 @@
 #include "pcbnew_settings.h"
 
 #include <pcb_group.h>
+#include <gal/graphics_abstraction_layer.h>
 
 using KIGFX::PCB_PAINTER;
 using KIGFX::PCB_RENDER_SETTINGS;
@@ -108,6 +109,8 @@ PAD::PAD( FOOTPRINT* parent ) :
 
     for( PCB_LAYER_ID layer : LAYER_RANGE( F_Cu, B_Cu, BoardCopperLayerCount() ) )
         m_zoneLayerOverrides[layer] = ZLO_NONE;
+
+    m_lastGalZoolLevel = 0.0;
 }
 
 
@@ -1786,9 +1789,16 @@ double PAD::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
         return lodScaleForThreshold( aView, minSize, pcbIUScale.mmToIU( 0.5 ) );
     }
 
-    // Hole walls always need a repaint when zoom changes
+    // Hole walls always need a repaint when zoom level changes after the last
+    // LAYER_PAD_HOLEWALLS shape rebuild
     if( aLayer == LAYER_PAD_HOLEWALLS )
-        aView->Update( this, KIGFX::REPAINT );
+    {
+        if( aView->GetGAL()->GetZoomFactor() != m_lastGalZoolLevel )
+        {
+            aView->Update( this, KIGFX::REPAINT );
+            m_lastGalZoolLevel = aView->GetGAL()->GetZoomFactor();
+        }
+    }
 
     VECTOR2L padSize = GetShape( pcbLayer ) != PAD_SHAPE::CUSTOM
                        ? VECTOR2L( GetSize( pcbLayer ) ) : GetBoundingBox().GetSize();
diff --git a/pcbnew/pad.h b/pcbnew/pad.h
index c108638651..9b74e0fe1a 100644
--- a/pcbnew/pad.h
+++ b/pcbnew/pad.h
@@ -948,6 +948,9 @@ private:
     mutable std::mutex                        m_polyBuildingLock;
     mutable LAYER_POLYGON_MAP                 m_effectivePolygons;
     mutable int                               m_effectiveBoundingRadius;
+    // Last zoom level used to draw the pad: the LAYER_PAD_HOLEWALLS layer shape
+    // depend on the zoom level. So keep trace on the last used zoom level
+    mutable double                            m_lastGalZoolLevel;
 
     int               m_subRatsnest;        // Variable used to handle subnet (block) number in
                                             //   ratsnest computations