Cutting down on ribbon bar bitmaps Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
wxBen
Experienced Solver
Experienced Solver
Posts: 65
Joined: Wed Jun 06, 2012 4:44 pm
Location: Calgary, Canada

Cutting down on ribbon bar bitmaps

Post by wxBen »

If you look at wxRibbonButtonBar::AddButton, you will see that it uses four bitmaps, so if you have a large application, you can easily end up with task manager showing you are using 2000 GDI objects, most of which come from these bitmaps. And most of these bitmaps will never be used. Windows limits an application to 10000 bitmaps by default.

Does anyone have any suggestions for cutting this down?

One idea would be to implement a wxBitmapOnDemand which returns a size for the ribbon bar sizing but doesnt create the bitmap until needed. However, that does not work because the Width type methods are non virtual in the wxGDIImage base class. So I cant overload them.

Another idea, since wxBitmaps use references, is to, if the button is enabled, pass the same bitmaps for disabled, and if the button becomes disabled, set all four bitmaps to the enabled ones. Then you can at least cut the bitmaps down to half the count, maybe. The problem becomes how do you modify the original bitmaps and not the copy that gets made if you start to modify a bitmap?

The only feasible options seems to be to add the button with the disabled and normal buttons the same, so there are only two bitmaps and not four. And then if the enabled state of the button changes, remove the button via DeleteButton and add it back again via InsertButton, with the right set of bitmaps.

Any ideas on this?
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4204
Joined: Sun Jan 03, 2010 5:45 pm

Re: Cutting down on ribbon bar bitmaps

Post by PB »

FWIW: The native WinAPI answer to GDI handle limits for bitmaps is ImageList, wrapped in wxWidgets as wxImageList. However, AFAIK the only wx controls using wxImageList are wxTreeCtrl and wxListCtrl. ImageList is used in native WinAPI by many other controls including toolbar and button, wxWidgets do not support image lists there either, not sure why. So it is not surprising that wxImageList was not used for wxRibbon either.

OTOH, the default limit of 10k GDI handles is still quite a lot, if you are really coming anywhere near to it, are you sure you are not leaking the handles somewhere?
Last edited by PB on Mon Jan 27, 2020 7:49 pm, edited 1 time in total.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7479
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Cutting down on ribbon bar bitmaps

Post by ONEEYEMAN »

Hi,
You should probably ask this on the wx-users ML.

Thank you.
wxBen
Experienced Solver
Experienced Solver
Posts: 65
Joined: Wed Jun 06, 2012 4:44 pm
Location: Calgary, Canada

Re: Cutting down on ribbon bar bitmaps

Post by wxBen »

We are not leaking GDI objects, I have been checking for that, trust me. It is just a bit odd that the application at startup is using nearly 2000 GDI images. Mind you, the number does not change much, and it is still far from the 10000, its just a bit surprising... But in general in very large complex applications I can see reaching that limit, which MS imposes to say "hey, if you are not leaking, find a better way of doing this".

I do see other people have the same issue, here for example:

viewtopic.php?t=44816

And the wxImageList indeed appears to be the solution... If only wxRibbonBar supported it! [-o< Let me look into that... THANKS!
wxBen
Experienced Solver
Experienced Solver
Posts: 65
Joined: Wed Jun 06, 2012 4:44 pm
Location: Calgary, Canada

Re: Cutting down on ribbon bar bitmaps

Post by wxBen »

It looks like the ribbon bar code does not do much with the images other than hangs onto them and draws them really. So making wxRibbonbar support wxImageList should be easy, famous last words. :lol:
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4204
Joined: Sun Jan 03, 2010 5:45 pm

Re: Cutting down on ribbon bar bitmaps

Post by PB »

Before coding anything, I would ask in the wx-users mailing list if such a change has any chance to be accepted.

Changes in the API aside, if one ribbon button requires 4 bitmaps, even if you ribbon has 250 buttons (I do not think even large applications have that many), it would still leave ~9k GDI handles to the rest of the application.
wxBen
Experienced Solver
Experienced Solver
Posts: 65
Joined: Wed Jun 06, 2012 4:44 pm
Location: Calgary, Canada

Re: Cutting down on ribbon bar bitmaps

Post by wxBen »

Thank you for all the help. I have also posed the information below as a new item viewtopic.php?f=1&t=46785 since it is really a separate question.
---------
I have been experimenting with using wxImageList in buttonbar.cpp, and it drastically reduces the number of GDI handles. NICE.

However, there is one problem, wxImageList::Add checks to see if the bitmap has an alpha (mine do, they are 32 bpp with a transparency layer), it converts it to a wxImage, it calls wxDIB::ConvertToImage which does something weird with the alpha layer.

So without using wxImageList the icons look like this:
Result when not using image list
Result when not using image list
noimglist.png (3.91 KiB) Viewed 1419 times
and with wxImageList they look like this:
Result when using image list
Result when using image list
imglist.png (3.93 KiB) Viewed 1419 times
Now I am hoping someone more familiar with wxWidgets can perhaps suggest a remedy of some sort? What can I do to my wxImages before adding them the imagelist to prevent this? Some better handling of the transparency layer? These images originally come from Windows icons.
wxBen
Experienced Solver
Experienced Solver
Posts: 65
Joined: Wed Jun 06, 2012 4:44 pm
Location: Calgary, Canada

Re: Cutting down on ribbon bar bitmaps

Post by wxBen »

I have implemented an enhancement around this, please see here https://trac.wxwidgets.org/ticket/18657
Post Reply