Refactor cc painted scrollbar
- Remove unused cc/layers/scrollbar_theme_painter.h
- Add comments in cc::Scrollbar
- Remove rect parameter from cc::Scrollbar::PaintPart() because the
rect can be easily calculated by blink, given that the coordinate
space of the canvas is clearly defined
- Improve performance of blink::ScrollbarLayerDelegate::HasTickMarks
(implementation of cc::Scrollbar::HasTickMarks()). The old
implementation queried all tick marks and see if it was empty, which
may be slow when there are a lot of tick marks (e.g. when searching
in a huge document).
- Add blink::ScrollbarTheme::PaintTrackAndButtonsForCompositor() to
avoid exposing too much details of ScrollbarTheme to outside.
This is a preparation for CompositeAfterPaint composited scrollbar
implementation.
Change-Id: Ibf8c7a90d80ddf972f215495d0fd89470fa2deb4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1834286
Reviewed-by: Philip Rogers <pdr@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#702201}
diff --git a/build/check_gn_headers_whitelist.txt b/build/check_gn_headers_whitelist.txt
index 0d8df0a..a6805c9 100644
--- a/build/check_gn_headers_whitelist.txt
+++ b/build/check_gn_headers_whitelist.txt
@@ -25,7 +25,6 @@
cc/input/scrollbar.h
cc/input/scroller_size_metrics.h
cc/layers/performance_properties.h
-cc/layers/scrollbar_theme_painter.h
cc/output/bsp_compare_result.h
cc/resources/release_callback_impl.h
cc/resources/return_callback.h
diff --git a/cc/input/scrollbar.h b/cc/input/scrollbar.h
index 5a35ed8..4c739c6 100644
--- a/cc/input/scrollbar.h
+++ b/cc/input/scrollbar.h
@@ -30,7 +30,6 @@
namespace cc {
enum ScrollbarOrientation { HORIZONTAL, VERTICAL };
-enum ScrollDirection { SCROLL_BACKWARD, SCROLL_FORWARD };
enum ScrollbarPart {
THUMB,
@@ -55,15 +54,26 @@
virtual bool SupportsDragSnapBack() const = 0;
virtual int ThumbThickness() const = 0;
virtual int ThumbLength() const = 0;
+
+ // Returns the track rect relative to the scrollbar's origin.
virtual gfx::Rect TrackRect() const = 0;
+ // Returns the back button rect relative to the scrollbar's origin.
virtual gfx::Rect BackButtonRect() const = 0;
+ // Returns the forward button rect relative to the scrollbar's origin.
virtual gfx::Rect ForwardButtonRect() const = 0;
+
virtual float ThumbOpacity() const = 0;
virtual bool HasTickmarks() const = 0;
+
+ // Whether we need to repaint the part. Only THUMB and TRACK are supported.
+ // For TRACK, the return value means that the track, any buttons or tickmarks
+ // need repaint.
virtual bool NeedsPaintPart(ScrollbarPart part) const = 0;
- virtual void PaintPart(PaintCanvas* canvas,
- ScrollbarPart part,
- const gfx::Rect& content_rect) = 0;
+ // Paints the part. Only THUMB, TRACK and TICKMARKS are supported. When TRACK
+ // is specified, track, buttons and tickmarks will be painted. The canvas's
+ // coordinate space is relative to the part's origin.
+ virtual void PaintPart(PaintCanvas* canvas, ScrollbarPart part) = 0;
+
virtual bool UsesNinePatchThumbResource() const = 0;
virtual gfx::Size NinePatchThumbCanvasSize() const = 0;
virtual gfx::Rect NinePatchThumbAperture() const = 0;
diff --git a/cc/layers/painted_overlay_scrollbar_layer.cc b/cc/layers/painted_overlay_scrollbar_layer.cc
index e6fcf5f..14faa69 100644
--- a/cc/layers/painted_overlay_scrollbar_layer.cc
+++ b/cc/layers/painted_overlay_scrollbar_layer.cc
@@ -44,6 +44,8 @@
scroll_element_id_(scroll_element_id),
thumb_thickness_(scrollbar_->ThumbThickness()),
thumb_length_(scrollbar_->ThumbLength()) {
+ DCHECK(scrollbar_->HasThumb());
+ DCHECK(scrollbar_->IsOverlay());
DCHECK(scrollbar_->UsesNinePatchThumbResource());
SetIsScrollbar(true);
}
@@ -117,9 +119,6 @@
bool updated = false;
updated |= Layer::Update();
- DCHECK(scrollbar_->HasThumb());
- DCHECK(scrollbar_->IsOverlay());
- DCHECK(scrollbar_->UsesNinePatchThumbResource());
updated |= UpdateProperty(scrollbar_->TrackRect(), &track_rect_);
updated |= UpdateProperty(scrollbar_->Location(), &location_);
updated |= UpdateProperty(scrollbar_->ThumbThickness(), &thumb_thickness_);
@@ -143,15 +142,9 @@
SkBitmap skbitmap;
skbitmap.allocN32Pixels(paint_rect.width(), paint_rect.height());
SkiaPaintCanvas canvas(skbitmap);
+ canvas.clear(SK_ColorTRANSPARENT);
- SkRect content_skrect = RectToSkRect(paint_rect);
- PaintFlags flags;
- flags.setAntiAlias(false);
- flags.setBlendMode(SkBlendMode::kClear);
- canvas.drawRect(content_skrect, flags);
- canvas.clipRect(content_skrect);
-
- scrollbar_->PaintPart(&canvas, THUMB, paint_rect);
+ scrollbar_->PaintPart(&canvas, THUMB);
// Make sure that the pixels are no longer mutable to unavoid unnecessary
// allocation and copying.
skbitmap.setImmutable();
@@ -183,15 +176,9 @@
SkBitmap skbitmap;
skbitmap.allocN32Pixels(paint_rect.width(), paint_rect.height());
SkiaPaintCanvas canvas(skbitmap);
+ canvas.clear(SK_ColorTRANSPARENT);
- SkRect content_skrect = RectToSkRect(paint_rect);
- PaintFlags flags;
- flags.setAntiAlias(false);
- flags.setBlendMode(SkBlendMode::kClear);
- canvas.drawRect(content_skrect, flags);
- canvas.clipRect(content_skrect);
-
- scrollbar_->PaintPart(&canvas, TICKMARKS, paint_rect);
+ scrollbar_->PaintPart(&canvas, TICKMARKS);
// Make sure that the pixels are no longer mutable to unavoid unnecessary
// allocation and copying.
skbitmap.setImmutable();
diff --git a/cc/layers/painted_overlay_scrollbar_layer.h b/cc/layers/painted_overlay_scrollbar_layer.h
index 931d96c..0f7ee5e 100644
--- a/cc/layers/painted_overlay_scrollbar_layer.h
+++ b/cc/layers/painted_overlay_scrollbar_layer.h
@@ -9,7 +9,6 @@
#include "cc/input/scrollbar.h"
#include "cc/layers/layer.h"
#include "cc/layers/scrollbar_layer_interface.h"
-#include "cc/layers/scrollbar_theme_painter.h"
#include "cc/resources/scoped_ui_resource.h"
namespace cc {
diff --git a/cc/layers/painted_overlay_scrollbar_layer_unittest.cc b/cc/layers/painted_overlay_scrollbar_layer_unittest.cc
index db2867d..e1a77c3a 100644
--- a/cc/layers/painted_overlay_scrollbar_layer_unittest.cc
+++ b/cc/layers/painted_overlay_scrollbar_layer_unittest.cc
@@ -19,9 +19,7 @@
public:
MockScrollbar() : FakeScrollbar(true, true, true) {}
- void PaintPart(PaintCanvas* canvas,
- ScrollbarPart part,
- const gfx::Rect& content_rect) override {
+ void PaintPart(PaintCanvas* canvas, ScrollbarPart part) override {
if (part == TICKMARKS)
paint_tickmarks_called_ = true;
}
diff --git a/cc/layers/painted_scrollbar_layer.cc b/cc/layers/painted_scrollbar_layer.cc
index 96ece18..16e7b4f 100644
--- a/cc/layers/painted_scrollbar_layer.cc
+++ b/cc/layers/painted_scrollbar_layer.cc
@@ -263,13 +263,8 @@
float scale_y =
content_rect.height() / static_cast<float>(layer_rect.height());
canvas.scale(SkFloatToScalar(scale_x), SkFloatToScalar(scale_y));
- // TODO(pdr): Scrollbars are painted with an offset (see Scrollbar::PaintPart)
- // and the canvas is translated so that scrollbars are drawn at the origin.
- // Refactor this code to not use an offset at all so Scrollbar::PaintPart
- // paints at the origin and no translation is needed below.
- canvas.translate(-layer_rect.x(), -layer_rect.y());
- scrollbar_->PaintPart(&canvas, part, layer_rect);
+ scrollbar_->PaintPart(&canvas, part);
// Make sure that the pixels are no longer mutable to unavoid unnecessary
// allocation and copying.
skbitmap.setImmutable();
diff --git a/cc/layers/painted_scrollbar_layer.h b/cc/layers/painted_scrollbar_layer.h
index c2f21c8b..8ba7bc7c 100644
--- a/cc/layers/painted_scrollbar_layer.h
+++ b/cc/layers/painted_scrollbar_layer.h
@@ -9,7 +9,6 @@
#include "cc/input/scrollbar.h"
#include "cc/layers/layer.h"
#include "cc/layers/scrollbar_layer_interface.h"
-#include "cc/layers/scrollbar_theme_painter.h"
#include "cc/resources/scoped_ui_resource.h"
namespace cc {
diff --git a/cc/layers/painted_scrollbar_layer_unittest.cc b/cc/layers/painted_scrollbar_layer_unittest.cc
index ee0c030..1852f64 100644
--- a/cc/layers/painted_scrollbar_layer_unittest.cc
+++ b/cc/layers/painted_scrollbar_layer_unittest.cc
@@ -21,11 +21,11 @@
class MockScrollbar : public FakeScrollbar {
public:
- MockScrollbar() : FakeScrollbar(true, true, true) {}
- MOCK_METHOD3(PaintPart,
- void(PaintCanvas* canvas,
- ScrollbarPart part,
- const gfx::Rect& content_rect));
+ MockScrollbar()
+ : FakeScrollbar(/*paint*/ true,
+ /*has_thumb*/ true,
+ /*is_overlay*/ false) {}
+ MOCK_METHOD2(PaintPart, void(PaintCanvas* canvas, ScrollbarPart part));
};
TEST(PaintedScrollbarLayerTest, NeedsPaint) {
@@ -52,28 +52,28 @@
// yet been initialized.
scrollbar->set_needs_paint_thumb(false);
scrollbar->set_needs_paint_track(false);
- EXPECT_CALL(*scrollbar, PaintPart(_, THUMB, _)).Times(1);
- EXPECT_CALL(*scrollbar, PaintPart(_, TRACK, _)).Times(1);
+ EXPECT_CALL(*scrollbar, PaintPart(_, THUMB)).Times(1);
+ EXPECT_CALL(*scrollbar, PaintPart(_, TRACK)).Times(1);
scrollbar_layer->Update();
Mock::VerifyAndClearExpectations(scrollbar);
// The next update will paint nothing because the first update caused a paint.
- EXPECT_CALL(*scrollbar, PaintPart(_, THUMB, _)).Times(0);
- EXPECT_CALL(*scrollbar, PaintPart(_, TRACK, _)).Times(0);
+ EXPECT_CALL(*scrollbar, PaintPart(_, THUMB)).Times(0);
+ EXPECT_CALL(*scrollbar, PaintPart(_, TRACK)).Times(0);
scrollbar_layer->Update();
Mock::VerifyAndClearExpectations(scrollbar);
// Enable the thumb.
- EXPECT_CALL(*scrollbar, PaintPart(_, THUMB, _)).Times(1);
- EXPECT_CALL(*scrollbar, PaintPart(_, TRACK, _)).Times(0);
+ EXPECT_CALL(*scrollbar, PaintPart(_, THUMB)).Times(1);
+ EXPECT_CALL(*scrollbar, PaintPart(_, TRACK)).Times(0);
scrollbar->set_needs_paint_thumb(true);
scrollbar->set_needs_paint_track(false);
scrollbar_layer->Update();
Mock::VerifyAndClearExpectations(scrollbar);
// Enable the track.
- EXPECT_CALL(*scrollbar, PaintPart(_, THUMB, _)).Times(0);
- EXPECT_CALL(*scrollbar, PaintPart(_, TRACK, _)).Times(1);
+ EXPECT_CALL(*scrollbar, PaintPart(_, THUMB)).Times(0);
+ EXPECT_CALL(*scrollbar, PaintPart(_, TRACK)).Times(1);
scrollbar->set_needs_paint_thumb(false);
scrollbar->set_needs_paint_track(true);
scrollbar_layer->Update();
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc
index 678551a..7f6c086f 100644
--- a/cc/layers/scrollbar_layer_unittest.cc
+++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -254,6 +254,9 @@
class FakeNinePatchScrollbar : public FakeScrollbar {
public:
+ FakeNinePatchScrollbar()
+ : FakeScrollbar(/*paint*/ true, /*has_thumb*/ true, /*is_overlay*/ true) {
+ }
bool UsesNinePatchThumbResource() const override { return true; }
};
@@ -1354,7 +1357,8 @@
scrollbar_layer->SetBounds(scrollbar_rect.size());
scrollbar_layer->SetPosition(gfx::PointF(scrollbar_rect.origin()));
scrollbar_layer->fake_scrollbar()->set_location(scrollbar_rect.origin());
- scrollbar_layer->fake_scrollbar()->set_track_rect(scrollbar_rect);
+ scrollbar_layer->fake_scrollbar()->set_track_rect(
+ gfx::Rect(scrollbar_rect.size()));
layer_tree_host_->SetViewportRectAndScale(
layer_tree_host_->device_viewport_rect(), test_scale,
diff --git a/cc/layers/scrollbar_theme_painter.h b/cc/layers/scrollbar_theme_painter.h
deleted file mode 100644
index 2733f44..0000000
--- a/cc/layers/scrollbar_theme_painter.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_LAYERS_SCROLLBAR_THEME_PAINTER_H_
-#define CC_LAYERS_SCROLLBAR_THEME_PAINTER_H_
-
-#include "cc/cc_export.h"
-
-class SkCanvas;
-
-namespace gfx {
-class Rect;
-}
-
-namespace cc {
-
-class CC_EXPORT ScrollbarThemePainter {
- public:
- virtual ~ScrollbarThemePainter() {}
-
- virtual void PaintScrollbarBackground(SkCanvas* canvas,
- const gfx::Rect& rect) = 0;
- virtual void PaintTrackBackground(SkCanvas* canvas,
- const gfx::Rect& rect) = 0;
- virtual void PaintBackTrackPart(SkCanvas* canvas,
- const gfx::Rect& rect) = 0;
- virtual void PaintForwardTrackPart(SkCanvas* canvas,
- const gfx::Rect& rect) = 0;
- virtual void PaintBackButtonStart(SkCanvas* canvas,
- const gfx::Rect& rect) = 0;
- virtual void PaintBackButtonEnd(SkCanvas* canvas,
- const gfx::Rect& rect) = 0;
- virtual void PaintForwardButtonStart(SkCanvas* canvas,
- const gfx::Rect& rect) = 0;
- virtual void PaintForwardButtonEnd(SkCanvas* canvas,
- const gfx::Rect& rect) = 0;
- virtual void PaintTickmarks(SkCanvas* canvas, const gfx::Rect& rect) = 0;
- virtual void PaintThumb(SkCanvas* canvas, const gfx::Rect& rect) = 0;
-};
-
-} // namespace cc
-
-#endif // CC_LAYERS_SCROLLBAR_THEME_PAINTER_H_
diff --git a/cc/test/fake_scrollbar.cc b/cc/test/fake_scrollbar.cc
index d8f0a47..6da534ef 100644
--- a/cc/test/fake_scrollbar.cc
+++ b/cc/test/fake_scrollbar.cc
@@ -88,9 +88,7 @@
return has_tickmarks_;
}
-void FakeScrollbar::PaintPart(PaintCanvas* canvas,
- ScrollbarPart part,
- const gfx::Rect& content_rect) {
+void FakeScrollbar::PaintPart(PaintCanvas* canvas, ScrollbarPart part) {
if (!paint_)
return;
@@ -100,12 +98,7 @@
flags.setAntiAlias(false);
flags.setColor(paint_fill_color());
flags.setStyle(PaintFlags::kFill_Style);
-
- // Emulate the how the real scrollbar works by using scrollbar's rect for
- // TRACK and the given content_rect for the THUMB
- SkRect rect = part == TRACK ? RectToSkRect(TrackRect())
- : RectToSkRect(content_rect);
- canvas->drawRect(rect, flags);
+ canvas->drawRect(RectToSkRect(GetPartRect(part)), flags);
}
bool FakeScrollbar::UsesNinePatchThumbResource() const {
@@ -120,4 +113,23 @@
return gfx::Rect();
}
+gfx::Rect FakeScrollbar::GetPartRect(ScrollbarPart part) const {
+ switch (part) {
+ case THUMB:
+ if (UsesNinePatchThumbResource())
+ return gfx::Rect(NinePatchThumbCanvasSize());
+ if (Orientation() == VERTICAL)
+ return gfx::Rect(ThumbThickness(), ThumbLength());
+ return gfx::Rect(ThumbLength(), ThumbThickness());
+ case TRACK:
+ return gfx::UnionRects(
+ TrackRect(), gfx::UnionRects(BackButtonRect(), ForwardButtonRect()));
+ case TICKMARKS:
+ return gfx::Rect(TrackRect().size());
+ default:
+ NOTREACHED();
+ return gfx::Rect();
+ }
+}
+
} // namespace cc
diff --git a/cc/test/fake_scrollbar.h b/cc/test/fake_scrollbar.h
index 84648c80..86f6203 100644
--- a/cc/test/fake_scrollbar.h
+++ b/cc/test/fake_scrollbar.h
@@ -40,9 +40,7 @@
float ThumbOpacity() const override;
bool NeedsPaintPart(ScrollbarPart part) const override;
bool HasTickmarks() const override;
- void PaintPart(PaintCanvas* canvas,
- ScrollbarPart part,
- const gfx::Rect& content_rect) override;
+ void PaintPart(PaintCanvas* canvas, ScrollbarPart part) override;
bool UsesNinePatchThumbResource() const override;
gfx::Size NinePatchThumbCanvasSize() const override;
gfx::Rect NinePatchThumbAperture() const override;
@@ -65,6 +63,8 @@
}
void set_has_tickmarks(bool has_tickmarks) { has_tickmarks_ = has_tickmarks; }
+ gfx::Rect GetPartRect(ScrollbarPart part) const;
+
private:
bool paint_;
bool has_thumb_;
diff --git a/cc/trees/layer_tree_host_pixeltest_scrollbars.cc b/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
index 131dba0..4be54575 100644
--- a/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
+++ b/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
@@ -11,6 +11,7 @@
#include "cc/layers/solid_color_layer.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
+#include "cc/test/fake_scrollbar.h"
#include "cc/test/layer_tree_pixel_test.h"
#include "cc/test/pixel_comparator.h"
#include "cc/trees/layer_tree_impl.h"
@@ -38,33 +39,23 @@
float device_scale_factor_ = 1.f;
};
-class PaintedScrollbar : public Scrollbar {
+class PaintedScrollbar : public FakeScrollbar {
public:
- ~PaintedScrollbar() override = default;
+ explicit PaintedScrollbar(const gfx::Size& size)
+ : FakeScrollbar(/*paint*/ true,
+ /*has_thumb*/ false,
+ HORIZONTAL,
+ /*is_left_side_vertical_scrollbar*/ false,
+ /*is_overlay*/ false) {
+ set_track_rect(gfx::Rect(size));
+ }
- ScrollbarOrientation Orientation() const override { return VERTICAL; }
- bool IsLeftSideVerticalScrollbar() const override { return false; }
- gfx::Point Location() const override { return gfx::Point(); }
- bool IsOverlay() const override { return false; }
- bool HasThumb() const override { return thumb_; }
- int ThumbThickness() const override { return rect_.width(); }
- int ThumbLength() const override { return rect_.height(); }
- gfx::Rect TrackRect() const override { return rect_; }
- gfx::Rect BackButtonRect() const override { return rect_; }
- gfx::Rect ForwardButtonRect() const override { return rect_; }
- bool SupportsDragSnapBack() const override { return false; }
- float ThumbOpacity() const override { return 1.f; }
- bool NeedsPaintPart(ScrollbarPart part) const override { return true; }
- bool HasTickmarks() const override { return false; }
- void PaintPart(PaintCanvas* canvas,
- ScrollbarPart part,
- const gfx::Rect& content_rect) override {
+ void PaintPart(PaintCanvas* canvas, ScrollbarPart part) override {
PaintFlags flags;
flags.setStyle(PaintFlags::kStroke_Style);
flags.setStrokeWidth(SkIntToScalar(paint_scale_));
flags.setColor(color_);
-
- gfx::Rect inset_rect = content_rect;
+ gfx::Rect inset_rect = GetPartRect(part);
while (!inset_rect.IsEmpty()) {
int big = paint_scale_ + 2;
int small = paint_scale_;
@@ -73,17 +64,12 @@
inset_rect.Inset(big, big, small, small);
}
}
- bool UsesNinePatchThumbResource() const override { return false; }
- gfx::Size NinePatchThumbCanvasSize() const override { return gfx::Size(); }
- gfx::Rect NinePatchThumbAperture() const override { return gfx::Rect(); }
void set_paint_scale(int scale) { paint_scale_ = scale; }
private:
int paint_scale_ = 4;
- bool thumb_ = false;
SkColor color_ = SK_ColorGREEN;
- gfx::Rect rect_;
};
LayerTreeTest::RendererType const kRendererTypes[] = {
@@ -102,7 +88,7 @@
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
- auto scrollbar = std::make_unique<PaintedScrollbar>();
+ auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(200, 200));
scoped_refptr<PaintedScrollbarLayer> layer =
PaintedScrollbarLayer::Create(std::move(scrollbar));
layer->SetIsDrawable(true);
@@ -121,7 +107,7 @@
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE);
- auto scrollbar = std::make_unique<PaintedScrollbar>();
+ auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(100, 100));
scoped_refptr<PaintedScrollbarLayer> layer =
PaintedScrollbarLayer::Create(std::move(scrollbar));
layer->SetIsDrawable(true);
@@ -136,7 +122,7 @@
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
- auto scrollbar = std::make_unique<PaintedScrollbar>();
+ auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(100, 100));
scoped_refptr<PaintedScrollbarLayer> layer =
PaintedScrollbarLayer::Create(std::move(scrollbar));
layer->SetIsDrawable(true);
@@ -163,7 +149,7 @@
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorWHITE);
- auto scrollbar = std::make_unique<PaintedScrollbar>();
+ auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(10, 400));
scrollbar->set_paint_scale(1);
scoped_refptr<PaintedScrollbarLayer> layer =
PaintedScrollbarLayer::Create(std::move(scrollbar));
@@ -216,18 +202,20 @@
float thickness_scale_;
};
-class PaintedOverlayScrollbar : public PaintedScrollbar {
+class PaintedOverlayScrollbar : public FakeScrollbar {
public:
- ~PaintedOverlayScrollbar() override = default;
+ PaintedOverlayScrollbar()
+ : FakeScrollbar(/*paint*/ true,
+ /*has_thumb*/ true,
+ VERTICAL,
+ /*is_left_side_vertical_scrollbar*/ false,
+ /*is_overlay*/ true) {
+ set_thumb_thickness(15);
+ set_thumb_length(50);
+ set_track_rect(gfx::Rect(0, 0, 15, 400));
+ }
- int ThumbThickness() const override { return 15; }
- int ThumbLength() const override { return 50; }
- gfx::Rect TrackRect() const override { return gfx::Rect(0, 0, 15, 400); }
- bool HasThumb() const override { return true; }
- bool IsOverlay() const override { return true; }
- void PaintPart(PaintCanvas* canvas,
- ScrollbarPart part,
- const gfx::Rect& content_rect) override {
+ void PaintPart(PaintCanvas* canvas, ScrollbarPart part) override {
// The outside of the rect will be painted with a 1 pixel black, red, then
// blue border. The inside will be solid blue. This will allow the test to
// ensure that scaling the thumb doesn't scale the border at all. Note
@@ -238,8 +226,7 @@
flags.setStrokeWidth(SkIntToScalar(1));
flags.setColor(SK_ColorBLACK);
- gfx::Rect inset_rect = content_rect;
-
+ gfx::Rect inset_rect = GetPartRect(part);
canvas->drawRect(RectToSkRect(inset_rect), flags);
flags.setColor(SK_ColorRED);
@@ -250,6 +237,7 @@
inset_rect.Inset(1, 1);
canvas->drawRect(RectToSkRect(inset_rect), flags);
}
+
bool UsesNinePatchThumbResource() const override { return true; }
gfx::Size NinePatchThumbCanvasSize() const override {
return gfx::Size(7, 7);
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc
index 023cfc5..aa9a8dc 100644
--- a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc
+++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc
@@ -679,6 +679,10 @@
return markers_to_paint;
}
+bool DocumentMarkerController::PossiblyHasTextMatchMarkers() const {
+ return PossiblyHasMarkers(DocumentMarker::kTextMatch);
+}
+
Vector<IntRect> DocumentMarkerController::LayoutRectsForTextMatchMarkers() {
DCHECK(!document_->View()->NeedsLayout());
DCHECK(!document_->NeedsLayoutTreeUpdate());
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller.h b/third_party/blink/renderer/core/editing/markers/document_marker_controller.h
index 20d0a08..f9d2b4f 100644
--- a/third_party/blink/renderer/core/editing/markers/document_marker_controller.h
+++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller.h
@@ -143,6 +143,7 @@
DocumentMarkerVector Markers() const;
DocumentMarkerVector ComputeMarkersToPaint(const Text&) const;
+ bool PossiblyHasTextMatchMarkers() const;
Vector<IntRect> LayoutRectsForTextMatchMarkers();
void InvalidateRectsForAllTextMatchMarkers();
void InvalidateRectsForTextMatchMarkersInNode(const Text&);
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc
index ad99877..b3c8bf5 100644
--- a/third_party/blink/renderer/core/exported/web_frame_test.cc
+++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -5220,8 +5220,7 @@
// Get the tickmarks for the original find request.
LocalFrameView* frame_view = web_view_helper.LocalMainFrame()->GetFrameView();
ScrollableArea* layout_viewport = frame_view->LayoutViewport();
- Vector<IntRect> original_tickmarks;
- layout_viewport->GetTickmarks(original_tickmarks);
+ Vector<IntRect> original_tickmarks = layout_viewport->GetTickmarks();
EXPECT_EQ(4u, original_tickmarks.size());
// Override the tickmarks.
@@ -5232,8 +5231,7 @@
main_frame->SetTickmarks(overriding_tickmarks_expected);
// Check the tickmarks are overriden correctly.
- Vector<IntRect> overriding_tickmarks_actual;
- layout_viewport->GetTickmarks(overriding_tickmarks_actual);
+ Vector<IntRect> overriding_tickmarks_actual = layout_viewport->GetTickmarks();
EXPECT_EQ(overriding_tickmarks_expected, overriding_tickmarks_actual);
// Reset the tickmark behavior.
@@ -5241,8 +5239,8 @@
main_frame->SetTickmarks(reset_tickmarks);
// Check that the original tickmarks are returned
- Vector<IntRect> original_tickmarks_after_reset;
- layout_viewport->GetTickmarks(original_tickmarks_after_reset);
+ Vector<IntRect> original_tickmarks_after_reset =
+ layout_viewport->GetTickmarks();
EXPECT_EQ(original_tickmarks, original_tickmarks_after_reset);
}
@@ -11379,8 +11377,8 @@
search_text, *options);
// Get the tickmarks for the original find request.
- Vector<IntRect> original_tickmarks;
- frame_view->LayoutViewport()->GetTickmarks(original_tickmarks);
+ Vector<IntRect> original_tickmarks =
+ frame_view->LayoutViewport()->GetTickmarks();
EXPECT_EQ(1u, original_tickmarks.size());
EXPECT_EQ(IntPoint(800, 2000), original_tickmarks[0].Location());
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc
index f709c11..30ebb63 100644
--- a/third_party/blink/renderer/core/layout/layout_view.cc
+++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -900,6 +900,11 @@
}
}
+bool LayoutView::HasTickmarks() const {
+ return !tickmarks_override_.IsEmpty() ||
+ GetDocument().Markers().PossiblyHasTextMatchMarkers();
+}
+
Vector<IntRect> LayoutView::GetTickmarks() const {
if (!tickmarks_override_.IsEmpty())
return tickmarks_override_;
diff --git a/third_party/blink/renderer/core/layout/layout_view.h b/third_party/blink/renderer/core/layout/layout_view.h
index ca4d4bb..4b32f408 100644
--- a/third_party/blink/renderer/core/layout/layout_view.h
+++ b/third_party/blink/renderer/core/layout/layout_view.h
@@ -243,8 +243,9 @@
PhysicalRect DebugRect() const override;
// Returns the coordinates of find-in-page scrollbar tickmarks. These come
- // from DocumentMarkerController, unless overridden by SetTickmarks.
+ // from DocumentMarkerController, unless overridden by OverrideTickmarks().
Vector<IntRect> GetTickmarks() const;
+ bool HasTickmarks() const;
// Sets the coordinates of find-in-page scrollbar tickmarks, bypassing
// DocumentMarkerController. This is used by the PDF plugin.
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index 985bb9b..d46dfac5 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -2332,9 +2332,14 @@
->GetCompositorAnimationTimeline();
}
-void PaintLayerScrollableArea::GetTickmarks(Vector<IntRect>& tickmarks) const {
+bool PaintLayerScrollableArea::HasTickmarks() const {
+ return layer_->IsRootLayer() && ToLayoutView(GetLayoutBox())->HasTickmarks();
+}
+
+Vector<IntRect> PaintLayerScrollableArea::GetTickmarks() const {
if (layer_->IsRootLayer())
- tickmarks = ToLayoutView(GetLayoutBox())->GetTickmarks();
+ return ToLayoutView(GetLayoutBox())->GetTickmarks();
+ return Vector<IntRect>();
}
void PaintLayerScrollableArea::ScrollbarManager::SetHasHorizontalScrollbar(
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
index 302a5da..60af30c4 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -337,7 +337,8 @@
WebColorScheme UsedColorScheme() const override;
cc::AnimationHost* GetCompositorAnimationHost() const override;
CompositorAnimationTimeline* GetCompositorAnimationTimeline() const override;
- void GetTickmarks(Vector<IntRect>&) const override;
+ bool HasTickmarks() const override;
+ Vector<IntRect> GetTickmarks() const override;
void VisibleSizeChanged();
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.h b/third_party/blink/renderer/core/scroll/scrollable_area.h
index 095da3a..e24c8bb 100644
--- a/third_party/blink/renderer/core/scroll/scrollable_area.h
+++ b/third_party/blink/renderer/core/scroll/scrollable_area.h
@@ -199,7 +199,8 @@
virtual bool IsScrollCornerVisible() const = 0;
virtual IntRect ScrollCornerRect() const = 0;
void SetScrollCornerNeedsPaintInvalidation();
- virtual void GetTickmarks(Vector<IntRect>&) const {}
+ virtual bool HasTickmarks() const { return false; }
+ virtual Vector<IntRect> GetTickmarks() const { return Vector<IntRect>(); }
// Convert points and rects between the scrollbar and its containing
// EmbeddedContentView. The client needs to implement these in order to be
diff --git a/third_party/blink/renderer/core/scroll/scrollbar.cc b/third_party/blink/renderer/core/scroll/scrollbar.cc
index 7aecdaf..5f1b857 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar.cc
+++ b/third_party/blink/renderer/core/scroll/scrollbar.cc
@@ -111,9 +111,15 @@
: kScrollbarOverlayColorThemeDark;
}
-void Scrollbar::GetTickmarks(Vector<IntRect>& tickmarks) const {
+bool Scrollbar::HasTickmarks() const {
+ return orientation_ == kVerticalScrollbar && scrollable_area_ &&
+ scrollable_area_->HasTickmarks();
+}
+
+Vector<IntRect> Scrollbar::GetTickmarks() const {
if (scrollable_area_)
- scrollable_area_->GetTickmarks(tickmarks);
+ return scrollable_area_->GetTickmarks();
+ return Vector<IntRect>();
}
bool Scrollbar::IsScrollableAreaActive() const {
diff --git a/third_party/blink/renderer/core/scroll/scrollbar.h b/third_party/blink/renderer/core/scroll/scrollbar.h
index b4a27d2f..363f3256 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar.h
+++ b/third_party/blink/renderer/core/scroll/scrollbar.h
@@ -79,7 +79,8 @@
const IntRect& FrameRect() const { return frame_rect_; }
ScrollbarOverlayColorTheme GetScrollbarOverlayColorTheme() const;
- void GetTickmarks(Vector<IntRect>&) const;
+ bool HasTickmarks() const;
+ Vector<IntRect> GetTickmarks() const;
bool IsScrollableAreaActive() const;
IntPoint ConvertFromRootFrame(const IntPoint&) const;
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc b/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc
index 6557dadb..0088012 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc
+++ b/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.cc
@@ -128,7 +128,7 @@
return theme_.NinePatchThumbAperture(*scrollbar_);
}
-bool ScrollbarLayerDelegate::HasTickmarks() const {
+bool ScrollbarLayerDelegate::ShouldPaint() const {
// TODO(crbug.com/860499): Remove this condition, it should not occur.
// Layers may exist and be painted for a |scrollbar_| that has had its
// ScrollableArea detached. This seems weird because if the area is detached
@@ -140,80 +140,45 @@
// HasTickmarks can't be known and may change once the frame is unthrottled.
if (scrollbar_->GetScrollableArea()->IsThrottled())
return false;
+ return true;
+}
- Vector<IntRect> tickmarks;
- scrollbar_->GetTickmarks(tickmarks);
- return !tickmarks.IsEmpty();
+bool ScrollbarLayerDelegate::HasTickmarks() const {
+ return ShouldPaint() && scrollbar_->HasTickmarks();
}
void ScrollbarLayerDelegate::PaintPart(cc::PaintCanvas* canvas,
- cc::ScrollbarPart part,
- const gfx::Rect& content_rect) {
- PaintCanvasAutoRestore auto_restore(canvas, true);
- blink::Scrollbar& scrollbar = *scrollbar_;
-
- // TODO(crbug.com/860499): Remove this condition, it should not occur.
- // Layers may exist and be painted for a |scrollbar_| that has had its
- // ScrollableArea detached. This seems weird because if the area is detached
- // the layer should be destroyed but here we are.
- if (!scrollbar_->GetScrollableArea())
- return;
- // When the frame is throttled, the scrollbar will not be painted because
- // the frame has not had its lifecycle updated.
- if (scrollbar.GetScrollableArea()->IsThrottled())
+ cc::ScrollbarPart part) {
+ if (!ShouldPaint())
return;
- if (part == cc::THUMB) {
- ScopedScrollbarPainter painter(*canvas, device_scale_factor_);
- theme_.PaintThumb(painter.Context(), scrollbar, IntRect(content_rect));
- if (!theme_.ShouldRepaintAllPartsOnInvalidation())
- scrollbar.ClearThumbNeedsRepaint();
- return;
- }
-
- if (part == cc::TICKMARKS) {
- ScopedScrollbarPainter painter(*canvas, device_scale_factor_);
- theme_.PaintTickmarks(painter.Context(), scrollbar, IntRect(content_rect));
- return;
- }
-
- canvas->clipRect(gfx::RectToSkRect(content_rect));
ScopedScrollbarPainter painter(*canvas, device_scale_factor_);
- GraphicsContext& context = painter.Context();
-
- theme_.PaintScrollbarBackground(context, scrollbar);
-
- if (theme_.HasButtons(scrollbar)) {
- theme_.PaintButton(context, scrollbar,
- theme_.BackButtonRect(scrollbar, kBackButtonStartPart),
- kBackButtonStartPart);
- theme_.PaintButton(context, scrollbar,
- theme_.BackButtonRect(scrollbar, kBackButtonEndPart),
- kBackButtonEndPart);
- theme_.PaintButton(
- context, scrollbar,
- theme_.ForwardButtonRect(scrollbar, kForwardButtonStartPart),
- kForwardButtonStartPart);
- theme_.PaintButton(
- context, scrollbar,
- theme_.ForwardButtonRect(scrollbar, kForwardButtonEndPart),
- kForwardButtonEndPart);
+ // The canvas coordinate space is relative to the part's origin.
+ switch (part) {
+ case cc::THUMB: {
+ IntRect rect(IntPoint(),
+ UsesNinePatchThumbResource()
+ ? theme_.NinePatchThumbCanvasSize(*scrollbar_)
+ : theme_.ThumbRect(*scrollbar_).Size());
+ theme_.PaintThumb(painter.Context(), *scrollbar_, rect);
+ scrollbar_->ClearThumbNeedsRepaint();
+ break;
+ }
+ case cc::TRACK: {
+ theme_.PaintTrackAndButtonsForCompositor(painter.Context(), *scrollbar_);
+ theme_.PaintTickmarks(painter.Context(), *scrollbar_,
+ IntRect(TrackRect()));
+ scrollbar_->ClearTrackNeedsRepaint();
+ break;
+ }
+ case cc::TICKMARKS: {
+ IntRect rect(IntPoint(), theme_.TrackRect(*scrollbar_).Size());
+ theme_.PaintTickmarks(painter.Context(), *scrollbar_, rect);
+ break;
+ }
+ default:
+ NOTREACHED();
}
-
- IntRect track_paint_rect = theme_.TrackRect(scrollbar);
- theme_.PaintTrackBackground(context, scrollbar, track_paint_rect);
-
- if (theme_.HasThumb(scrollbar)) {
- theme_.PaintTrackPiece(painter.Context(), scrollbar, track_paint_rect,
- kForwardTrackPart);
- theme_.PaintTrackPiece(painter.Context(), scrollbar, track_paint_rect,
- kBackTrackPart);
- }
-
- theme_.PaintTickmarks(painter.Context(), scrollbar, track_paint_rect);
-
- if (!theme_.ShouldRepaintAllPartsOnInvalidation())
- scrollbar.ClearTrackNeedsRepaint();
}
} // namespace blink
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h b/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h
index 6c2d8ec6..c0136ed9 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h
+++ b/third_party/blink/renderer/core/scroll/scrollbar_layer_delegate.h
@@ -52,15 +52,15 @@
float ThumbOpacity() const override;
bool NeedsPaintPart(cc::ScrollbarPart part) const override;
bool HasTickmarks() const override;
- void PaintPart(cc::PaintCanvas* canvas,
- cc::ScrollbarPart part,
- const gfx::Rect& content_rect) override;
+ void PaintPart(cc::PaintCanvas* canvas, cc::ScrollbarPart part) override;
bool UsesNinePatchThumbResource() const override;
gfx::Size NinePatchThumbCanvasSize() const override;
gfx::Rect NinePatchThumbAperture() const override;
private:
+ bool ShouldPaint() const;
+
// Accessed by main and compositor threads, e.g., the compositor thread
// checks |Orientation()|.
CrossThreadPersistent<blink::Scrollbar> scrollbar_;
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme.cc b/third_party/blink/renderer/core/scroll/scrollbar_theme.cc
index f71b889..f5a2d8aa 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar_theme.cc
+++ b/third_party/blink/renderer/core/scroll/scrollbar_theme.cc
@@ -223,8 +223,7 @@
return;
// Get the tickmarks for the frameview.
- Vector<IntRect> tickmarks;
- scrollbar.GetTickmarks(tickmarks);
+ Vector<IntRect> tickmarks = scrollbar.GetTickmarks();
if (!tickmarks.size())
return;
@@ -394,6 +393,43 @@
return g_mock_scrollbars_enabled_;
}
+void ScrollbarTheme::PaintTrackAndButtonsForCompositor(
+ GraphicsContext& context,
+ const Scrollbar& scrollbar) {
+ // We paint compositor scrollbars in the space relative to the scrollbar's
+ // origin.
+ IntPoint offset = -scrollbar.Location();
+
+ if (HasButtons(scrollbar)) {
+ IntRect back_button_rect = BackButtonRect(scrollbar, kBackButtonStartPart);
+ back_button_rect.MoveBy(offset);
+ PaintButton(context, scrollbar, back_button_rect, kBackButtonStartPart);
+
+ IntRect forward_button_rect =
+ ForwardButtonRect(scrollbar, kForwardButtonEndPart);
+ forward_button_rect.MoveBy(offset);
+ PaintButton(context, scrollbar, forward_button_rect, kForwardButtonEndPart);
+
+ // Composited scrollbars don't have kBackButtonEndPart and
+ // kForwardButtonStartPart.
+ DCHECK(BackButtonRect(scrollbar, kBackButtonEndPart).IsEmpty());
+ DCHECK(ForwardButtonRect(scrollbar, kForwardButtonStartPart).IsEmpty());
+ }
+
+ IntRect track_rect = TrackRect(scrollbar);
+ track_rect.MoveBy(offset);
+ PaintTrackBackground(context, scrollbar, track_rect);
+
+ if (HasThumb(scrollbar)) {
+ // We don't repaint composited scrollbars on thumb position change, so
+ // the back track and forward track can't depend on thumb position. Just
+ // paint them on the whole track. All scrollbar themes for composited
+ // scrollbars know how to handle this case.
+ PaintTrackPiece(context, scrollbar, track_rect, kBackTrackPart);
+ PaintTrackPiece(context, scrollbar, track_rect, kForwardTrackPart);
+ }
+}
+
DisplayItem::Type ScrollbarTheme::ButtonPartToDisplayItemType(
ScrollbarPart part) {
switch (part) {
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme.h b/third_party/blink/renderer/core/scroll/scrollbar_theme.h
index 531d146..e2787208 100644
--- a/third_party/blink/renderer/core/scroll/scrollbar_theme.h
+++ b/third_party/blink/renderer/core/scroll/scrollbar_theme.h
@@ -156,29 +156,9 @@
IntRect& thumb,
IntRect& end_track);
- virtual void PaintScrollbarBackground(GraphicsContext&, const Scrollbar&) {}
- virtual void PaintTrackBackground(GraphicsContext&,
- const Scrollbar&,
- const IntRect&) {}
- virtual void PaintTrackPiece(GraphicsContext&,
- const Scrollbar&,
- const IntRect&,
- ScrollbarPart) {}
- virtual void PaintButton(GraphicsContext&,
- const Scrollbar&,
- const IntRect&,
- ScrollbarPart) {}
virtual void PaintThumb(GraphicsContext&, const Scrollbar&, const IntRect&) {}
- // Paint the thumb with ThumbOpacity() applied.
- virtual void PaintThumbWithOpacity(GraphicsContext& context,
- const Scrollbar& scrollbar,
- const IntRect& rect) {
- // By default this method just calls PaintThumb(). A theme with custom
- // ThumbOpacity() should override this method to apply the opacity.
- DCHECK_EQ(1.0f, ThumbOpacity(scrollbar));
- PaintThumb(context, scrollbar, rect);
- }
+ void PaintTrackAndButtonsForCompositor(GraphicsContext&, const Scrollbar&);
virtual int MaxOverlapBetweenPages() {
return std::numeric_limits<int>::max();
@@ -226,6 +206,29 @@
protected:
virtual int TickmarkBorderWidth() { return 0; }
+ virtual void PaintScrollbarBackground(GraphicsContext&, const Scrollbar&) {}
+ virtual void PaintTrackBackground(GraphicsContext&,
+ const Scrollbar&,
+ const IntRect&) {}
+ virtual void PaintTrackPiece(GraphicsContext&,
+ const Scrollbar&,
+ const IntRect&,
+ ScrollbarPart) {}
+ virtual void PaintButton(GraphicsContext&,
+ const Scrollbar&,
+ const IntRect&,
+ ScrollbarPart) {}
+
+ // Paint the thumb with ThumbOpacity() applied.
+ virtual void PaintThumbWithOpacity(GraphicsContext& context,
+ const Scrollbar& scrollbar,
+ const IntRect& rect) {
+ // By default this method just calls PaintThumb(). A theme with custom
+ // ThumbOpacity() should override this method to apply the opacity.
+ DCHECK_EQ(1.0f, ThumbOpacity(scrollbar));
+ PaintThumb(context, scrollbar, rect);
+ }
+
static DisplayItem::Type ButtonPartToDisplayItemType(ScrollbarPart);
static DisplayItem::Type TrackPiecePartToDisplayItemType(ScrollbarPart);
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
index 55dcbfa..6e0b01d6 100755
--- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
+++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -267,6 +267,7 @@
'cc::HORIZONTAL',
'cc::VERTICAL',
'cc::THUMB',
+ 'cc::TRACK',
'cc::TICKMARKS',
'cc::BrowserControlsState',
'cc::EventListenerClass',