Chromium Code Reviews| Index: chrome/browser/ui/views/tabs/tab.cc |
| diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc |
| index 4b854bcfbe4b1bf089ab06e6bbaf58f9954d4cd4..da49b038fb0bf5b50525da9900d25a831331130a 100644 |
| --- a/chrome/browser/ui/views/tabs/tab.cc |
| +++ b/chrome/browser/ui/views/tabs/tab.cc |
| @@ -44,6 +44,7 @@ |
| #include "ui/gfx/color_analysis.h" |
| #include "ui/gfx/favicon_size.h" |
| #include "ui/gfx/geometry/rect_conversions.h" |
| +#include "ui/gfx/image/canvas_image_source.h" |
| #include "ui/gfx/image/image_skia_operations.h" |
| #include "ui/gfx/paint_vector_icon.h" |
| #include "ui/gfx/path.h" |
| @@ -119,19 +120,25 @@ const char kTabCloseButtonName[] = "TabCloseButton"; |
| // Parameters for PaintTabBackgroundUsingParams(). |
| struct PaintBackgroundParams { |
| PaintBackgroundParams(bool is_active, |
| - gfx::ImageSkia* fill_image_ptr, |
| + gfx::ImageSkia* fill_image, |
| bool has_custom_image, |
| - gfx::Rect rect, |
| + const gfx::Rect& rect, |
| SkColor stroke_color, |
| SkColor toolbar_color, |
| - SkColor background_tab_color) |
| + SkColor background_tab_color, |
| + bool draw_hover, |
| + const gfx::Point& hover_location, |
| + SkAlpha hover_alpha) |
| : is_active(is_active), |
| - fill_image(fill_image_ptr ? *fill_image_ptr : gfx::ImageSkia()), |
| + fill_image(fill_image ? *fill_image : gfx::ImageSkia()), |
| has_custom_image(has_custom_image), |
| rect(rect), |
| stroke_color(stroke_color), |
| toolbar_color(toolbar_color), |
| - background_tab_color(background_tab_color) {} |
| + background_tab_color(background_tab_color), |
| + draw_hover(draw_hover), |
| + hover_location(PointToSkPoint(hover_location)), |
| + hover_alpha(hover_alpha) {} |
| const bool is_active; |
| const gfx::ImageSkia fill_image; |
| @@ -140,8 +147,61 @@ struct PaintBackgroundParams { |
| const SkColor stroke_color; |
| const SkColor toolbar_color; |
| const SkColor background_tab_color; |
| + const bool draw_hover; |
| + const SkPoint hover_location; |
| + const SkAlpha hover_alpha; |
| }; |
| +void PaintTabBackgroundUsingParams(gfx::Canvas* fill_canvas, |
| + gfx::Canvas* stroke_canvas, |
| + const PaintBackgroundParams& params); |
| + |
| +//////////////////////////////////////////////////////////////////////////////// |
| +// TabImageSource |
| +// |
| +// This subclass of CanvasImageSource allows the inactive tab image to be cached |
| +// once and rendered correctly for all scale factors. |
| +class TabImageSource : public gfx::CanvasImageSource { |
| + public: |
| + enum UseCanvas { FILL, STROKE, BOTH }; |
| + |
| + TabImageSource(UseCanvas use_canvas, Tab* tab, int fill_id, int y_offset); |
| + ~TabImageSource() override {} |
| + |
| + // gfx::CanvasImageSource override. |
| + void Draw(gfx::Canvas* canvas) override; |
| + |
| + private: |
| + const UseCanvas use_canvas_; |
| + const PaintBackgroundParams params_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(TabImageSource); |
| +}; |
| + |
| +TabImageSource::TabImageSource(UseCanvas use_canvas, |
| + Tab* tab, |
| + int fill_id, |
| + int y_offset) |
| + : gfx::CanvasImageSource(tab->size(), true), |
| + use_canvas_(use_canvas), |
| + params_(false, |
| + tab->GetThemeProvider()->GetImageSkiaNamed(fill_id), |
| + false, |
| + gfx::Rect(gfx::Point(0, y_offset), tab->size()), |
| + tab->controller()->GetToolbarTopSeparatorColor(), |
| + tab->GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR), |
| + tab->GetThemeProvider()->GetColor( |
| + ThemeProperties::COLOR_BACKGROUND_TAB), |
| + false, |
| + gfx::Point(), |
| + 255) {} |
| + |
| +void TabImageSource::Draw(gfx::Canvas* canvas) { |
| + PaintTabBackgroundUsingParams(use_canvas_ != STROKE ? canvas : nullptr, |
|
Peter Kasting
2016/08/11 22:51:15
Nit: Prefer "use_canvas_ == STROKE ? nullptr : can
Greg Levin
2016/08/12 19:48:15
Obsolete due to other change.
|
| + use_canvas_ != FILL ? canvas : nullptr, |
| + params_); |
| +} |
| + |
| //////////////////////////////////////////////////////////////////////////////// |
| // ImageCacheEntryMetadata |
| // |
| @@ -151,7 +211,6 @@ struct ImageCacheEntryMetadata { |
| SkColor fill_color, |
| SkColor stroke_color, |
| bool use_fill_and_stroke_images, |
| - ui::ScaleFactor scale_factor, |
| const gfx::Size& size); |
| ~ImageCacheEntryMetadata(); |
| @@ -162,7 +221,6 @@ struct ImageCacheEntryMetadata { |
| SkColor fill_color; // Both colors only needed by MD |
| SkColor stroke_color; |
| bool use_fill_and_stroke_images; |
| - ui::ScaleFactor scale_factor; |
| gfx::Size size; |
| }; |
| @@ -171,16 +229,12 @@ ImageCacheEntryMetadata::ImageCacheEntryMetadata( |
| SkColor fill_color, |
| SkColor stroke_color, |
| bool use_fill_and_stroke_images, |
| - ui::ScaleFactor scale_factor, |
| const gfx::Size& size) |
| : resource_id(resource_id), |
| fill_color(fill_color), |
| stroke_color(stroke_color), |
| use_fill_and_stroke_images(use_fill_and_stroke_images), |
| - scale_factor(scale_factor), |
| size(size) { |
| - DCHECK_NE(ui::SCALE_FACTOR_NONE, scale_factor); |
| - |
| // Some fields are only relevant for pre-MD vs. MD. Erase the irrelevant ones |
| // so they don't cause incorrect cache misses. |
| // TODO(pkasting): Remove |resource_id| field when non-MD code is deleted. |
| @@ -197,7 +251,7 @@ bool ImageCacheEntryMetadata::operator==( |
| return resource_id == rhs.resource_id && fill_color == rhs.fill_color && |
| stroke_color == rhs.stroke_color && |
| use_fill_and_stroke_images == rhs.use_fill_and_stroke_images && |
| - scale_factor == rhs.scale_factor && size == rhs.size; |
| + size == rhs.size; |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| @@ -206,8 +260,9 @@ bool ImageCacheEntryMetadata::operator==( |
| // A cached image and the metadata used to generate it. |
| struct ImageCacheEntry { |
| ImageCacheEntry(const ImageCacheEntryMetadata& metadata, |
| - const gfx::ImageSkia& fill_image, |
| - const gfx::ImageSkia& stroke_image); |
| + Tab* tab, |
| + int fill_id, |
| + int y_offset); |
| ~ImageCacheEntry(); |
| ImageCacheEntryMetadata metadata; |
| @@ -216,9 +271,21 @@ struct ImageCacheEntry { |
| }; |
| ImageCacheEntry::ImageCacheEntry(const ImageCacheEntryMetadata& metadata, |
| - const gfx::ImageSkia& fill_image, |
| - const gfx::ImageSkia& stroke_image) |
| - : metadata(metadata), fill_image(fill_image), stroke_image(stroke_image) {} |
| + Tab* tab, |
| + int fill_id, |
| + int y_offset) |
| + : metadata(metadata) { |
| + if (metadata.use_fill_and_stroke_images) { |
| + fill_image = gfx::ImageSkia( |
| + new TabImageSource(TabImageSource::FILL, tab, fill_id, y_offset), |
| + tab->size()); |
| + } |
| + TabImageSource::UseCanvas use = metadata.use_fill_and_stroke_images |
| + ? TabImageSource::STROKE |
| + : TabImageSource::BOTH; |
| + stroke_image = gfx::ImageSkia(new TabImageSource(use, tab, fill_id, y_offset), |
| + tab->size()); |
| +} |
| ImageCacheEntry::~ImageCacheEntry() {} |
| @@ -483,17 +550,13 @@ void PaintTabFill(gfx::Canvas* canvas, |
| void PaintTabBackgroundUsingParams(gfx::Canvas* fill_canvas, |
| gfx::Canvas* stroke_canvas, |
| - views::GlowHoverController* hc, |
| const PaintBackgroundParams& params) { |
| const gfx::Rect& rect = params.rect; |
| const SkScalar kMinHoverRadius = 16; |
| const SkScalar radius = |
| std::max(SkFloatToScalar(rect.width() / 4.f), kMinHoverRadius); |
| - const bool draw_hover = !params.is_active && hc; |
| - SkPoint hover_location( |
| - gfx::PointToSkPoint(draw_hover ? hc->location() : gfx::Point())); |
| const SkColor hover_color = |
| - SkColorSetA(params.toolbar_color, draw_hover ? hc->GetAlpha() : 255); |
| + SkColorSetA(params.toolbar_color, params.hover_alpha); |
| if (ui::MaterialDesignController::IsModeMaterial()) { |
| gfx::Path fill; |
| @@ -501,7 +564,7 @@ void PaintTabBackgroundUsingParams(gfx::Canvas* fill_canvas, |
| paint.setAntiAlias(true); |
| // Draw the fill. |
| - { |
| + if (fill_canvas) { |
| gfx::ScopedCanvas scoped_canvas(fill_canvas); |
| const float scale = fill_canvas->UndoDeviceScaleFactor(); |
| @@ -521,16 +584,15 @@ void PaintTabBackgroundUsingParams(gfx::Canvas* fill_canvas, |
| gfx::ScaleToEnclosingRect(gfx::Rect(rect.size()), scale), |
| paint); |
| } |
| - if (draw_hover) { |
| - hover_location.scale(SkFloatToScalar(scale)); |
| - DrawHighlight(fill_canvas, hover_location, radius * scale, |
| - hover_color); |
| + if (params.draw_hover) { |
| + DrawHighlight(fill_canvas, params.hover_location * scale, |
| + radius * scale, hover_color); |
| } |
| } |
| } |
| // Draw the stroke. |
| - { |
| + if (stroke_canvas) { |
| gfx::ScopedCanvas scoped_canvas(stroke_canvas); |
| const float scale = stroke_canvas->UndoDeviceScaleFactor(); |
| @@ -547,7 +609,7 @@ void PaintTabBackgroundUsingParams(gfx::Canvas* fill_canvas, |
| } |
| } else { |
| gfx::Canvas* canvas = stroke_canvas; |
| - if (draw_hover) { |
| + if (params.draw_hover) { |
| // Draw everything to a temporary canvas so we can extract an image for |
| // use in masking the hover glow. |
| gfx::Canvas background_canvas(rect.size(), canvas->image_scale(), false); |
| @@ -557,7 +619,7 @@ void PaintTabBackgroundUsingParams(gfx::Canvas* fill_canvas, |
| canvas->DrawImageInt(background_image, 0, 0); |
| gfx::Canvas hover_canvas(rect.size(), canvas->image_scale(), false); |
| - DrawHighlight(&hover_canvas, hover_location, radius, hover_color); |
| + DrawHighlight(&hover_canvas, params.hover_location, radius, hover_color); |
| gfx::ImageSkia result = gfx::ImageSkiaOperations::CreateMaskedImage( |
| gfx::ImageSkia(hover_canvas.ExtractImageRep()), background_image); |
| canvas->DrawImageInt(result, 0, 0); |
| @@ -1522,26 +1584,12 @@ void Tab::PaintInactiveTabBackground(gfx::Canvas* canvas, |
| const ImageCacheEntryMetadata metadata( |
| fill_id, tp->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB), |
| controller_->GetToolbarTopSeparatorColor(), use_fill_and_stroke_images, |
| - ui::GetSupportedScaleFactor(canvas->image_scale()), size()); |
| + size()); |
| auto it = std::find_if( |
| g_image_cache->begin(), g_image_cache->end(), |
| [&metadata](const ImageCacheEntry& e) { return e.metadata == metadata; }); |
| if (it == g_image_cache->end()) { |
| - gfx::Canvas tmp_canvas(size(), canvas->image_scale(), false); |
| - if (use_fill_and_stroke_images) { |
| - gfx::Canvas tmp_fill_canvas(size(), canvas->image_scale(), false); |
| - PaintTabBackgroundUsingFillId(&tmp_fill_canvas, &tmp_canvas, false, |
| - fill_id, false, y_offset); |
| - g_image_cache->emplace_front( |
| - metadata, gfx::ImageSkia(tmp_fill_canvas.ExtractImageRep()), |
| - gfx::ImageSkia(tmp_canvas.ExtractImageRep())); |
| - } else { |
| - PaintTabBackgroundUsingFillId(&tmp_canvas, &tmp_canvas, false, fill_id, |
| - false, y_offset); |
| - g_image_cache->emplace_front( |
| - metadata, gfx::ImageSkia(), |
| - gfx::ImageSkia(tmp_canvas.ExtractImageRep())); |
| - } |
| + g_image_cache->emplace_front(metadata, this, fill_id, y_offset); |
| if (g_image_cache->size() > kMaxImageCacheSize) |
| g_image_cache->pop_back(); |
| it = g_image_cache->begin(); |
| @@ -1562,8 +1610,6 @@ void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* fill_canvas, |
| int fill_id, |
| bool has_custom_image, |
| int y_offset) { |
| - views::GlowHoverController* hc = |
| - hover_controller_.ShouldDraw() ? &hover_controller_ : nullptr; |
| gfx::ImageSkia* fill_image = |
| has_custom_image || !ui::MaterialDesignController::IsModeMaterial() |
| ? GetThemeProvider()->GetImageSkiaNamed(fill_id) |
| @@ -1577,9 +1623,11 @@ void Tab::PaintTabBackgroundUsingFillId(gfx::Canvas* fill_canvas, |
| is_active, fill_image, has_custom_image, rect, |
| controller_->GetToolbarTopSeparatorColor(), |
| GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR), |
| - GetThemeProvider()->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB)); |
| + GetThemeProvider()->GetColor(ThemeProperties::COLOR_BACKGROUND_TAB), |
| + !is_active && hover_controller_.ShouldDraw(), |
| + hover_controller_.location(), hover_controller_.GetAlpha()); |
| - PaintTabBackgroundUsingParams(fill_canvas, stroke_canvas, hc, params); |
| + PaintTabBackgroundUsingParams(fill_canvas, stroke_canvas, params); |
| } |
| void Tab::PaintPinnedTabTitleChangedIndicatorAndIcon( |