Opened 13 years ago

Closed 12 years ago

Last modified 12 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:
Has a Patch: no 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 13 years ago.

Download all attachments as: .zip

Change History (28)

comment:1 Changed 13 years ago by jackburton

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 Changed 13 years ago by diver

It's on real hardware with supported nvidia card.

comment:3 Changed 13 years ago by jackburton

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

comment:4 Changed 13 years ago by jackburton

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

comment:5 Changed 13 years ago by jackburton

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 Changed 13 years ago by jackburton

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

comment:7 Changed 13 years ago by axeld

Owner: changed from axeld to jackburton

comment:8 Changed 13 years ago by jackburton

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 Changed 13 years ago by axeld

Priority: normallow

comment:10 Changed 13 years ago by kaoutsis

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 Changed 13 years ago by kaoutsis

Cc: kaoutsis@… added

Changed 13 years ago by kaoutsis

Attachment: EmptyMenuApplication.cpp added

comment:12 Changed 13 years ago by kaoutsis

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

comment:13 Changed 12 years ago by jackburton

Owner: changed from axeld to jackburton

comment:14 Changed 12 years ago by stippi

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

comment:15 in reply to:  14 ; Changed 12 years ago by bonefish

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.

comment:16 in reply to:  15 Changed 12 years ago by kaoutsis

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 Changed 12 years ago by marcusoverhagen

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

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

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.

comment:19 in reply to:  18 Changed 12 years ago by jackburton

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 Changed 12 years ago by jackburton

Status: newassigned

comment:21 Changed 12 years ago by jackburton

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 Changed 12 years ago by 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.

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.

comment:23 in reply to:  22 ; Changed 12 years ago by 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).

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

comment:24 in reply to:  23 Changed 12 years ago by bonefish

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 Changed 12 years ago by jackburton

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 Changed 12 years ago by axeld

Sure, why not.

comment:27 in reply to:  26 Changed 12 years ago by jackburton

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.