Title: [295291] trunk/Source/WebCore
Revision
295291
Author
[email protected]
Date
2022-06-06 10:50:50 -0700 (Mon, 06 Jun 2022)

Log Message

InteractionRegionOverlay should use RenderLayer-cached regions instead of computing them itself
https://bugs.webkit.org/show_bug.cgi?id=241338

Reviewed by Simon Fraser.

* Source/WebCore/page/DebugPageOverlays.cpp:
(WebCore::RegionOverlay::shouldPaintOverlayIntoLayer):
(WebCore::InteractionRegionOverlay::updateRegion):
Stop computing InteractionRegions ourselves.

(WebCore::InteractionRegionOverlay::activeLayer):
Determine the layer from which to retrieve InteractionRegions. For now, we just
use the root layer, because that's where we stash all regions. Later, we'll
do a hit-test here to find the region under the mouse.

(WebCore::InteractionRegionOverlay::activeRegion):
Look up InteractionRegions cached on the aforementioned active layer, instead of
computing them ourselves.

(WebCore::InteractionRegionOverlay::drawRect):
Stop painting region-indicating borders into the overlay (see RenderLayerBacking changes).

(WebCore::InteractionRegionOverlay::mouseEvent):
Correctly map into layer coordinates. For now this is a no-op because we're using
the root layer, but it will be important in a future patch where we use regions
on a per-layer basis.

(WebCore::DebugPageOverlays::shouldPaintOverlayIntoLayer):
* Source/WebCore/page/DebugPageOverlays.h:
(WebCore::DebugPageOverlays::shouldPaintOverlayIntoLayerForRegionType):

* Source/WebCore/rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::paintDebugOverlays):
(WebCore::RenderLayerBacking::paintContents):
Paint region-indicating borders into the layer, instead of into the page overlay.
This will make them correctly scroll along with the content, and layer correctly.

Canonical link: https://commits.webkit.org/251337@main

Modified Paths

Diff

Modified: trunk/Source/WebCore/page/DebugPageOverlays.cpp (295290 => 295291)


--- trunk/Source/WebCore/page/DebugPageOverlays.cpp	2022-06-06 17:36:12 UTC (rev 295290)
+++ trunk/Source/WebCore/page/DebugPageOverlays.cpp	2022-06-06 17:50:50 UTC (rev 295291)
@@ -40,6 +40,9 @@
 #include "PathUtilities.h"
 #include "PlatformMouseEvent.h"
 #include "Region.h"
+#include "RenderLayer.h"
+#include "RenderLayerBacking.h"
+#include "RenderView.h"
 #include "ScrollingCoordinator.h"
 #include "Settings.h"
 #include <wtf/SortedArrayMap.h>
@@ -58,6 +61,8 @@
 
     void setRegionChanged() { m_regionChanged = true; }
 
+    virtual bool shouldPaintOverlayIntoLayer() const { return true; }
+
 protected:
     RegionOverlay(Page&, Color);
 
@@ -257,11 +262,14 @@
 
     bool mouseEvent(PageOverlay&, const PlatformMouseEvent&) final;
 
-    FloatRect rectForSettingAtIndex(unsigned);
-    bool valueForSetting(ASCIILiteral);
-        
-    std::optional<InteractionRegion> activeRegion();
+    FloatRect rectForSettingAtIndex(unsigned) const;
+    bool valueForSetting(ASCIILiteral) const;
 
+    std::optional<std::pair<RenderLayer&, GraphicsLayer&>> activeLayer() const;
+    std::optional<InteractionRegion> activeRegion() const;
+
+    bool shouldPaintOverlayIntoLayer() const override { return valueForSetting("regions"_s); }
+
     struct Setting {
         ASCIILiteral key;
         ASCIILiteral name;
@@ -278,8 +286,7 @@
         { "hover"_s, "CSS Hover"_s, false },
         { "regions"_s, "Show Regions"_s, false }
     };
-    
-    Vector<InteractionRegion> m_regions;
+
     IntPoint m_mouseLocationInContentCoordinates;
 };
 
@@ -286,8 +293,6 @@
 bool InteractionRegionOverlay::updateRegion()
 {
     m_overlay->setNeedsDisplay();
-    m_regions = interactionRegions(m_page, { { 0, 0 }, m_page.mainFrame().view()->contentsSize() });
-    
     return true;
 }
 
