Changeset 246301 in webkit


Ignore:
Timestamp:
Jun 10, 2019 5:54:11 PM (5 years ago)
Author:
Simon Fraser
Message:

Add visualization of touch action regions
https://bugs.webkit.org/show_bug.cgi?id=198718

Reviewed by Antoine Quint.

Add a way to show which elements of the page have touch-action set on them by
painting an overlay with small text that shows the type of action(s).

The event regions are painted into GraphicsLayers at paint time in
RenderLayerBacking by making a pattern image and filling the region rects
with the pattern.

  • page/DebugPageOverlays.cpp:

(WebCore::touchEventRegionColors):

  • rendering/EventRegion.cpp:

(WebCore::EventRegion::regionForTouchAction const):

  • rendering/EventRegion.h:

(WebCore::EventRegion::region const):

  • rendering/RenderLayerBacking.cpp:

(WebCore::RenderLayerBacking::updateEventRegion):
(WebCore::patternForTouchAction):
(WebCore::RenderLayerBacking::paintContents):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r246288 r246301  
     12019-06-10  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Add visualization of touch action regions
     4        https://bugs.webkit.org/show_bug.cgi?id=198718
     5
     6        Reviewed by Antoine Quint.
     7
     8        Add a way to show which elements of the page have touch-action set on them by
     9        painting an overlay with small text that shows the type of action(s).
     10
     11        The event regions are painted into GraphicsLayers at paint time in
     12        RenderLayerBacking by making a pattern image and filling the region rects
     13        with the pattern.
     14
     15        * page/DebugPageOverlays.cpp:
     16        (WebCore::touchEventRegionColors):
     17        * rendering/EventRegion.cpp:
     18        (WebCore::EventRegion::regionForTouchAction const):
     19        * rendering/EventRegion.h:
     20        (WebCore::EventRegion::region const):
     21        * rendering/RenderLayerBacking.cpp:
     22        (WebCore::RenderLayerBacking::updateEventRegion):
     23        (WebCore::patternForTouchAction):
     24        (WebCore::RenderLayerBacking::paintContents):
     25
    1262019-06-10  Basuke Suzuki  <Basuke.Suzuki@sony.com>
    227
  • trunk/Source/WebCore/page/DebugPageOverlays.cpp

    r242293 r246301  
    163163        HashMap<String, Color> map;
    164164        for (auto& entry : entries)
    165             map.add(entry.name, Color { entry.r, entry.g, entry.b, 80 });
     165            map.add(entry.name, Color { entry.r, entry.g, entry.b, 50 });
    166166        return map;
    167167    }());
  • trunk/Source/WebCore/rendering/EventRegion.cpp

    r245293 r246301  
    158158}
    159159
     160const Region* EventRegion::regionForTouchAction(TouchAction action) const
     161{
     162    unsigned actionIndex = toIndex(action);
     163    if (actionIndex >= m_touchActionRegions.size())
     164        return nullptr;
     165
     166    return &m_touchActionRegions[actionIndex];
     167}
     168
    160169OptionSet<TouchAction> EventRegion::touchActionsForPoint(const IntPoint& point) const
    161170{
     
    197206}
    198207
    199 #endif
     208#endif // ENABLE(POINTER_EVENTS)
    200209
    201210TextStream& operator<<(TextStream& ts, const EventRegion& eventRegion)
  • trunk/Source/WebCore/rendering/EventRegion.h

    r245293 r246301  
    6868    bool contains(const IntRect& rect) const { return m_region.contains(rect); }
    6969
     70    const Region& region() const { return m_region; }
     71
    7072#if ENABLE(POINTER_EVENTS)
    7173    bool hasTouchActions() const { return !m_touchActionRegions.isEmpty(); }
    7274    WEBCORE_EXPORT OptionSet<TouchAction> touchActionsForPoint(const IntPoint&) const;
     75
     76    const Region* regionForTouchAction(TouchAction) const;
    7377#endif
    7478
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r246278 r246301  
    27342734}
    27352735
     2736#if ENABLE(POINTER_EVENTS)
     2737static RefPtr<Pattern> patternForTouchAction(TouchAction touchAction, FloatSize contentOffset, GraphicsContext& destContext)
     2738{
     2739    auto toIndex = [](TouchAction touchAction) -> unsigned {
     2740        switch (touchAction) {
     2741        case TouchAction::Manipulation:
     2742            return 1;
     2743        case TouchAction::PanX:
     2744            return 2;
     2745        case TouchAction::PanY:
     2746            return 3;
     2747        case TouchAction::PinchZoom:
     2748            return 4;
     2749        case TouchAction::None:
     2750        case TouchAction::Auto:
     2751            break;
     2752        }
     2753        return 0;
     2754    };
     2755
     2756    struct TouchActionAndRGB {
     2757        TouchAction action;
     2758        ASCIILiteral name;
     2759        FloatSize phase;
     2760    };
     2761    static const TouchActionAndRGB actionsAndColors[] = {
     2762        { TouchAction::None, "none"_s, { } },
     2763        { TouchAction::Manipulation, "manip"_s, { } },
     2764        { TouchAction::PanX, "pan-x"_s, { } },
     2765        { TouchAction::PanY, "pan-y"_s, { 0, 9 } },
     2766        { TouchAction::PinchZoom, "p-z"_s, { 16, 4.5 } },
     2767    };
     2768   
     2769    auto actionIndex = toIndex(touchAction);
     2770    if (!actionIndex || actionIndex >= ARRAY_SIZE(actionsAndColors))
     2771        return nullptr;
     2772
     2773    const FloatSize tileSize { 32, 18 };
     2774
     2775    auto imageBuffer = ImageBuffer::createCompatibleBuffer(tileSize, ColorSpaceSRGB, destContext);
     2776    if (!imageBuffer)
     2777        return nullptr;
     2778
     2779    const auto& touchActionData = actionsAndColors[actionIndex];
     2780    {
     2781        GraphicsContext& imageContext = imageBuffer->context();
     2782
     2783        FontCascadeDescription fontDescription;
     2784        fontDescription.setOneFamily("Helvetica");
     2785        fontDescription.setSpecifiedSize(10);
     2786        fontDescription.setComputedSize(10);
     2787        fontDescription.setWeight(FontSelectionValue(500));
     2788        FontCascade font(WTFMove(fontDescription), 0, 0);
     2789        font.update(nullptr);
     2790
     2791        TextRun textRun = TextRun(touchActionData.name);
     2792        imageContext.setFillColor(Color(0, 0, 0, 128));
     2793
     2794        constexpr float textGap = 4;
     2795        constexpr float yOffset = 12;
     2796        imageContext.drawText(font, textRun, { textGap, yOffset }, 0);
     2797    }
     2798
     2799    auto tileImage = ImageBuffer::sinkIntoImage(WTFMove(imageBuffer));
     2800    auto fillPattern = Pattern::create(tileImage.releaseNonNull(), true, true);
     2801    AffineTransform patternOffsetTransform;
     2802    patternOffsetTransform.translate(contentOffset + touchActionData.phase);
     2803    patternOffsetTransform.scale(1 / destContext.scaleFactor());
     2804    fillPattern->setPatternSpaceTransform(patternOffsetTransform);
     2805
     2806    return fillPattern;
     2807}
     2808#endif // ENABLE(POINTER_EVENTS)
     2809
     2810void RenderLayerBacking::paintDebugOverlays(const GraphicsLayer* graphicsLayer, GraphicsContext& context)
     2811{
     2812    if (graphicsLayer->eventRegion().isEmpty())
     2813        return;
     2814
     2815    GraphicsContextStateSaver stateSaver(context);
     2816
     2817    // The region is offset by contentOffsetInCompositingLayer() so undo that.
     2818    auto contentOffset = roundedIntSize(contentOffsetInCompositingLayer());
     2819    context.translate(-contentOffset);
     2820
     2821    // The interactive part.
     2822    auto& eventRegion = graphicsLayer->eventRegion();
     2823    Color regionColor(0, 0, 0, 5);
     2824    context.setFillColor(regionColor);
     2825    for (auto rect : eventRegion.region().rects())
     2826        context.fillRect(rect);
     2827
     2828#if ENABLE(POINTER_EVENTS)
     2829    const TouchAction touchActionList[] = {
     2830        TouchAction::None,
     2831        TouchAction::Manipulation,
     2832        TouchAction::PanX,
     2833        TouchAction::PanY,
     2834        TouchAction::PinchZoom,
     2835    };
     2836
     2837    for (auto action : touchActionList) {
     2838        auto* actionRegion = graphicsLayer->eventRegion().regionForTouchAction(action);
     2839        if (!actionRegion)
     2840            continue;
     2841
     2842        auto fillPattern = patternForTouchAction(action, contentOffsetInCompositingLayer(), context);
     2843        if (!fillPattern)
     2844            continue;
     2845
     2846        context.setFillPattern(fillPattern.releaseNonNull());
     2847        for (auto rect : actionRegion->rects())
     2848            context.fillRect(rect);
     2849    }
     2850#endif // ENABLE(POINTER_EVENTS)
     2851}
     2852
    27362853// Up-call from compositing layer drawing callback.
    27372854void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, OptionSet<GraphicsLayerPaintingPhase> paintingPhase, const FloatRect& clip, GraphicsLayerPaintBehavior layerPaintBehavior)
     
    27722889
    27732890        paintIntoLayer(graphicsLayer, context, dirtyRect, behavior, paintingPhase);
     2891
     2892        if (renderer().settings().visibleDebugOverlayRegions() & NonFastScrollableRegion) // Piggy-back off the setting that shows touch handler regions.
     2893            paintDebugOverlays(graphicsLayer, context);
     2894
    27742895    } else if (graphicsLayer == layerForHorizontalScrollbar()) {
    27752896        paintScrollbar(m_owningLayer.horizontalScrollbar(), context, dirtyRect);
  • trunk/Source/WebCore/rendering/RenderLayerBacking.h

    r246278 r246301  
    385385
    386386    void paintIntoLayer(const GraphicsLayer*, GraphicsContext&, const IntRect& paintDirtyRect, OptionSet<PaintBehavior>, OptionSet<GraphicsLayerPaintingPhase>);
     387   
     388    void paintDebugOverlays(const GraphicsLayer*, GraphicsContext&);
    387389
    388390    static CSSPropertyID graphicsLayerToCSSProperty(AnimatedPropertyID);
Note: See TracChangeset for help on using the changeset viewer.