diff options
author | tony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 22:42:38 +0000 |
---|---|---|
committer | tony@chromium.org <tony@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 22:42:38 +0000 |
commit | ad56887647def949c5b3e44b63a474891f42f3f2 (patch) | |
tree | e17551961298e0c1d4b3eb08f5d1cd28a8a32337 /chrome | |
parent | 4057fcf12b921369a829244e90e8b57dec87d08c (diff) | |
download | chromium_src-ad56887647def949c5b3e44b63a474891f42f3f2.zip chromium_src-ad56887647def949c5b3e44b63a474891f42f3f2.tar.gz chromium_src-ad56887647def949c5b3e44b63a474891f42f3f2.tar.bz2 |
Cache the left and right tab curve images. We were spending a lot
of time regenerating the images for all the tabs. This speeds
up the time needed to paint a tab by about 30%.
This helps a bit, but we're still slow. We need to calculate
damage rects and only redraw damage rects (most of the remaining
time is spent on painting to the canvas now).
BUG=15872
Review URL: http://codereview.chromium.org/174095
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23771 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/gtk/tabs/tab_renderer_gtk.cc | 83 | ||||
-rw-r--r-- | chrome/browser/gtk/tabs/tab_renderer_gtk.h | 23 |
2 files changed, 73 insertions, 33 deletions
diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc index 3110b8d..5b42dfe 100644 --- a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc @@ -5,6 +5,7 @@ #include "chrome/browser/gtk/tabs/tab_renderer_gtk.h" #include <algorithm> +#include <utility> #include "app/gfx/canvas_paint.h" #include "app/gfx/favicon_size.h" @@ -119,7 +120,7 @@ TabRendererGtk::LoadingAnimation::Data::Data( bool TabRendererGtk::initialized_ = false; TabRendererGtk::TabImage TabRendererGtk::tab_active_ = {0}; TabRendererGtk::TabImage TabRendererGtk::tab_inactive_ = {0}; -TabRendererGtk::TabImage TabRendererGtk::tab_alpha = {0}; +TabRendererGtk::TabImage TabRendererGtk::tab_alpha_ = {0}; gfx::Font* TabRendererGtk::title_font_ = NULL; int TabRendererGtk::title_font_height_ = 0; int TabRendererGtk::close_button_width_ = 0; @@ -250,6 +251,10 @@ TabRendererGtk::TabRendererGtk(ThemeProvider* theme_provider) TabRendererGtk::~TabRendererGtk() { tab_.Destroy(); + for (BitmapCache::iterator it = cached_bitmaps_.begin(); + it != cached_bitmaps_.end(); ++it) { + delete it->second.bitmap; + } } void TabRendererGtk::UpdateData(TabContents* contents, bool loading_only) { @@ -367,8 +372,8 @@ int TabRendererGtk::GetContentHeight() { void TabRendererGtk::LoadTabImages() { ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - tab_alpha.image_l = rb.GetBitmapNamed(IDR_TAB_ALPHA_LEFT); - tab_alpha.image_r = rb.GetBitmapNamed(IDR_TAB_ALPHA_RIGHT); + tab_alpha_.image_l = rb.GetBitmapNamed(IDR_TAB_ALPHA_LEFT); + tab_alpha_.image_r = rb.GetBitmapNamed(IDR_TAB_ALPHA_RIGHT); tab_active_.image_l = rb.GetBitmapNamed(IDR_TAB_ACTIVE_LEFT); tab_active_.image_c = rb.GetBitmapNamed(IDR_TAB_ACTIVE_CENTER); @@ -603,6 +608,33 @@ void TabRendererGtk::MoveCloseButtonWidget() { } } +SkBitmap* TabRendererGtk::GetMaskedBitmap(const SkBitmap* mask, + const SkBitmap* background, int bg_offset_x, int bg_offset_y) { + // We store a bitmap for each mask + background pair (4 total bitmaps). We + // replace the cached image if the tab has moved relative to the background. + BitmapCache::iterator it = cached_bitmaps_.find(std::make_pair(mask, + background)); + if (it != cached_bitmaps_.end()) { + if (it->second.bg_offset_x == bg_offset_x && + it->second.bg_offset_y == bg_offset_y) { + return it->second.bitmap; + } + // The background offset changed so we should re-render with the new + // offsets. + delete it->second.bitmap; + } + SkBitmap image = skia::ImageOperations::CreateTiledBitmap( + *background, bg_offset_x, bg_offset_y, mask->width(), + height() + kToolbarOverlap); + CachedBitmap bitmap = { + bg_offset_x, + bg_offset_y, + new SkBitmap(skia::ImageOperations::CreateMaskedBitmap(image, *mask)) + }; + cached_bitmaps_[std::make_pair(mask, background)] = bitmap; + return bitmap.bitmap; +} + void TabRendererGtk::PaintTab(GdkEventExpose* event) { gfx::CanvasPaint canvas(event, false); if (canvas.is_empty()) @@ -706,7 +738,7 @@ void TabRendererGtk::PaintInactiveTabBackground(gfx::Canvas* canvas) { // The tab image needs to be lined up with the background image // so that it feels partially transparent. - int offset = background_offset_x_; + int offset_x = background_offset_x_; int tab_id = is_otr ? IDR_THEME_TAB_BACKGROUND_INCOGNITO : IDR_THEME_TAB_BACKGROUND; @@ -719,25 +751,19 @@ void TabRendererGtk::PaintInactiveTabBackground(gfx::Canvas* canvas) { int offset_y = theme_provider_->HasCustomImage(tab_id) ? 0 : 20; // Draw left edge. - SkBitmap tab_l = skia::ImageOperations::CreateTiledBitmap( - *tab_bg, offset, offset_y, - tab_active_.l_width, height() + kToolbarOverlap); - SkBitmap theme_l = skia::ImageOperations::CreateMaskedBitmap( - tab_l, *tab_alpha.image_l); - canvas->DrawBitmapInt(theme_l, 0, 0); + SkBitmap* theme_l = GetMaskedBitmap(tab_alpha_.image_l, tab_bg, offset_x, + offset_y); + canvas->DrawBitmapInt(*theme_l, 0, 0); // Draw right edge. - SkBitmap tab_r = skia::ImageOperations::CreateTiledBitmap( - *tab_bg, - offset + width() - tab_active_.r_width, offset_y, - tab_active_.r_width, height() + kToolbarOverlap); - SkBitmap theme_r = skia::ImageOperations::CreateMaskedBitmap( - tab_r, *tab_alpha.image_r); - canvas->DrawBitmapInt(theme_r, width() - theme_r.width(), 0); + SkBitmap* theme_r = GetMaskedBitmap(tab_alpha_.image_r, tab_bg, + offset_x + width() - tab_active_.r_width, offset_y); + + canvas->DrawBitmapInt(*theme_r, width() - theme_r->width(), 0); // Draw center. canvas->TileImageInt(*tab_bg, - offset + tab_active_.l_width, kDropShadowOffset + offset_y, + offset_x + tab_active_.l_width, kDropShadowOffset + offset_y, tab_active_.l_width, 2, width() - tab_active_.l_width - tab_active_.r_width, height() - 2); @@ -749,29 +775,22 @@ void TabRendererGtk::PaintInactiveTabBackground(gfx::Canvas* canvas) { } void TabRendererGtk::PaintActiveTabBackground(gfx::Canvas* canvas) { - int offset = background_offset_x_; + int offset_x = background_offset_x_; SkBitmap* tab_bg = theme_provider_->GetBitmapNamed(IDR_THEME_TOOLBAR); // Draw left edge. - SkBitmap tab_l = skia::ImageOperations::CreateTiledBitmap( - *tab_bg, offset, 0, tab_active_.l_width, height() + kToolbarOverlap); - SkBitmap theme_l = skia::ImageOperations::CreateMaskedBitmap( - tab_l, *tab_alpha.image_l); - canvas->DrawBitmapInt(theme_l, 0, 0); + SkBitmap* theme_l = GetMaskedBitmap(tab_alpha_.image_l, tab_bg, offset_x, 0); + canvas->DrawBitmapInt(*theme_l, 0, 0); // Draw right edge. - SkBitmap tab_r = skia::ImageOperations::CreateTiledBitmap( - *tab_bg, - offset + width() - tab_active_.r_width, 0, - tab_active_.r_width, height() + kToolbarOverlap); - SkBitmap theme_r = skia::ImageOperations::CreateMaskedBitmap( - tab_r, *tab_alpha.image_r); - canvas->DrawBitmapInt(theme_r, width() - tab_active_.r_width, 0); + SkBitmap* theme_r = GetMaskedBitmap(tab_alpha_.image_r, tab_bg, + offset_x + width() - tab_active_.r_width, 0); + canvas->DrawBitmapInt(*theme_r, width() - tab_active_.r_width, 0); // Draw center. canvas->TileImageInt(*tab_bg, - offset + tab_active_.l_width, kDropShadowHeight, + offset_x + tab_active_.l_width, kDropShadowHeight, tab_active_.l_width, kDropShadowHeight, width() - tab_active_.l_width - tab_active_.r_width, height() - kDropShadowHeight); diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.h b/chrome/browser/gtk/tabs/tab_renderer_gtk.h index c9a19d8..3c8e3bd 100644 --- a/chrome/browser/gtk/tabs/tab_renderer_gtk.h +++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_GTK_TABS_TAB_RENDERER_GTK_H_ #include <gtk/gtk.h> +#include <map> #include "app/animation.h" #include "app/gfx/canvas.h" @@ -190,6 +191,17 @@ class TabRendererGtk : public AnimationDelegate { private: class FavIconCrashAnimation; + // The data structure used to hold cached bitmaps. We need to manually free + // the bitmap in CachedBitmap when we remove it from |cached_bitmaps_|. We + // handle this when we replace images in the map and in the destructor. + struct CachedBitmap { + int bg_offset_x; + int bg_offset_y; + SkBitmap* bitmap; + }; + typedef std::map<std::pair<const SkBitmap*, const SkBitmap*>, CachedBitmap> + BitmapCache; + // Model data. We store this here so that we don't need to ask the underlying // model, which is tricky since instances of this object can outlive the // corresponding objects in the underlying model. @@ -244,6 +256,15 @@ class TabRendererGtk : public AnimationDelegate { // Returns the largest of the favicon, title text, and the close button. static int GetContentHeight(); + // A helper method for generating the masked bitmaps used to draw the curved + // edges of tabs. We cache the generated bitmaps because they can take a + // long time to compute. + SkBitmap* GetMaskedBitmap(const SkBitmap* mask, + const SkBitmap* background, + int bg_offset_x, + int bg_offset_y); + BitmapCache cached_bitmaps_; + // Paints the tab, minus the close button. void PaintTab(GdkEventExpose* event); @@ -297,7 +318,7 @@ class TabRendererGtk : public AnimationDelegate { static TabImage tab_active_; static TabImage tab_inactive_; - static TabImage tab_alpha; + static TabImage tab_alpha_; static gfx::Font* title_font_; static int title_font_height_; |