⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 251640 in webkit


Ignore:
Timestamp:
Oct 27, 2019, 9:33:01 AM (7 years ago)
Author:
Alan Bujtas
Message:

[LFC][Painting] Use the dirty rect to decide what to paint
https://bugs.webkit.org/show_bug.cgi?id=203467
<rdar://problem/56653229>

Reviewed by Antti Koivisto.

This is a very basic dirty rect instersect check since we don't yet have layout overflow.
It enables us to not paint the entire content on every paint frame.

  • layout/LayoutContext.cpp:

(WebCore::Layout::LayoutContext::paint):

  • layout/LayoutContext.h:
  • layout/displaytree/DisplayPainter.cpp:

(WebCore::Display::paintBoxDecorationAndChildren):
(WebCore::Display::Painter::paint):

  • layout/displaytree/DisplayPainter.h:
  • page/FrameView.cpp:

(WebCore::FrameView::paintContents):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r251639 r251640  
     12019-10-27  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][Painting] Use the dirty rect to decide what to paint
     4        https://bugs.webkit.org/show_bug.cgi?id=203467
     5        <rdar://problem/56653229>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        This is a very basic dirty rect instersect check since we don't yet have layout overflow.
     10        It enables us to not paint the entire content on every paint frame.
     11
     12        * layout/LayoutContext.cpp:
     13        (WebCore::Layout::LayoutContext::paint):
     14        * layout/LayoutContext.h:
     15        * layout/displaytree/DisplayPainter.cpp:
     16        (WebCore::Display::paintBoxDecorationAndChildren):
     17        (WebCore::Display::Painter::paint):
     18        * layout/displaytree/DisplayPainter.h:
     19        * page/FrameView.cpp:
     20        (WebCore::FrameView::paintContents):
     21
    1222019-10-26  youenn fablet  <youenn@apple.com>
    223
  • trunk/Source/WebCore/layout/LayoutContext.cpp

    r251638 r251640  
    171171}
    172172
    173 void LayoutContext::paint(const LayoutState& layoutState, GraphicsContext& context)
     173void LayoutContext::paint(const LayoutState& layoutState, GraphicsContext& context, const IntRect& dirtyRect)
    174174{
    175     Display::Painter::paint(layoutState, context);
     175    Display::Painter::paint(layoutState, context, dirtyRect);
    176176}
    177177
  • trunk/Source/WebCore/layout/LayoutContext.h

    r251638 r251640  
    3535
    3636class GraphicsContext;
     37class IntRect;
    3738class RenderView;
    3839
     
    5657    // FIXME: These are temporary entry points for LFC layout.
    5758    static std::unique_ptr<LayoutState> runLayoutAndVerify(const RenderView&);
    58     static void paint(const LayoutState&, GraphicsContext&);
     59    static void paint(const LayoutState&, GraphicsContext&, const IntRect& dirtyRect);
    5960
    6061    LayoutContext(LayoutState&);
  • trunk/Source/WebCore/layout/displaytree/DisplayPainter.cpp

    r251239 r251640  
    3535#include "InlineFormattingState.h"
    3636#include "InlineTextItem.h"
     37#include "IntRect.h"
    3738#include "LayoutContainer.h"
    3839#include "LayoutDescendantIterator.h"
     
    146147}
    147148
    148 static void paintBoxDecorationAndChildren(GraphicsContext& context, const Layout::LayoutState& layoutState, const Layout::Box& layoutBox)
     149static void paintBoxDecorationAndChildren(GraphicsContext& context, const Layout::LayoutState& layoutState, const Layout::Box& layoutBox, const IntRect& dirtyRect)
    149150{
    150     if (!layoutBox.isAnonymous())
    151         paintBoxDecoration(context, absoluteDisplayBox(layoutState, layoutBox), layoutBox.style(), layoutBox.isBodyBox());
     151    if (!layoutBox.isAnonymous()) {
     152        auto absoluteDisplayBox = Display::absoluteDisplayBox(layoutState, layoutBox);
     153        if (dirtyRect.intersects(snappedIntRect(absoluteDisplayBox.rect())))
     154            paintBoxDecoration(context, absoluteDisplayBox, layoutBox.style(), layoutBox.isBodyBox());
     155    }
    152156
    153157    if (!is<Layout::Container>(layoutBox))
     
    156160        if (childLayoutBox.style().visibility() != Visibility::Visible)
    157161            continue;
    158         paintBoxDecorationAndChildren(context, layoutState, childLayoutBox);
     162        paintBoxDecorationAndChildren(context, layoutState, childLayoutBox, dirtyRect);
    159163    }
    160164}
    161165
    162 void Painter::paint(const Layout::LayoutState& layoutState, GraphicsContext& context)
     166void Painter::paint(const Layout::LayoutState& layoutState, GraphicsContext& context, const IntRect& dirtyRect)
    163167{
    164168    auto& layoutRoot = layoutState.root();
    165     auto& rootDisplayBox = layoutState.displayBoxForLayoutBox(layoutRoot);
    166     context.fillRect({ FloatPoint { }, FloatSize { rootDisplayBox.borderBoxWidth(), rootDisplayBox.borderBoxHeight() } }, Color::white);
    167169    if (!layoutRoot.firstChild())
    168170        return;
     171    // Fill the entire content area.
     172    auto rootRect = LayoutRect { layoutState.displayBoxForLayoutBox(layoutRoot).rect() };
     173    for (auto& layoutBox : Layout::descendantsOfType<Layout::Box>(layoutRoot))
     174        rootRect.uniteIfNonZero(Display::absoluteDisplayBox(layoutState, layoutBox).rect());
     175    context.fillRect(rootRect, Color::white);
    169176
    170177    // 1. Paint box decoration (both block and inline).
    171     paintBoxDecorationAndChildren(context, layoutState, *layoutRoot.firstChild());
     178    paintBoxDecorationAndChildren(context, layoutState, *layoutRoot.firstChild(), dirtyRect);
    172179
    173180    // 2. Paint content
    174181    for (auto& layoutBox : Layout::descendantsOfType<Layout::Box>(layoutRoot)) {
     182        auto absoluteDisplayBox = Display::absoluteDisplayBox(layoutState, layoutBox);
     183        // FIXME: This is the best we can do with no layout overflow support.
     184        if (!dirtyRect.intersects(snappedIntRect(absoluteDisplayBox.rect())))
     185            continue;
    175186        if (layoutBox.style().visibility() != Visibility::Visible)
    176187            continue;
    177188        if (layoutBox.establishesInlineFormattingContext()) {
    178189            auto& container = downcast<Layout::Container>(layoutBox);
    179             paintInlineContent(context, absoluteDisplayBox(layoutState, container), downcast<Layout::InlineFormattingState>(layoutState.establishedFormattingState(container)));
     190            paintInlineContent(context, absoluteDisplayBox, downcast<Layout::InlineFormattingState>(layoutState.establishedFormattingState(container)));
    180191            continue;
    181192        }
  • trunk/Source/WebCore/layout/displaytree/DisplayPainter.h

    r250769 r251640  
    3131
    3232class GraphicsContext;
     33class IntRect;
    3334
    3435namespace Layout {
     
    4041class Painter {
    4142public:
    42     static void paint(const Layout::LayoutState&, GraphicsContext&);
     43    static void paint(const Layout::LayoutState&, GraphicsContext&, const IntRect& dirtyRect);
    4344};
    4445
  • trunk/Source/WebCore/page/FrameView.cpp

    r251638 r251640  
    41824182    if (RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextEnabled()) {
    41834183        if (auto* layoutState = layoutContext().initialLayoutState())
    4184             Layout::LayoutContext::paint(*layoutState, context);
     4184            Layout::LayoutContext::paint(*layoutState, context, dirtyRect);
    41854185        return;
    41864186    }
Note: See TracChangeset for help on using the changeset viewer.