OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "platform/graphics/paint/DisplayItemPropertyTreeBuilder.h" | 6 #include "platform/graphics/paint/DisplayItemPropertyTreeBuilder.h" |
7 | 7 |
| 8 #include "platform/RuntimeEnabledFeatures.h" |
8 #include "platform/graphics/paint/DisplayItem.h" | 9 #include "platform/graphics/paint/DisplayItem.h" |
9 #include "platform/graphics/paint/DisplayItemClipTree.h" | 10 #include "platform/graphics/paint/DisplayItemClipTree.h" |
10 #include "platform/graphics/paint/DisplayItemTransformTree.h" | 11 #include "platform/graphics/paint/DisplayItemTransformTree.h" |
| 12 #include "platform/graphics/paint/FixedPositionDisplayItem.h" |
11 #include "platform/graphics/paint/ScrollDisplayItem.h" | 13 #include "platform/graphics/paint/ScrollDisplayItem.h" |
12 #include "platform/graphics/paint/Transform3DDisplayItem.h" | 14 #include "platform/graphics/paint/Transform3DDisplayItem.h" |
13 #include "platform/graphics/paint/TransformDisplayItem.h" | 15 #include "platform/graphics/paint/TransformDisplayItem.h" |
14 | 16 |
15 namespace blink { | 17 namespace blink { |
16 | 18 |
17 DisplayItemPropertyTreeBuilder::DisplayItemPropertyTreeBuilder() | 19 DisplayItemPropertyTreeBuilder::DisplayItemPropertyTreeBuilder() |
18 : m_transformTree(adoptPtr(new DisplayItemTransformTree)) | 20 : m_transformTree(adoptPtr(new DisplayItemTransformTree)) |
19 , m_clipTree(adoptPtr(new DisplayItemClipTree)) | 21 , m_clipTree(adoptPtr(new DisplayItemClipTree)) |
20 , m_rangeBeginIndex(0) | 22 , m_rangeBeginIndex(0) |
(...skipping 28 matching lines...) Expand all Loading... |
49 output.swap(m_rangeRecords); | 51 output.swap(m_rangeRecords); |
50 return output; | 52 return output; |
51 } | 53 } |
52 | 54 |
53 void DisplayItemPropertyTreeBuilder::processDisplayItem(const DisplayItem& displ
ayItem) | 55 void DisplayItemPropertyTreeBuilder::processDisplayItem(const DisplayItem& displ
ayItem) |
54 { | 56 { |
55 if (displayItem.isBegin()) | 57 if (displayItem.isBegin()) |
56 processBeginItem(displayItem); | 58 processBeginItem(displayItem); |
57 else if (displayItem.isEnd()) | 59 else if (displayItem.isEnd()) |
58 processEndItem(displayItem); | 60 processEndItem(displayItem); |
| 61 else if (displayItem.type() == DisplayItem::FixedPositionContainer) |
| 62 processAnchorItem(displayItem); |
59 m_currentIndex++; | 63 m_currentIndex++; |
60 } | 64 } |
61 | 65 |
62 namespace { | 66 namespace { |
63 | 67 |
64 enum TransformKind { NotATransform = 0, Only2DTranslation, RequiresTransformNode
}; | 68 enum TransformKind { NotATransform = 0, Only2DTranslation, RequiresTransformNode
}; |
65 enum ClipKind { NotAClip = 0, RequiresClipNode }; | 69 enum ClipKind { NotAClip = 0, RequiresClipNode }; |
| 70 enum SpecialKind { NotSpecial = 0, IsFixedPosition }; |
66 | 71 |
67 struct BeginDisplayItemClassification { | 72 struct BeginDisplayItemClassification { |
68 TransformKind transformKind = NotATransform; | 73 TransformKind transformKind = NotATransform; |
69 TransformationMatrix matrix; | 74 TransformationMatrix matrix; |
70 ClipKind clipKind = NotAClip; | 75 ClipKind clipKind = NotAClip; |
71 FloatRect clipRect; | 76 FloatRect clipRect; |
| 77 SpecialKind specialKind = NotSpecial; |
| 78 DisplayItemClient anchorKey; |
72 }; | 79 }; |
73 | 80 |
74 // Classifies a begin display item based on how it affects the property trees. | 81 // Classifies a begin display item based on how it affects the property trees. |
75 static BeginDisplayItemClassification classifyBeginItem(const DisplayItem& begin
DisplayItem) | 82 static BeginDisplayItemClassification classifyBeginItem(const DisplayItem& begin
DisplayItem) |
76 { | 83 { |
77 ASSERT(beginDisplayItem.isBegin()); | 84 ASSERT(beginDisplayItem.isBegin()); |
78 | 85 |
79 BeginDisplayItemClassification result; | 86 BeginDisplayItemClassification result; |
80 DisplayItem::Type type = beginDisplayItem.type(); | 87 DisplayItem::Type type = beginDisplayItem.type(); |
81 if (DisplayItem::isTransform3DType(type)) { | 88 if (DisplayItem::isTransform3DType(type)) { |
82 const auto& begin3D = static_cast<const BeginTransform3DDisplayItem&>(be
ginDisplayItem); | 89 const auto& begin3D = static_cast<const BeginTransform3DDisplayItem&>(be
ginDisplayItem); |
83 result.matrix = begin3D.transform(); | 90 result.matrix = begin3D.transform(); |
84 result.transformKind = result.matrix.isIdentityOr2DTranslation() ? Only2
DTranslation : RequiresTransformNode; | 91 result.transformKind = result.matrix.isIdentityOr2DTranslation() ? Only2
DTranslation : RequiresTransformNode; |
85 } else if (type == DisplayItem::BeginTransform) { | 92 } else if (type == DisplayItem::BeginTransform) { |
86 const auto& begin2D = static_cast<const BeginTransformDisplayItem&>(begi
nDisplayItem); | 93 const auto& begin2D = static_cast<const BeginTransformDisplayItem&>(begi
nDisplayItem); |
87 result.matrix = begin2D.transform(); | 94 result.matrix = begin2D.transform(); |
88 result.transformKind = begin2D.transform().isIdentityOrTranslation() ? O
nly2DTranslation : RequiresTransformNode; | 95 result.transformKind = begin2D.transform().isIdentityOrTranslation() ? O
nly2DTranslation : RequiresTransformNode; |
89 } else if (DisplayItem::isScrollType(type)) { | 96 } else if (DisplayItem::isScrollType(type)) { |
90 const auto& beginScroll = static_cast<const BeginScrollDisplayItem&>(beg
inDisplayItem); | 97 const auto& beginScroll = static_cast<const BeginScrollDisplayItem&>(beg
inDisplayItem); |
91 const IntSize& offset = beginScroll.currentOffset(); | 98 const IntSize& offset = beginScroll.currentOffset(); |
92 result.matrix.translate(-offset.width(), -offset.height()); | 99 result.matrix.translate(-offset.width(), -offset.height()); |
93 result.transformKind = Only2DTranslation; | 100 result.transformKind = Only2DTranslation; |
| 101 } else if (type == DisplayItem::BeginFixedPosition) { |
| 102 result.specialKind = IsFixedPosition; |
| 103 result.anchorKey = static_cast<const BeginFixedPositionDisplayItem&>(beg
inDisplayItem).anchor(); |
94 } | 104 } |
95 return result; | 105 return result; |
96 } | 106 } |
97 | 107 |
98 } // namespace | 108 } // namespace |
99 | 109 |
100 void DisplayItemPropertyTreeBuilder::processBeginItem(const DisplayItem& display
Item) | 110 void DisplayItemPropertyTreeBuilder::processBeginItem(const DisplayItem& display
Item) |
101 { | 111 { |
102 BeginDisplayItemClassification classification = classifyBeginItem(displayIte
m); | 112 BeginDisplayItemClassification classification = classifyBeginItem(displayIte
m); |
103 | 113 |
104 if (!classification.transformKind && !classification.clipKind) { | 114 if (!classification.transformKind && !classification.clipKind && !classifica
tion.specialKind) { |
105 currentState().ignoredBeginCount++; | 115 currentState().ignoredBeginCount++; |
106 return; | 116 return; |
107 } | 117 } |
108 | 118 |
109 finishRange(); | 119 finishRange(); |
110 BuilderState newState(currentState()); | 120 BuilderState newState(currentState()); |
111 newState.ignoredBeginCount = 0; | 121 newState.ignoredBeginCount = 0; |
112 | 122 |
113 switch (classification.transformKind) { | 123 switch (classification.transformKind) { |
114 case NotATransform: | 124 case NotATransform: |
(...skipping 15 matching lines...) Expand all Loading... |
130 break; | 140 break; |
131 case RequiresClipNode: | 141 case RequiresClipNode: |
132 // Emit a clip node. | 142 // Emit a clip node. |
133 FloatRect adjustedClipRect = classification.clipRect; | 143 FloatRect adjustedClipRect = classification.clipRect; |
134 adjustedClipRect.move(newState.offset); | 144 adjustedClipRect.move(newState.offset); |
135 newState.clipNode = m_clipTree->createNewNode( | 145 newState.clipNode = m_clipTree->createNewNode( |
136 newState.clipNode, newState.transformNode, adjustedClipRect); | 146 newState.clipNode, newState.transformNode, adjustedClipRect); |
137 break; | 147 break; |
138 } | 148 } |
139 | 149 |
| 150 switch (classification.specialKind) { |
| 151 case NotSpecial: |
| 152 break; |
| 153 case IsFixedPosition: |
| 154 BuilderState referredState(m_anchors.get(classification.anchorKey)); |
| 155 newState.transformNode = referredState.transformNode; |
| 156 newState.offset = referredState.offset; |
| 157 newState.clipNode = referredState.clipNode; |
| 158 { |
| 159 // Note: This is only temporarily workaround before we implement tru
e |
| 160 // transform-tree-based rasterization. |
| 161 ASSERT(currentState().transformNode == newState.transformNode); |
| 162 static_cast<const BeginFixedPositionDisplayItem&>(displayItem).setCo
unterScroll(newState.offset - currentState().offset); |
| 163 } |
| 164 break; |
| 165 } |
| 166 |
140 m_stateStack.append(newState); | 167 m_stateStack.append(newState); |
141 } | 168 } |
142 | 169 |
143 void DisplayItemPropertyTreeBuilder::processEndItem(const DisplayItem& displayIt
em) | 170 void DisplayItemPropertyTreeBuilder::processEndItem(const DisplayItem& displayIt
em) |
144 { | 171 { |
145 if (currentState().ignoredBeginCount) { | 172 if (currentState().ignoredBeginCount) { |
146 // Ignored this end display item. | 173 // Ignored this end display item. |
147 currentState().ignoredBeginCount--; | 174 currentState().ignoredBeginCount--; |
148 } else { | 175 } else { |
149 // We've closed the scope of some property. | 176 // We've closed the scope of some property. |
150 finishRange(); | 177 finishRange(); |
151 m_stateStack.removeLast(); | 178 m_stateStack.removeLast(); |
152 ASSERT(!m_stateStack.isEmpty()); | 179 ASSERT(!m_stateStack.isEmpty()); |
153 } | 180 } |
154 } | 181 } |
155 | 182 |
| 183 void DisplayItemPropertyTreeBuilder::processAnchorItem(const DisplayItem& displa
yItem) |
| 184 { |
| 185 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 186 // Anchors can duplicate when we have reflection or fragments. |
| 187 // We can't assert uniqueness here. However we may assume the most recent on
e is valid. |
| 188 m_anchors.set(displayItem.client(), currentState()); |
| 189 } |
| 190 |
156 void DisplayItemPropertyTreeBuilder::finishRange() | 191 void DisplayItemPropertyTreeBuilder::finishRange() |
157 { | 192 { |
158 // Don't emit an empty range record. | 193 // Don't emit an empty range record. |
159 if (m_rangeBeginIndex < m_currentIndex) { | 194 if (m_rangeBeginIndex < m_currentIndex) { |
160 const auto& current = currentState(); | 195 const auto& current = currentState(); |
161 RangeRecord rangeRecord; | 196 RangeRecord rangeRecord; |
162 rangeRecord.displayListBeginIndex = m_rangeBeginIndex; | 197 rangeRecord.displayListBeginIndex = m_rangeBeginIndex; |
163 rangeRecord.displayListEndIndex = m_currentIndex; | 198 rangeRecord.displayListEndIndex = m_currentIndex; |
164 rangeRecord.transformNodeIndex = current.transformNode; | 199 rangeRecord.transformNodeIndex = current.transformNode; |
165 rangeRecord.offset = current.offset; | 200 rangeRecord.offset = current.offset; |
166 rangeRecord.clipNodeIndex = current.clipNode; | 201 rangeRecord.clipNodeIndex = current.clipNode; |
167 m_rangeRecords.append(rangeRecord); | 202 m_rangeRecords.append(rangeRecord); |
168 } | 203 } |
169 | 204 |
170 // The current display item is a boundary. | 205 // The current display item is a boundary. |
171 // The earliest the next range could begin is the next one. | 206 // The earliest the next range could begin is the next one. |
172 m_rangeBeginIndex = m_currentIndex + 1; | 207 m_rangeBeginIndex = m_currentIndex + 1; |
173 } | 208 } |
174 | 209 |
175 } // namespace blink | 210 } // namespace blink |
OLD | NEW |