@@ -301,12 +306,41 @@
     return PathUtilities::pathsWithShrinkWrappedRects(rects, std::max(region.borderRadius, radius));
 }
 
-std::optional<InteractionRegion> InteractionRegionOverlay::activeRegion()
+std::optional<std::pair<RenderLayer&, GraphicsLayer&>> InteractionRegionOverlay::activeLayer() const
 {
+    // FIXME: This should hit-test to find the correct layer, once we store InteractionRegions
+    // on each layer instead of keeping them all on the root.
+    auto* frameView = m_page.mainFrame().view();
+    if (!frameView || !frameView->renderView())
+        return std::nullopt;
+
+    auto* layer = frameView->renderView()->enclosingLayer();
+    if (!layer || !layer->backing())
+        return std::nullopt;
+
+    auto* graphicsLayer = layer->backing()->graphicsLayer();
+    if (!graphicsLayer)
+        return std::nullopt;
+
+    return { { *layer, *graphicsLayer } };
+}
+
+std::optional<InteractionRegion> InteractionRegionOverlay::activeRegion() const
+{
+#if ENABLE(INTERACTION_REGIONS_IN_EVENT_REGION)
+    auto layerPair = activeLayer();
+    if (!layerPair)
+        return std::nullopt;
+    auto& [layer, graphicsLayer] = *layerPair;
+
     std::optional<InteractionRegion> hitRegion;
     float hitRegionArea = 0;
     
-    for (const auto& region : m_regions) {
+    FloatSize offset(layer.offsetFromAncestor(&layer.compositor().rootRenderLayer()));
+    FloatPoint mouseLocationInLayerCoordinates = m_mouseLocationInContentCoordinates - offset;
+
+    auto regions = graphicsLayer.eventRegion().interactionRegions();
+    for (const auto& region : regions) {
         float area = 0;
         FloatRect boundingRect;
         for (const auto& rect : region.regionInLayerCoordinates.rects()) {
@@ -317,13 +351,13 @@
             area += rect.area();
         }
 
-        if (!boundingRect.contains(m_mouseLocationInContentCoordinates))
+        if (!boundingRect.contains(mouseLocationInLayerCoordinates))
             continue;
 
         auto paths = pathsForRegion(region);
         bool didHitRegion = false;
         for (const auto& path : paths) {
-            if (path.contains(m_mouseLocationInContentCoordinates)) {
+            if (path.contains(mouseLocationInLayerCoordinates)) {
                 didHitRegion = true;
                 break;
             }
@@ -341,7 +375,13 @@
         }
     }
     
+    if (hitRegion)
+        hitRegion->regionInLayerCoordinates.translate(roundedIntSize(offset));
+
     return hitRegion;
+#else
+    return std::nullopt;
+#endif
 }
 
 static void drawCheckbox(const String& text, GraphicsContext& context, const FontCascade& font, const FloatRect& box, bool state)
@@ -369,7 +409,7 @@
     context.strokePath(checkboxPath);
 }
 
-FloatRect InteractionRegionOverlay::rectForSettingAtIndex(unsigned index)
+FloatRect InteractionRegionOverlay::rectForSettingAtIndex(unsigned index) const
 {
     auto viewSize = m_page.mainFrame().view()->layoutSize();
     static constexpr float settingsWidth = 150;
@@ -381,7 +421,7 @@
     };
 }
 
-bool InteractionRegionOverlay::valueForSetting(ASCIILiteral name)
+bool InteractionRegionOverlay::valueForSetting(ASCIILiteral name) const
 {
     for (const auto& setting : m_settings) {
         if (name == setting.key)
@@ -428,16 +468,6 @@
     
     context.clearRect(dirtyRect);
 
-    if (valueForSetting("regions"_s)) {
-        context.setStrokeThickness(2);
-        context.setStrokeColor(Color::green);
-
-        for (const auto& region : m_regions) {
-            for (const auto& rect : region.regionInLayerCoordinates.rects())
-                context.strokeRect(rect, 2);
-        }
-    }
-
     auto region = activeRegion();
 
     if (region || !valueForSetting("constrain"_s)) {
@@ -536,6 +566,7 @@
         cursorToSet = handCursor();
         if (event.button() == LeftButton && event.type() == PlatformEvent::MousePressed) {
             m_settings[i].value = !m_settings[i].value;
+            m_page.forceRepaintAllFrames();
             return true;
         }
     }
@@ -738,4 +769,11 @@
     DebugPageOverlays::singleton().updateOverlayRegionVisibility(page, activeOverlayRegions);
 }
 
+bool DebugPageOverlays::shouldPaintOverlayIntoLayer(Page& page, RegionType regionType) const
+{
+    if (auto* overlay = regionOverlayForPage(page, regionType))
+        return overlay->shouldPaintOverlayIntoLayer();
+    return false;
 }
+
+}

