Opened 19 years ago

Closed 17 years ago

Last modified 17 years ago

#505 closed bug (fixed)

First click on BMenuBar will show empty MenuWindow

Reported by: diver Owned by: jackburton
Priority: low Milestone: R1
Component: - General Version:
Keywords: Cc: kaoutsis@…
Blocked By: Blocking:
Platform: All

Description (last modified by jackburton)

First click on BMenuBar will show empty BPopUpMenu list, half second later menu items will appear.

Attachments (1)

EmptyMenuApplication.cpp (5.1 KB ) - added by kaoutsis 18 years ago.

Download all attachments as: .zip

Change History (28)

comment:1 by jackburton, 19 years ago

First click on any menubar causes a new BWindow to be created, maybe that's what is taking so much time ? By the way, On real hardware or emulated ? I definitely can see this on vmware.

comment:2 by diver, 19 years ago

It's on real hardware with supported nvidia card.

comment:3 by jackburton, 19 years ago

Summary: First click on BMenuBar will show empty BPopUpMenu listFirst click on BMenuBar will show empty MenuWindow

comment:4 by jackburton, 19 years ago

So we have to find out why it's taking so much time to create the menu window.

comment:5 by jackburton, 19 years ago

I might have found out what's happening: BMenu::AttachedToWindow() calls get_key_map(). get_key_map() calls control_input_server(). If it's the first time that application calls that method, a BMessenger is created using this constructor: BMessenger(const char *signature) (it's cached later), and that might be the reason for the slow start (and not the window creation as I said before, as the window is obviously shown on screen immediately).

comment:6 by jackburton, 19 years ago

I just tried removing that call but the problem is still there...

comment:7 by axeld, 19 years ago

Owner: changed from axeld to jackburton

comment:8 by jackburton, 18 years ago

Description: modified (diff)
Owner: changed from jackburton to axeld
Platform: All

Reassign to Axel, because the culprit seems to be windows creation + first show. Feel free to reassign it to me if you find out it's not the case.

comment:9 by axeld, 18 years ago

Priority: normallow

comment:10 by kaoutsis, 18 years ago

some testing (with hrev19133):

GLTeapot has delay only in <File> menu. everything else response ok.

StyledEdit

has delay only in <File> or <Edit> (those one that clicked first). everything else response ok.

Terminal

has delay in <Terminal> or <Edit> (those one that clicked first) but also in MenuItem <Window Size> or <Font Encoding> (those one that clicked first).

comment:11 by kaoutsis, 18 years ago

Cc: kaoutsis@… added

by kaoutsis, 18 years ago

Attachment: EmptyMenuApplication.cpp added

comment:12 by kaoutsis, 18 years ago

The application EmptyMenuApplication doesn't do anything useful, but the menus have no delay!

comment:13 by jackburton, 17 years ago

Owner: changed from axeld to jackburton

comment:14 by stippi, 17 years ago

Could this be the effects of the vm paging in application code on demand (lazily)?

in reply to:  14 ; comment:15 by bonefish, 17 years ago

Replying to stippi:

Could this be the effects of the vm paging in application code on demand (lazily)?

All code is loaded and mapped lazily, so it necessarily runs slower the first time, but half a second is really a lot of time. It hasn't been mentioned whether this happens only with the first instance of an application or every time. The second time the code is already loaded and it definitely shouldn't take a lot of time to just map it.

I think, it shouldn't be too hard to track down what takes so long by adding a bit of debug output with timestamps.

in reply to:  15 comment:16 by kaoutsis, 17 years ago

Replying to bonefish:

...It hasn't been mentioned whether this happens only with the first instance of an application or every time. The second time the code is already loaded and it definitely shouldn't take a lot of time to just map it.

This might help: (tested on an old 233mmx): open Terminal, click Terminal on Menubar; An empty menu is showed up, and filled after 3-4 secs. Quit Terminal; Open Terminal again. The same behavior.

also one can find additional infos at ticket #913 which is marked as duplicate of this one.

comment:17 by marcusoverhagen, 17 years ago

perhaps using strace will show where it is stuck during that half second

in reply to:  17 ; comment:18 by jackburton, 17 years ago

Replying to marcusoverhagen:

perhaps using strace will show where it is stuck during that half second

Looks like what it's taking so much it's the BBitmap::ImportBits() calls in BMenuItem::_DrawShortcutSymbol(). I tried to uncomment those calls and the menu showed up instantly. Note that Drawing the bitmap themselves doesn't take so much time, instead.

in reply to:  18 comment:19 by jackburton, 17 years ago

Replying to jackburton:

Looks like what it's taking so much it's the BBitmap::ImportBits() calls in BMenuItem::_DrawShortcutSymbol(). I tried to uncomment those calls and the menu showed up instantly. Note that Drawing the bitmap themselves doesn't take so much time, instead.

And, I tracked it down further, and found out which it's the building of the color list inside PaletteConverter::SetTo() call, called because the MenuItems's Bitmaps are CMAP8, so they need a palette to be converted. Note that there's already a TODO Item in there. Maybe we should find a way to use the palette supplied by the app_server (already generated at startup), for bitmaps which have a connection with the app_server. Might not be trivial to be able to differentiate between the two, though.

comment:20 by jackburton, 17 years ago

Status: newassigned

comment:21 by jackburton, 17 years ago

Resolution: fixed
Status: assignedclosed

It's fixed in hrev22508. Now BApplications which have a connection to the app_server (all, except BServers) initialize the PaletteConverter on construction, using system_colors(), which uses the app_server's colormap, thus we avoid the loop which builds the colors, and avoid storing an extra colormap.

comment:22 by bonefish, 17 years ago

I don't think sharing the palette data even for apps without an app server connection should be all that big of a problem. The app server could put it into a separate area that could be cloned (read-only) by clients, regardless of whether they have a app server connection or not.

Regarding the algorithm computing the index mapping: It's absolutely brute force. I didn't think that it would survive for such a long time, when I wrote it. It could be replaced by something more intelligent.

in reply to:  22 ; comment:23 by jackburton, 17 years ago

Replying to bonefish:

I don't think sharing the palette data even for apps without an app server connection should be all that big of a problem. The app server could put it into a separate area that could be cloned (read-only) by clients, regardless of whether they have a app server connection or not.

Note, though, that that code is also used by the app_server, and that one can't obviously use BScreen::ColorMap() to get the palette (it would deadlock).

Regarding the algorithm computing the index mapping: It's absolutely brute force. I didn't think that it would survive for such a long time, when I wrote it. It could be replaced by something more intelligent.

BTW I copied the same code to generate the palette within the app_server, so remember to change it there too :P

in reply to:  23 comment:24 by bonefish, 17 years ago

Replying to jackburton:

Replying to bonefish:

I don't think sharing the palette data even for apps without an app server connection should be all that big of a problem. The app server could put it into a separate area that could be cloned (read-only) by clients, regardless of whether they have a app server connection or not.

Note, though, that that code is also used by the app_server, and that one can't obviously use BScreen::ColorMap() to get the palette (it would deadlock).

That depends on the implementation of BScreen::ColorMap(), and as I wrote, I wouldn't use an app server connection at all (sending 32 KB through a port doesn't sound that nice anyway). The app server would do a manual initialization, everyone else would clone the app server's area lazily. The code for the app server's manual initialization could be reused as a fallback in clients (i.e. for the unlikely case that there's no app server).

Regarding the algorithm computing the index mapping: It's absolutely brute force. I didn't think that it would survive for such a long time, when I wrote it. It could be replaced by something more intelligent.

BTW I copied the same code to generate the palette within the app_server, so remember to change it there too :P

Don't worry, I'm not going to change anything in this area anytime soon. :-)

comment:25 by jackburton, 17 years ago

Would it make sense to reuse the "server_read_only_memory" area ? Currently it's only 4096 byte, though, so it'd need to be enlarged.

comment:26 by axeld, 17 years ago

Sure, why not.

in reply to:  26 comment:27 by jackburton, 17 years ago

Replying to axeld:

Sure, why not.

Ok. I already did that locally, but for some reason haiku doesn't boot on qemu anymore. And vmware doesn't work anymore after upgrading to ubuntu 7.10. Great. That will have to wait.

Note: See TracTickets for help on using tickets.