| 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 |