Commit 741f20e9 authored by Philip Rogers's avatar Philip Rogers Committed by Commit Bot

Paint non-fast scrollable regions for plugins with wheel handlers

Non-fast scrollable regions are regions on a cc::Layer where the
compositor should not handle scroll events. These are primarily for non-
composited scrollers but are also used for resize controls and plugins.
This patch paints non-fast scrollable regions for plugins that have
blocking wheel event handlers. A design doc for this approach of
painting non-fast scrollable regions is at:
https://docs.google.com/document/d/1IyYJ6bVF7KZq96b_s5NrAzGtVoBXn_LQnya9y4yT3iw/view#heading=h.rrlzkp4v3huj

This patch shares the pattern used by non-composited scrollers of
emitting ScrollHitTestDisplayItems. ScrollHitTestDisplayItem has a field
for supporting both scrolling (kScrollHitTest) and non-scrolling
(kPluginScrollHitTest) usecases. This field was required because it will
be possible to have two ScrollHitTestDisplayItems for one scroller: one
for non-composited scrolling, and a second for a resizer.

ScrollingCoordinatorTest::NonFastScrollableRegionsForPlugins is the
interesting new test. It shows that PaintNonFastScrollableRegions
matches the current behavior for non-fixed plugins, and shows that fixed
plugin non-fast regions are now painted in a different layer. Painting
the fixed non-fast region into the fixed layer fixes a bug where the
non-fast regions would not be updated after compositor changes such as
scrolling.

