Changeset 208998 in webkit
- Timestamp:
- Nov 28, 2016 7:58:35 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r208996 r208998 1 2016-11-28 Antti Koivisto <antti@apple.com> 2 3 Remove FIRST_LINE_INHERITED fake pseudo style 4 https://bugs.webkit.org/show_bug.cgi?id=165071 5 6 Reviewed by Andreas Kling. 7 8 Expand the test case a bit. 9 10 * fast/css/pseudo-cache-stale-expected.html: 11 * fast/css/pseudo-cache-stale.html: 12 1 13 2016-11-28 Per Arne Vollan <pvollan@apple.com> 2 14 -
trunk/LayoutTests/fast/css/pseudo-cache-stale-expected.html
r202066 r208998 11 11 This sentence should be extra-extra-large. 12 12 </div> 13 <div id="first-line" style="font-size: xx-large;"> 14 This sentence should be extra-extra-large too. 15 </div> 13 16 <input type="search" placeholder="This should be green"> 14 17 </body> -
trunk/LayoutTests/fast/css/pseudo-cache-stale.html
r202066 r208998 16 16 } 17 17 18 .green #first-line-inherit:first-line { 19 font-size: xx-large; 20 } 21 18 22 .green input::placeholder { 19 23 color: green; … … 27 31 This sentence should be extra-extra-large. 28 32 </div> 33 <div id="first-line-inherit"> 34 <span>This sentence should be extra-extra-large too.</span> 35 </div> 29 36 <input type="search" placeholder="This should be green"> 30 37 <script> -
trunk/Source/WebCore/ChangeLog
r208997 r208998 1 2016-11-28 Antti Koivisto <antti@apple.com> 2 3 Remove FIRST_LINE_INHERITED fake pseudo style 4 https://bugs.webkit.org/show_bug.cgi?id=165071 5 6 Reviewed by Andreas Kling. 7 8 These are create during layout an then cached to the RenderStyle. Cache computed first line style to 9 RenderObject rare data instead, avoiding style mutation an other confusing messiness. 10 11 * rendering/RenderElement.cpp: 12 (WebCore::RenderElement::RenderElement): 13 (WebCore::RenderElement::computeFirstLineStyle): 14 (WebCore::RenderElement::firstLineStyle): 15 16 Cache the first line style. 17 18 (WebCore::RenderElement::invalidateCachedFirstLineStyle): 19 (WebCore::RenderElement::styleWillChange): 20 21 Invalidate subtree if we have cached first line style. 22 23 (WebCore::RenderElement::getUncachedPseudoStyle): 24 (WebCore::RenderElement::uncachedFirstLineStyle): Deleted. 25 (WebCore::RenderElement::cachedFirstLineStyle): Deleted. 26 * rendering/RenderElement.h: 27 * rendering/RenderObject.cpp: 28 (WebCore::RenderObject::rareDataMap): 29 (WebCore::RenderObject::rareData): 30 (WebCore::RenderObject::ensureRareData): 31 * rendering/RenderObject.h: 32 33 Stop copying rare data objects. 34 35 * rendering/style/RenderStyle.cpp: 36 (WebCore::RenderStyle::changeRequiresLayout): 37 38 Use the normal mechanism for invalidating layout for first-line instead of a hack in pseudoStyleCacheIsInvalid. 39 40 * rendering/style/RenderStyleConstants.h: 41 * style/RenderTreeUpdater.cpp: 42 (WebCore::pseudoStyleCacheIsInvalid): 43 44 Simplify. 45 1 46 2016-11-28 Miguel Gomez <magomez@igalia.com> 2 47 -
trunk/Source/WebCore/rendering/RenderElement.cpp
r208797 r208998 105 105 , m_isCSSAnimating(false) 106 106 , m_hasContinuation(false) 107 , m_hasValidCachedFirstLineStyle(false) 107 108 , m_renderBlockHasMarginBeforeQuirk(false) 108 109 , m_renderBlockHasMarginAfterQuirk(false) … … 216 217 } 217 218 218 std::unique_ptr<RenderStyle> RenderElement::uncachedFirstLineStyle(RenderStyle* style) const 219 std::unique_ptr<RenderStyle> RenderElement::computeFirstLineStyle() const 220 { 221 ASSERT(view().usesFirstLineRules()); 222 223 RenderElement& rendererForFirstLineStyle = isBeforeOrAfterContent() ? *parent() : const_cast<RenderElement&>(*this); 224 225 if (rendererForFirstLineStyle.isRenderBlockFlow() || rendererForFirstLineStyle.isRenderButton()) { 226 RenderBlock* firstLineBlock = rendererForFirstLineStyle.firstLineBlock(); 227 if (!firstLineBlock) 228 return nullptr; 229 auto* firstLineStyle = firstLineBlock->getCachedPseudoStyle(FIRST_LINE, &style()); 230 if (!firstLineStyle) 231 return nullptr; 232 return RenderStyle::clonePtr(*firstLineStyle); 233 } 234 235 if (rendererForFirstLineStyle.isAnonymous() || !rendererForFirstLineStyle.isRenderInline()) 236 return nullptr; 237 238 auto& parentStyle = rendererForFirstLineStyle.parent()->firstLineStyle(); 239 if (&parentStyle == &rendererForFirstLineStyle.parent()->style()) 240 return nullptr; 241 return rendererForFirstLineStyle.element()->styleResolver().styleForElement(*element(), &parentStyle).renderStyle; 242 } 243 244 const RenderStyle& RenderElement::firstLineStyle() const 219 245 { 220 246 if (!view().usesFirstLineRules()) 221 return nullptr; 222 223 RenderElement& rendererForFirstLineStyle = isBeforeOrAfterContent() ? *parent() : const_cast<RenderElement&>(*this); 224 225 if (rendererForFirstLineStyle.isRenderBlockFlow() || rendererForFirstLineStyle.isRenderButton()) { 226 if (RenderBlock* firstLineBlock = rendererForFirstLineStyle.firstLineBlock()) 227 return firstLineBlock->getUncachedPseudoStyle(PseudoStyleRequest(FIRST_LINE), style, firstLineBlock == this ? style : nullptr); 228 } else if (!rendererForFirstLineStyle.isAnonymous() && rendererForFirstLineStyle.isRenderInline()) { 229 auto& parentStyle = rendererForFirstLineStyle.parent()->firstLineStyle(); 230 if (&parentStyle != &rendererForFirstLineStyle.parent()->style()) 231 return rendererForFirstLineStyle.getUncachedPseudoStyle(PseudoStyleRequest(FIRST_LINE_INHERITED), &parentStyle, style); 232 } 233 return nullptr; 234 } 235 236 const RenderStyle* RenderElement::cachedFirstLineStyle() const 237 { 238 ASSERT(view().usesFirstLineRules()); 239 240 RenderElement& rendererForFirstLineStyle = isBeforeOrAfterContent() ? *parent() : const_cast<RenderElement&>(*this); 241 242 if (rendererForFirstLineStyle.isRenderBlockFlow() || rendererForFirstLineStyle.isRenderButton()) { 243 if (RenderBlock* firstLineBlock = rendererForFirstLineStyle.firstLineBlock()) 244 return firstLineBlock->getCachedPseudoStyle(FIRST_LINE, &style()); 245 } else if (!rendererForFirstLineStyle.isAnonymous() && rendererForFirstLineStyle.isRenderInline()) { 246 auto& parentStyle = rendererForFirstLineStyle.parent()->firstLineStyle(); 247 if (&parentStyle != &rendererForFirstLineStyle.parent()->style()) { 248 // A first-line style is in effect. Cache a first-line style for ourselves. 249 rendererForFirstLineStyle.m_style.setHasPseudoStyle(FIRST_LINE_INHERITED); 250 return rendererForFirstLineStyle.getCachedPseudoStyle(FIRST_LINE_INHERITED, &parentStyle); 251 } 252 } 253 254 return &style(); 255 } 256 257 const RenderStyle& RenderElement::firstLineStyle() const 258 { 259 return view().usesFirstLineRules() ? *cachedFirstLineStyle() : style(); 247 return style(); 248 249 if (!m_hasValidCachedFirstLineStyle) { 250 auto firstLineStyle = computeFirstLineStyle(); 251 if (firstLineStyle || hasRareData()) 252 const_cast<RenderElement&>(*this).ensureRareData().cachedFirstLineStyle = WTFMove(firstLineStyle); 253 m_hasValidCachedFirstLineStyle = true; 254 } 255 256 return (hasRareData() && rareData().cachedFirstLineStyle) ? *rareData().cachedFirstLineStyle : style(); 260 257 } 261 258 … … 817 814 { 818 815 return renderer && renderer->hasBackground(); 816 } 817 818 void RenderElement::invalidateCachedFirstLineStyle() 819 { 820 if (!m_hasValidCachedFirstLineStyle) 821 return; 822 m_hasValidCachedFirstLineStyle = false; 823 // Invalidate the subtree as descendant's first line style may depend on ancestor's. 824 for (auto& descendant : descendantsOfType<RenderElement>(*this)) 825 descendant.m_hasValidCachedFirstLineStyle = false; 819 826 } 820 827 … … 878 885 clearPositionedState(); 879 886 } 887 if (newStyle.hasPseudoStyle(FIRST_LINE) || oldStyle->hasPseudoStyle(FIRST_LINE)) 888 invalidateCachedFirstLineStyle(); 889 880 890 setHorizontalWritingMode(true); 881 891 setHasVisibleBoxDecorations(false); … … 1546 1556 auto& styleResolver = element()->styleResolver(); 1547 1557 1548 std::unique_ptr<RenderStyle> style; 1549 if (pseudoStyleRequest.pseudoId == FIRST_LINE_INHERITED) { 1550 style = styleResolver.styleForElement(*element(), parentStyle).renderStyle; 1551 style->setStyleType(FIRST_LINE_INHERITED); 1552 } else 1553 style = styleResolver.pseudoStyleForElement(*element(), pseudoStyleRequest, *parentStyle); 1558 std::unique_ptr<RenderStyle> style = styleResolver.pseudoStyleForElement(*element(), pseudoStyleRequest, *parentStyle); 1554 1559 1555 1560 if (style) -
trunk/Source/WebCore/rendering/RenderElement.h
r208797 r208998 132 132 RenderElement& rendererForRootBackground(); 133 133 134 // Used only by Element::pseudoStyleCacheIsInvalid to get a first line style based off of a135 // given new style, without accessing the cache.136 std::unique_ptr<RenderStyle> uncachedFirstLineStyle(RenderStyle*) const;137 138 134 // Updates only the local style ptr of the object. Does not update the state of the object, 139 135 // and so only should be called when the style is known not to have changed (or from setStyle). … … 307 303 308 304 StyleDifference adjustStyleDifference(StyleDifference, unsigned contextSensitiveProperties) const; 309 const RenderStyle* cachedFirstLineStyle() const; 305 std::unique_ptr<RenderStyle> computeFirstLineStyle() const; 306 void invalidateCachedFirstLineStyle(); 310 307 311 308 void newImageAnimationFrameAvailable(CachedImage&) final; … … 329 326 unsigned m_isCSSAnimating : 1; 330 327 unsigned m_hasContinuation : 1; 328 mutable unsigned m_hasValidCachedFirstLineStyle : 1; 331 329 332 330 unsigned m_renderBlockHasMarginBeforeQuirk : 1; -
trunk/Source/WebCore/rendering/RenderObject.cpp
r208661 r208998 1979 1979 } 1980 1980 1981 RenderObject::RareData Hash& RenderObject::rareDataMap()1982 { 1983 static NeverDestroyed<RareData Hash> map;1981 RenderObject::RareDataMap& RenderObject::rareDataMap() 1982 { 1983 static NeverDestroyed<RareDataMap> map; 1984 1984 return map; 1985 1985 } 1986 1986 1987 RenderObject::RenderObjectRareData RenderObject::rareData() const 1988 { 1989 if (!hasRareData()) 1990 return RenderObjectRareData(); 1991 1992 return rareDataMap().get(this); 1987 const RenderObject::RenderObjectRareData& RenderObject::rareData() const 1988 { 1989 ASSERT(hasRareData()); 1990 return *rareDataMap().get(this); 1993 1991 } 1994 1992 … … 1996 1994 { 1997 1995 setHasRareData(true); 1998 return rareDataMap().add(this, RenderObjectRareData()).iterator->value;1996 return *rareDataMap().ensure(this, [] { return std::make_unique<RenderObjectRareData>(); }).iterator->value; 1999 1997 } 2000 1998 -
trunk/Source/WebCore/rendering/RenderObject.h
r208661 r208998 971 971 RenderObjectBitfields m_bitfields; 972 972 973 // FIXME: This should be RenderElementRareData. 973 974 class RenderObjectRareData { 974 975 public: … … 990 991 ADD_BOOLEAN_BITFIELD(isRegisteredForVisibleInViewportCallback, IsRegisteredForVisibleInViewportCallback); 991 992 ADD_ENUM_BITFIELD(visibleInViewportState, VisibleInViewportState, VisibleInViewportState, 2); 992 993 std::unique_ptr<RenderStyle> cachedFirstLineStyle; 993 994 }; 994 995 995 RenderObjectRareDatarareData() const;996 const RenderObject::RenderObjectRareData& rareData() const; 996 997 RenderObjectRareData& ensureRareData(); 997 998 void removeRareData(); 998 999 999 // Note: RenderObjectRareData is stored by value. 1000 typedef HashMap<const RenderObject*, RenderObjectRareData> RareDataHash; 1001 1002 static RareDataHash& rareDataMap(); 1000 typedef HashMap<const RenderObject*, std::unique_ptr<RenderObjectRareData>> RareDataMap; 1001 1002 static RareDataMap& rareDataMap(); 1003 1003 1004 1004 #undef ADD_BOOLEAN_BITFIELD -
trunk/Source/WebCore/rendering/style/RenderStyle.cpp
r208460 r208998 760 760 } 761 761 } 762 762 763 bool hasFirstLineStyle = hasPseudoStyle(FIRST_LINE); 764 if (hasFirstLineStyle != other.hasPseudoStyle(FIRST_LINE)) 765 return true; 766 if (hasFirstLineStyle) { 767 auto* firstLineStyle = getCachedPseudoStyle(FIRST_LINE); 768 if (!firstLineStyle) 769 return true; 770 auto* otherFirstLineStyle = other.getCachedPseudoStyle(FIRST_LINE); 771 if (!otherFirstLineStyle) 772 return true; 773 // FIXME: Not all first line style changes actually need layout. 774 if (*firstLineStyle != *otherFirstLineStyle) 775 return true; 776 } 777 763 778 return false; 764 779 } -
trunk/Source/WebCore/rendering/style/RenderStyleConstants.h
r208914 r208998 78 78 enum PseudoId : unsigned char { 79 79 // The order must be NOP ID, public IDs, and then internal IDs. 80 NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, FIRST_LINE_INHERITED,SCROLLBAR,80 NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, SELECTION, SCROLLBAR, 81 81 // Internal IDs follow: 82 82 SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER, -
trunk/Source/WebCore/style/RenderTreeUpdater.cpp
r208985 r208998 236 236 237 237 for (auto& cache : *pseudoStyleCache) { 238 std::unique_ptr<RenderStyle> newPseudoStyle;239 238 PseudoId pseudoId = cache->styleType(); 240 if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED) 241 newPseudoStyle = renderer->uncachedFirstLineStyle(newStyle); 242 else 243 newPseudoStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId), newStyle, newStyle); 239 std::unique_ptr<RenderStyle> newPseudoStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId), newStyle, newStyle); 244 240 if (!newPseudoStyle) 245 241 return true; 246 242 if (*newPseudoStyle != *cache) { 247 if (pseudoId < FIRST_INTERNAL_PSEUDOID)248 newStyle->setHasPseudoStyle(pseudoId);249 243 newStyle->addCachedPseudoStyle(WTFMove(newPseudoStyle)); 250 if (pseudoId == FIRST_LINE || pseudoId == FIRST_LINE_INHERITED) {251 // FIXME: We should do an actual diff to determine whether a repaint vs. layout252 // is needed, but for now just assume a layout will be required. The diff code253 // in RenderObject::setStyle would need to be factored out so that it could be reused.254 renderer->setNeedsLayoutAndPrefWidthsRecalc();255 }256 244 return true; 257 245 }
Note: See TracChangeset
for help on using the changeset viewer.