Changeset 230544 in webkit


Ignore:
Timestamp:
Apr 11, 2018 1:29:49 PM (6 years ago)
Author:
commit-queue@webkit.org
Message:

Cache glyphs (using display lists) when painting at high frequency
https://bugs.webkit.org/show_bug.cgi?id=178750
<rdar://problem/35201729>

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2018-04-11
Reviewed by Antti Koivisto.

This patch adds support for caching of glyph drawing commands when painting
at high frequency. Caching the glyph drawing will be done using DisplayLists.

GlyphDisplayListCache is basically a hash map which maps InlineTextBox
or SimpleLineLayout::Run to DisplayList. Before adding a new entry to it
we have to check whether the conditions for caching the glyph DisplayList
are met or not. If no entry is found for a given run, a new DisplayList
is created and a new entry is add to the cache.

  • WebCore.xcodeproj/project.pbxproj:
  • page/MemoryRelease.cpp:

(WebCore::releaseNoncriticalMemory): Make GlyphDisplayListCache respond
to memory pressure.

  • platform/graphics/FontCascade.cpp:

(WebCore::FontCascade::displayListForTextRun const):

  • platform/graphics/FontCascade.h:

(WebCore::FontCascade::displayListForTextRun):
Record the drawing of a glyph run into a DisplayList.

  • rendering/GlyphDisplayListCache.h: Added.

(WebCore::GlyphDisplayListCache::singleton):
(WebCore::GlyphDisplayListCache::get):
(WebCore::GlyphDisplayListCache::remove):
(WebCore::GlyphDisplayListCache::clear):
(WebCore::GlyphDisplayListCache::size const):
(WebCore::GlyphDisplayListCache::sizeInBytes const):
A simple cache for the TextRun DisplayList. Adding a new entry in the
cache happens under restricted conditions. So this cache is not expected
to grow much.

  • rendering/InlineTextBox.cpp:

(WebCore::InlineTextBox::~InlineTextBox):
(WebCore::InlineTextBox::paint):
(WebCore::InlineTextBox::paintMarkedTexts):
(WebCore::InlineTextBox::paintMarkedTextBackground):
(WebCore::InlineTextBox::paintMarkedTextForeground):
(WebCore::InlineTextBox::paintMarkedTextDecoration):
(WebCore::InlineTextBox::paintCompositionBackground):
(WebCore::InlineTextBox::paintCompositionUnderlines const):
(WebCore::InlineTextBox::paintCompositionUnderline const):

  • rendering/InlineTextBox.h:

(WebCore::InlineTextBox::paintMarkedTexts):
InlineTextBox::paintMarkedTextForeground() now requires PaintInfo to know
whether the entry in the GlyphDisplayListCache should be removed or not.
Change all the GraphicsContext arguments to be PaintInfo.

  • rendering/SimpleLineLayout.cpp:

(WebCore::SimpleLineLayout::Layout::~Layout):

  • rendering/SimpleLineLayout.h:
  • rendering/SimpleLineLayoutFunctions.cpp:

(WebCore::SimpleLineLayout::paintFlow):
(WebCore::SimpleLineLayout::simpleLineLayoutWillBeDeleted):

  • rendering/SimpleLineLayoutFunctions.h:
  • rendering/SimpleLineLayoutResolver.h:

(WebCore::SimpleLineLayout::RunResolver::Run::simpleRun const):
Implement the glyph caching for SimpleLineLayout::Run.

  • rendering/TextPainter.cpp:

(WebCore::TextPainter::paintTextOrEmphasisMarks): If the DisplayList is
available, replay it back into the GraphicsContext. Make sure to reset to
the DisplayList pointer to nullptr after painting.

(WebCore::TextPainter::clearGlyphDisplayLists):
(WebCore::TextPainter::shouldUseGlyphDisplayList): Check whether we should
use DisplayList to the draw glyph run.

  • rendering/TextPainter.h:

