Changeset 289457 in webkit


Ignore:
Timestamp:
Feb 8, 2022 11:35:37 PM (5 months ago)
Author:
Antti Koivisto
Message:

[CSS Container Queries] Track query containers so they can be invalidated on size change
https://bugs.webkit.org/show_bug.cgi?id=236297

Reviewed by Alan Bujtas.

Add container size tracking.

  • dom/Document.cpp:

(WebCore::Document::updateLayout):

  • dom/Element.cpp:

(WebCore::Element::invalidateForQueryContainerChange):

  • dom/Element.h:
  • page/FrameView.cpp:

(WebCore::FrameView::updateLayoutAndStyleIfNeededRecursive):

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::willBeDestroyed):
(WebCore::RenderBox::styleWillChange):

  • rendering/RenderView.cpp:

(WebCore::RenderView::registerContainerQueryBox):
(WebCore::RenderView::unregisterContainerQueryBox):

  • rendering/RenderView.h:
  • style/StyleScope.cpp:

(WebCore::Style::Scope::updateQueryContainerState):

Save the sizes after layout and invalidate if needed.

  • style/StyleScope.h:
Location:
trunk/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r289455 r289457  
     12022-02-08  Antti Koivisto  <antti@apple.com>
     2
     3        [CSS Container Queries] Track query containers so they can be invalidated on size change
     4        https://bugs.webkit.org/show_bug.cgi?id=236297
     5
     6        Reviewed by Alan Bujtas.
     7
     8        Add container size tracking.
     9
     10        * dom/Document.cpp:
     11        (WebCore::Document::updateLayout):
     12        * dom/Element.cpp:
     13        (WebCore::Element::invalidateForQueryContainerChange):
     14        * dom/Element.h:
     15        * page/FrameView.cpp:
     16        (WebCore::FrameView::updateLayoutAndStyleIfNeededRecursive):
     17        * rendering/RenderBox.cpp:
     18        (WebCore::RenderBox::willBeDestroyed):
     19        (WebCore::RenderBox::styleWillChange):
     20        * rendering/RenderView.cpp:
     21        (WebCore::RenderView::registerContainerQueryBox):
     22        (WebCore::RenderView::unregisterContainerQueryBox):
     23        * rendering/RenderView.h:
     24        * style/StyleScope.cpp:
     25        (WebCore::Style::Scope::updateQueryContainerState):
     26
     27        Save the sizes after layout and invalidate if needed.
     28
     29        * style/StyleScope.h:
     30
    1312022-02-08  Antoine Quint  <graouts@webkit.org>
    232
  • trunk/Source/WebCore/dom/Document.cpp

    r289246 r289457  
    21992199    StackStats::LayoutCheckPoint layoutCheckPoint;
    22002200
    2201     // Only do a layout if changes have occurred that make it necessary.     
    2202     if (frameView && renderView() && (frameView->layoutContext().isLayoutPending() || renderView()->needsLayout()))
    2203         frameView->layoutContext().layout();
     2201    if (!frameView || !renderView())
     2202        return;
     2203    if (!frameView->layoutContext().isLayoutPending() && !renderView()->needsLayout())
     2204        return;
     2205
     2206    frameView->layoutContext().layout();
     2207
     2208    if (styleScope().updateQueryContainerState())
     2209        updateLayout();
    22042210}
    22052211
  • trunk/Source/WebCore/dom/Element.cpp

    r289246 r289457  
    21312131}
    21322132
     2133void Element::invalidateForQueryContainerChange()
     2134{
     2135    // FIXME: This doesn't really need to recompute the element style.
     2136    Node::invalidateStyle(Style::Validity::ElementInvalid);
     2137}
     2138
    21332139void Element::invalidateEventListenerRegions()
    21342140{
  • trunk/Source/WebCore/dom/Element.h

    r289246 r289457  
    636636    void invalidateStyleInternal();
    637637    void invalidateStyleForSubtreeInternal();
     638    void invalidateForQueryContainerChange();
    638639
    639640    void invalidateEventListenerRegions();
  • trunk/Source/WebCore/page/FrameView.cpp

    r288008 r289457  
    45404540            if (view->needsLayout()) {
    45414541                view->layoutContext().layout();
     4542                view->frame().document()->styleScope().updateQueryContainerState();
    45424543                didWork = true;
    45434544            }
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r289443 r289457  
    174174    removeControlStatesForRenderer(*this);
    175175
    176     if (hasInitializedStyle() && style().hasSnapPosition())
    177         view().unregisterBoxWithScrollSnapPositions(*this);
     176    if (hasInitializedStyle()) {
     177        if (style().hasSnapPosition())
     178            view().unregisterBoxWithScrollSnapPositions(*this);
     179        if (style().containerType() != ContainerType::None)
     180            view().unregisterContainerQueryBox(*this);
     181    }
    178182
    179183    RenderBoxModelObject::willBeDestroyed();
     
    293297            view().unregisterBoxWithScrollSnapPositions(*this);
    294298    }
     299
     300    if (newStyle.containerType() != ContainerType::None)
     301        view().registerContainerQueryBox(*this);
     302    else if (oldStyle && oldStyle->containerType() != ContainerType::None)
     303        view().unregisterContainerQueryBox(*this);
    295304
    296305    RenderBoxModelObject::styleWillChange(diff, newStyle);
  • trunk/Source/WebCore/rendering/RenderView.cpp

    r288069 r289457  
    963963}
    964964
     965void RenderView::registerContainerQueryBox(const RenderBox& box)
     966{
     967    m_containerQueryBoxes.add(box);
     968}
     969
     970void RenderView::unregisterContainerQueryBox(const RenderBox& box)
     971{
     972    m_containerQueryBoxes.remove(box);
     973}
     974
    965975} // namespace WebCore
  • trunk/Source/WebCore/rendering/RenderView.h

    r285345 r289457  
    3030#include <wtf/HashSet.h>
    3131#include <wtf/ListHashSet.h>
     32#include <wtf/WeakHashSet.h>
    3233
    3334namespace WebCore {
     
    205206    const HashSet<const RenderBox*>& boxesWithScrollSnapPositions() { return m_boxesWithScrollSnapPositions; }
    206207
     208    void registerContainerQueryBox(const RenderBox&);
     209    void unregisterContainerQueryBox(const RenderBox&);
     210    const WeakHashSet<const RenderBox>& containerQueryBoxes() const { return m_containerQueryBoxes; }
     211
    207212private:
    208213    void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, OptionSet<MapCoordinatesMode>, bool* wasFixed) const override;
     
    271276
    272277    HashSet<const RenderBox*> m_boxesWithScrollSnapPositions;
     278    WeakHashSet<const RenderBox> m_containerQueryBoxes;
    273279};
    274280
  • trunk/Source/WebCore/style/StyleScope.cpp

    r287325 r289457  
    4242#include "Logging.h"
    4343#include "ProcessingInstruction.h"
     44#include "RenderView.h"
    4445#include "SVGElementTypeHelpers.h"
    4546#include "SVGStyleElement.h"
     
    783784}
    784785
     786bool Scope::updateQueryContainerState()
     787{
     788    ASSERT(!m_shadowRoot);
     789    ASSERT(m_document.renderView());
     790
     791    auto previousStates = WTFMove(m_queryContainerStates);
     792    m_queryContainerStates.clear();
     793
     794    Vector<Element*> changedContainers;
     795
     796    for (auto& containerRenderer : m_document.renderView()->containerQueryBoxes()) {
     797        auto* containerElement = containerRenderer.element();
     798        if (!containerElement)
     799            continue;
     800        auto size = containerRenderer.size();
     801        auto it = previousStates.find(*containerElement);
     802        bool changed = it == previousStates.end() || it->value != size;
     803        if (changed)
     804            changedContainers.append(containerElement);
     805        m_queryContainerStates.add(*containerElement, size);
     806    }
     807
     808    for (auto* toInvalidate : changedContainers)
     809        toInvalidate->invalidateForQueryContainerChange();
     810
     811    return !changedContainers.isEmpty();
     812}
     813
    785814HTMLSlotElement* assignedSlotForScopeOrdinal(const Element& element, ScopeOrdinal scopeOrdinal)
    786815{
  • trunk/Source/WebCore/style/StyleScope.h

    r287325 r289457  
    2828#pragma once
    2929
     30#include "LayoutSize.h"
    3031#include "MediaQueryEvaluator.h"
    3132#include "StyleScopeOrdinal.h"
     
    3940#include <wtf/RefPtr.h>
    4041#include <wtf/Vector.h>
     42#include <wtf/WeakHashMap.h>
    4143#include <wtf/text/WTFString.h>
    4244
     
    128130    static Scope* forOrdinal(Element&, ScopeOrdinal);
    129131
     132    bool updateQueryContainerState();
     133
    130134private:
    131135    Scope& documentScope();
     
    202206
    203207    std::optional<MediaQueryViewportState> m_viewportStateOnPreviousMediaQueryEvaluation;
     208    WeakHashMap<Element, LayoutSize> m_queryContainerStates;
    204209
    205210    // FIXME: These (and some things above) are only relevant for the root scope.
Note: See TracChangeset for help on using the changeset viewer.