WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
patch.txt (text/plain), 34.18 KB, created by
Dave Hyatt
on 2017-10-26 09:33:22 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Dave Hyatt
Created:
2017-10-26 09:33:22 PDT
Size:
34.18 KB
patch
obsolete
>Index: Source/WebCore/platform/graphics/FontCascade.h >=================================================================== >--- Source/WebCore/platform/graphics/FontCascade.h (revision 223973) >+++ Source/WebCore/platform/graphics/FontCascade.h (working copy) >@@ -196,15 +196,16 @@ public: > bool primaryFontIsSystemFont() const; > > WeakPtr<FontCascade> createWeakPtr() const { return m_weakPtrFactory.createWeakPtr(*const_cast<FontCascade*>(this)); } >+ >+ void drawGlyphBuffer(GraphicsContext&, const GlyphBuffer&, FloatPoint&, CustomFontNotReadyAction) const; >+ float glyphBufferForTextRun(CodePath, const TextRun&, unsigned from, unsigned to, GlyphBuffer&) const; > > private: > enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis }; > >- float glyphBufferForTextRun(CodePath, const TextRun&, unsigned from, unsigned to, GlyphBuffer&) const; > // Returns the initial in-stream advance. > float getGlyphsAndAdvancesForSimpleText(const TextRun&, unsigned from, unsigned to, GlyphBuffer&, ForTextEmphasisOrNot = NotForTextEmphasis) const; > void drawEmphasisMarksForSimpleText(GraphicsContext&, const TextRun&, const AtomicString& mark, const FloatPoint&, unsigned from, unsigned to) const; >- void drawGlyphBuffer(GraphicsContext&, const GlyphBuffer&, FloatPoint&, CustomFontNotReadyAction) const; > void drawEmphasisMarks(GraphicsContext&, const GlyphBuffer&, const AtomicString&, const FloatPoint&) const; > float floatWidthForSimpleText(const TextRun&, HashSet<const Font*>* fallbackFonts = 0, GlyphOverflow* = 0) const; > int offsetForPositionForSimpleText(const TextRun&, float position, bool includePartialGlyphs) const; >Index: Source/WebCore/rendering/InlineTextBox.cpp >=================================================================== >--- Source/WebCore/rendering/InlineTextBox.cpp (revision 223973) >+++ Source/WebCore/rendering/InlineTextBox.cpp (working copy) >@@ -39,6 +39,7 @@ > #include "PaintInfo.h" > #include "RenderBlock.h" > #include "RenderCombineText.h" >+#include "RenderLayer.h" > #include "RenderLineBreak.h" > #include "RenderRubyRun.h" > #include "RenderRubyText.h" >@@ -62,14 +63,20 @@ struct SameSizeAsInlineTextBox : public > }; > > COMPILE_ASSERT(sizeof(InlineTextBox) == sizeof(SameSizeAsInlineTextBox), InlineTextBox_should_stay_small); >- >+ > typedef WTF::HashMap<const InlineTextBox*, LayoutRect> InlineTextBoxOverflowMap; >+typedef WTF::HashMap<const InlineTextBox*, GlyphBufferInfo*> InlineTextBoxGlyphBufferMap; >+ > static InlineTextBoxOverflowMap* gTextBoxesWithOverflow; >+static InlineTextBoxGlyphBufferMap* gTextBoxesWithGlyphBuffers; > > InlineTextBox::~InlineTextBox() > { > if (!knownToHaveNoOverflow() && gTextBoxesWithOverflow) > gTextBoxesWithOverflow->remove(this); >+ >+ if (gTextBoxesWithGlyphBuffers) >+ gTextBoxesWithGlyphBuffers->remove(this); > } > > void InlineTextBox::markDirty(bool dirty) >@@ -519,6 +526,9 @@ void InlineTextBox::paint(PaintInfo& pai > else > textOrigin.setX(roundToDevicePixel(LayoutUnit(textOrigin.x()), renderer().document().deviceScaleFactor())); > >+ if (!gTextBoxesWithGlyphBuffers) >+ gTextBoxesWithGlyphBuffers = new InlineTextBoxGlyphBufferMap; >+ > TextPainter textPainter(context); > textPainter.setFont(font); > textPainter.setStyle(textPaintStyle); >@@ -528,6 +538,26 @@ void InlineTextBox::paint(PaintInfo& pai > textPainter.setSelectionShadow(selectionShadow); > textPainter.setEmphasisMark(emphasisMark, emphasisMarkOffset, combinedText); > >+ GlyphBufferInfo* glyphBufferInfo = gTextBoxesWithGlyphBuffers->get(this); >+ if (paintInfo.enclosingSelfPaintingLayer()) { >+ if (paintInfo.paintingFrequently()) { >+ if (!glyphBufferInfo) { >+ // Generate and cache the glyph buffer info. >+ FontCascade::CodePath codePathToUse = font.codePath(textRun); >+ glyphBufferInfo = new GlyphBufferInfo(); >+ float glyphInitialAdvance = font.glyphBufferForTextRun(codePathToUse, textRun, 0, length, (*glyphBufferInfo).glyphBuffer); >+ glyphBufferInfo->initialAdvance = glyphInitialAdvance; >+ gTextBoxesWithGlyphBuffers->add(this, glyphBufferInfo); >+ } >+ } else if (glyphBufferInfo) { >+ gTextBoxesWithGlyphBuffers->remove(this); >+ glyphBufferInfo = nullptr; >+ } >+ paintInfo.enclosingSelfPaintingLayer()->notifyPaintHasCachableResources(); >+ } >+ if (glyphBufferInfo) >+ textPainter.setGlyphBuffer(&glyphBufferInfo->glyphBuffer, glyphBufferInfo->initialAdvance); >+ > auto draggedContentRanges = renderer().draggedContentRangesBetweenOffsets(m_start, m_start + m_len); > if (!draggedContentRanges.isEmpty() && !paintSelectedTextOnly && !paintNonSelectedTextOnly) { > // FIXME: Painting with text effects ranges currently only works if we're not also painting the selection. >Index: Source/WebCore/rendering/InlineTextBox.h >=================================================================== >--- Source/WebCore/rendering/InlineTextBox.h (revision 223973) >+++ Source/WebCore/rendering/InlineTextBox.h (working copy) >@@ -23,6 +23,7 @@ > #pragma once > > #include "InlineBox.h" >+#include "GlyphBuffer.h" > #include "RenderText.h" > #include "TextRun.h" > >@@ -38,6 +39,12 @@ struct TextPaintStyle; > const unsigned short cNoTruncation = USHRT_MAX; > const unsigned short cFullTruncation = USHRT_MAX - 1; > >+struct GlyphBufferInfo >+{ >+ float initialAdvance; >+ GlyphBuffer glyphBuffer; >+}; >+ > class InlineTextBox : public InlineBox { > public: > explicit InlineTextBox(RenderText& renderer) >Index: Source/WebCore/rendering/PaintInfo.h >=================================================================== >--- Source/WebCore/rendering/PaintInfo.h (revision 223973) >+++ Source/WebCore/rendering/PaintInfo.h (working copy) >@@ -38,6 +38,7 @@ namespace WebCore { > > class OverlapTestRequestClient; > class RenderInline; >+class RenderLayer; > class RenderLayerModelObject; > class RenderObject; > >@@ -51,6 +52,7 @@ struct PaintInfo { > PaintInfo(GraphicsContext& newContext, const LayoutRect& newRect, PaintPhase newPhase, PaintBehavior newPaintBehavior, > RenderObject* newSubtreePaintRoot = nullptr, ListHashSet<RenderInline*>* newOutlineObjects = nullptr, > OverlapTestRequestMap* overlapTestRequests = nullptr, const RenderLayerModelObject* newPaintContainer = nullptr, >+ RenderLayer* enclosingSelfPaintingLayer = nullptr, bool paintingFrequently = false, > bool newRequireSecurityOriginAccessForWidgets = false) > : rect(newRect) > , phase(newPhase) >@@ -60,6 +62,8 @@ struct PaintInfo { > , overlapTestRequests(overlapTestRequests) > , paintContainer(newPaintContainer) > , requireSecurityOriginAccessForWidgets(newRequireSecurityOriginAccessForWidgets) >+ , m_paintingFrequently(paintingFrequently) >+ , m_enclosingSelfPaintingLayer(enclosingSelfPaintingLayer) > , m_context(&newContext) > { > } >@@ -100,6 +104,9 @@ struct PaintInfo { > bool skipRootBackground() const { return paintBehavior & PaintBehaviorSkipRootBackground; } > bool paintRootBackgroundOnly() const { return paintBehavior & PaintBehaviorRootBackgroundOnly; } > >+ RenderLayer* enclosingSelfPaintingLayer() { return m_enclosingSelfPaintingLayer; } >+ bool paintingFrequently() const { return m_paintingFrequently; } >+ > void applyTransform(const AffineTransform& localToAncestorTransform) > { > if (localToAncestorTransform.isIdentity()) >@@ -123,6 +130,8 @@ struct PaintInfo { > OverlapTestRequestMap* overlapTestRequests; > const RenderLayerModelObject* paintContainer; // the layer object that originates the current painting > bool requireSecurityOriginAccessForWidgets { false }; >+ bool m_paintingFrequently { false }; >+ RenderLayer* m_enclosingSelfPaintingLayer { nullptr }; > > private: > GraphicsContext* m_context; >Index: Source/WebCore/rendering/RenderLayer.cpp >=================================================================== >--- Source/WebCore/rendering/RenderLayer.cpp (revision 223973) >+++ Source/WebCore/rendering/RenderLayer.cpp (working copy) >@@ -123,6 +123,7 @@ > #include "TranslateTransformOperation.h" > #include "WheelEventTestTrigger.h" > #include <stdio.h> >+#include <wtf/MonotonicTime.h> > #include <wtf/StdLibExtras.h> > #include <wtf/text/CString.h> > #include <wtf/text/TextStream.h> >@@ -133,6 +134,9 @@ > > #define MIN_INTERSECT_FOR_REVEAL 32 > >+#define PAINT_FREQUENCY_FPS_THRESHOLD 30 >+#define PAINT_FREQUENCY_SECONDS_IDLE_THRESHOLD 5 >+ > namespace WebCore { > > using namespace HTMLNames; >@@ -4291,6 +4295,19 @@ void RenderLayer::paintLayerContents(Gra > > bool selectionAndBackgroundsOnly = paintingInfo.paintBehavior & PaintBehaviorSelectionAndBackgroundsOnly; > bool selectionOnly = paintingInfo.paintBehavior & PaintBehaviorSelectionOnly; >+ >+ bool paintingFrequently = false; >+ if (shouldPaintContent) { >+ m_paintFrequencyInfo.paintedCachedResource = false; >+ if (m_paintFrequencyInfo.totalPaintsSinceFirst > 0) { >+ MonotonicTime now = MonotonicTime::now(); >+ if ((now - m_paintFrequencyInfo.lastPaintTime).seconds() > PAINT_FREQUENCY_SECONDS_IDLE_THRESHOLD) { >+ m_paintFrequencyInfo.firstPaintTime = m_paintFrequencyInfo.lastPaintTime = MonotonicTime(); >+ m_paintFrequencyInfo.totalPaintsSinceFirst = 0; >+ } else if ((m_paintFrequencyInfo.totalPaintsSinceFirst / (now - m_paintFrequencyInfo.firstPaintTime).seconds()) > PAINT_FREQUENCY_FPS_THRESHOLD) >+ paintingFrequently = true; >+ } >+ } > > LayerFragments layerFragments; > RenderObject* subtreePaintRootForRenderer = nullptr; >@@ -4354,7 +4371,7 @@ void RenderLayer::paintLayerContents(Gra > // Paint only the backgrounds for all of the fragments of the layer. > if (shouldPaintContent && !selectionOnly) { > paintBackgroundForFragments(layerFragments, currentContext, context, paintingInfo.paintDirtyRect, haveTransparency, >- localPaintingInfo, paintBehavior, subtreePaintRootForRenderer); >+ localPaintingInfo, paintBehavior, subtreePaintRootForRenderer, paintingFrequently); > } > } > >@@ -4365,12 +4382,12 @@ void RenderLayer::paintLayerContents(Gra > if (isPaintingCompositedForeground) { > if (shouldPaintContent) { > paintForegroundForFragments(layerFragments, currentContext, context, paintingInfo.paintDirtyRect, haveTransparency, >- localPaintingInfo, paintBehavior, subtreePaintRootForRenderer); >+ localPaintingInfo, paintBehavior, subtreePaintRootForRenderer, paintingFrequently); > } > } > > if (shouldPaintOutline) >- paintOutlineForFragments(layerFragments, currentContext, localPaintingInfo, paintBehavior, subtreePaintRootForRenderer); >+ paintOutlineForFragments(layerFragments, currentContext, localPaintingInfo, paintBehavior, subtreePaintRootForRenderer, paintingFrequently); > > if (isPaintingCompositedForeground) { > // Paint any child layers that have overflow. >@@ -4411,17 +4428,17 @@ void RenderLayer::paintLayerContents(Gra > > if (shouldPaintMask(paintingInfo.paintBehavior, localPaintFlags)) { > // Paint the mask for the fragments. >- paintMaskForFragments(layerFragments, context, paintingInfo, paintBehavior, subtreePaintRootForRenderer); >+ paintMaskForFragments(layerFragments, context, paintingInfo, paintBehavior, subtreePaintRootForRenderer, paintingFrequently); > } > > if (!(paintFlags & PaintLayerPaintingCompositingMaskPhase) && (paintFlags & PaintLayerPaintingCompositingClipPathPhase)) { > // Re-use paintChildClippingMaskForFragments to paint black for the compositing clipping mask. >- paintChildClippingMaskForFragments(layerFragments, context, paintingInfo, paintBehavior, subtreePaintRootForRenderer); >+ paintChildClippingMaskForFragments(layerFragments, context, paintingInfo, paintBehavior, subtreePaintRootForRenderer, paintingFrequently); > } > > if ((localPaintFlags & PaintLayerPaintingChildClippingMaskPhase)) { > // Paint the border radius mask for the fragments. >- paintChildClippingMaskForFragments(layerFragments, context, paintingInfo, paintBehavior, subtreePaintRootForRenderer); >+ paintChildClippingMaskForFragments(layerFragments, context, paintingInfo, paintBehavior, subtreePaintRootForRenderer, paintingFrequently); > } > } > >@@ -4684,7 +4701,7 @@ void RenderLayer::paintTransformedLayerI > > void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragments, GraphicsContext& context, GraphicsContext& contextForTransparencyLayer, > const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, >- RenderObject* subtreePaintRootForRenderer) >+ RenderObject* subtreePaintRootForRenderer, bool paintingFrequently) > { > for (const auto& fragment : layerFragments) { > if (!fragment.shouldPaintContent) >@@ -4702,7 +4719,7 @@ void RenderLayer::paintBackgroundForFrag > > // Paint the background. > // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info. >- PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseBlockBackground, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer()); >+ PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseBlockBackground, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer(), this, paintingFrequently); > renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset)); > > if (localPaintingInfo.clipToDirtyRect) >@@ -4712,7 +4729,7 @@ void RenderLayer::paintBackgroundForFrag > > void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragments, GraphicsContext& context, GraphicsContext& contextForTransparencyLayer, > const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, >- RenderObject* subtreePaintRootForRenderer) >+ RenderObject* subtreePaintRootForRenderer, bool paintingFrequently) > { > // Begin transparency if we have something to paint. > if (haveTransparency) { >@@ -4753,12 +4770,12 @@ void RenderLayer::paintForegroundForFrag > // interleaving of the fragments to work properly. > bool selectionOnly = localPaintingInfo.paintBehavior & (PaintBehaviorSelectionAndBackgroundsOnly | PaintBehaviorSelectionOnly); > paintForegroundForFragmentsWithPhase(selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds, layerFragments, >- context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer); >+ context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer, paintingFrequently); > > if (!selectionOnly) { >- paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer); >- paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer); >- paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer); >+ paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer, paintingFrequently); >+ paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer, paintingFrequently); >+ paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, localPaintBehavior, subtreePaintRootForRenderer, paintingFrequently); > } > > if (shouldClip) >@@ -4766,7 +4783,7 @@ void RenderLayer::paintForegroundForFrag > } > > void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const LayerFragments& layerFragments, GraphicsContext& context, >- const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* subtreePaintRootForRenderer) >+ const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* subtreePaintRootForRenderer, bool paintingFrequently) > { > bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() > 1; > >@@ -4777,7 +4794,7 @@ void RenderLayer::paintForegroundForFrag > if (shouldClip) > clipToRect(context, localPaintingInfo, fragment.foregroundRect); > >- PaintInfo paintInfo(context, fragment.foregroundRect.rect(), phase, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer(), localPaintingInfo.requireSecurityOriginAccessForWidgets); >+ PaintInfo paintInfo(context, fragment.foregroundRect.rect(), phase, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer(), this, paintingFrequently, localPaintingInfo.requireSecurityOriginAccessForWidgets); > if (phase == PaintPhaseForeground) > paintInfo.overlapTestRequests = localPaintingInfo.overlapTestRequests; > renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset)); >@@ -4788,14 +4805,14 @@ void RenderLayer::paintForegroundForFrag > } > > void RenderLayer::paintOutlineForFragments(const LayerFragments& layerFragments, GraphicsContext& context, const LayerPaintingInfo& localPaintingInfo, >- PaintBehavior paintBehavior, RenderObject* subtreePaintRootForRenderer) >+ PaintBehavior paintBehavior, RenderObject* subtreePaintRootForRenderer, bool paintingFrequently) > { > for (const auto& fragment : layerFragments) { > if (fragment.backgroundRect.isEmpty()) > continue; > > // Paint our own outline >- PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseSelfOutline, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer()); >+ PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseSelfOutline, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer(), this, paintingFrequently); > clipToRect(context, localPaintingInfo, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); > renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset)); > restoreClip(context, localPaintingInfo, fragment.backgroundRect); >@@ -4803,7 +4820,7 @@ void RenderLayer::paintOutlineForFragmen > } > > void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, GraphicsContext& context, const LayerPaintingInfo& localPaintingInfo, >- PaintBehavior paintBehavior, RenderObject* subtreePaintRootForRenderer) >+ PaintBehavior paintBehavior, RenderObject* subtreePaintRootForRenderer, bool paintingFrequently) > { > for (const auto& fragment : layerFragments) { > if (!fragment.shouldPaintContent) >@@ -4814,7 +4831,7 @@ void RenderLayer::paintMaskForFragments( > > // Paint the mask. > // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info. >- PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseMask, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer()); >+ PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseMask, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer(), this, paintingFrequently); > renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset)); > > if (localPaintingInfo.clipToDirtyRect) >@@ -4822,7 +4839,7 @@ void RenderLayer::paintMaskForFragments( > } > } > >-void RenderLayer::paintChildClippingMaskForFragments(const LayerFragments& layerFragments, GraphicsContext& context, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* subtreePaintRootForRenderer) >+void RenderLayer::paintChildClippingMaskForFragments(const LayerFragments& layerFragments, GraphicsContext& context, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* subtreePaintRootForRenderer, bool paintingFrequently) > { > for (const auto& fragment : layerFragments) { > if (!fragment.shouldPaintContent) >@@ -4832,7 +4849,7 @@ void RenderLayer::paintChildClippingMask > clipToRect(context, localPaintingInfo, fragment.foregroundRect, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self. > > // Paint the clipped mask. >- PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseClippingMask, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer()); >+ PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseClippingMask, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &localPaintingInfo.rootLayer->renderer(), this, paintingFrequently); > renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset)); > > if (localPaintingInfo.clipToDirtyRect) >@@ -6795,6 +6812,21 @@ RenderStyle RenderLayer::createReflectio > return newStyle; > } > >+void RenderLayer::notifyPaintHasCachableResources() >+{ >+ if (m_paintFrequencyInfo.paintedCachedResource) >+ return; >+ >+ m_paintFrequencyInfo.paintedCachedResource = true; >+ >+ MonotonicTime now = MonotonicTime::now(); >+ if (!m_paintFrequencyInfo.firstPaintTime) >+ m_paintFrequencyInfo.firstPaintTime = now; >+ m_paintFrequencyInfo.lastPaintTime = now; >+ >+ m_paintFrequencyInfo.totalPaintsSinceFirst++; >+} >+ > void RenderLayer::updateOrRemoveFilterClients() > { > if (!hasFilter()) { >Index: Source/WebCore/rendering/RenderLayer.h >=================================================================== >--- Source/WebCore/rendering/RenderLayer.h (revision 223973) >+++ Source/WebCore/rendering/RenderLayer.h (working copy) >@@ -717,6 +717,8 @@ public: > > bool shouldPlaceBlockDirectionScrollbarOnLeft() const final { return renderer().shouldPlaceBlockDirectionScrollbarOnLeft(); } > >+ void notifyPaintHasCachableResources(); >+ > private: > enum CollectLayersBehavior { StopAtStackingContexts, StopAtStackingContainers }; > >@@ -842,14 +844,14 @@ private: > > void updatePaintingInfoForFragments(LayerFragments&, const LayerPaintingInfo&, PaintLayerFlags, bool shouldPaintContent, const LayoutSize& offsetFromRoot); > void paintBackgroundForFragments(const LayerFragments&, GraphicsContext&, GraphicsContext& transparencyLayerContext, >- const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer); >+ const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, bool paintingFrequently); > void paintForegroundForFragments(const LayerFragments&, GraphicsContext&, GraphicsContext& transparencyLayerContext, >- const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer); >- void paintForegroundForFragmentsWithPhase(PaintPhase, const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer); >- void paintOutlineForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer); >+ const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, bool paintingFrequently); >+ void paintForegroundForFragmentsWithPhase(PaintPhase, const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, bool paintingFrequently); >+ void paintOutlineForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, bool paintingFrequently); > void paintOverflowControlsForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&); >- void paintMaskForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer); >- void paintChildClippingMaskForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer); >+ void paintMaskForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, bool paintingFrequently); >+ void paintChildClippingMaskForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, bool paintingFrequently); > void paintTransformedLayerIntoFragments(GraphicsContext&, const LayerPaintingInfo&, PaintLayerFlags); > > RenderLayer* transparentPaintingAncestor(); >@@ -1025,6 +1027,13 @@ private: > > bool overflowControlsIntersectRect(const IntRect& localRect) const; > >+ struct PaintFrequencyInfo { >+ MonotonicTime firstPaintTime { }; >+ MonotonicTime lastPaintTime { }; >+ unsigned totalPaintsSinceFirst { 0 }; >+ bool paintedCachedResource { false }; >+ }; >+ > // The bitfields are up here so they will fall into the padding from ScrollableArea on 64-bit. > > const bool m_isRenderViewLayer : 1; >@@ -1170,6 +1179,8 @@ private: > IntRect m_blockSelectionGapsBounds; > > std::unique_ptr<RenderLayerBacking> m_backing; >+ >+ PaintFrequencyInfo m_paintFrequencyInfo; > }; > > inline void RenderLayer::clearZOrderLists() >Index: Source/WebCore/rendering/SimpleLineLayout.cpp >=================================================================== >--- Source/WebCore/rendering/SimpleLineLayout.cpp (revision 223973) >+++ Source/WebCore/rendering/SimpleLineLayout.cpp (working copy) >@@ -28,6 +28,7 @@ > > #include "FontCache.h" > #include "Frame.h" >+#include "GlyphBuffer.h" > #include "GraphicsContext.h" > #include "HTMLTextFormControlElement.h" > #include "HitTestLocation.h" >@@ -72,6 +73,28 @@ namespace SimpleLineLayout { > } > #endif > >+typedef WTF::HashMap<const Run*, GlyphBufferInfo*> RunGlyphBufferMap; >+static RunGlyphBufferMap* gRunsWithGlyphBuffers; >+ >+GlyphBufferInfo* Layout::glyphBufferForRun(const Run* run) const >+{ >+ if (!gRunsWithGlyphBuffers) >+ return nullptr; >+ return gRunsWithGlyphBuffers->get(run); >+} >+ >+void Layout::setGlyphBufferForRun(const Run* run, GlyphBufferInfo* info) const >+{ >+ if (!info) { >+ if (gRunsWithGlyphBuffers) >+ gRunsWithGlyphBuffers->remove(run); >+ return; >+ } >+ >+ if (!gRunsWithGlyphBuffers) >+ gRunsWithGlyphBuffers = new RunGlyphBufferMap(); >+ gRunsWithGlyphBuffers->add(run, info); >+} > > template <typename CharacterType> AvoidanceReasonFlags canUseForCharacter(CharacterType, bool textIsJustified, IncludeReasons); > >@@ -976,6 +999,15 @@ Layout::Layout(const RunVector& runVecto > { > memcpy(m_runs, runVector.data(), m_runCount * sizeof(Run)); > } >+ >+Layout::~Layout() >+{ >+ if (gRunsWithGlyphBuffers) { >+ for (unsigned i = 0; i < runCount(); ++i) >+ gRunsWithGlyphBuffers->remove(&runAt(i)); >+ >+ } >+} > > } > } >Index: Source/WebCore/rendering/SimpleLineLayout.h >=================================================================== >--- Source/WebCore/rendering/SimpleLineLayout.h (revision 223973) >+++ Source/WebCore/rendering/SimpleLineLayout.h (working copy) >@@ -37,6 +37,7 @@ > > namespace WebCore { > >+struct GlyphBufferInfo; > class RenderBlockFlow; > > namespace SimpleLineLayout { >@@ -91,6 +92,12 @@ public: > bool hasLineStruts() const { return !m_lineStruts.isEmpty(); } > void setLineStruts(SimpleLineStruts&& lineStruts) { m_lineStruts = lineStruts; } > const SimpleLineStruts& struts() const { return m_lineStruts; } >+ >+ GlyphBufferInfo* glyphBufferForRun(const Run*) const; >+ void setGlyphBufferForRun(const Run*, GlyphBufferInfo*) const; >+ >+ ~Layout(); >+ > private: > Layout(const RunVector&, unsigned lineCount); > >Index: Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp >=================================================================== >--- Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp (revision 223973) >+++ Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp (working copy) >@@ -36,6 +36,7 @@ > #include "PaintInfo.h" > #include "RenderBlockFlow.h" > #include "RenderIterator.h" >+#include "RenderLayer.h" > #include "RenderStyle.h" > #include "RenderText.h" > #include "RenderView.h" >@@ -120,7 +121,29 @@ void paintFlow(const RenderBlockFlow& fl > TextRun textRun(run.hasHyphen() ? textWithHyphen : run.text(), 0, run.expansion(), run.expansionBehavior()); > textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize()); > FloatPoint textOrigin = FloatPoint(rect.x() + paintOffset.x(), roundToDevicePixel(run.baselinePosition() + paintOffset.y(), deviceScaleFactor)); >+ >+ GlyphBufferInfo* glyphBufferInfo = layout.glyphBufferForRun(&run.simpleRun()); >+ if (paintInfo.enclosingSelfPaintingLayer()) { >+ if (paintInfo.paintingFrequently()) { >+ if (!glyphBufferInfo) { >+ // Generate and cache the glyph buffer info. >+ FontCascade::CodePath codePathToUse = style.fontCascade().codePath(textRun); >+ glyphBufferInfo = new GlyphBufferInfo(); >+ float glyphInitialAdvance = style.fontCascade().glyphBufferForTextRun(codePathToUse, textRun, 0, run.text().length(), (*glyphBufferInfo).glyphBuffer); >+ glyphBufferInfo->initialAdvance = glyphInitialAdvance; >+ layout.setGlyphBufferForRun(&run.simpleRun(), glyphBufferInfo); >+ } >+ } else if (glyphBufferInfo) { >+ layout.setGlyphBufferForRun(&run.simpleRun(), nullptr); >+ glyphBufferInfo = nullptr; >+ } >+ paintInfo.enclosingSelfPaintingLayer()->notifyPaintHasCachableResources(); >+ } >+ if (glyphBufferInfo) >+ textPainter.setGlyphBuffer(&glyphBufferInfo->glyphBuffer, glyphBufferInfo->initialAdvance); >+ > textPainter.paint(textRun, textRun.length(), rect, textOrigin); >+ > if (textDecorationPainter) { > textDecorationPainter->setWidth(rect.width()); > textDecorationPainter->paintTextDecoration(textRun, textOrigin, rect.location() + paintOffset); >Index: Source/WebCore/rendering/SimpleLineLayoutResolver.h >=================================================================== >--- Source/WebCore/rendering/SimpleLineLayoutResolver.h (revision 223973) >+++ Source/WebCore/rendering/SimpleLineLayoutResolver.h (working copy) >@@ -58,6 +58,8 @@ public: > bool hasHyphen() const { return m_iterator.simpleRun().hasHyphen; } > > unsigned lineIndex() const; >+ >+ const SimpleLineLayout::Run& simpleRun() const { return m_iterator.simpleRun(); } > > private: > float computeBaselinePosition() const; >Index: Source/WebCore/rendering/TextPainter.cpp >=================================================================== >--- Source/WebCore/rendering/TextPainter.cpp (revision 223973) >+++ Source/WebCore/rendering/TextPainter.cpp (working copy) >@@ -98,9 +98,14 @@ void TextPainter::paintTextOrEmphasisMar > float emphasisMarkOffset, const FloatPoint& textOrigin, unsigned startOffset, unsigned endOffset) > { > ASSERT(startOffset < endOffset); >- if (emphasisMark.isEmpty()) >- m_context.drawText(font, textRun, textOrigin, startOffset, endOffset); >- else >+ if (emphasisMark.isEmpty()) { >+ if (!m_context.paintingDisabled() && startOffset == 0 && endOffset == textRun.length() && m_glyphBuffer && !m_glyphBuffer->isEmpty()) { >+ float startX = textOrigin.x() + m_glyphBufferInitialAdvance; >+ FloatPoint startPoint(startX, textOrigin.y()); >+ font.drawGlyphBuffer(m_context, *m_glyphBuffer, startPoint, FontCascade::CustomFontNotReadyAction::DoNotPaintIfFontNotReady); >+ } else >+ m_context.drawText(font, textRun, textOrigin, startOffset, endOffset); >+ } else > m_context.drawEmphasisMarks(font, textRun, emphasisMark, textOrigin + FloatSize(0, emphasisMarkOffset), startOffset, endOffset); > } > >Index: Source/WebCore/rendering/TextPainter.h >=================================================================== >--- Source/WebCore/rendering/TextPainter.h (revision 223973) >+++ Source/WebCore/rendering/TextPainter.h (working copy) >@@ -31,6 +31,7 @@ > namespace WebCore { > > class FontCascade; >+class GlyphBuffer; > class RenderCombineText; > class ShadowData; > class TextRun; >@@ -61,6 +62,12 @@ public: > > void setEmphasisMark(const AtomicString& mark, float offset, const RenderCombineText*); > >+ void setGlyphBuffer(const GlyphBuffer* glyphBuffer, float initialAdvance) >+ { >+ m_glyphBuffer = glyphBuffer; >+ m_glyphBufferInitialAdvance = initialAdvance; >+ } >+ > void paintRange(const TextRun&, const FloatRect& boxRect, const FloatPoint& textOrigin, unsigned start, unsigned end); > void paint(const TextRun&, unsigned length, const FloatRect& boxRect, const FloatPoint& textOrigin, unsigned selectionStart = 0, unsigned selectionEnd = 0, bool paintSelectedTextOnly = false, bool paintSelectedTextSeparately = false, bool paintNonSelectedTextOnly = false); > >@@ -82,6 +89,8 @@ private: > const RenderCombineText* m_combinedText { nullptr }; > float m_emphasisMarkOffset { 0 }; > bool m_textBoxIsHorizontal { true }; >+ const GlyphBuffer* m_glyphBuffer { nullptr }; >+ float m_glyphBufferInitialAdvance { 0 }; > }; > > inline void TextPainter::setEmphasisMark(const AtomicString& mark, float offset, const RenderCombineText* combinedText)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 178750
:
324721
|
325018
|
325031
|
325045
|
325089
|
325363
|
326363
|
326379
|
326381
|
326390
|
326393
|
326414
|
336601
|
336612
|
336679
|
336884
|
337006
|
337020
|
337031
|
337470
|
337567
|
337585
|
337623
|
337629
|
337638
|
337640
|
337642
|
337644
|
337646
|
337664