| 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 #ifndef ObjectPaintProperties_h | 5 #ifndef ObjectPaintProperties_h |
| 6 #define ObjectPaintProperties_h | 6 #define ObjectPaintProperties_h |
| 7 | 7 |
| 8 #include "core/CoreExport.h" | 8 #include "core/CoreExport.h" |
| 9 #include "platform/geometry/LayoutPoint.h" | 9 #include "platform/geometry/LayoutPoint.h" |
| 10 #include "platform/graphics/paint/ClipPaintPropertyNode.h" | 10 #include "platform/graphics/paint/ClipPaintPropertyNode.h" |
| 11 #include "platform/graphics/paint/EffectPaintPropertyNode.h" | 11 #include "platform/graphics/paint/EffectPaintPropertyNode.h" |
| 12 #include "platform/graphics/paint/PaintChunkProperties.h" | 12 #include "platform/graphics/paint/PaintChunkProperties.h" |
| 13 #include "platform/graphics/paint/PropertyTreeState.h" | 13 #include "platform/graphics/paint/PropertyTreeState.h" |
| 14 #include "platform/graphics/paint/ScrollPaintPropertyNode.h" | 14 #include "platform/graphics/paint/ScrollPaintPropertyNode.h" |
| 15 #include "platform/graphics/paint/TransformPaintPropertyNode.h" | 15 #include "platform/graphics/paint/TransformPaintPropertyNode.h" |
| 16 #include "wtf/PassRefPtr.h" | 16 #include "wtf/PassRefPtr.h" |
| 17 #include "wtf/PtrUtil.h" | 17 #include "wtf/PtrUtil.h" |
| 18 #include "wtf/RefPtr.h" | 18 #include "wtf/RefPtr.h" |
| 19 #include <memory> | 19 #include <memory> |
| 20 | 20 |
| 21 namespace blink { | 21 namespace blink { |
| 22 | 22 |
| 23 // This class stores the paint property nodes associated with a LayoutObject. | 23 // This class stores the paint property nodes created by a LayoutObject. The |
| 24 // The object owns each of the property nodes directly set here (e.g, m_cssClip, | 24 // object owns each of the property nodes directly and RefPtrs are only used to |
| 25 // m_paintOffsetTranslation, etc.) and RefPtrs are only used to harden against | 25 // harden against use-after-free bugs. These paint properties are built/updated |
| 26 // use-after-free bugs. These paint properties are built/updated by | 26 // by PaintPropertyTreeBuilder during the PrePaint lifecycle step. |
| 27 // PaintPropertyTreeBuilder during the PrePaint lifecycle step. | |
| 28 // | |
| 29 // There are two groups of information stored on ObjectPaintProperties: | |
| 30 // 1. The set of property nodes created locally and owned by this LayoutObject. | |
| 31 // 2. The set of property nodes (inherited, or created locally) that can be used | |
| 32 // along with LayoutObject::paintOffset to paint the border box of this | |
| 33 // LayoutObject (see: localBorderBoxProperties). | |
| 34 // | 27 // |
| 35 // [update & clear implementation note] This class has update[property](...) and | 28 // [update & clear implementation note] This class has update[property](...) and |
| 36 // clear[property]() helper functions for efficiently creating and updating | 29 // clear[property]() helper functions for efficiently creating and updating |
| 37 // properties. These functions return true if the property tree structure | 30 // properties. These functions return true if the property tree structure |
| 38 // changes (e.g., a node is added or removed), and false otherwise. Property | 31 // changes (e.g., a node is added or removed), and false otherwise. Property |
| 39 // nodes store parent pointers but not child pointers and these return values | 32 // nodes store parent pointers but not child pointers and these return values |
| 40 // are important for catching property tree structure changes which require | 33 // are important for catching property tree structure changes which require |
| 41 // updating descendant's parent pointers. The update functions use a | 34 // updating descendant's parent pointers. The update functions use a |
| 42 // create-or-update pattern of re-using existing properties for efficiency: | 35 // create-or-update pattern of re-using existing properties for efficiency: |
| 43 // 1. It avoids extra allocations. | 36 // 1. It avoids extra allocations. |
| 44 // 2. It preserves existing child->parent pointers. | 37 // 2. It preserves existing child->parent pointers. |
| 45 class CORE_EXPORT ObjectPaintProperties { | 38 class CORE_EXPORT ObjectPaintProperties { |
| 46 WTF_MAKE_NONCOPYABLE(ObjectPaintProperties); | 39 WTF_MAKE_NONCOPYABLE(ObjectPaintProperties); |
| 47 USING_FAST_MALLOC(ObjectPaintProperties); | 40 USING_FAST_MALLOC(ObjectPaintProperties); |
| 48 | 41 |
| 49 public: | 42 public: |
| 50 static std::unique_ptr<ObjectPaintProperties> create() { | 43 static std::unique_ptr<ObjectPaintProperties> create() { |
| 51 return WTF::wrapUnique(new ObjectPaintProperties()); | 44 return WTF::wrapUnique(new ObjectPaintProperties()); |
| 52 } | 45 } |
| 53 | 46 |
| 54 // The hierarchy of the transform subtree created by a LayoutObject is as | 47 // The hierarchy of the transform subtree created by a LayoutObject is as |
| 55 // follows: | 48 // follows: |
| 56 // [ paintOffsetTranslation ] Normally paint offset is accumulated | 49 // [ paintOffsetTranslation ] Normally paint offset is accumulated |
| 57 // | without creating a node until we see, | 50 // | without creating a node until we see, |
| 58 // | for example, transform or | 51 // | for example, transform or |
| 59 // | position:fixed. | 52 // | position:fixed. |
| 60 // +---[ transform ] The space created by CSS transform. | 53 // +---[ transform ] The space created by CSS transform. |
| 61 // | This is the local border box space, | 54 // | This is the local border box space. |
| 62 // | see: localBorderBoxProperties below. | |
| 63 // +---[ perspective ] The space created by CSS perspective. | 55 // +---[ perspective ] The space created by CSS perspective. |
| 64 // | +---[ svgLocalToBorderBoxTransform ] Additional transform for | 56 // | +---[ svgLocalToBorderBoxTransform ] Additional transform for |
| 65 // children of the outermost root SVG. | 57 // children of the outermost root SVG. |
| 66 // | OR (SVG does not support scrolling.) | 58 // | OR (SVG does not support scrolling.) |
| 67 // | +---[ scrollTranslation ] The space created by overflow clip. | 59 // | +---[ scrollTranslation ] The space created by overflow clip. |
| 68 // +---[ scrollbarPaintOffset ] TODO(trchen): Remove this once we bake | 60 // +---[ scrollbarPaintOffset ] TODO(trchen): Remove this once we bake |
| 69 // the paint offset into frameRect. This | 61 // the paint offset into frameRect. This |
| 70 // is equivalent to the local border box | 62 // is equivalent to the local border box |
| 71 // space above, with pixel snapped paint | 63 // space above, with pixel snapped paint |
| 72 // offset baked in. It is really | 64 // offset baked in. It is really |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 const ClipPaintPropertyNode* cssClipFixedPosition() const { | 124 const ClipPaintPropertyNode* cssClipFixedPosition() const { |
| 133 return m_cssClipFixedPosition.get(); | 125 return m_cssClipFixedPosition.get(); |
| 134 } | 126 } |
| 135 const ClipPaintPropertyNode* innerBorderRadiusClip() const { | 127 const ClipPaintPropertyNode* innerBorderRadiusClip() const { |
| 136 return m_innerBorderRadiusClip.get(); | 128 return m_innerBorderRadiusClip.get(); |
| 137 } | 129 } |
| 138 const ClipPaintPropertyNode* overflowClip() const { | 130 const ClipPaintPropertyNode* overflowClip() const { |
| 139 return m_overflowClip.get(); | 131 return m_overflowClip.get(); |
| 140 } | 132 } |
| 141 | 133 |
| 142 // This is a complete set of property nodes that should be used as a starting | |
| 143 // point to paint this layout object. This is cached because some properties | |
| 144 // inherit from the containing block chain instead of the painting parent and | |
| 145 // cannot be derived in O(1) during the paint walk. For example: | |
| 146 // <div style='opacity: 0.3;'/> would have a propertyTreeState.effect() | |
| 147 // with opacity of 0.3 which was created by the div itself. Note that | |
| 148 // propertyTreeState.transform() would not be null but would instead point to | |
| 149 // the transform space setup by div's ancestors. | |
| 150 const PropertyTreeState* localBorderBoxProperties() const { | |
| 151 return m_localBorderBoxProperties.get(); | |
| 152 } | |
| 153 | |
| 154 // This is the complete set of property nodes that can be used to paint the | 134 // This is the complete set of property nodes that can be used to paint the |
| 155 // contents of this object. It is similar to localBorderBoxProperties but | 135 // contents of this object. It is similar to the local border box properties |
| 156 // includes properties (e.g., overflow clip, scroll translation) that apply to | 136 // but also includes properties (e.g., overflow clip, scroll translation) that |
| 157 // contents. This is suitable for paint invalidation. | 137 // apply to an object's contents. |
| 158 const PropertyTreeState* contentsProperties() const { | 138 static std::unique_ptr<PropertyTreeState> contentsProperties( |
| 159 if (!m_contentsProperties) { | 139 PropertyTreeState* localBorderBoxProperties, |
| 160 if (!m_localBorderBoxProperties) | 140 ObjectPaintProperties*); |
| 161 return nullptr; | |
| 162 updateContentsProperties(); | |
| 163 } else { | |
| 164 #if DCHECK_IS_ON() | |
| 165 // Check if the cached m_contentsProperties is valid. | |
| 166 DCHECK(m_localBorderBoxProperties); | |
| 167 std::unique_ptr<PropertyTreeState> oldProperties = | |
| 168 std::move(m_contentsProperties); | |
| 169 updateContentsProperties(); | |
| 170 DCHECK(*m_contentsProperties == *oldProperties); | |
| 171 #endif | |
| 172 } | |
| 173 return m_contentsProperties.get(); | |
| 174 }; | |
| 175 | |
| 176 void updateLocalBorderBoxProperties( | |
| 177 const TransformPaintPropertyNode* transform, | |
| 178 const ClipPaintPropertyNode* clip, | |
| 179 const EffectPaintPropertyNode* effect) { | |
| 180 if (m_localBorderBoxProperties) { | |
| 181 m_localBorderBoxProperties->setTransform(transform); | |
| 182 m_localBorderBoxProperties->setClip(clip); | |
| 183 m_localBorderBoxProperties->setEffect(effect); | |
| 184 } else { | |
| 185 m_localBorderBoxProperties = WTF::wrapUnique( | |
| 186 new PropertyTreeState(PropertyTreeState(transform, clip, effect))); | |
| 187 } | |
| 188 m_contentsProperties = nullptr; | |
| 189 } | |
| 190 void clearLocalBorderBoxProperties() { | |
| 191 m_localBorderBoxProperties = nullptr; | |
| 192 m_contentsProperties = nullptr; | |
| 193 } | |
| 194 | 141 |
| 195 // The following clear* functions return true if the property tree structure | 142 // The following clear* functions return true if the property tree structure |
| 196 // changes (an existing node was deleted), and false otherwise. See the | 143 // changes (an existing node was deleted), and false otherwise. See the |
| 197 // class-level comment ("update & clear implementation note") for details | 144 // class-level comment ("update & clear implementation note") for details |
| 198 // about why this is needed for efficient updates. | 145 // about why this is needed for efficient updates. |
| 199 bool clearPaintOffsetTranslation() { return clear(m_paintOffsetTranslation); } | 146 bool clearPaintOffsetTranslation() { return clear(m_paintOffsetTranslation); } |
| 200 bool clearTransform() { return clear(m_transform); } | 147 bool clearTransform() { return clear(m_transform); } |
| 201 bool clearEffect() { return clear(m_effect); } | 148 bool clearEffect() { return clear(m_effect); } |
| 202 bool clearFilter() { return clear(m_filter); } | 149 bool clearFilter() { return clear(m_filter); } |
| 203 bool clearMask() { return clear(m_mask); } | 150 bool clearMask() { return clear(m_mask); } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 if (m_perspective) | 260 if (m_perspective) |
| 314 cloned->m_perspective = m_perspective->clone(); | 261 cloned->m_perspective = m_perspective->clone(); |
| 315 if (m_svgLocalToBorderBoxTransform) { | 262 if (m_svgLocalToBorderBoxTransform) { |
| 316 cloned->m_svgLocalToBorderBoxTransform = | 263 cloned->m_svgLocalToBorderBoxTransform = |
| 317 m_svgLocalToBorderBoxTransform->clone(); | 264 m_svgLocalToBorderBoxTransform->clone(); |
| 318 } | 265 } |
| 319 if (m_scrollTranslation) | 266 if (m_scrollTranslation) |
| 320 cloned->m_scrollTranslation = m_scrollTranslation->clone(); | 267 cloned->m_scrollTranslation = m_scrollTranslation->clone(); |
| 321 if (m_scrollbarPaintOffset) | 268 if (m_scrollbarPaintOffset) |
| 322 cloned->m_scrollbarPaintOffset = m_scrollbarPaintOffset->clone(); | 269 cloned->m_scrollbarPaintOffset = m_scrollbarPaintOffset->clone(); |
| 323 if (m_localBorderBoxProperties) { | |
| 324 cloned->m_localBorderBoxProperties = | |
| 325 WTF::wrapUnique(new PropertyTreeState(*m_localBorderBoxProperties)); | |
| 326 } | |
| 327 return cloned; | 270 return cloned; |
| 328 } | 271 } |
| 329 #endif | 272 #endif |
| 330 | 273 |
| 331 private: | 274 private: |
| 332 ObjectPaintProperties() {} | 275 ObjectPaintProperties() {} |
| 333 | 276 |
| 334 // Return true if the property tree structure changes (an existing node was | 277 // Return true if the property tree structure changes (an existing node was |
| 335 // deleted), and false otherwise. See the class-level comment ("update & clear | 278 // deleted), and false otherwise. See the class-level comment ("update & clear |
| 336 // implementation note") for details about why this is needed for efficiency. | 279 // implementation note") for details about why this is needed for efficiency. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 RefPtr<ClipPaintPropertyNode> m_maskClip; | 311 RefPtr<ClipPaintPropertyNode> m_maskClip; |
| 369 RefPtr<ClipPaintPropertyNode> m_cssClip; | 312 RefPtr<ClipPaintPropertyNode> m_cssClip; |
| 370 RefPtr<ClipPaintPropertyNode> m_cssClipFixedPosition; | 313 RefPtr<ClipPaintPropertyNode> m_cssClipFixedPosition; |
| 371 RefPtr<ClipPaintPropertyNode> m_innerBorderRadiusClip; | 314 RefPtr<ClipPaintPropertyNode> m_innerBorderRadiusClip; |
| 372 RefPtr<ClipPaintPropertyNode> m_overflowClip; | 315 RefPtr<ClipPaintPropertyNode> m_overflowClip; |
| 373 RefPtr<TransformPaintPropertyNode> m_perspective; | 316 RefPtr<TransformPaintPropertyNode> m_perspective; |
| 374 // TODO(pdr): Only LayoutSVGRoot needs this and it should be moved there. | 317 // TODO(pdr): Only LayoutSVGRoot needs this and it should be moved there. |
| 375 RefPtr<TransformPaintPropertyNode> m_svgLocalToBorderBoxTransform; | 318 RefPtr<TransformPaintPropertyNode> m_svgLocalToBorderBoxTransform; |
| 376 RefPtr<TransformPaintPropertyNode> m_scrollTranslation; | 319 RefPtr<TransformPaintPropertyNode> m_scrollTranslation; |
| 377 RefPtr<TransformPaintPropertyNode> m_scrollbarPaintOffset; | 320 RefPtr<TransformPaintPropertyNode> m_scrollbarPaintOffset; |
| 378 | |
| 379 std::unique_ptr<PropertyTreeState> m_localBorderBoxProperties; | |
| 380 mutable std::unique_ptr<PropertyTreeState> m_contentsProperties; | |
| 381 }; | 321 }; |
| 382 | 322 |
| 383 } // namespace blink | 323 } // namespace blink |
| 384 | 324 |
| 385 #endif // ObjectPaintProperties_h | 325 #endif // ObjectPaintProperties_h |
| OLD | NEW |