Reuse the visibility bitmap bundles to reduce gdi object exhaustion

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21386#note_2654658071
This commit is contained in:
Mark Roszko 2025-08-15 08:14:51 -04:00
parent 49a1323945
commit 53e8d051e3
2 changed files with 19 additions and 10 deletions

View File

@ -415,6 +415,11 @@ APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFo
// Correct the min size from wxformbuilder not using fromdip
SetMinSize( FromDIP( GetMinSize() ) );
// We pregenerate the visibility bundles to reuse to reduce gdi exhaustion on windows
// We can get a crazy amount of nets and netclasses
m_visibleBitmapBundle = KiBitmapBundle( BITMAPS::visibility );
m_notVisibileBitmapBundle = KiBitmapBundle( BITMAPS::visibility_off );
int screenHeight = wxSystemSettings::GetMetric( wxSYS_SCREEN_Y );
m_iconProvider = new ROW_ICON_PROVIDER( KIUI::c_IndicatorSizeDIP, this );
m_pointSize = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT ).GetPointSize();
@ -528,8 +533,8 @@ APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFo
syncLayerPresetSelection();
} );
m_toggleGridRenderer = new GRID_BITMAP_TOGGLE_RENDERER( KiBitmapBundle( BITMAPS::visibility ),
KiBitmapBundle( BITMAPS::visibility_off ) );
m_toggleGridRenderer = new GRID_BITMAP_TOGGLE_RENDERER( m_visibleBitmapBundle,
m_notVisibileBitmapBundle );
m_netsGrid->RegisterDataType( wxT( "bool" ), m_toggleGridRenderer, new wxGridCellBoolEditor );
@ -555,7 +560,7 @@ APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFo
wxSize size = ConvertDialogToPixels( SWATCH_SIZE_SMALL_DU );
m_netsGrid->SetColSize( NET_GRID_TABLE::COL_COLOR, size.x + cellPadding );
size = KiBitmapBundle( BITMAPS::visibility ).GetPreferredBitmapSizeFor( this );
size = m_visibleBitmapBundle.GetPreferredBitmapSizeFor( this );
m_netsGrid->SetColSize( NET_GRID_TABLE::COL_VISIBILITY, size.x + cellPadding );
m_netsGrid->SetDefaultCellFont( font );
@ -1588,8 +1593,8 @@ void APPEARANCE_CONTROLS::rebuildLayers()
swatch->SetToolTip( _( "Double click or middle click for color change, right click for menu" ) );
BITMAP_TOGGLE* btn_visible = new BITMAP_TOGGLE( panel, layer,
KiBitmapBundle( BITMAPS::visibility ),
KiBitmapBundle( BITMAPS::visibility_off ),
m_visibleBitmapBundle,
m_notVisibileBitmapBundle,
aSetting->visible );
btn_visible->SetToolTip( _( "Show or hide this layer" ) );
@ -2199,7 +2204,7 @@ void APPEARANCE_CONTROLS::rebuildObjects()
int swatchWidth = m_windowObjects->ConvertDialogToPixels( wxSize( 8, 0 ) ).x;
int labelWidth = 0;
int btnWidth = KiBitmapBundle( BITMAPS::visibility ).GetPreferredLogicalSizeFor( m_windowObjects ).x;
int btnWidth = m_visibleBitmapBundle.GetPreferredLogicalSizeFor( m_windowObjects ).x;
m_objectSettings.clear();
m_objectsOuterSizer->Clear( true );
@ -2240,8 +2245,8 @@ void APPEARANCE_CONTROLS::rebuildObjects()
if( aSetting->can_control_visibility )
{
btn_visible = new BITMAP_TOGGLE( m_windowObjects, layer,
KiBitmapBundle( BITMAPS::visibility ),
KiBitmapBundle( BITMAPS::visibility_off ),
m_visibleBitmapBundle,
m_notVisibileBitmapBundle,
aSetting->visible );
tip.Printf( _( "Show or hide %s" ), aSetting->label.Lower() );
@ -2503,8 +2508,8 @@ void APPEARANCE_CONTROLS::rebuildNets()
setting->ctl_color->Hide();
setting->ctl_visibility = new BITMAP_TOGGLE( setting->ctl_panel, aId,
KiBitmapBundle( BITMAPS::visibility ),
KiBitmapBundle( BITMAPS::visibility_off ),
m_visibleBitmapBundle,
m_notVisibileBitmapBundle,
!hiddenClasses.count( name ) );
wxString tip;

View File

@ -476,6 +476,10 @@ private:
wxRadioButton* m_rbRatsnestVisLayers;
wxRadioButton* m_rbRatsnestNone;
// Bitmap caches
wxBitmapBundle m_visibleBitmapBundle;
wxBitmapBundle m_notVisibileBitmapBundle;
enum POPUP_ID
{
ID_CHANGE_COLOR = wxID_HIGHEST,