Modified: trunk/Source/WebCore/page/DebugPageOverlays.h (295290 => 295291)


--- trunk/Source/WebCore/page/DebugPageOverlays.h	2022-06-06 17:36:12 UTC (rev 295290)
+++ trunk/Source/WebCore/page/DebugPageOverlays.h	2022-06-06 17:50:50 UTC (rev 295291)
@@ -40,7 +40,7 @@
 public:
     static DebugPageOverlays& singleton();
 
-    enum class RegionType {
+    enum class RegionType : uint8_t {
         WheelEventHandlers,
         NonFastScrollableRegion,
         InteractionRegion,
@@ -51,6 +51,8 @@
     static void didChangeEventHandlers(Frame&);
     static void doAfterUpdateRendering(Page&);
 
+    static bool shouldPaintOverlayIntoLayerForRegionType(Page&, RegionType);
+
     WEBCORE_EXPORT static void settingsChanged(Page&);
 
 private:
@@ -70,6 +72,8 @@
     
     void updateOverlayRegionVisibility(Page&, OptionSet<DebugOverlayRegions>);
 
+    bool shouldPaintOverlayIntoLayer(Page&, RegionType) const;
+
     RegionOverlay* regionOverlayForPage(Page&, RegionType) const;
     RegionOverlay& ensureRegionOverlayForPage(Page&, RegionType);
 
@@ -116,4 +120,11 @@
     sharedDebugOverlays->updateRegionIfNecessary(page, RegionType::InteractionRegion);
 }
 
+inline bool DebugPageOverlays::shouldPaintOverlayIntoLayerForRegionType(Page& page, RegionType regionType)
+{
+    if (LIKELY(!hasOverlays(page)))
+        return false;
+    return sharedDebugOverlays->shouldPaintOverlayIntoLayer(page, regionType);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (295290 => 295291)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2022-06-06 17:36:12 UTC (rev 295290)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2022-06-06 17:50:50 UTC (rev 295291)
@@ -3476,6 +3476,21 @@
             context.fillRect(rect);
     }
 #endif
+
+#if ENABLE(INTERACTION_REGIONS_IN_EVENT_REGION)
+    if (DebugPageOverlays::shouldPaintOverlayIntoLayerForRegionType(renderer().page(), DebugPageOverlays::RegionType::InteractionRegion)) {
+        context.setStrokeColor(Color::green);
+        context.setStrokeThickness(1);
+
+        for (const auto& region : eventRegion.interactionRegions()) {
+            for (auto rect : region.regionInLayerCoordinates.rects()) {
+                Path path;
+                path.addRoundedRect(rect, { region.borderRadius, region.borderRadius });
+                context.strokePath(path);
+            }
+        }
+    }
+#endif
 }
 
 // Up-call from compositing layer drawing callback.
@@ -3518,7 +3533,7 @@
         paintIntoLayer(graphicsLayer, context, dirtyRect, behavior);
 
         auto visibleDebugOverlayRegions = OptionSet<DebugOverlayRegions>::fromRaw(renderer().settings().visibleDebugOverlayRegions());
-        if (visibleDebugOverlayRegions.containsAny({ DebugOverlayRegions::TouchActionRegion, DebugOverlayRegions::EditableElementRegion, DebugOverlayRegions::WheelEventHandlerRegion }))
+        if (visibleDebugOverlayRegions.containsAny({ DebugOverlayRegions::TouchActionRegion, DebugOverlayRegions::EditableElementRegion, DebugOverlayRegions::WheelEventHandlerRegion, DebugOverlayRegions::InteractionRegion }))
             paintDebugOverlays(graphicsLayer, context);
 
     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to