(WebCore::TextPainter::setGlyphDisplayListIfNeeded): Check whether we should
should use DisplayList to the draw glyph run and if we should, ensure first
the DisplayList is cached and set it in the TextPainter so it uses it when
the run is painted.

(WebCore::TextPainter::removeGlyphDisplayList): Remove the cached DisplayList
entry for a glyph layout run.

Location:
trunk/Source/WebCore
Files:
1 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r230542 r230544  
     12018-04-11  Said Abou-Hallawa  <sabouhallawa@apple.com>
     2
     3        Cache glyphs (using display lists) when painting at high frequency
     4        https://bugs.webkit.org/show_bug.cgi?id=178750
     5        <rdar://problem/35201729>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        This patch adds support for caching of glyph drawing commands when painting
     10        at high frequency. Caching the glyph drawing will be done using DisplayLists.
     11
     12        GlyphDisplayListCache is basically a hash map which maps InlineTextBox
     13        or SimpleLineLayout::Run to DisplayList. Before adding a new entry to it
     14        we have to check whether the conditions for caching the glyph DisplayList
     15        are met or not. If no entry is found for a given run, a new DisplayList
     16        is created and a new entry is add to the cache.
     17
     18        * WebCore.xcodeproj/project.pbxproj:
     19        * page/MemoryRelease.cpp:
     20        (WebCore::releaseNoncriticalMemory): Make GlyphDisplayListCache respond
     21        to memory pressure.
     22
     23        * platform/graphics/FontCascade.cpp:
     24        (WebCore::FontCascade::displayListForTextRun const):
     25        * platform/graphics/FontCascade.h:
     26        (WebCore::FontCascade::displayListForTextRun):
     27        Record the drawing of a glyph run into a DisplayList.
     28
     29        * rendering/GlyphDisplayListCache.h: Added.
     30        (WebCore::GlyphDisplayListCache::singleton):
     31        (WebCore::GlyphDisplayListCache::get):
     32        (WebCore::GlyphDisplayListCache::remove):
     33        (WebCore::GlyphDisplayListCache::clear):
     34        (WebCore::GlyphDisplayListCache::size const):
     35        (WebCore::GlyphDisplayListCache::sizeInBytes const):
     36        A simple cache for the TextRun DisplayList. Adding a new entry in the
     37        cache happens under restricted conditions. So this cache is not expected
     38        to grow much.
     39
     40        * rendering/InlineTextBox.cpp:
     41        (WebCore::InlineTextBox::~InlineTextBox):
     42        (WebCore::InlineTextBox::paint):
     43        (WebCore::InlineTextBox::paintMarkedTexts):
     44        (WebCore::InlineTextBox::paintMarkedTextBackground):
     45        (WebCore::InlineTextBox::paintMarkedTextForeground):
     46        (WebCore::InlineTextBox::paintMarkedTextDecoration):
     47        (WebCore::InlineTextBox::paintCompositionBackground):
     48        (WebCore::InlineTextBox::paintCompositionUnderlines const):
     49        (WebCore::InlineTextBox::paintCompositionUnderline const):
     50        * rendering/InlineTextBox.h:
     51        (WebCore::InlineTextBox::paintMarkedTexts):
     52        InlineTextBox::paintMarkedTextForeground() now requires PaintInfo to know
     53        whether the entry in the GlyphDisplayListCache should be removed or not.
     54        Change all the GraphicsContext arguments to be PaintInfo.
     55
     56        * rendering/SimpleLineLayout.cpp:
     57        (WebCore::SimpleLineLayout::Layout::~Layout):
     58        * rendering/SimpleLineLayout.h:
     59        * rendering/SimpleLineLayoutFunctions.cpp:
     60        (WebCore::SimpleLineLayout::paintFlow):
     61        (WebCore::SimpleLineLayout::simpleLineLayoutWillBeDeleted):
     62        * rendering/SimpleLineLayoutFunctions.h:
     63        * rendering/SimpleLineLayoutResolver.h:
     64        (WebCore::SimpleLineLayout::RunResolver::Run::simpleRun const):
     65        Implement the glyph caching for SimpleLineLayout::Run.
     66
     67        * rendering/TextPainter.cpp:
     68        (WebCore::TextPainter::paintTextOrEmphasisMarks): If the DisplayList is
     69        available, replay it back into the GraphicsContext. Make sure to reset to
     70        the DisplayList pointer to nullptr after painting.
     71
     72        (WebCore::TextPainter::clearGlyphDisplayLists):
     73        (WebCore::TextPainter::shouldUseGlyphDisplayList): Check whether we should
     74        use DisplayList to the draw glyph run.
     75
     76        * rendering/TextPainter.h:
     77        (WebCore::TextPainter::setGlyphDisplayListIfNeeded): Check whether we should
     78        should use DisplayList to the draw glyph run and if we should, ensure first
     79        the DisplayList is cached and set it in the TextPainter so it uses it when
     80        the run is painted.
     81
     82        (WebCore::TextPainter::removeGlyphDisplayList): Remove the cached DisplayList
     83        entry for a glyph layout run.
     84
    1852018-04-11  Brent Fulgham  <bfulgham@apple.com>
    286
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r230368 r230544  
    82558255                5576A5621D88A70800CCC04C /* ImageFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFrame.cpp; sourceTree = "<group>"; };
    82568256                5576A5631D88A70800CCC04C /* ImageFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFrame.h; sourceTree = "<group>"; };
     8257                5597FCCB2076C06800D35BB0 /* GlyphDisplayListCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlyphDisplayListCache.h; sourceTree = "<group>"; };
    82578258                55A336F61D8209F40022C4C7 /* NativeImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeImage.h; sourceTree = "<group>"; };
    82588259                55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBackingStore.h; sourceTree = "<group>"; };
     
    2547925480                                9A528E8217D7F52F00AA9518 /* FloatingObjects.h */,
    2548025481                                935C477409AC4D8D00A6AAB4 /* GapRects.h */,
     25482                                5597FCCB2076C06800D35BB0 /* GlyphDisplayListCache.h */,
    2548125483                                E112F4701E3A85F200D6CDFD /* Grid.cpp */,
    2548225484                                E112F46F1E3A85D800D6CDFD /* Grid.h */,
  • trunk/Source/WebCore/page/MemoryRelease.cpp

    r230211 r230544  
    4747#include "StyleScope.h"
    4848#include "StyledElement.h"
     49#include "TextPainter.h"
    4950#include "WorkerThread.h"
    5051#include <wtf/FastMalloc.h>
     
    6566
    6667    clearWidthCaches();
     68    TextPainter::clearGlyphDisplayLists();
    6769
    6870    for (auto* document : Document::allDocuments())
  • trunk/Source/WebCore/platform/graphics/FontCascade.cpp

    r224223 r230544  
    2727#include "CharacterProperties.h"
    2828#include "ComplexTextController.h"
     29#include "DisplayListRecorder.h"
    2930#include "FloatRect.h"
    3031#include "FontCache.h"
     
    306307}
    307308
     309std::unique_ptr<DisplayList::DisplayList> FontCascade::displayListForTextRun(GraphicsContext& context, const TextRun& run, unsigned from, std::optional<unsigned> to, CustomFontNotReadyAction customFontNotReadyAction) const
     310{
     311    ASSERT(!context.paintingDisabled());
     312    unsigned destination = to.value_or(run.length());
     313   
     314    // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
     315    CodePath codePathToUse = codePath(run);
     316    if (codePathToUse != Complex && (enableKerning() || requiresShaping()) && (from || destination != run.length()))
     317        codePathToUse = Complex;
     318   
     319    GlyphBuffer glyphBuffer;
     320    float startX = glyphBufferForTextRun(codePathToUse, run, from, destination, glyphBuffer);
     321    // We couldn't generate any glyphs for the run. Give up.
     322    if (glyphBuffer.isEmpty())
     323        return nullptr;
     324   
     325    std::unique_ptr<DisplayList::DisplayList> displayList = std::make_unique<DisplayList::DisplayList>();
     326    GraphicsContext recordingContext([&](GraphicsContext& displayListContext) {
     327        return std::make_unique<DisplayList::Recorder>(displayListContext, *displayList, context.state(), FloatRect(), AffineTransform());
     328    });
     329   
     330    FloatPoint startPoint(startX, 0);
     331    drawGlyphBuffer(recordingContext, glyphBuffer, startPoint, customFontNotReadyAction);
     332    return displayList;
     333}
     334   
    308335float FontCascade::widthOfTextRange(const TextRun& run, unsigned from, unsigned to, HashSet<const Font*>* fallbackFonts, float* outWidthBeforeRange, float* outWidthAfterRange) const
    309336{
  • trunk/Source/WebCore/platform/graphics/FontCascade.h

    r224223 r230544  
    4949class TextRun;
    5050
     51namespace DisplayList {
     52class DisplayList;
     53}
     54   
    5155struct GlyphData;
    5256
     
    198202    WeakPtr<FontCascade> createWeakPtr() const { return m_weakPtrFactory.createWeakPtr(*const_cast<FontCascade*>(this)); }
    199203
     204    std::unique_ptr<DisplayList::DisplayList> displayListForTextRun(GraphicsContext&, const TextRun&, unsigned from = 0, std::optional<unsigned> to = { }, CustomFontNotReadyAction = CustomFontNotReadyAction::DoNotPaintIfFontNotReady) const;
     205   
    200206private:
    201207    enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis };
  • trunk/Source/WebCore/rendering/InlineTextBox.cpp

    r230452 r230544  
    7474    if (!knownToHaveNoOverflow() && gTextBoxesWithOverflow)
    7575        gTextBoxesWithOverflow->remove(this);
     76    TextPainter::removeGlyphDisplayList(*this);
    7677}
    7778
     
    504505    if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseTextClip && !isPrinting) {
    505506        if (containsComposition && !useCustomUnderlines)
    506             paintCompositionBackground(context, boxOrigin);
     507            paintCompositionBackground(paintInfo, boxOrigin);
    507508
    508509        Vector<MarkedText> markedTexts = collectMarkedTextsForDocumentMarkers(TextPaintPhase::Background);
     
    519520        auto coalescedStyledMarkedTexts = coalesceAdjacentMarkedTexts(styledMarkedTexts, &MarkedTextStyle::areBackgroundMarkedTextStylesEqual);
    520521
    521         paintMarkedTexts(context, TextPaintPhase::Background, boxRect, coalescedStyledMarkedTexts);
     522        paintMarkedTexts(paintInfo, TextPaintPhase::Background, boxRect, coalescedStyledMarkedTexts);
    522523    }
    523524
     
    565566    auto coalescedStyledMarkedTexts = coalesceAdjacentMarkedTexts(styledMarkedTexts, &MarkedTextStyle::areForegroundMarkedTextStylesEqual);
    566567
    567     paintMarkedTexts(context, TextPaintPhase::Foreground, boxRect, coalescedStyledMarkedTexts);
     568    paintMarkedTexts(paintInfo, TextPaintPhase::Foreground, boxRect, coalescedStyledMarkedTexts);
    568569
    569570    // Paint decorations
     
    602603        auto coalescedStyledMarkedTexts = coalesceAdjacentMarkedTexts(styledMarkedTexts, &MarkedTextStyle::areDecorationMarkedTextStylesEqual);
    603604
    604         paintMarkedTexts(context, TextPaintPhase::Decoration, boxRect, coalescedStyledMarkedTexts, textDecorationSelectionClipOutRect);
     605        paintMarkedTexts(paintInfo, TextPaintPhase::Decoration, boxRect, coalescedStyledMarkedTexts, textDecorationSelectionClipOutRect);
    605606    }
    606607
     
    610611
    611612        if (useCustomUnderlines)
    612             paintCompositionUnderlines(context, boxOrigin);
     613            paintCompositionUnderlines(paintInfo, boxOrigin);
    613614    }
    614615   
     
    944945}
    945946
    946 void InlineTextBox::paintMarkedTexts(GraphicsContext& context, TextPaintPhase phase, const FloatRect& boxRect, const Vector<StyledMarkedText>& markedTexts, const FloatRect& decorationClipOutRect)
     947void InlineTextBox::paintMarkedTexts(PaintInfo& paintInfo, TextPaintPhase phase, const FloatRect& boxRect, const Vector<StyledMarkedText>& markedTexts, const FloatRect& decorationClipOutRect)
    947948{
    948949    switch (phase) {
    949950    case TextPaintPhase::Background:
    950951        for (auto& markedText : markedTexts)
    951             paintMarkedTextBackground(context, boxRect.location(), markedText.style.backgroundColor, markedText.startOffset, markedText.endOffset);
     952            paintMarkedTextBackground(paintInfo, boxRect.location(), markedText.style.backgroundColor, markedText.startOffset, markedText.endOffset);
    952953        return;
    953954    case TextPaintPhase::Foreground:
    954955        for (auto& markedText : markedTexts)
    955             paintMarkedTextForeground(context, boxRect, markedText);
     956            paintMarkedTextForeground(paintInfo, boxRect, markedText);
    956957        return;
    957958    case TextPaintPhase::Decoration:
    958959        for (auto& markedText : markedTexts)
    959             paintMarkedTextDecoration(context, boxRect, decorationClipOutRect, markedText);
    960         return;
    961     }
    962 }
    963 
    964 void InlineTextBox::paintMarkedTextBackground(GraphicsContext& context, const FloatPoint& boxOrigin, const Color& color, unsigned clampedStartOffset, unsigned clampedEndOffset)
     960            paintMarkedTextDecoration(paintInfo, boxRect, decorationClipOutRect, markedText);
     961        return;
     962    }
     963}
     964
     965void InlineTextBox::paintMarkedTextBackground(PaintInfo& paintInfo, const FloatPoint& boxOrigin, const Color& color, unsigned clampedStartOffset, unsigned clampedEndOffset)
    965966{
    966967    if (clampedStartOffset >= clampedEndOffset)
    967968        return;
    968969
     970    GraphicsContext& context = paintInfo.context();
    969971    GraphicsContextStateSaver stateSaver { context };
    970972    updateGraphicsContext(context, TextPaintStyle { color }); // Don't draw text at all!
     
    990992}
    991993
    992 void InlineTextBox::paintMarkedTextForeground(GraphicsContext& context, const FloatRect& boxRect, const StyledMarkedText& markedText)
     994void InlineTextBox::paintMarkedTextForeground(PaintInfo& paintInfo, const FloatRect& boxRect, const StyledMarkedText& markedText)
    993995{
    994996    if (markedText.startOffset >= markedText.endOffset)
    995997        return;
    996998
     999    GraphicsContext& context = paintInfo.context();
    9971000    const FontCascade& font = lineFont();
    9981001    const RenderStyle& lineStyle = this->lineStyle();
     
    10131016    textPainter.setEmphasisMark(emphasisMark, emphasisMarkOffset, combinedText());
    10141017
     1018    TextRun textRun = createTextRun();
     1019    textPainter.setGlyphDisplayListIfNeeded(*this, paintInfo, font, context, textRun);
     1020
    10151021    GraphicsContextStateSaver stateSaver { context, false };
    10161022    if (markedText.type == MarkedText::DraggedContent) {
     
    10191025    }
    10201026    // TextPainter wants the box rectangle and text origin of the entire line box.
    1021     textPainter.paintRange(createTextRun(), boxRect, textOriginFromBoxRect(boxRect), markedText.startOffset, markedText.endOffset);
    1022 }
    1023 
    1024 void InlineTextBox::paintMarkedTextDecoration(GraphicsContext& context, const FloatRect& boxRect, const FloatRect& clipOutRect, const StyledMarkedText& markedText)
     1027    textPainter.paintRange(textRun, boxRect, textOriginFromBoxRect(boxRect), markedText.startOffset, markedText.endOffset);
     1028}
     1029
     1030void InlineTextBox::paintMarkedTextDecoration(PaintInfo& paintInfo, const FloatRect& boxRect, const FloatRect& clipOutRect, const StyledMarkedText& markedText)
    10251031{
    10261032    if (m_truncation == cFullTruncation)
    10271033        return;
    10281034
     1035    GraphicsContext& context = paintInfo.context();
    10291036    updateGraphicsContext(context, markedText.style.textStyles);
    10301037
     
    10741081}
    10751082
    1076 void InlineTextBox::paintCompositionBackground(GraphicsContext& context, const FloatPoint& boxOrigin)
    1077 {
    1078     paintMarkedTextBackground(context, boxOrigin, Color::compositionFill, clampedOffset(renderer().frame().editor().compositionStart()), clampedOffset(renderer().frame().editor().compositionEnd()));
    1079 }
    1080 
    1081 void InlineTextBox::paintCompositionUnderlines(GraphicsContext& context, const FloatPoint& boxOrigin) const
     1083void InlineTextBox::paintCompositionBackground(PaintInfo& paintInfo, const FloatPoint& boxOrigin)
     1084{
     1085    paintMarkedTextBackground(paintInfo, boxOrigin, Color::compositionFill, clampedOffset(renderer().frame().editor().compositionStart()), clampedOffset(renderer().frame().editor().compositionEnd()));
     1086}
     1087
     1088void InlineTextBox::paintCompositionUnderlines(PaintInfo& paintInfo, const FloatPoint& boxOrigin) const
    10821089{
    10831090    if (m_truncation == cFullTruncation)
     
    10961103
    10971104        // Underline intersects this run. Paint it.
    1098         paintCompositionUnderline(context, boxOrigin, underline);
     1105        paintCompositionUnderline(paintInfo, boxOrigin, underline);
    10991106
    11001107        if (underline.endOffset > end() + 1)
     
    11101117}
    11111118
    1112 void InlineTextBox::paintCompositionUnderline(GraphicsContext& context, const FloatPoint& boxOrigin, const CompositionUnderline& underline) const
     1119void InlineTextBox::paintCompositionUnderline(PaintInfo& paintInfo, const FloatPoint& boxOrigin, const CompositionUnderline& underline) const
    11131120{
    11141121    if (m_truncation == cFullTruncation)
     
    11511158    width -= 2;
    11521159
     1160    GraphicsContext& context = paintInfo.context();
    11531161    context.setStrokeColor(underline.compositionUnderlineColor == CompositionUnderlineColor::TextColor ? renderer().style().visitedDependentColor(CSSPropertyWebkitTextFillColor) : underline.color);
    11541162    context.setStrokeThickness(lineThickness);
  • trunk/Source/WebCore/rendering/InlineTextBox.h

    r230452 r230544  
    169169    FloatPoint textOriginFromBoxRect(const FloatRect&) const;
    170170
    171     void paintMarkedTexts(GraphicsContext&, TextPaintPhase, const FloatRect& boxRect, const Vector<StyledMarkedText>&, const FloatRect& decorationClipOutRect = { });
     171    void paintMarkedTexts(PaintInfo&, TextPaintPhase, const FloatRect& boxRect, const Vector<StyledMarkedText>&, const FloatRect& decorationClipOutRect = { });
    172172
    173173    void paintPlatformDocumentMarker(GraphicsContext&, const FloatPoint& boxOrigin, const MarkedText&);
    174174    void paintPlatformDocumentMarkers(GraphicsContext&, const FloatPoint& boxOrigin);
    175175
    176     void paintCompositionBackground(GraphicsContext&, const FloatPoint& boxOrigin);
    177     void paintCompositionUnderlines(GraphicsContext&, const FloatPoint& boxOrigin) const;
    178     void paintCompositionUnderline(GraphicsContext&, const FloatPoint& boxOrigin, const CompositionUnderline&) const;
    179 
    180     void paintMarkedTextBackground(GraphicsContext&, const FloatPoint& boxOrigin, const Color&, unsigned clampedStartOffset, unsigned clampedEndOffset);
    181     void paintMarkedTextForeground(GraphicsContext&, const FloatRect& boxRect, const StyledMarkedText&);
    182     void paintMarkedTextDecoration(GraphicsContext&, const FloatRect& boxRect, const FloatRect& clipOutRect, const StyledMarkedText&);
     176    void paintCompositionBackground(PaintInfo&, const FloatPoint& boxOrigin);
     177    void paintCompositionUnderlines(PaintInfo&, const FloatPoint& boxOrigin) const;
     178    void paintCompositionUnderline(PaintInfo&, const FloatPoint& boxOrigin, const CompositionUnderline&) const;
     179
     180    void paintMarkedTextBackground(PaintInfo&, const FloatPoint& boxOrigin, const Color&, unsigned clampedStartOffset, unsigned clampedEndOffset);
     181    void paintMarkedTextForeground(PaintInfo&, const FloatRect& boxRect, const StyledMarkedText&);
     182    void paintMarkedTextDecoration(PaintInfo&, const FloatRect& boxRect, const FloatRect& clipOutRect, const StyledMarkedText&);
    183183
    184184    const RenderCombineText* combinedText() const;
  • trunk/Source/WebCore/rendering/SimpleLineLayout.cpp

    r230452 r230544  
    979979}
    980980
    981 }
    982 }
     981Layout::~Layout()
     982{
     983    simpleLineLayoutWillBeDeleted(*this);
     984}
     985
     986}
     987}
  • trunk/Source/WebCore/rendering/SimpleLineLayout.h

    r213009 r230544  
    8282    static std::unique_ptr<Layout> create(const RunVector&, unsigned lineCount);
    8383
     84    ~Layout();
     85
    8486    unsigned lineCount() const { return m_lineCount; }
    8587
  • trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp

    r226138 r230544  
    121121        textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize());
    122122        FloatPoint textOrigin { rect.x() + paintOffset.x(), roundToDevicePixel(run.baselinePosition() + paintOffset.y(), deviceScaleFactor) };
     123
     124        textPainter.setGlyphDisplayListIfNeeded(run.simpleRun(), paintInfo, style.fontCascade(), paintInfo.context(), textRun);
    123125        textPainter.paint(textRun, rect, textOrigin);
    124126        if (textDecorationPainter) {
     
    262264}
    263265
     266void simpleLineLayoutWillBeDeleted(const Layout& layout)
     267{
     268    for (unsigned i = 0; i < layout.runCount(); ++i)
     269        TextPainter::removeGlyphDisplayList(layout.runAt(i));
     270}
     271
    264272#if ENABLE(TREE_DEBUGGING)
    265273static void printPrefix(TextStream& stream, int& printedCharacters, int depth)
  • trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.h

    r225117 r230544  
    6666
    6767const RenderObject& rendererForPosition(const FlowContents&, unsigned);
     68
     69void simpleLineLayoutWillBeDeleted(const Layout&);
    6870
    6971#if ENABLE(TREE_DEBUGGING)
  • trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.h

    r218793 r230544  
    5757        bool isEndOfLine() const;
    5858        bool hasHyphen() const { return m_iterator.simpleRun().hasHyphen; }
     59        const SimpleLineLayout::Run& simpleRun() const { return m_iterator.simpleRun(); }
    5960
    6061        unsigned lineIndex() const;
  • trunk/Source/WebCore/rendering/TextPainter.cpp

    r226138 r230544  
    2424#include "TextPainter.h"
    2525
     26#include "DisplayListReplayer.h"
    2627#include "GraphicsContext.h"
    2728#include "InlineTextBox.h"
    2829#include "RenderCombineText.h"
     30#include "RenderLayer.h"
    2931#include "ShadowData.h"
    3032#include <wtf/NeverDestroyed.h>
     
    99101{
    100102    ASSERT(startOffset < endOffset);
    101     if (emphasisMark.isEmpty())
     103    if (!emphasisMark.isEmpty())
     104        m_context.drawEmphasisMarks(font, textRun, emphasisMark, textOrigin + FloatSize(0, emphasisMarkOffset), startOffset, endOffset);
     105    else if (startOffset || endOffset < textRun.length() || !m_glyphDisplayList)
    102106        m_context.drawText(font, textRun, textOrigin, startOffset, endOffset);
    103     else
    104         m_context.drawEmphasisMarks(font, textRun, emphasisMark, textOrigin + FloatSize(0, emphasisMarkOffset), startOffset, endOffset);
     107    else {
     108        // Replaying back a whole cached glyph run to the GraphicsContext.
     109        m_context.translate(textOrigin);
     110        DisplayList::Replayer replayer(m_context, *m_glyphDisplayList);
     111        replayer.replay();
     112        m_context.translate(-textOrigin);
     113    }
     114    m_glyphDisplayList = nullptr;
    105115}
    106116
     
    196206}
    197207
     208void TextPainter::clearGlyphDisplayLists()
     209{
     210    GlyphDisplayListCache<InlineTextBox>::singleton().clear();
     211    GlyphDisplayListCache<SimpleLineLayout::Run>::singleton().clear();
     212}
     213
     214bool TextPainter::shouldUseGlyphDisplayList(const PaintInfo& paintInfo)
     215{
     216    return !paintInfo.context().paintingDisabled() && paintInfo.enclosingSelfPaintingLayer() && paintInfo.enclosingSelfPaintingLayer()->paintingFrequently();
     217}
     218
    198219} // namespace WebCore
  • trunk/Source/WebCore/rendering/TextPainter.h

    r226138 r230544  
    2525#include "AffineTransform.h"
    2626#include "FloatRect.h"
     27#include "GlyphDisplayListCache.h"
    2728#include "TextFlags.h"
    2829#include "TextPaintStyle.h"
     
    5960    void paintRange(const TextRun&, const FloatRect& boxRect, const FloatPoint& textOrigin, unsigned start, unsigned end);
    6061
     62    template<typename LayoutRun>
     63    void setGlyphDisplayListIfNeeded(const LayoutRun& run, const PaintInfo& paintInfo, const FontCascade& font, GraphicsContext& context, const TextRun& textRun)
     64    {
     65        if (!TextPainter::shouldUseGlyphDisplayList(paintInfo))
     66            TextPainter::removeGlyphDisplayList(run);
     67        else
     68            m_glyphDisplayList = GlyphDisplayListCache<LayoutRun>::singleton().get(run, font, context, textRun);
     69    }
     70
     71    template<typename LayoutRun>
     72    static void removeGlyphDisplayList(const LayoutRun& run) { GlyphDisplayListCache<LayoutRun>::singleton().remove(run); }
     73
     74    static void clearGlyphDisplayLists();
     75    static bool shouldUseGlyphDisplayList(const PaintInfo&);
     76
    6177private:
    6278    void paintTextOrEmphasisMarks(const FontCascade&, const TextRun&, const AtomicString& emphasisMark, float emphasisMarkOffset,
     
    7591    float m_emphasisMarkOffset { 0 };
    7692    bool m_textBoxIsHorizontal { true };
     93    DisplayList::DisplayList* m_glyphDisplayList { nullptr };
    7794};
    7895
Note: See TracChangeset for help on using the changeset viewer.