diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-14 02:32:31 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-14 02:32:31 +0000 |
commit | 4c9af7049b3d2bc242fcee0e804ed71e85f5e543 (patch) | |
tree | 38d8228bc0e1a46a84ffe7d45044f978107e82bf | |
parent | 097dde28cb2f5967871351232406ebb7ec317ad3 (diff) | |
download | chromium_src-4c9af7049b3d2bc242fcee0e804ed71e85f5e543.zip chromium_src-4c9af7049b3d2bc242fcee0e804ed71e85f5e543.tar.gz chromium_src-4c9af7049b3d2bc242fcee0e804ed71e85f5e543.tar.bz2 |
GTK: reduce cpu usage of upgrade notification animation.
First, don't queue excessive draws when the animation isn't changing. This should reduce cpu usage by about 75%.
Second, don't animate the little dot when the browser window isn't active. For WMs that support _NET_ACTIVE_WINDOW, this should keep CPU usage steady no matter how many browser windows are open.
The net effect of this patch is to reduce CPU usage from 100% in certain cases (when many windows are open) to a negligible amount (on metacity on my workstation).
BUG=48909
TEST=open many windows and inspect CPU usage according to top
Review URL: http://codereview.chromium.org/2985006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52271 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.cc | 49 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.h | 19 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 6 |
3 files changed, 56 insertions, 18 deletions
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc index b88bcc2..b45d4c5c 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_toolbar_gtk.cc @@ -95,6 +95,7 @@ BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window) profile_(NULL), menu_bar_helper_(this), upgrade_reminder_animation_(this), + upgrade_reminder_canceled_(false), collapsed_(false) { browser_->command_updater()->AddCommandObserver(IDC_BACK, this); browser_->command_updater()->AddCommandObserver(IDC_FORWARD, this); @@ -110,11 +111,13 @@ BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window) upgrade_reminder_animation_.SetThrobDuration(kThrobDuration); - if (Singleton<UpgradeDetector>::get()->notify_upgrade()) - ShowUpgradeReminder(); + ActiveWindowWatcherX::AddObserver(this); + MaybeShowUpgradeReminder(); } BrowserToolbarGtk::~BrowserToolbarGtk() { + ActiveWindowWatcherX::RemoveObserver(this); + browser_->command_updater()->RemoveCommandObserver(IDC_BACK, this); browser_->command_updater()->RemoveCommandObserver(IDC_FORWARD, this); browser_->command_updater()->RemoveCommandObserver(IDC_HOME, this); @@ -448,7 +451,7 @@ void BrowserToolbarGtk::Observe(NotificationType type, UpdateRoundedness(); } else if (type == NotificationType::UPGRADE_RECOMMENDED) { - ShowUpgradeReminder(); + MaybeShowUpgradeReminder(); } else { NOTREACHED(); } @@ -745,8 +748,15 @@ void BrowserToolbarGtk::NotifyPrefChanged(const std::wstring* pref) { !home_page_is_new_tab_page_.IsManaged()); } -void BrowserToolbarGtk::ShowUpgradeReminder() { - upgrade_reminder_animation_.StartThrobbing(-1); +void BrowserToolbarGtk::MaybeShowUpgradeReminder() { + // Only show the upgrade reminder animation for the currently active window. + if (window_->IsActive() && + Singleton<UpgradeDetector>::get()->notify_upgrade() && + !upgrade_reminder_canceled_) { + upgrade_reminder_animation_.StartThrobbing(-1); + } else { + upgrade_reminder_animation_.Reset(); + } } bool BrowserToolbarGtk::ShouldOnlyShowLocation() const { @@ -779,20 +789,29 @@ void BrowserToolbarGtk::PopupForButtonNextTo(GtkWidget* button, } void BrowserToolbarGtk::AnimationEnded(const Animation* animation) { - AnimationProgressed(animation); + DCHECK_EQ(animation, &upgrade_reminder_animation_); + gtk_widget_queue_draw(app_menu_image_.get()); } void BrowserToolbarGtk::AnimationProgressed(const Animation* animation) { DCHECK_EQ(animation, &upgrade_reminder_animation_); - gtk_widget_queue_draw(app_menu_image_.get()); + if (UpgradeAnimationIsFaded()) + gtk_widget_queue_draw(app_menu_image_.get()); } void BrowserToolbarGtk::AnimationCanceled(const Animation* animation) { - AnimationProgressed(animation); + AnimationEnded(animation); +} + +void BrowserToolbarGtk::ActiveWindowChanged(GdkWindow* active_window) { + MaybeShowUpgradeReminder(); } void BrowserToolbarGtk::OnAppMenuShow(GtkWidget* sender) { - upgrade_reminder_animation_.Reset(); + if (upgrade_reminder_animation_.is_animating()) { + upgrade_reminder_canceled_ = true; + MaybeShowUpgradeReminder(); + } } gboolean BrowserToolbarGtk::OnAppMenuImageExpose(GtkWidget* sender, @@ -801,10 +820,7 @@ gboolean BrowserToolbarGtk::OnAppMenuImageExpose(GtkWidget* sender, return FALSE; SkBitmap badge; - if (upgrade_reminder_animation_.cycles_remaining() > 0 && - // This funky looking math makes the badge throb for 2 seconds once - // every 8 seconds. - ((upgrade_reminder_animation_.cycles_remaining() - 1) / 2) % 4 == 0) { + if (UpgradeAnimationIsFaded()) { badge = SkBitmapOperations::CreateBlendedBitmap( *theme_provider_->GetBitmapNamed(IDR_UPGRADE_DOT_ACTIVE), *theme_provider_->GetBitmapNamed(IDR_UPGRADE_DOT_INACTIVE), @@ -825,3 +841,10 @@ gboolean BrowserToolbarGtk::OnAppMenuImageExpose(GtkWidget* sender, return FALSE; } + +bool BrowserToolbarGtk::UpgradeAnimationIsFaded() { + return upgrade_reminder_animation_.cycles_remaining() > 0 && + // This funky looking math makes the badge throb for 2 seconds once + // every 8 seconds. + ((upgrade_reminder_animation_.cycles_remaining() - 1) / 2) % 4 == 0; +} diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h index a0619b2..20860de9 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.h +++ b/chrome/browser/gtk/browser_toolbar_gtk.h @@ -8,6 +8,7 @@ #include <gtk/gtk.h> #include <string> +#include "app/active_window_watcher_x.h" #include "app/gtk_signal.h" #include "app/menus/simple_menu_model.h" #include "app/throb_animation.h" @@ -44,7 +45,8 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, public MenuGtk::Delegate, public NotificationObserver, public MenuBarHelper::Delegate, - public AnimationDelegate { + public AnimationDelegate, + public ActiveWindowWatcherX::Observer { public: explicit BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window); virtual ~BrowserToolbarGtk(); @@ -126,6 +128,9 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, virtual void AnimationProgressed(const Animation* animation); virtual void AnimationCanceled(const Animation* animation); + // ActiveWindowWatcher::Observer implementation ------------------------------ + virtual void ActiveWindowChanged(GdkWindow* active_window); + private: // Builds a toolbar button with all the properties set. // |spacing| is the width of padding (in pixels) on the left and right of the @@ -156,6 +161,10 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, // was taken (the roundedness was already correct), true otherwise. bool UpdateRoundedness(); + // Calculates whether the upgrade notification dot should be faded at all + // (as opposed to solid). + bool UpgradeAnimationIsFaded(); + // Gtk callback for the "expose-event" signal. // The alignment contains the toolbar. CHROMEGTK_CALLBACK_1(BrowserToolbarGtk, gboolean, OnAlignmentExpose, @@ -185,8 +194,9 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, // Updates preference-dependent state. void NotifyPrefChanged(const std::wstring* pref); - // Start the upgrade notification animation. - void ShowUpgradeReminder(); + // Start the upgrade notification animation if we have detected an upgrade + // and the current toolbar is focused. + void MaybeShowUpgradeReminder(); static void SetSyncMenuLabel(GtkWidget* widget, gpointer userdata); @@ -268,6 +278,9 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, ThrobAnimation upgrade_reminder_animation_; + // We have already shown and dismissed the upgrade reminder animation. + bool upgrade_reminder_canceled_; + // When collapsed, the toolbar is just a tiny strip, no controls are visible. bool collapsed_; diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index be48032..fe4148b 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -333,6 +333,10 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser) maximize_after_show_(false), suppress_window_raise_(false), accel_group_(NULL) { + // We register first so that other views like the toolbar can use the + // is_active() function in their ActiveWindowChanged() handlers. + ActiveWindowWatcherX::AddObserver(this); + use_custom_frame_pref_.Init(prefs::kUseCustomChromeFrame, browser_->profile()->GetPrefs(), this); @@ -374,8 +378,6 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser) registrar_.Add(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, NotificationService::AllSources()); - - ActiveWindowWatcherX::AddObserver(this); } BrowserWindowGtk::~BrowserWindowGtk() { |