OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "core/paint/ViewDisplayList.h" | 6 #include "core/paint/ViewDisplayList.h" |
7 | 7 |
8 #include "platform/NotImplemented.h" | 8 #include "platform/NotImplemented.h" |
9 #include "platform/RuntimeEnabledFeatures.h" | 9 #include "platform/RuntimeEnabledFeatures.h" |
10 | 10 |
11 #ifndef NDEBUG | 11 #ifndef NDEBUG |
12 #include "core/rendering/RenderObject.h" | 12 #include "core/rendering/RenderObject.h" |
13 #include "wtf/text/WTFString.h" | 13 #include "wtf/text/WTFString.h" |
14 #endif | 14 #endif |
15 | 15 |
16 namespace blink { | 16 namespace blink { |
17 | 17 |
18 // DisplayItem types must be kept in sync with PaintPhase. | 18 // DisplayItem types must be kept in sync with PaintPhase. |
19 COMPILE_ASSERT((unsigned)DisplayItem::DrawingPaintPhaseBlockBackground == (unsig
ned)PaintPhaseBlockBackground, DisplayItem_Type_should_stay_in_sync); | 19 COMPILE_ASSERT((unsigned)DisplayItem::DrawingPaintPhaseBlockBackground == (unsig
ned)PaintPhaseBlockBackground, DisplayItem_Type_should_stay_in_sync); |
20 COMPILE_ASSERT((unsigned)DisplayItem::DrawingPaintPhaseClippingMask == (unsigned
)PaintPhaseClippingMask, DisplayItem_Type_should_stay_in_sync); | 20 COMPILE_ASSERT((unsigned)DisplayItem::DrawingPaintPhaseClippingMask == (unsigned
)PaintPhaseClippingMask, DisplayItem_Type_should_stay_in_sync); |
21 | 21 |
22 const PaintList& ViewDisplayList::paintList() | 22 const PaintList& ViewDisplayList::paintList() |
23 { | 23 { |
24 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); | 24 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); |
25 | 25 |
26 updatePaintList(); | 26 updatePaintList(); |
27 return m_newPaints; | 27 return m_paintList; |
28 } | 28 } |
29 | 29 |
30 void ViewDisplayList::add(WTF::PassOwnPtr<DisplayItem> displayItem) | 30 void ViewDisplayList::add(WTF::PassOwnPtr<DisplayItem> displayItem) |
31 { | 31 { |
32 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); | 32 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); |
33 m_newPaints.append(displayItem); | 33 m_newPaints.append(displayItem); |
34 } | 34 } |
35 | 35 |
36 void ViewDisplayList::invalidate(const RenderObject* renderer) | 36 void ViewDisplayList::invalidate(const RenderObject* renderer) |
37 { | 37 { |
38 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); | 38 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); |
39 m_invalidated.add(renderer); | 39 m_invalidated.add(renderer); |
40 } | 40 } |
41 | 41 |
42 bool ViewDisplayList::isRepaint(PaintList::iterator begin, const DisplayItem& di
splayItem) | 42 PaintList::iterator ViewDisplayList::findDisplayItem(PaintList::iterator begin,
const DisplayItem& displayItem) |
43 { | 43 { |
44 notImplemented(); | 44 PaintList::iterator end = m_paintList.end(); |
45 return false; | 45 if (displayItem.renderer() && !m_paintListRenderers.contains(displayItem.ren
derer())) |
| 46 return end; |
| 47 |
| 48 for (PaintList::iterator it = begin; it != end; ++it) { |
| 49 DisplayItem& existing = **it; |
| 50 if (existing.idsEqual(displayItem)) |
| 51 return it; |
| 52 } |
| 53 |
| 54 // FIXME: Properly handle clips. |
| 55 ASSERT(!displayItem.renderer()); |
| 56 return end; |
46 } | 57 } |
47 | 58 |
48 // Update the existing paintList by removing invalidated entries, updating repai
nted existing ones, and | 59 bool ViewDisplayList::wasInvalidated(const DisplayItem& displayItem) const |
49 // appending new items. | 60 { |
| 61 // FIXME: Use a bit on RenderObject instead of tracking m_invalidated. |
| 62 return displayItem.renderer() && m_invalidated.contains(displayItem.renderer
()); |
| 63 } |
| 64 |
| 65 static void appendDisplayItem(PaintList& list, HashSet<const RenderObject*>& ren
derers, WTF::PassOwnPtr<DisplayItem> displayItem) |
| 66 { |
| 67 if (const RenderObject* renderer = displayItem->renderer()) |
| 68 renderers.add(renderer); |
| 69 list.append(displayItem); |
| 70 } |
| 71 |
| 72 // Update the existing paintList by removing invalidated entries, updating |
| 73 // repainted ones, and appending new items. |
50 // | 74 // |
51 // The algorithm should be O(|existing paint list| + |newly painted list|). By u
sing the ordering | 75 // The algorithm is O(|existing paint list| + |newly painted list|): by using |
52 // implied by the existing paint list, extra treewalks are avoided. | 76 // the ordering implied by the existing paint list, extra treewalks are avoided. |
53 void ViewDisplayList::updatePaintList() | 77 void ViewDisplayList::updatePaintList() |
54 { | 78 { |
55 notImplemented(); | 79 PaintList updatedList; |
| 80 HashSet<const RenderObject*> updatedRenderers; |
| 81 |
| 82 if (int maxCapacity = m_newPaints.size() + std::max(0, (int)m_paintList.size
() - (int)m_invalidated.size())) |
| 83 updatedList.reserveCapacity(maxCapacity); |
| 84 |
| 85 PaintList::iterator paintListIt = m_paintList.begin(); |
| 86 PaintList::iterator paintListEnd = m_paintList.end(); |
| 87 |
| 88 for (OwnPtr<DisplayItem>& newDisplayItem : m_newPaints) { |
| 89 if (!wasInvalidated(*newDisplayItem)) { |
| 90 PaintList::iterator repaintIt = findDisplayItem(paintListIt, *newDis
playItem); |
| 91 if (repaintIt != paintListEnd) { |
| 92 // Copy all of the existing items over until we hit the repaint. |
| 93 for (; paintListIt != repaintIt; ++paintListIt) { |
| 94 if (!wasInvalidated(**paintListIt)) |
| 95 appendDisplayItem(updatedList, updatedRenderers, paintLi
stIt->release()); |
| 96 } |
| 97 paintListIt++; |
| 98 } |
| 99 } |
| 100 // Copy over the new item. |
| 101 appendDisplayItem(updatedList, updatedRenderers, newDisplayItem.release(
)); |
| 102 } |
| 103 |
| 104 // Copy over any remaining items that were not invalidated. |
| 105 for (; paintListIt != paintListEnd; ++paintListIt) { |
| 106 if (!wasInvalidated(**paintListIt)) |
| 107 appendDisplayItem(updatedList, updatedRenderers, paintListIt->releas
e()); |
| 108 } |
| 109 |
| 110 m_invalidated.clear(); |
| 111 m_newPaints.clear(); |
| 112 m_paintList.clear(); |
| 113 m_paintList.swap(updatedList); |
| 114 m_paintListRenderers.clear(); |
| 115 m_paintListRenderers.swap(updatedRenderers); |
56 } | 116 } |
57 | 117 |
58 #ifndef NDEBUG | 118 #ifndef NDEBUG |
59 WTF::String DisplayItem::typeAsDebugString(DisplayItem::Type type) | 119 WTF::String DisplayItem::typeAsDebugString(DisplayItem::Type type) |
60 { | 120 { |
61 switch (type) { | 121 switch (type) { |
62 case DisplayItem::DrawingPaintPhaseBlockBackground: return "DrawingPaintPhas
eBlockBackground"; | 122 case DisplayItem::DrawingPaintPhaseBlockBackground: return "DrawingPaintPhas
eBlockBackground"; |
63 case DisplayItem::DrawingPaintPhaseChildBlockBackground: return "DrawingPain
tPhaseChildBlockBackground"; | 123 case DisplayItem::DrawingPaintPhaseChildBlockBackground: return "DrawingPain
tPhaseChildBlockBackground"; |
64 case DisplayItem::DrawingPaintPhaseChildBlockBackgrounds: return "DrawingPai
ntPhaseChildBlockBackgrounds"; | 124 case DisplayItem::DrawingPaintPhaseChildBlockBackgrounds: return "DrawingPai
ntPhaseChildBlockBackgrounds"; |
65 case DisplayItem::DrawingPaintPhaseFloat: return "DrawingPaintPhaseFloat"; | 125 case DisplayItem::DrawingPaintPhaseFloat: return "DrawingPaintPhaseFloat"; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } | 178 } |
119 | 179 |
120 void ViewDisplayList::showDebugData() const | 180 void ViewDisplayList::showDebugData() const |
121 { | 181 { |
122 fprintf(stderr, "paint list: [%s]\n", paintListAsDebugString(m_paintList).ut
f8().data()); | 182 fprintf(stderr, "paint list: [%s]\n", paintListAsDebugString(m_paintList).ut
f8().data()); |
123 fprintf(stderr, "new paints: [%s]\n", paintListAsDebugString(m_newPaints).ut
f8().data()); | 183 fprintf(stderr, "new paints: [%s]\n", paintListAsDebugString(m_newPaints).ut
f8().data()); |
124 } | 184 } |
125 #endif | 185 #endif |
126 | 186 |
127 } // namespace blink | 187 } // namespace blink |
OLD | NEW |