Changeset 159560 in webkit
- Timestamp:
- Nov 20, 2013, 7:14:00 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r159559 r159560 1 2013-11-20 Antti Koivisto <antti@apple.com> 2 3 Don't paint simple text runs outside the paint rect 4 https://bugs.webkit.org/show_bug.cgi?id=124651 5 6 Reviewed by Anders Carlsson. 7 8 This speeds up partial paints for long text paragraphs. 9 Also add the same optimization for hit testing. 10 11 * rendering/SimpleLineLayoutFunctions.cpp: 12 (WebCore::SimpleLineLayout::paintFlow): 13 14 Iterate over the run range that needs painting. 15 16 (WebCore::SimpleLineLayout::hitTestFlow): 17 18 Iterate over the line range that needs painting. 19 20 * rendering/SimpleLineLayoutResolver.h: 21 (WebCore::SimpleLineLayout::Range::Range): 22 (WebCore::SimpleLineLayout::Range::begin): 23 (WebCore::SimpleLineLayout::Range::end): 24 25 Add Range type. 26 27 (WebCore::SimpleLineLayout::RunResolver::Iterator::Iterator): 28 (WebCore::SimpleLineLayout::RunResolver::Iterator::operator++): 29 (WebCore::SimpleLineLayout::RunResolver::Iterator::advance): 30 (WebCore::SimpleLineLayout::RunResolver::Iterator::advanceLines): 31 32 Optimize case where runCount==lineCount. In this case we can just directly jump 33 to the right run/line. 34 35 (WebCore::SimpleLineLayout::RunResolver::begin): 36 (WebCore::SimpleLineLayout::RunResolver::end): 37 (WebCore::SimpleLineLayout::RunResolver::lineIndexForHeight): 38 (WebCore::SimpleLineLayout::RunResolver::rangeForRect): 39 40 Get the range corresponding to a rect. This currently cares about y coordinates only. 41 42 (WebCore::SimpleLineLayout::LineResolver::Iterator::operator++): 43 (WebCore::SimpleLineLayout::LineResolver::Iterator::operator*): 44 (WebCore::SimpleLineLayout::LineResolver::rangeForRect): 45 1 46 2013-11-20 Antoine Quint <graouts@apple.com> 2 47 -
trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp
r159385 r159560 82 82 updateGraphicsContext(context, textPaintStyle); 83 83 84 LayoutRect paintRect = paintInfo.rect; 85 paintRect.moveBy(-paintOffset); 86 84 87 auto resolver = runResolver(flow, layout); 85 for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) { 86 auto run = *it; 88 auto range = resolver.rangeForRect(paintRect); 89 for (auto it = range.begin(), end = range.end(); it != end; ++it) { 90 const auto& run = *it; 91 if (!run.rect().intersects(paintRect)) 92 continue; 87 93 TextRun textRun(run.text()); 88 94 textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize()); … … 107 113 RenderText& textRenderer = toRenderText(*flow.firstChild()); 108 114 115 LayoutRect rangeRect = locationInContainer.boundingBox(); 116 rangeRect.moveBy(-accumulatedOffset); 117 109 118 auto resolver = lineResolver(flow, layout); 110 for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) { 119 auto range = resolver.rangeForRect(rangeRect); 120 for (auto it = range.begin(), end = range.end(); it != end; ++it) { 111 121 auto lineRect = *it; 112 122 lineRect.moveBy(accumulatedOffset); … … 163 173 auto resolver = runResolver(toRenderBlockFlow(*textRenderer.parent()), layout); 164 174 for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) { 165 autorun = *it;175 const auto& run = *it; 166 176 auto rect = run.rect(); 167 177 rects.append(enclosingIntRect(FloatRect(accumulatedOffset + rect.location(), rect.size()))); … … 175 185 auto resolver = runResolver(toRenderBlockFlow(*textRenderer.parent()), layout); 176 186 for (auto it = resolver.begin(), end = resolver.end(); it != end; ++it) { 177 autorun = *it;187 const auto& run = *it; 178 188 auto rect = run.rect(); 179 189 quads.append(textRenderer.localToAbsoluteQuad(FloatQuad(rect), 0, wasFixed)); -
trunk/Source/WebCore/rendering/SimpleLineLayoutResolver.h
r159345 r159560 37 37 namespace SimpleLineLayout { 38 38 39 template <class IteratorType> 40 class Range { 41 public: 42 Range(IteratorType begin, IteratorType end) : m_begin(begin), m_end(end) { } 43 44 IteratorType begin() const { return m_begin; } 45 IteratorType end() const { return m_end; } 46 47 private: 48 IteratorType m_begin; 49 IteratorType m_end; 50 }; 51 39 52 class RunResolver { 40 53 public: … … 60 73 class Iterator { 61 74 public: 62 Iterator(const RunResolver&, unsigned lineIndex);75 Iterator(const RunResolver&, unsigned runIndex, unsigned lineIndex); 63 76 64 77 Iterator& operator++(); 78 65 79 bool operator==(const Iterator&) const; 66 80 bool operator!=(const Iterator&) const; 67 81 68 82 Run operator*() const; 83 84 Iterator& advance(); 85 Iterator& advanceLines(unsigned); 69 86 70 87 const RunResolver& resolver() const { return m_resolver; } … … 83 100 Iterator end() const; 84 101 102 Range<Iterator> rangeForRect(const LayoutRect&) const; 103 85 104 private: 105 unsigned lineIndexForHeight(LayoutUnit) const; 106 86 107 const Layout& m_layout; 87 108 const String m_string; … … 117 138 Iterator end() const; 118 139 140 Range<Iterator> rangeForRect(const LayoutRect&) const; 141 119 142 private: 120 143 RunResolver m_runResolver; … … 170 193 } 171 194 172 inline RunResolver::Iterator::Iterator(const RunResolver& resolver, unsigned runIndex )195 inline RunResolver::Iterator::Iterator(const RunResolver& resolver, unsigned runIndex, unsigned lineIndex) 173 196 : m_resolver(resolver) 174 197 , m_runIndex(runIndex) 175 , m_lineIndex( 0)198 , m_lineIndex(lineIndex) 176 199 { 177 200 } 178 201 179 202 inline RunResolver::Iterator& RunResolver::Iterator::operator++() 203 { 204 return advance(); 205 } 206 207 inline bool RunResolver::Iterator::operator==(const Iterator& other) const 208 { 209 ASSERT(&m_resolver == &other.m_resolver); 210 return m_runIndex == other.m_runIndex; 211 } 212 213 inline bool RunResolver::Iterator::operator!=(const Iterator& other) const 214 { 215 return !(*this == other); 216 } 217 218 inline RunResolver::Run RunResolver::Iterator::operator*() const 219 { 220 return Run(*this); 221 } 222 223 inline RunResolver::Iterator& RunResolver::Iterator::advance() 180 224 { 181 225 if (simpleRun().isEndOfLine) … … 185 229 } 186 230 187 inline bool RunResolver::Iterator::operator==(const Iterator& other) const 188 { 189 ASSERT(&m_resolver == &other.m_resolver); 190 return m_runIndex == other.m_runIndex; 191 } 192 193 inline bool RunResolver::Iterator::operator!=(const Iterator& other) const 194 { 195 return !(*this == other); 196 } 197 198 inline RunResolver::Run RunResolver::Iterator::operator*() const 199 { 200 return Run(*this); 231 inline RunResolver::Iterator& RunResolver::Iterator::advanceLines(unsigned lineCount) 232 { 233 unsigned runCount = m_resolver.m_layout.runCount(); 234 if (runCount == m_resolver.m_layout.lineCount()) { 235 m_runIndex = std::min(runCount, m_runIndex + lineCount); 236 m_lineIndex = m_runIndex; 237 return *this; 238 } 239 unsigned target = m_lineIndex + lineCount; 240 while (m_lineIndex < target && m_runIndex < runCount) 241 advance(); 242 243 return *this; 201 244 } 202 245 … … 219 262 inline RunResolver::Iterator RunResolver::begin() const 220 263 { 221 return Iterator(*this, 0 );264 return Iterator(*this, 0, 0); 222 265 } 223 266 224 267 inline RunResolver::Iterator RunResolver::end() const 225 268 { 226 return Iterator(*this, m_layout.runCount()); 269 return Iterator(*this, m_layout.runCount(), m_layout.lineCount()); 270 } 271 272 inline unsigned RunResolver::lineIndexForHeight(LayoutUnit height) const 273 { 274 ASSERT(m_lineHeight); 275 float y = std::max<float>(height - m_contentOffset.y() - m_baseline + m_ascent, 0); 276 return std::min<unsigned>(y / m_lineHeight, m_layout.lineCount() - 1); 277 } 278 279 inline Range<RunResolver::Iterator> RunResolver::rangeForRect(const LayoutRect& rect) const 280 { 281 if (!m_lineHeight) 282 return Range<Iterator>(begin(), end()); 283 284 unsigned firstLine = lineIndexForHeight(rect.y()); 285 unsigned lastLine = lineIndexForHeight(rect.maxY()); 286 287 auto rangeBegin = begin().advanceLines(firstLine); 288 if (rangeBegin == end()) 289 return Range<Iterator>(end(), end()); 290 auto rangeEnd = rangeBegin; 291 rangeEnd.advanceLines(lastLine - firstLine + 1); 292 return Range<Iterator>(rangeBegin, rangeEnd); 227 293 } 228 294 … … 234 300 inline LineResolver::Iterator& LineResolver::Iterator::operator++() 235 301 { 236 unsigned previousLine = m_runIterator.lineIndex(); 237 while ((++m_runIterator).lineIndex() == previousLine) { } 238 302 m_runIterator.advanceLines(1); 239 303 return *this; 240 304 } … … 255 319 auto it = m_runIterator; 256 320 LayoutRect rect = (*it).rect(); 257 while ( (++it).lineIndex() == currentLine)321 while (it.advance().lineIndex() == currentLine) 258 322 rect.unite((*it).rect()); 259 323 … … 276 340 } 277 341 342 inline Range<LineResolver::Iterator> LineResolver::rangeForRect(const LayoutRect& rect) const 343 { 344 auto runRange = m_runResolver.rangeForRect(rect); 345 return Range<Iterator>(Iterator(runRange.begin()), Iterator(runRange.end())); 346 } 347 278 348 inline RunResolver runResolver(const RenderBlockFlow& flow, const Layout& layout) 279 349 {
Note:
See TracChangeset
for help on using the changeset viewer.