Bug: 864567
Change-Id: If72e084241d1684e54d4c02e5d1efc04d91cc858
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1729551Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Commit-Queue: Philip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#683165}
parent de7c587b
...@@ -103,6 +103,7 @@ ...@@ -103,6 +103,7 @@
#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h"
#include "third_party/blink/renderer/platform/keyboard_codes.h" #include "third_party/blink/renderer/platform/keyboard_codes.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/assertions.h"
...@@ -149,6 +150,15 @@ void WebPluginContainerImpl::Paint(GraphicsContext& context, ...@@ -149,6 +150,15 @@ void WebPluginContainerImpl::Paint(GraphicsContext& context,
if (!cull_rect.Intersects(FrameRect())) if (!cull_rect.Intersects(FrameRect()))
return; return;
if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) {
if (WantsWheelEvents()) {
ScrollHitTestDisplayItem::Record(
context, *GetLayoutEmbeddedContent(),
DisplayItem::kPluginScrollHitTest, nullptr,
GetLayoutEmbeddedContent()->FirstFragment().VisualRect());
}
}
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && layer_) { if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && layer_) {
layer_->SetBounds(gfx::Size(Size())); layer_->SetBounds(gfx::Size(Size()));
layer_->SetIsDrawable(true); layer_->SetIsDrawable(true);
...@@ -639,6 +649,12 @@ void WebPluginContainerImpl::SetWantsWheelEvents(bool wants_wheel_events) { ...@@ -639,6 +649,12 @@ void WebPluginContainerImpl::SetWantsWheelEvents(bool wants_wheel_events) {
if (IsAttached()) { if (IsAttached()) {
LocalFrameView* frame_view = element_->GetDocument().GetFrame()->View(); LocalFrameView* frame_view = element_->GetDocument().GetFrame()->View();
scrolling_coordinator->NotifyGeometryChanged(frame_view); scrolling_coordinator->NotifyGeometryChanged(frame_view);
if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) {
// Scroll hit test display items depend on wheel events. The scroll
// hit test display items paint in the background phase.
GetLayoutEmbeddedContent()->SetBackgroundNeedsFullPaintInvalidation();
}
} }
} }
} }
...@@ -722,7 +738,7 @@ bool WebPluginContainerImpl::CanProcessDrag() const { ...@@ -722,7 +738,7 @@ bool WebPluginContainerImpl::CanProcessDrag() const {
return web_plugin_->CanProcessDrag(); return web_plugin_->CanProcessDrag();
} }
bool WebPluginContainerImpl::WantsWheelEvents() { bool WebPluginContainerImpl::WantsWheelEvents() const {
return wants_wheel_events_; return wants_wheel_events_;
} }
......
...@@ -103,7 +103,7 @@ class CORE_EXPORT WebPluginContainerImpl final ...@@ -103,7 +103,7 @@ class CORE_EXPORT WebPluginContainerImpl final
bool SupportsKeyboardFocus() const; bool SupportsKeyboardFocus() const;
bool SupportsInputMethod() const; bool SupportsInputMethod() const;
bool CanProcessDrag() const; bool CanProcessDrag() const;
bool WantsWheelEvents(); bool WantsWheelEvents() const;
void UpdateAllLifecyclePhases(); void UpdateAllLifecyclePhases();
void InvalidateRect(const IntRect&); void InvalidateRect(const IntRect&);
void SetFocused(bool, WebFocusType); void SetFocused(bool, WebFocusType);
......
...@@ -1074,10 +1074,6 @@ TEST_P(ScrollingCoordinatorTest, PluginBecomesLayoutInline) { ...@@ -1074,10 +1074,6 @@ TEST_P(ScrollingCoordinatorTest, PluginBecomesLayoutInline) {
// Ensure NonFastScrollableRegions are correctly generated for both fixed and // Ensure NonFastScrollableRegions are correctly generated for both fixed and
// in-flow plugins that need them. // in-flow plugins that need them.
TEST_P(ScrollingCoordinatorTest, NonFastScrollableRegionsForPlugins) { TEST_P(ScrollingCoordinatorTest, NonFastScrollableRegionsForPlugins) {
// TODO(pdr): Paint non-fast scrollable regions for plugins.
if (RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled())
return;
LoadHTML(R"HTML( LoadHTML(R"HTML(
<style> <style>
body { body {
...@@ -1114,17 +1110,47 @@ TEST_P(ScrollingCoordinatorTest, NonFastScrollableRegionsForPlugins) { ...@@ -1114,17 +1110,47 @@ TEST_P(ScrollingCoordinatorTest, NonFastScrollableRegionsForPlugins) {
ForceFullCompositingUpdate(); ForceFullCompositingUpdate();
Region scrolling; if (!RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) {
Region fixed; Region scrolling;
Page* page = GetFrame()->GetPage(); Region fixed;
page->GetScrollingCoordinator() Page* page = GetFrame()->GetPage();
->ComputeShouldHandleScrollGestureOnMainThreadRegion( page->GetScrollingCoordinator()
To<LocalFrame>(page->MainFrame()), &scrolling, &fixed); ->ComputeShouldHandleScrollGestureOnMainThreadRegion(
To<LocalFrame>(page->MainFrame()), &scrolling, &fixed);
EXPECT_TRUE(scrolling.IsRect());
EXPECT_TRUE(fixed.IsRect()); EXPECT_TRUE(scrolling.IsRect());
EXPECT_EQ(scrolling.Rects().at(0), IntRect(0, 0, 300, 300)); EXPECT_TRUE(fixed.IsRect());
EXPECT_EQ(fixed.Rects().at(0), IntRect(0, 500, 200, 200)); EXPECT_EQ(scrolling.Rects().at(0), IntRect(0, 0, 300, 300));
EXPECT_EQ(fixed.Rects().at(0), IntRect(0, 500, 200, 200));
}
// The non-fixed plugin should create a non-fast scrollable region in the
// scrolling contents layer of the LayoutView.
auto* layout_viewport = GetFrame()->View()->LayoutViewport();
auto* mapping = layout_viewport->Layer()->GetCompositedLayerMapping();
auto* viewport_non_fast_layer = mapping->ScrollingContentsLayer()->CcLayer();
EXPECT_EQ(viewport_non_fast_layer->non_fast_scrollable_region().bounds(),
gfx::Rect(0, 0, 300, 300));
// The fixed plugin should create a non-fast scrollable region in a fixed
// cc::Layer.
if (!RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()) {
// The fixed non-fast region should be on the visual viewport's scrolling
// layer. This is not correct in all cases and is a restriction of the
// pre-PaintNonFsatScrollableRegions code.
auto* non_fast_layer =
GetFrame()->GetPage()->GetVisualViewport().ScrollLayer()->CcLayer();
EXPECT_EQ(non_fast_layer->non_fast_scrollable_region().bounds(),
gfx::Rect(0, 500, 200, 200));
} else {
auto* fixed = GetFrame()->GetDocument()->getElementById("fixed");
auto* fixed_object = ToLayoutBox(fixed->GetLayoutObject());
auto* fixed_graphics_layer =
fixed_object->EnclosingLayer()->GraphicsLayerBacking(fixed_object);
EXPECT_EQ(
fixed_graphics_layer->CcLayer()->non_fast_scrollable_region().bounds(),
gfx::Rect(0, 0, 200, 200));
}
} }
TEST_P(ScrollingCoordinatorTest, NonFastScrollableRegionWithBorder) { TEST_P(ScrollingCoordinatorTest, NonFastScrollableRegionWithBorder) {
......
...@@ -1930,13 +1930,12 @@ void CompositedLayerMapping::UpdateDrawsContentAndPaintsHitTest() { ...@@ -1930,13 +1930,12 @@ void CompositedLayerMapping::UpdateDrawsContentAndPaintsHitTest() {
// expensive. // expensive.
bool paints_hit_test = bool paints_hit_test =
has_painted_content || GetLayoutObject().HasEffectiveAllowedTouchAction(); has_painted_content || GetLayoutObject().HasEffectiveAllowedTouchAction();
// TODO(pdr): When PaintNonFastScrollableRegions supports painting plugins
// that request wheel events, this should be updated to check:
// GetPluginContainer(GetLayoutObject())->WantsWheelEvents()).
bool paints_scroll_hit_test = bool paints_scroll_hit_test =
RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled() && RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled() &&
(owning_layer_.GetScrollableArea() && ((owning_layer_.GetScrollableArea() &&
owning_layer_.GetScrollableArea()->ScrollsOverflow()); owning_layer_.GetScrollableArea()->ScrollsOverflow()) ||
(GetPluginContainer(GetLayoutObject()) &&
GetPluginContainer(GetLayoutObject())->WantsWheelEvents()));
graphics_layer_->SetPaintsHitTest(paints_hit_test || paints_scroll_hit_test); graphics_layer_->SetPaintsHitTest(paints_hit_test || paints_scroll_hit_test);
if (scrolling_layer_) { if (scrolling_layer_) {
......
...@@ -629,7 +629,8 @@ void PaintArtifactCompositor::LayerizeGroup( ...@@ -629,7 +629,8 @@ void PaintArtifactCompositor::LayerizeGroup(
// Case A: The next chunk belongs to the current group but no subgroup. // Case A: The next chunk belongs to the current group but no subgroup.
const auto& last_display_item = const auto& last_display_item =
paint_artifact.GetDisplayItemList()[chunk_it->begin_index]; paint_artifact.GetDisplayItemList()[chunk_it->begin_index];
bool item_for_scrolling = last_display_item.IsScrollHitTest(); bool item_for_scrolling = last_display_item.IsScrollHitTest() &&
!last_display_item.IsPluginScrollHitTest();
bool requires_own_layer = last_display_item.IsForeignLayer() || bool requires_own_layer = last_display_item.IsForeignLayer() ||
// TODO(pdr): This should require a direct // TODO(pdr): This should require a direct
// compositing reason. // compositing reason.
......
...@@ -150,6 +150,7 @@ WTF::String DisplayItem::TypeAsDebugString(Type type) { ...@@ -150,6 +150,7 @@ WTF::String DisplayItem::TypeAsDebugString(Type type) {
switch (type) { switch (type) {
DEBUG_STRING_CASE(HitTest); DEBUG_STRING_CASE(HitTest);
DEBUG_STRING_CASE(ScrollHitTest); DEBUG_STRING_CASE(ScrollHitTest);
DEBUG_STRING_CASE(PluginScrollHitTest);
DEBUG_STRING_CASE(LayerChunkBackground); DEBUG_STRING_CASE(LayerChunkBackground);
DEBUG_STRING_CASE(LayerChunkNegativeZOrderChildren); DEBUG_STRING_CASE(LayerChunkNegativeZOrderChildren);
DEBUG_STRING_CASE(LayerChunkDescendantBackgrounds); DEBUG_STRING_CASE(LayerChunkDescendantBackgrounds);
......
...@@ -130,6 +130,8 @@ class PLATFORM_EXPORT DisplayItem { ...@@ -130,6 +130,8 @@ class PLATFORM_EXPORT DisplayItem {
// Used both for specifying the paint-order scroll location, and for non- // Used both for specifying the paint-order scroll location, and for non-
// composited scroll hit testing (see: scroll_hit_test_display_item.h). // composited scroll hit testing (see: scroll_hit_test_display_item.h).
kScrollHitTest, kScrollHitTest,
// Used to prevent composited scrolling on plugins with wheel handlers.
kPluginScrollHitTest,
kLayerChunkBackground, kLayerChunkBackground,
kLayerChunkNegativeZOrderChildren, kLayerChunkNegativeZOrderChildren,
...@@ -244,7 +246,10 @@ class PLATFORM_EXPORT DisplayItem { ...@@ -244,7 +246,10 @@ class PLATFORM_EXPORT DisplayItem {
DEFINE_PAINT_PHASE_CONVERSION_METHOD(SVGEffect) DEFINE_PAINT_PHASE_CONVERSION_METHOD(SVGEffect)
bool IsHitTest() const { return type_ == kHitTest; } bool IsHitTest() const { return type_ == kHitTest; }
bool IsScrollHitTest() const { return type_ == kScrollHitTest; } bool IsScrollHitTest() const {
return type_ == kScrollHitTest || IsPluginScrollHitTest();
}
bool IsPluginScrollHitTest() const { return type_ == kPluginScrollHitTest; }
bool IsCacheable() const { return is_cacheable_; } bool IsCacheable() const { return is_cacheable_; }
void SetUncacheable() { is_cacheable_ = false; } void SetUncacheable() { is_cacheable_ = false; }
......
...@@ -19,7 +19,19 @@ ScrollHitTestDisplayItem::ScrollHitTestDisplayItem( ...@@ -19,7 +19,19 @@ ScrollHitTestDisplayItem::ScrollHitTestDisplayItem(
scroll_offset_node_(scroll_offset_node), scroll_offset_node_(scroll_offset_node),
scroll_container_bounds_(scroll_container_bounds) { scroll_container_bounds_(scroll_container_bounds) {
DCHECK(RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled()); DCHECK(RuntimeEnabledFeatures::PaintNonFastScrollableRegionsEnabled());
DCHECK(IsScrollHitTest()); #if DCHECK_IS_ON()
if (type == DisplayItem::Type::kPluginScrollHitTest) {
// Plugin scroll hit tests are only used to prevent composited scrolling
// and should not have a scroll offset node.
DCHECK(!scroll_offset_node);
} else if (type == DisplayItem::Type::kScrollHitTest) {
DCHECK(scroll_offset_node);
// The scroll offset transform node should have an associated scroll node.
DCHECK(scroll_offset_node_->ScrollNode());
} else {
NOTREACHED();
}
#endif
} }
ScrollHitTestDisplayItem::~ScrollHitTestDisplayItem() = default; ScrollHitTestDisplayItem::~ScrollHitTestDisplayItem() = default;
......
...@@ -515,9 +515,6 @@ crbug.com/980290 scrollingcoordinator/non-fast-scrollable-region-transformed-ifr ...@@ -515,9 +515,6 @@ crbug.com/980290 scrollingcoordinator/non-fast-scrollable-region-transformed-ifr
crbug.com/980290 scrollingcoordinator/non-fast-scrollable-transform-changed.html [ Failure ] crbug.com/980290 scrollingcoordinator/non-fast-scrollable-transform-changed.html [ Failure ]
crbug.com/980290 scrollingcoordinator/non-fast-scrollable-visibility-change.html [ Failure ] crbug.com/980290 scrollingcoordinator/non-fast-scrollable-visibility-change.html [ Failure ]
# Need to support painting non-fast scrollable regions for plugins.
crbug.com/864567 scrollingcoordinator/plugin-with-wheel-handler.html [ Failure ]
# These failures need to be triaged and are being added to unblock the CQ (see: https://crbug.com/966981). # These failures need to be triaged and are being added to unblock the CQ (see: https://crbug.com/966981).
crbug.com/966981 virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-disabled-frame-no-scroll-manual.tentative.html [ Failure ] crbug.com/966981 virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-disabled-frame-no-scroll-manual.tentative.html [ Failure ]
crbug.com/966981 virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-main-frame-manual.tentative.html [ Failure ] crbug.com/966981 virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-main-frame-manual.tentative.html [ Failure ]
......
...@@ -150,12 +150,6 @@ crbug.com/980290 virtual/composite-after-paint/scrollingcoordinator/non-fast-scr ...@@ -150,12 +150,6 @@ crbug.com/980290 virtual/composite-after-paint/scrollingcoordinator/non-fast-scr
crbug.com/980290 virtual/composite-after-paint/scrollingcoordinator/non-fast-scrollable-transform-changed.html [ Failure ] crbug.com/980290 virtual/composite-after-paint/scrollingcoordinator/non-fast-scrollable-transform-changed.html [ Failure ]
crbug.com/980290 virtual/composite-after-paint/scrollingcoordinator/non-fast-scrollable-visibility-change.html [ Failure ] crbug.com/980290 virtual/composite-after-paint/scrollingcoordinator/non-fast-scrollable-visibility-change.html [ Failure ]
# Need to support painting non-fast scrollable regions for plugins.
crbug.com/864567 virtual/composite-after-paint/scrollingcoordinator/plugin-with-wheel-handler.html [ Failure ]
crbug.com/864567 virtual/paint-non-fast-scrollable-regions/scrollingcoordinator/plugin-with-wheel-handler.html [ Failure ]
crbug.com/864567 virtual/paint-non-fast-scrollable-regions/scrollingcoordinator/donot-compute-non-fast-scrollable-region-for-hidden-frames.html [ Failure ]
crbug.com/864567 virtual/paint-non-fast-scrollable-regions/scrollingcoordinator/non-fast-scrollable-region-nested.html [ Failure ]
# Subpixel differences # Subpixel differences
crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-color-5.html [ Failure ] crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-color-5.html [ Failure ]
crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ] crbug.com/771643 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ]
......
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