Commit b1d25268 authored by Jinfeng Ma's avatar Jinfeng Ma Committed by Commit Bot

Avoid unnecessary scrollable area layer's main thread scrolling repaint.

CompositedLayerMapping::NeedsRepaint always returned true if the target graphics
layer is a scrollable area layer. This can be optimized because we can get paint
invalidation flag from the overflow controls.

Change-Id: Ie2612794403fabd8dcb8dad7aca41a60dfbb0c69
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1943501Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720456}
parent 7a63e7a0
...@@ -2103,9 +2103,8 @@ LayoutSize CompositedLayerMapping::SubpixelAccumulation() const { ...@@ -2103,9 +2103,8 @@ LayoutSize CompositedLayerMapping::SubpixelAccumulation() const {
bool CompositedLayerMapping::NeedsRepaint( bool CompositedLayerMapping::NeedsRepaint(
const GraphicsLayer& graphics_layer) const { const GraphicsLayer& graphics_layer) const {
return IsScrollableAreaLayer(&graphics_layer) return IsScrollableAreaLayerWhichNeedsRepaint(&graphics_layer) ||
? true owning_layer_.SelfOrDescendantNeedsRepaint();
: owning_layer_.SelfOrDescendantNeedsRepaint();
} }
bool CompositedLayerMapping::AdjustForCompositedScrolling( bool CompositedLayerMapping::AdjustForCompositedScrolling(
...@@ -2242,6 +2241,23 @@ bool CompositedLayerMapping::IsScrollableAreaLayer( ...@@ -2242,6 +2241,23 @@ bool CompositedLayerMapping::IsScrollableAreaLayer(
graphics_layer == LayerForScrollCorner(); graphics_layer == LayerForScrollCorner();
} }
bool CompositedLayerMapping::IsScrollableAreaLayerWhichNeedsRepaint(
const GraphicsLayer* graphics_layer) const {
if (PaintLayerScrollableArea* scrollable_area =
owning_layer_.GetScrollableArea()) {
if (graphics_layer == LayerForHorizontalScrollbar())
return scrollable_area->HorizontalScrollbarNeedsPaintInvalidation();
if (graphics_layer == LayerForVerticalScrollbar())
return scrollable_area->VerticalScrollbarNeedsPaintInvalidation();
if (graphics_layer == LayerForScrollCorner())
return scrollable_area->ScrollCornerNeedsPaintInvalidation();
}
return false;
}
bool CompositedLayerMapping::ShouldThrottleRendering() const { bool CompositedLayerMapping::ShouldThrottleRendering() const {
return GetLayoutObject().GetFrame()->ShouldThrottleRendering(); return GetLayoutObject().GetFrame()->ShouldThrottleRendering();
} }
......
...@@ -299,6 +299,10 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient { ...@@ -299,6 +299,10 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
// associated with this mapping. // associated with this mapping.
bool IsScrollableAreaLayer(const GraphicsLayer*) const; bool IsScrollableAreaLayer(const GraphicsLayer*) const;
// Returns whether the given layer is a repaint needed part of the scrollable
// area, if any, associated with this mapping.
bool IsScrollableAreaLayerWhichNeedsRepaint(const GraphicsLayer*) const;
// Helper methods to updateGraphicsLayerGeometry: // Helper methods to updateGraphicsLayerGeometry:
void ComputeGraphicsLayerParentLocation( void ComputeGraphicsLayerParentLocation(
const PaintLayer* compositing_container, const PaintLayer* compositing_container,
......
...@@ -1721,4 +1721,67 @@ TEST_F(CompositedLayerMappingTest, CompositedHiddenAnimatingLayer) { ...@@ -1721,4 +1721,67 @@ TEST_F(CompositedLayerMappingTest, CompositedHiddenAnimatingLayer) {
CompositingReason::kActiveTransformAnimation); CompositingReason::kActiveTransformAnimation);
} }
TEST_F(CompositedLayerMappingTest,
RepaintScrollableAreaLayersInMainThreadScrolling) {
SetHtmlInnerHTML(R"HTML(
<style>
#scroller {
width: 200px;
height: 100px;
overflow: scroll;
opacity: 0.8; /*MainThreadScrollingReason::kHasOpacityAndLCDText*/
}
#child {
width: 100px;
height: 200px;
transform: translate3d(0, 0, 0);
overflow: hidden;
}
#uncorrelated {
transform: translate3d(0, 0, 0);
height: 100px;
width: 100px;
background-color: red;
}
</style>
<div id="scroller">
<div id="child">
</div>
</div>
<div id="uncorrelated"></div>
)HTML");
PaintLayer* scroller =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"))->Layer();
PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
ASSERT_TRUE(scrollable_area);
GraphicsLayer* vertical_scrollbar =
scrollable_area->GraphicsLayerForVerticalScrollbar();
ASSERT_TRUE(vertical_scrollbar);
CompositedLayerMapping* mapping = scroller->GetCompositedLayerMapping();
ASSERT_TRUE(mapping);
// Input events, animations and DOM changes, etc, can trigger cc::ProxyMain::
// BeginMainFrame, which may check if all graphics layers need repaint.
//
// We shouldn't repaint scrollable area layer which has no paint invalidation
// in many uncorrelated BeginMainFrame scenes, such as moving mouse over the
// non-scrollbar area, animating or DOM changes in another composited layer.
GetDocument()
.getElementById("uncorrelated")
->setAttribute(html_names::kStyleAttr, "width: 200px");
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
EXPECT_FALSE(mapping->NeedsRepaint(*vertical_scrollbar));
GetDocument().getElementById("child")->setAttribute(html_names::kStyleAttr,
"height: 300px");
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
EXPECT_TRUE(mapping->NeedsRepaint(*vertical_scrollbar));
}
} // namespace blink } // namespace blink
...@@ -385,6 +385,16 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin { ...@@ -385,6 +385,16 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
bool HasLayerForVerticalScrollbar() const; bool HasLayerForVerticalScrollbar() const;
bool HasLayerForScrollCorner() const; bool HasLayerForScrollCorner() const;
bool HorizontalScrollbarNeedsPaintInvalidation() const {
return horizontal_scrollbar_needs_paint_invalidation_;
}
bool VerticalScrollbarNeedsPaintInvalidation() const {
return vertical_scrollbar_needs_paint_invalidation_;
}
bool ScrollCornerNeedsPaintInvalidation() const {
return scroll_corner_needs_paint_invalidation_;
}
void LayerForScrollingDidChange(CompositorAnimationTimeline*); void LayerForScrollingDidChange(CompositorAnimationTimeline*);
bool NeedsShowScrollbarLayers() const { return needs_show_scrollbar_layers_; } bool NeedsShowScrollbarLayers() const { return needs_show_scrollbar_layers_; }
void DidShowScrollbarLayers() { needs_show_scrollbar_layers_ = false; } void DidShowScrollbarLayers() { needs_show_scrollbar_layers_ = false; }
...@@ -493,15 +503,6 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin { ...@@ -493,15 +503,6 @@ class CORE_EXPORT ScrollableArea : public GarbageCollectedMixin {
friend class ScrollAnimatorCompositorCoordinator; friend class ScrollAnimatorCompositorCoordinator;
void ScrollOffsetChanged(const ScrollOffset&, ScrollType); void ScrollOffsetChanged(const ScrollOffset&, ScrollType);
bool HorizontalScrollbarNeedsPaintInvalidation() const {
return horizontal_scrollbar_needs_paint_invalidation_;
}
bool VerticalScrollbarNeedsPaintInvalidation() const {
return vertical_scrollbar_needs_paint_invalidation_;
}
bool ScrollCornerNeedsPaintInvalidation() const {
return scroll_corner_needs_paint_invalidation_;
}
void ClearNeedsPaintInvalidationForScrollControls() { void ClearNeedsPaintInvalidationForScrollControls() {
horizontal_scrollbar_needs_paint_invalidation_ = false; horizontal_scrollbar_needs_paint_invalidation_ = false;
vertical_scrollbar_needs_paint_invalidation_ = false; vertical_scrollbar_needs_paint_invalidation_ = false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment