summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-16 16:52:36 +0000
committertc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-16 16:52:36 +0000
commitde2baedbb8df526db72fb6ddc151e9435db8b78f (patch)
treeb31900fe03fd0421907ae79f1216f5b55042363f
parent6deb272a76b6214157cb9dec271e4c4e1a6d3e8f (diff)
downloadchromium_src-de2baedbb8df526db72fb6ddc151e9435db8b78f.zip
chromium_src-de2baedbb8df526db72fb6ddc151e9435db8b78f.tar.gz
chromium_src-de2baedbb8df526db72fb6ddc151e9435db8b78f.tar.bz2
Have ResourceBundle own GdkPixbufs.
This is the same as how ResourceBundle owns the SkBitmaps it loads. This should be faster than before because ResourceBundle will only load each bitmap once and cache the image. Also fix a memory leak in GdkPixbufFromSkBitmap. valgrind says we're not leaking here. BUG=9988 Review URL: http://codereview.chromium.org/67179 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13847 0039d316-1c4b-4281-b951-d872f2087c98
-rwxr-xr-xbase/gfx/gtk_util.cc2
-rwxr-xr-xchrome/browser/autocomplete/autocomplete_popup_view_gtk.cc10
-rw-r--r--chrome/browser/gtk/bookmark_bar_gtk.cc15
-rw-r--r--chrome/browser/gtk/bookmark_bar_gtk.h6
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.cc18
-rw-r--r--chrome/browser/gtk/custom_button.cc12
-rw-r--r--chrome/browser/gtk/download_item_gtk.cc72
-rw-r--r--chrome/browser/gtk/download_shelf_gtk.cc3
-rw-r--r--chrome/browser/gtk/gtk_chrome_button.cc36
-rw-r--r--chrome/browser/gtk/infobar_gtk.cc2
-rw-r--r--chrome/browser/gtk/nine_box.cc4
-rw-r--r--chrome/common/resource_bundle.h23
-rw-r--r--chrome/common/resource_bundle_linux.cc101
13 files changed, 181 insertions, 123 deletions
diff --git a/base/gfx/gtk_util.cc b/base/gfx/gtk_util.cc
index 0d2eee0..c307976 100755
--- a/base/gfx/gtk_util.cc
+++ b/base/gfx/gtk_util.cc
@@ -77,8 +77,6 @@ GdkPixbuf* GdkPixbufFromSkBitmap(const SkBitmap* bitmap) {
8,
width, height, stride, &FreePixels, data);
- // Assume ownership of pixbuf.
- g_object_ref_sink(pixbuf);
bitmap->unlockPixels();
return pixbuf;
}
diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_gtk.cc b/chrome/browser/autocomplete/autocomplete_popup_view_gtk.cc
index d87f996..1aebd30 100755
--- a/chrome/browser/autocomplete/autocomplete_popup_view_gtk.cc
+++ b/chrome/browser/autocomplete/autocomplete_popup_view_gtk.cc
@@ -279,11 +279,11 @@ gboolean AutocompletePopupViewGtk::HandleExpose(GtkWidget* widget,
// TODO(deanm): These would be better as pixmaps someday.
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- static GdkPixbuf* o2_globe = rb.LoadPixbuf(IDR_O2_GLOBE);
- static GdkPixbuf* o2_history = rb.LoadPixbuf(IDR_O2_HISTORY);
- static GdkPixbuf* o2_more = rb.LoadPixbuf(IDR_O2_MORE);
- static GdkPixbuf* o2_search = rb.LoadPixbuf(IDR_O2_SEARCH);
- static GdkPixbuf* o2_star = rb.LoadPixbuf(IDR_O2_STAR);
+ static GdkPixbuf* o2_globe = rb.GetPixbufNamed(IDR_O2_GLOBE);
+ static GdkPixbuf* o2_history = rb.GetPixbufNamed(IDR_O2_HISTORY);
+ static GdkPixbuf* o2_more = rb.GetPixbufNamed(IDR_O2_MORE);
+ static GdkPixbuf* o2_search = rb.GetPixbufNamed(IDR_O2_SEARCH);
+ static GdkPixbuf* o2_star = rb.GetPixbufNamed(IDR_O2_STAR);
GdkRectangle window_rect = GetWindowRect(event->window);
// Handle when our window is super narrow. A bunch of the calculations
diff --git a/chrome/browser/gtk/bookmark_bar_gtk.cc b/chrome/browser/gtk/bookmark_bar_gtk.cc
index 4a7783c..4c8abea 100644
--- a/chrome/browser/gtk/bookmark_bar_gtk.cc
+++ b/chrome/browser/gtk/bookmark_bar_gtk.cc
@@ -54,9 +54,6 @@ BookmarkBarGtk::~BookmarkBarGtk() {
RemoveAllBookmarkButtons();
bookmark_toolbar_.Destroy();
container_.Destroy();
-
- g_object_unref(default_bookmark_icon_);
- g_object_unref(folder_icon_);
}
void BookmarkBarGtk::SetProfile(Profile* profile) {
@@ -91,8 +88,7 @@ void BookmarkBarGtk::SetPageNavigator(PageNavigator* navigator) {
void BookmarkBarGtk::Init(Profile* profile) {
// Load the default images from the resource bundle.
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- default_bookmark_icon_ = rb.LoadPixbuf(IDR_DEFAULT_FAVICON);
- folder_icon_ = rb.LoadPixbuf(IDR_BOOKMARK_BAR_FOLDER);
+ static GdkPixbuf* folder_icon = rb.GetPixbufNamed(IDR_BOOKMARK_BAR_FOLDER);
bookmark_hbox_ = gtk_hbox_new(FALSE, 0);
container_.Own(gfx::CreateGtkBorderBin(bookmark_hbox_, &kBackgroundColor,
@@ -127,7 +123,7 @@ void BookmarkBarGtk::Init(Profile* profile) {
gtk_button_set_label(GTK_BUTTON(other_bookmarks_button_),
"Other bookmarks");
gtk_button_set_image(GTK_BUTTON(other_bookmarks_button_),
- gtk_image_new_from_pixbuf(folder_icon_));
+ gtk_image_new_from_pixbuf(folder_icon));
// TODO(erg): Hook up a popup menu to |other_bookmarks_button_|.
gtk_box_pack_start(GTK_BOX(bookmark_hbox_), other_bookmarks_button_,
FALSE, FALSE, 0);
@@ -290,10 +286,13 @@ void BookmarkBarGtk::ConfigureButtonForNode(BookmarkNode* node,
GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&node->GetFavIcon());
gtk_button_set_image(GTK_BUTTON(button),
gtk_image_new_from_pixbuf(pixbuf));
- gdk_pixbuf_unref(pixbuf);
+ g_object_unref(pixbuf);
} else {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ static GdkPixbuf* default_bookmark_icon = rb.GetPixbufNamed(
+ IDR_DEFAULT_FAVICON);
gtk_button_set_image(GTK_BUTTON(button),
- gtk_image_new_from_pixbuf(default_bookmark_icon_));
+ gtk_image_new_from_pixbuf(default_bookmark_icon));
}
}
}
diff --git a/chrome/browser/gtk/bookmark_bar_gtk.h b/chrome/browser/gtk/bookmark_bar_gtk.h
index e1747461..d45fcdbb 100644
--- a/chrome/browser/gtk/bookmark_bar_gtk.h
+++ b/chrome/browser/gtk/bookmark_bar_gtk.h
@@ -186,12 +186,6 @@ class BookmarkBarGtk : public BookmarkModelObserver {
// We create a GtkToolbarItem from |dragged_node_| for display.
GtkToolItem* toolbar_drop_item_;
- // Default bookmark icon to display.
- GdkPixbuf* default_bookmark_icon_;
-
- // Icon for bookmark folders.
- GdkPixbuf* folder_icon_;
-
// Whether we should show the instructional text in the bookmark bar.
bool show_instructions_;
};
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc
index 2083b58..798c2f7 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_toolbar_gtk.cc
@@ -261,7 +261,7 @@ void BrowserToolbarGtk::BuildToolbarMenuButton(
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
gtk_container_set_border_width(GTK_CONTAINER(button), 2);
gtk_container_add(GTK_CONTAINER(button),
- gtk_image_new_from_pixbuf(rb.LoadPixbuf(icon_id)));
+ gtk_image_new_from_pixbuf(rb.GetPixbufNamed(icon_id)));
gtk_widget_set_tooltip_text(button, localized_tooltip.c_str());
g_signal_connect(G_OBJECT(button), "button-press-event",
@@ -404,15 +404,15 @@ void BrowserToolbarGtk::InitNineBox() {
ResourceBundle &rb = ResourceBundle::GetSharedInstance();
GdkPixbuf* images[9] = {
- rb.LoadPixbuf(IDR_CONTENT_TOP_LEFT_CORNER),
- rb.LoadPixbuf(IDR_CONTENT_TOP_CENTER),
- rb.LoadPixbuf(IDR_CONTENT_TOP_RIGHT_CORNER),
- rb.LoadPixbuf(IDR_CONTENT_LEFT_SIDE),
+ rb.GetPixbufNamed(IDR_CONTENT_TOP_LEFT_CORNER),
+ rb.GetPixbufNamed(IDR_CONTENT_TOP_CENTER),
+ rb.GetPixbufNamed(IDR_CONTENT_TOP_RIGHT_CORNER),
+ rb.GetPixbufNamed(IDR_CONTENT_LEFT_SIDE),
NULL,
- rb.LoadPixbuf(IDR_CONTENT_RIGHT_SIDE),
- rb.LoadPixbuf(IDR_CONTENT_BOTTOM_LEFT_CORNER),
- rb.LoadPixbuf(IDR_CONTENT_BOTTOM_CENTER),
- rb.LoadPixbuf(IDR_CONTENT_BOTTOM_RIGHT_CORNER)
+ rb.GetPixbufNamed(IDR_CONTENT_RIGHT_SIDE),
+ rb.GetPixbufNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER),
+ rb.GetPixbufNamed(IDR_CONTENT_BOTTOM_CENTER),
+ rb.GetPixbufNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER)
};
background_ninebox_.reset(new NineBox(images));
}
diff --git a/chrome/browser/gtk/custom_button.cc b/chrome/browser/gtk/custom_button.cc
index 3110dea..e7389cb 100644
--- a/chrome/browser/gtk/custom_button.cc
+++ b/chrome/browser/gtk/custom_button.cc
@@ -17,20 +17,16 @@ CustomDrawButtonBase::CustomDrawButtonBase(
int depressed_id) {
// Load the button images from the resource bundle.
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- pixbufs_[GTK_STATE_NORMAL] = normal_id ? rb.LoadPixbuf(normal_id) : NULL;
- pixbufs_[GTK_STATE_ACTIVE] = active_id ? rb.LoadPixbuf(active_id) : NULL;
+ pixbufs_[GTK_STATE_NORMAL] = normal_id ? rb.GetPixbufNamed(normal_id) : NULL;
+ pixbufs_[GTK_STATE_ACTIVE] = active_id ? rb.GetPixbufNamed(active_id) : NULL;
pixbufs_[GTK_STATE_PRELIGHT] =
- highlight_id ? rb.LoadPixbuf(highlight_id) : NULL;
+ highlight_id ? rb.GetPixbufNamed(highlight_id) : NULL;
pixbufs_[GTK_STATE_SELECTED] = NULL;
pixbufs_[GTK_STATE_INSENSITIVE] =
- depressed_id ? rb.LoadPixbuf(depressed_id) : NULL;
+ depressed_id ? rb.GetPixbufNamed(depressed_id) : NULL;
}
CustomDrawButtonBase::~CustomDrawButtonBase() {
- for (size_t i = 0; i < arraysize(pixbufs_); ++i) {
- if (pixbufs_[i])
- g_object_unref(pixbufs_[i]);
- }
}
gboolean CustomDrawButtonBase::OnExpose(GtkWidget* widget, GdkEventExpose* e) {
diff --git a/chrome/browser/gtk/download_item_gtk.cc b/chrome/browser/gtk/download_item_gtk.cc
index 4e2fab8..e877590 100644
--- a/chrome/browser/gtk/download_item_gtk.cc
+++ b/chrome/browser/gtk/download_item_gtk.cc
@@ -226,73 +226,73 @@ void DownloadItemGtk::InitNineBoxes() {
ResourceBundle &rb = ResourceBundle::GetSharedInstance();
int i = 0;
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_TOP);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_CENTER_TOP);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_RIGHT_TOP);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM);
body_nine_box_normal_ = new NineBox(images);
i = 0;
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_TOP_H);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_CENTER_TOP_H);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_H);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE_H);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE_H);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_H);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM_H);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM_H);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_H);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP_H);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP_H);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_H);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE_H);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE_H);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_H);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM_H);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM_H);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_H);
body_nine_box_prelight_ = new NineBox(images);
i = 0;
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_TOP_P);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_CENTER_TOP_P);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_P);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE_P);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE_P);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_P);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM_P);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM_P);
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_P);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP_P);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP_P);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_RIGHT_TOP_P);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE_P);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_CENTER_MIDDLE_P);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_RIGHT_MIDDLE_P);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM_P);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM_P);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_P);
body_nine_box_active_ = new NineBox(images);
i = 0;
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_TOP);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP);
images[i++] = NULL;
images[i++] = NULL;
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE);
images[i++] = NULL;
images[i++] = NULL;
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM);
images[i++] = NULL;
images[i++] = NULL;
menu_nine_box_normal_ = new NineBox(images);
i = 0;
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_TOP_H);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP_H);
images[i++] = NULL;
images[i++] = NULL;
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_H);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_H);
images[i++] = NULL;
images[i++] = NULL;
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_H);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_H);
images[i++] = NULL;
images[i++] = NULL;
menu_nine_box_prelight_ = new NineBox(images);
i = 0;
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_TOP_P);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_MENU_TOP_P);
images[i++] = NULL;
images[i++] = NULL;
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_P);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_P);
images[i++] = NULL;
images[i++] = NULL;
- images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_P);
+ images[i++] = rb.GetPixbufNamed(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_P);
images[i++] = NULL;
images[i++] = NULL;
menu_nine_box_active_ = new NineBox(images);
diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc
index d0071f2..0dd3a5e 100644
--- a/chrome/browser/gtk/download_shelf_gtk.cc
+++ b/chrome/browser/gtk/download_shelf_gtk.cc
@@ -95,9 +95,8 @@ DownloadShelfGtk::DownloadShelfGtk(TabContents* tab_contents)
// Make the download arrow icon.
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- GdkPixbuf* download_pixbuf = rb.LoadPixbuf(IDR_DOWNLOADS_FAVICON);
+ GdkPixbuf* download_pixbuf = rb.GetPixbufNamed(IDR_DOWNLOADS_FAVICON);
GtkWidget* download_image = gtk_image_new_from_pixbuf(download_pixbuf);
- gdk_pixbuf_unref(download_pixbuf);
// Pack the link and the icon in an hbox.
link_hbox_ = gtk_hbox_new(FALSE, 5);
diff --git a/chrome/browser/gtk/gtk_chrome_button.cc b/chrome/browser/gtk/gtk_chrome_button.cc
index 3e53a2e..193a295 100644
--- a/chrome/browser/gtk/gtk_chrome_button.cc
+++ b/chrome/browser/gtk/gtk_chrome_button.cc
@@ -33,27 +33,27 @@ static void gtk_chrome_button_class_init(GtkChromeButtonClass *button_class) {
int i = 0;
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_TOP_LEFT_H);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_TOP_H);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_TOP_RIGHT_H);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_LEFT_H);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_CENTER_H);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_RIGHT_H);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_BOTTOM_LEFT_H);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_BOTTOM_H);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_BOTTOM_RIGHT_H);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_TOP_LEFT_H);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_TOP_H);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_TOP_RIGHT_H);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_LEFT_H);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_CENTER_H);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_RIGHT_H);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_BOTTOM_LEFT_H);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_BOTTOM_H);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_BOTTOM_RIGHT_H);
nine_box_prelight.reset(new NineBox(images));
i = 0;
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_TOP_LEFT_P);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_TOP_P);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_TOP_RIGHT_P);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_LEFT_P);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_CENTER_P);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_RIGHT_P);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_BOTTOM_LEFT_P);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_BOTTOM_P);
- images[i++] = rb.LoadPixbuf(IDR_TEXTBUTTON_BOTTOM_RIGHT_P);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_TOP_LEFT_P);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_TOP_P);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_TOP_RIGHT_P);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_LEFT_P);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_CENTER_P);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_RIGHT_P);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_BOTTOM_LEFT_P);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_BOTTOM_P);
+ images[i++] = rb.GetPixbufNamed(IDR_TEXTBUTTON_BOTTOM_RIGHT_P);
nine_box_active.reset(new NineBox(images));
}
diff --git a/chrome/browser/gtk/infobar_gtk.cc b/chrome/browser/gtk/infobar_gtk.cc
index 4aba0e2..a8456b7 100644
--- a/chrome/browser/gtk/infobar_gtk.cc
+++ b/chrome/browser/gtk/infobar_gtk.cc
@@ -57,7 +57,7 @@ InfoBar::InfoBar(InfoBarDelegate* delegate)
if (icon) {
GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(icon);
GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf);
- gdk_pixbuf_unref(pixbuf);
+ g_object_unref(pixbuf);
gtk_box_pack_start(GTK_BOX(hbox_), image, FALSE, FALSE, 0);
}
diff --git a/chrome/browser/gtk/nine_box.cc b/chrome/browser/gtk/nine_box.cc
index e2c42f6..c1147c7 100644
--- a/chrome/browser/gtk/nine_box.cc
+++ b/chrome/browser/gtk/nine_box.cc
@@ -38,10 +38,6 @@ NineBox::NineBox(GdkPixbuf* images[9]) {
}
NineBox::~NineBox() {
- for (int i = 0; i < 9; ++i) {
- if (images_[i])
- gdk_pixbuf_unref(images_[i]);
- }
}
void NineBox::RenderToWidget(GtkWidget* dst) {
diff --git a/chrome/common/resource_bundle.h b/chrome/common/resource_bundle.h
index 6fa3a7e..2532953 100644
--- a/chrome/common/resource_bundle.h
+++ b/chrome/common/resource_bundle.h
@@ -25,7 +25,7 @@ namespace base {
class DataPack;
};
#endif
-#if defined(OS_LINUX)
+#if defined(TOOLKIT_GTK)
typedef struct _GdkPixbuf GdkPixbuf;
#endif
class ChromeFont;
@@ -66,9 +66,8 @@ class ResourceBundle {
// Gets the bitmap with the specified resource_id, first by looking into the
// theme data, than in the current module data if applicable.
- // Returns a pointer to a shared instance of the SkBitmap in the given out
- // parameter. This shared bitmap is owned by the resource bundle and should
- // not be freed.
+ // Returns a pointer to a shared instance of the SkBitmap. This shared bitmap
+ // is owned by the resource bundle and should not be freed.
//
// The bitmap is assumed to exist. This function will log in release, and
// assert in debug mode if it does not. On failure, this will return a
@@ -115,8 +114,16 @@ class ResourceBundle {
// Loads and returns a cursor from the app module.
HCURSOR LoadCursor(int cursor_id);
#elif defined(TOOLKIT_GTK)
- // Load a theme image as a GdkPixbuf.
- GdkPixbuf* LoadPixbuf(int resource_id);
+ // Gets the GdkPixbuf with the specified resource_id, first by looking into
+ // the theme data, than in the current module data if applicable. Returns a
+ // pointer to a shared instance of the GdkPixbuf. This shared GdkPixbuf is
+ // owned by the resource bundle and should not be freed.
+ //
+ // The bitmap is assumed to exist. This function will log in release, and
+ // assert in debug mode if it does not. On failure, this will return a
+ // pointer to a shared empty placeholder bitmap so it will be visible what
+ // is missing.
+ GdkPixbuf* GetPixbufNamed(int resource_id);
#endif
// Sets an Extension object that can handle theme resource requests.
@@ -176,6 +183,10 @@ class ResourceBundle {
// ownership of the pointers.
typedef std::map<int, SkBitmap*> SkImageMap;
SkImageMap skia_images_;
+#if defined(TOOLKIT_GTK)
+ typedef std::map<int, GdkPixbuf*> GdkPixbufMap;
+ GdkPixbufMap gdk_pixbufs_;
+#endif
// The various fonts used. Cached to avoid repeated GDI creation/destruction.
scoped_ptr<ChromeFont> base_font_;
diff --git a/chrome/common/resource_bundle_linux.cc b/chrome/common/resource_bundle_linux.cc
index 870d817..57cce50 100644
--- a/chrome/common/resource_bundle_linux.cc
+++ b/chrome/common/resource_bundle_linux.cc
@@ -12,6 +12,7 @@
#include "base/data_pack.h"
#include "base/file_path.h"
#include "base/file_util.h"
+#include "base/gfx/gtk_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_piece.h"
@@ -19,9 +20,48 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/gfx/chrome_font.h"
#include "chrome/common/l10n_util.h"
+#include "SkBitmap.h"
+
+namespace {
+
+#if defined(TOOLKIT_GTK)
+// Convert the raw image data into a GdkPixbuf. The GdkPixbuf that is returned
+// has a ref count of 1 so the caller must call g_object_unref to free the
+// memory.
+GdkPixbuf* LoadPixbuf(std::vector<unsigned char>& data) {
+ GdkPixbufLoader* loader = gdk_pixbuf_loader_new();
+ bool ok = gdk_pixbuf_loader_write(loader, static_cast<guint8*>(data.data()),
+ data.size(), NULL);
+ if (!ok)
+ return NULL;
+ // Calling gdk_pixbuf_loader_close forces the data to be parsed by the
+ // loader. We must do this before calling gdk_pixbuf_loader_get_pixbuf.
+ ok = gdk_pixbuf_loader_close(loader, NULL);
+ if (!ok)
+ return NULL;
+ GdkPixbuf* pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
+ if (!pixbuf)
+ return NULL;
+
+ // The pixbuf is owned by the loader, so add a ref so when we delete the
+ // loader, the pixbuf still exists.
+ g_object_ref(pixbuf);
+ g_object_unref(loader);
+
+ return pixbuf;
+}
+#endif
+
+} // namespace
ResourceBundle::~ResourceBundle() {
FreeImages();
+ // Free GdkPixbufs.
+ for (GdkPixbufMap::iterator i = gdk_pixbufs_.begin();
+ i != gdk_pixbufs_.end(); i++) {
+ g_object_unref(i->second);
+ }
+ gdk_pixbufs_.clear();
delete locale_resources_data_;
locale_resources_data_ = NULL;
@@ -123,27 +163,52 @@ string16 ResourceBundle::GetLocalizedString(int message_id) {
}
#if defined(TOOLKIT_GTK)
-GdkPixbuf* ResourceBundle::LoadPixbuf(int resource_id) {
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+GdkPixbuf* ResourceBundle::GetPixbufNamed(int resource_id) {
+ // Check to see if we already have the pixbuf in the cache.
+ {
+ AutoLock lock_scope(lock_);
+ GdkPixbufMap::const_iterator found = gdk_pixbufs_.find(resource_id);
+ if (found != gdk_pixbufs_.end())
+ return found->second;
+ }
+
+
std::vector<unsigned char> data;
- rb.LoadImageResourceBytes(resource_id, &data);
+ LoadImageResourceBytes(resource_id, &data);
+ GdkPixbuf* pixbuf = LoadPixbuf(data);
- GdkPixbufLoader* loader = gdk_pixbuf_loader_new();
- bool ok = gdk_pixbuf_loader_write(loader, static_cast<guint8*>(data.data()),
- data.size(), NULL);
- DCHECK(ok) << "failed to write " << resource_id;
- // Calling gdk_pixbuf_loader_close forces the data to be parsed by the
- // loader. We must do this before calling gdk_pixbuf_loader_get_pixbuf.
- ok = gdk_pixbuf_loader_close(loader, NULL);
- DCHECK(ok) << "close failed " << resource_id;
- GdkPixbuf* pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
- DCHECK(pixbuf) << "failed to load " << resource_id << " " << data.size();
+ // We loaded successfully. Cache the pixbuf.
+ if (pixbuf) {
+ AutoLock lock_scope(lock_);
- // The pixbuf is owned by the loader, so add a ref so when we delete the
- // loader, the pixbuf still exists.
- g_object_ref(pixbuf);
- g_object_unref(loader);
+ // Another thread raced us, and has already cached the pixbuf.
+ if (gdk_pixbufs_.count(resource_id)) {
+ g_object_unref(pixbuf);
+ return gdk_pixbufs_[resource_id];
+ }
- return pixbuf;
+ gdk_pixbufs_[resource_id] = pixbuf;
+ return pixbuf;
+ }
+
+ // We failed to retrieve the bitmap, show a debugging red square.
+ {
+ LOG(WARNING) << "Unable to load GdkPixbuf with id " << resource_id;
+ NOTREACHED(); // Want to assert in debug mode.
+
+ AutoLock lock_scope(lock_); // Guard empty_bitmap initialization.
+
+ static GdkPixbuf* empty_bitmap = NULL;
+ if (!empty_bitmap) {
+ // The placeholder bitmap is bright red so people notice the problem.
+ // This bitmap will be leaked, but this code should never be hit.
+ scoped_ptr<SkBitmap> skia_bitmap(new SkBitmap());
+ skia_bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32);
+ skia_bitmap->allocPixels();
+ skia_bitmap->eraseARGB(255, 255, 0, 0);
+ empty_bitmap = gfx::GdkPixbufFromSkBitmap(skia_bitmap.get());
+ }
+ return empty_bitmap;
+ }
}
#endif