[Nautilus-list] long-standing icon-factory bug
- From: Alex Larsson <alexl redhat com>
- To: nautilus-list eazel com
- Subject: [Nautilus-list] long-standing icon-factory bug
- Date: Tue, 26 Feb 2002 23:45:01 -0500 (EST)
While working on resolving the SVG scaling issues i came upon a really
subtle bug that made nautilus a lot larger than it needed.
In nautilus-icon-factory.c::load_icon_for_scaling() we have this code to
calculate the max size of the icon:
size_request.maximum_width = MAXIMUM_ICON_SIZE * requested_size / NAUTILUS_ZOOM_LEVEL_STANDARD;
My take on this code is that it sets one max size for each zoom level
nominal size, in order to not store the same pixmap in the cache with only
the max size different.
Do you see the bug though? It's very subtle. It should be:
size_request.maximum_width = MAXIMUM_ICON_SIZE * requested_size / NAUTILUS_ICON_SIZE_STANDARD;
So instead of multiplying the requested size by 2 (basically scaling the
normal max size with the zoom level) it uses the enum value for the zoom
level! So it ends up multiplying by 96/3 = 32. Eventually this item will
be returned to the top level get_icon_from_cache() that will store a copy
in the cache with the requested max size (which typically is nominal*2),
so instead of using the old cached value we store a duplicate!!!
Before fix:
20742 alex 11 0 18928 18M 9112 S 4.9 3.6 0:04 nautilus
After fix:
17986 alex 11 0 14788 14M 9104 S 0.0 2.8 0:04 nautilus
Woops! Apparently this saved 4 megs of unused pixmap cache. And this is
measured directly after startup having rendered my home dir.
The fix was a bit more complicated due to the fact that the old code never
handled the fact that the inner get_icon_from_cache() call could return
the "same" icon as the outer call. In fact, there was even a g_assert()
that this was not the case.
I'm attaching the patch I checked in. I'm reasonably certain that it is
correct, and I did test it some. Nevertheless i would like for someone
else to verify the correctness of the ref-counting, as we don't want to
leak stuff in the cache.
I now have a plan of attack for the remaining SVG issues, namely that the
svg icons (especially emblems) are rendered to large and then scaled down,
and that we need scalable embedded text and emblem attach point
definitions. I'm to tired to do that tonight though.
/ Alex
Index: nautilus-icon-factory.c
===================================================================
RCS file:
/cvs/gnome/nautilus/libnautilus-private/nautilus-icon-factory.c,v
retrieving revision 1.257
diff -u -p -r1.257 nautilus-icon-factory.c
--- nautilus-icon-factory.c 2002/02/25 21:05:55 1.257
+++ nautilus-icon-factory.c 2002/02/27 04:20:42
@@ -1603,7 +1603,7 @@ load_icon_for_scaling (NautilusScalableI
REQUEST_PICKY_BY_NAME_SECOND_CHOICE
};
- size_request.maximum_width = MAXIMUM_ICON_SIZE * requested_size / NAUTILUS_ZOOM_LEVEL_STANDARD;
+ size_request.maximum_width = MAXIMUM_ICON_SIZE * requested_size / NAUTILUS_ICON_SIZE_STANDARD;
size_request.maximum_height = size_request.maximum_width;
for (i = 0; i < G_N_ELEMENTS (requests); i++) {
@@ -1945,13 +1945,20 @@ get_icon_from_cache (NautilusScalableIco
/* Create the key and icon for the hash table. */
key = g_new (CacheKey, 1);
- nautilus_scalable_icon_ref (scalable_icon);
key->scalable_icon = scalable_icon;
key->size = *size;
+ /* recursive get_icon_from_cache might already have placed icon
+ * in hash table if there was an exact match */
+ if (g_hash_table_lookup (hash_table, key) != NULL) {
+ g_free (key);
+ return icon;
+ }
+
/* Add the item to the hash table. */
- g_assert (g_hash_table_lookup (hash_table, key) == NULL);
+ nautilus_scalable_icon_ref (scalable_icon);
g_hash_table_insert (hash_table, key, icon);
+
}
/* Hand back a ref to the caller. */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]