Closed
Bug 326714
Opened 19 years ago
Closed 19 years ago
GNOME/GTK icon code is extremely slow
Categories
(Core :: Graphics: ImageLib, defect, P2)
Tracking
()
RESOLVED
FIXED
mozilla1.9alpha1
People
(Reporter: dbaron, Assigned: dbaron)
References
Details
(Keywords: fixed1.8.1, perf, Whiteboard: [patch])
Attachments
(4 files, 4 obsolete files)
(deleted),
patch
|
dbaron
:
review+
roc
:
superreview+
roc
:
approval-branch-1.8.1+
|
Details | Diff | Splinter Review |
(deleted),
patch
|
dbaron
:
review+
dbaron
:
superreview+
|
Details | Diff | Splinter Review |
(deleted),
text/html
|
Details | |
(deleted),
text/html
|
Details |
N.B.: Most people don't use builds with the code that this bug is complaining about -- it's not enabled in release builds since --disable-gnomeui defaults to doing a configure test for the version, and the build machines don't *currently* have that version, although that could change in the future. But it does show up in builds that people do on relatively new distributions.
The GNOME icon code in modules/libpr0n/decoders/icon/gtk/ is really really slow. I've described this on IRC in the past, and some people had useful suggestions. On my machine, it takes a few hundred milliseconds *per icon*. This is a significant slowdown just when opening a dialog that has OK and Cancel buttons (since we do two such icon loads in that case, at least the first time). But it's a much much more serious problem for bookmarks, where we do an icon load for every single file: URL in any displayed bookmarks -- if a bookmarks folder, or the personal toolbar, has a lot of file: URLs in it, this is a huge slowdown, and can lead to multi-second delays waiting for bookmarks menus to open.
Using some printf(!) timing, since profiling of things involving X server, etc., can be a little unreliable, the slowest pieces of nsIconChannel::InitWithGnome seem to be:
* the call to gnome_icon_lookup, typically around 300ms
* the g_object_unref of the icon theme (odd), typically around 50ms
* the pixmap manipulation from there to the end of the function varies a lot -- sometimes it's almost instantaneous, sometimes it's near 50ms, sometimes in between
When I brought this up on IRC, a bunch of people had suggestions for improving the last part, but that's actually not the bulk of the time.
I don't think Mozilla should ship this code in official builds until these problems are resolved.
Assignee | ||
Comment 1•19 years ago
|
||
(And, for what it's worth, the gdk_pixbuf_save call in the third bullet point causes a pile of UMRs reported by valgrind.)
Updated•19 years ago
|
Assignee: pavlov → cbiesinger
Assignee | ||
Comment 2•19 years ago
|
||
This might help a drop, although really avoiding doing PNG encoding (expensive) would probably help a good bit more. "bmp" and "ico" are apparently alternatives.
Attachment #211426 -
Flags: review?(cbiesinger)
Comment 3•19 years ago
|
||
Comment on attachment 211426 [details] [diff] [review]
avoid going through temp files when gdk_pixbuf_save_to_buffer is available
(the 2.4 dependency is why I didn't write it this way)
this means that if the build system has gtk 2.4 installed but the user doesn't, it won't work there...
I recently thought about this, and the way to fix it is imo to make nsIconDecoder able to accept ARGB data as produced by gdk-pixbuf.
Assignee | ||
Updated•19 years ago
|
Attachment #211426 -
Flags: review?(cbiesinger) → review-
Assignee | ||
Comment 4•19 years ago
|
||
One point, though: the thing you're discussing fixing is only around 20% of the time.
Comment 5•19 years ago
|
||
your patch is (partially) addressing the same issue though, right?
Assignee | ||
Comment 6•19 years ago
|
||
You could also just turn the data from gdk_pixbuf into the format nsIconDecoder wants; that's pretty trivial if you have to deal with only a small number of gdk_pixbuf format variants and probably much faster than round-tripping through PNG.
Assignee | ||
Comment 7•19 years ago
|
||
This adds one byte to the Icon decoder's format: a 1 or an 8 to indicate the number of bytes of alpha. (I was considering using a gfx_format, except that's a long, for some silly reason. I guess I could anyway.)
This contains the following changes:
* Adds a USE_ICON_DECODER makefile variable and define so that it's easier to change, and adds the MOZ_ENABLE_GNOMEUI case to it
* documents the change to the Icon decoder data, as well as documenting the existing rules better
* implements that change in the Icon decoder, and also cleans up nsIconDecoder::WriteFrom a bit: removes unused variables, prefers PRUint8 over char so that images with dimensions 128 <= dim < 256 work on platforms where char is signed, and does one notify at the end rather than one per line, and adds some rudimentary error handling to avoid reading past the end of a malformed buffer
* converts the beos, mac, and os2 icon code to add the (char)1 to their buffer
* converts moz_gdk_pixbuf_to_channel to create icon data instead of PNG data by reading data as described at http://developer.gimp.org/api/2.0/gdk-pixbuf/gdk-pixbuf-gdk-pixbuf.html , with error handling to ensure that it's actually what it expects
Attachment #211426 -
Attachment is obsolete: true
Attachment #211514 -
Flags: review?(cbiesinger)
Assignee | ||
Comment 8•19 years ago
|
||
So it turns out caching the GnomeIconTheme object makes a phenomenal performance difference here. Patch coming shortly...
Assignee | ||
Comment 9•19 years ago
|
||
Assignee | ||
Comment 10•19 years ago
|
||
Note that attachment 211527 [details] [diff] [review] applies on top of attachment 211514 [details] [diff] [review] (and was generated by diff rather than cvs diff).
Priority: -- → P2
Whiteboard: [patch]
Target Milestone: --- → mozilla1.9alpha
Assignee | ||
Comment 11•19 years ago
|
||
Wall clock time to open a personal toolbar submenu (i.e., a sub-sub-folder of the personal toolbar folder) with 21 file URLs in it,
after a clean start of Firefox and opening the personal toolbar menu
containing the submenu, which has one file URL in it. Scrolling to and
opening the submenu was done with keyboard instead of mouse for better
timing and hopefully avoiding the hover->open delay time.
no patch: 8.34 7.59 7.42
with only first patch: 7.65 7.80 7.68
with both patches: 0.83 0.71 0.78
So I actually couldn't detect a statistically significant effect from the first patch with my stopwatch, although it may have reduced the variability.
Assignee | ||
Comment 12•19 years ago
|
||
with only the second patch: 0.87 0.78 0.72
I think I still want to get the first patch in; there are advantages to being more like other platforms, not using files in /tmp, and not going through a PNG encoder that gives UMRs.
Assignee | ||
Comment 13•19 years ago
|
||
(And there could have been a real performance difference that I just couldn't measure with a stopwatch. The margin of error for my 0.* stopwatch timings practically includes 0.)
Comment 14•19 years ago
|
||
Comment on attachment 211514 [details] [diff] [review]
use the Icon decoder (should fix PNG and file I/O perf issues)
nsIconDecoder.cpp
+ PRInt32 w = *(data++);
+ PRInt32 h = *(data++);
+ PRInt32 alphaBits = *(data++);
hm, why signed?
+ mFrame->SetImageData(data, bpr, rownum*bpr);
+ mFrame->SetAlphaData(data, abpr, rownum*abpr);
I'd put spaces around the *...
beos/nsIconChannel.cpp
+ buffer[2] = 1; // alpha bits per pixel
// RGB data
uint8* destByte = buffer + 2;
doesn't this need to be +3 now?
gtk/nsIconChannel.cpp
+ guchar * const pixels = gdk_pixbuf_get_pixels(aPixbuf);
hmm... this constness seems insufficient. shouldn't this use one that doesn't allow calling free on the pointer?
Attachment #211514 -
Flags: review?(cbiesinger) → review+
Assignee | ||
Comment 15•19 years ago
|
||
(In reply to comment #14)
> (From update of attachment 211514 [details] [diff] [review] [edit])
> nsIconDecoder.cpp
>
> + PRInt32 w = *(data++);
> + PRInt32 h = *(data++);
> + PRInt32 alphaBits = *(data++);
>
> hm, why signed?
Because that's what they were before, and that's what the functions they're used for take? But I'll make alphaBits a PRUint8.
Comment 16•19 years ago
|
||
Comment on attachment 211527 [details] [diff] [review]
cache the GnomeIconTheme
nsIconChannel.cpp
+ char* name = gnome_icon_lookup(gIconTheme, NULL, spec.get(), NULL, &fileInfo,
+ type.get(), GNOME_ICON_LOOKUP_FLAGS_NONE, NULL);
why not align the second line so that it lines up with the first parameter?
Attachment #211527 -
Flags: review?(cbiesinger) → review+
Assignee | ||
Comment 17•19 years ago
|
||
Addresses biesi's comments.
Attachment #211514 -
Attachment is obsolete: true
Attachment #211543 -
Flags: superreview?(roc)
Attachment #211543 -
Flags: review+
Assignee | ||
Comment 18•19 years ago
|
||
Addresses biesi's comments (wraps to 3 lines now, though).
Attachment #211527 -
Attachment is obsolete: true
Attachment #211544 -
Flags: superreview?(roc)
Attachment #211544 -
Flags: review+
Assignee | ||
Updated•19 years ago
|
Attachment #211543 -
Flags: branch-1.8.1?(roc)
Assignee | ||
Updated•19 years ago
|
Attachment #211544 -
Flags: branch-1.8.1?(roc)
Comment on attachment 211543 [details] [diff] [review]
use the Icon decoder (should fix PNG and file I/O perf issues)
In moz_gdk_pixbuf_to_channel, you could fuse the color and alpha passes just by maintaining color_out and alpha_out pointers. This would be slightly less code and probably slightly more efficient.
Attachment #211543 -
Flags: superreview?(roc)
Attachment #211543 -
Flags: superreview+
Attachment #211543 -
Flags: approval-branch-1.8.1?(roc)
Attachment #211543 -
Flags: approval-branch-1.8.1+
Attachment #211544 -
Flags: superreview?(roc)
Attachment #211544 -
Flags: superreview+
Attachment #211544 -
Flags: approval-branch-1.8.1?(roc)
Attachment #211544 -
Flags: approval-branch-1.8.1+
Assignee | ||
Comment 20•19 years ago
|
||
Addresses roc's comments
Attachment #211543 -
Attachment is obsolete: true
Attachment #211650 -
Flags: superreview+
Attachment #211650 -
Flags: review+
Assignee | ||
Comment 21•19 years ago
|
||
Both patches checked in to trunk.
Status: ASSIGNED → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
Assignee | ||
Comment 22•19 years ago
|
||
The only icon-related performance issues in a jprof profile of this testcase are:
38979 0 77 nsIconChannel::Init(nsIURI*)
75 gtk_widget_render_icon
1 moz_gdk_pixbuf_to_channel(_GdkPixbuf*, nsIURI*, nsIChannel**)
1 ensure_stock_image_widget()
Assignee | ||
Comment 23•19 years ago
|
||
The only icon-related performance issues in a jprof profile of this testcase are:
14746 0 52 nsIconChannel::InitWithGnome(nsIMozIconURI*)
40 gnome_icon_lookup
7 gdk_pixbuf_new_from_file
5 gdk_pixbuf_scale_simple
Comment 24•19 years ago
|
||
Note:
The for loop's for SetImageData and SetAlphaData are not needed, see bug 318699.
The patch for that bug also fixes the potential leak in nsIconDecoder.
You need to log in
before you can comment on or make changes to this bug.
Description
•