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/GeometryPropertyTreeState.h" | |
13 #include "platform/graphics/paint/PaintChunkProperties.h" | 12 #include "platform/graphics/paint/PaintChunkProperties.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 // A complete set of paint properties including those that are inherited from ot
her objects. | |
24 // RefPtrs are used to guard against use-after-free bugs and DCHECKs ensure Prop
ertyTreeState never | |
25 // retains the last reference to a property tree node. | |
26 class PropertyTreeState { | |
27 public: | |
28 PropertyTreeState(const TransformPaintPropertyNode* transform, | |
29 const ClipPaintPropertyNode* clip, | |
30 const EffectPaintPropertyNode* effect, | |
31 const ScrollPaintPropertyNode* scroll) | |
32 : m_transform(transform), | |
33 m_clip(clip), | |
34 m_effect(effect), | |
35 m_scroll(scroll) { | |
36 DCHECK(!m_transform->hasOneRef() && !m_clip->hasOneRef() && | |
37 !m_effect->hasOneRef() && !m_scroll->hasOneRef()); | |
38 } | |
39 | |
40 const TransformPaintPropertyNode* transform() const { | |
41 DCHECK(!m_transform->hasOneRef()); | |
42 return m_transform.get(); | |
43 } | |
44 const ClipPaintPropertyNode* clip() const { | |
45 DCHECK(!m_clip->hasOneRef()); | |
46 return m_clip.get(); | |
47 } | |
48 const EffectPaintPropertyNode* effect() const { | |
49 DCHECK(!m_effect->hasOneRef()); | |
50 return m_effect.get(); | |
51 } | |
52 const ScrollPaintPropertyNode* scroll() const { | |
53 DCHECK(!m_scroll->hasOneRef()); | |
54 return m_scroll.get(); | |
55 } | |
56 | |
57 private: | |
58 RefPtr<const TransformPaintPropertyNode> m_transform; | |
59 RefPtr<const ClipPaintPropertyNode> m_clip; | |
60 RefPtr<const EffectPaintPropertyNode> m_effect; | |
61 RefPtr<const ScrollPaintPropertyNode> m_scroll; | |
62 }; | |
63 | |
64 // This class stores property tree related information associated with a LayoutO
bject. | 23 // This class stores property tree related information associated with a LayoutO
bject. |
65 // Currently there are two groups of information: | 24 // Currently there are two groups of information: |
66 // 1. The set of property nodes created locally by this LayoutObject. | 25 // 1. The set of property nodes created locally by this LayoutObject. |
67 // 2. [Optional] A suite of property nodes (PaintChunkProperties) and paint offs
et | 26 // 2. The set of property nodes (inherited, or created locally) and paint offset
that can be used |
68 // that can be used to paint the border box of this LayoutObject. | 27 // to paint the border box of this LayoutObject (see: localBorderBoxPropertie
s). |
69 class CORE_EXPORT ObjectPaintProperties { | 28 class CORE_EXPORT ObjectPaintProperties { |
70 WTF_MAKE_NONCOPYABLE(ObjectPaintProperties); | 29 WTF_MAKE_NONCOPYABLE(ObjectPaintProperties); |
71 USING_FAST_MALLOC(ObjectPaintProperties); | 30 USING_FAST_MALLOC(ObjectPaintProperties); |
72 | 31 |
73 public: | 32 public: |
74 struct LocalBorderBoxProperties; | |
75 | |
76 static std::unique_ptr<ObjectPaintProperties> create() { | 33 static std::unique_ptr<ObjectPaintProperties> create() { |
77 return wrapUnique(new ObjectPaintProperties()); | 34 return wrapUnique(new ObjectPaintProperties()); |
78 } | 35 } |
79 | 36 |
80 // The hierarchy of the transform subtree created by a LayoutObject is as foll
ows: | 37 // The hierarchy of the transform subtree created by a LayoutObject is as foll
ows: |
81 // [ paintOffsetTranslation ] Normally paint offset is accumulated w
ithout creating a node | 38 // [ paintOffsetTranslation ] Normally paint offset is accumulated w
ithout creating a node |
82 // | until we see, for example, transform o
r position:fixed. | 39 // | until we see, for example, transform o
r position:fixed. |
83 // +---[ transform ] The space created by CSS transform. | 40 // +---[ transform ] The space created by CSS transform. |
84 // | This is the local border box space, se
e: LocalBorderBoxProperties below. | 41 // | This is the local border box space, se
e: localBorderBoxProperties below. |
85 // +---[ perspective ] The space created by CSS perspective. | 42 // +---[ perspective ] The space created by CSS perspective. |
86 // | +---[ svgLocalToBorderBoxTransform ] Additional transform for child
ren of the outermost root SVG. | 43 // | +---[ svgLocalToBorderBoxTransform ] Additional transform for child
ren of the outermost root SVG. |
87 // | OR (SVG does not support scrolling.) | 44 // | OR (SVG does not support scrolling.) |
88 // | +---[ scrollTranslation ] The space created by overflow clip. | 45 // | +---[ scrollTranslation ] The space created by overflow clip. |
89 // +---[ scrollbarPaintOffset ] TODO(trchen): Remove this once we bake
the paint offset into frameRect. | 46 // +---[ scrollbarPaintOffset ] TODO(trchen): Remove this once we bake
the paint offset into frameRect. |
90 // This is equivalent to the local border
box space above, | 47 // This is equivalent to the local border
box space above, |
91 // with pixel snapped paint offset baked
in. It is really redundant, | 48 // with pixel snapped paint offset baked
in. It is really redundant, |
92 // but it is a pain to teach scrollbars t
o paint with an offset. | 49 // but it is a pain to teach scrollbars t
o paint with an offset. |
93 const TransformPaintPropertyNode* paintOffsetTranslation() const { | 50 const TransformPaintPropertyNode* paintOffsetTranslation() const { |
94 return m_paintOffsetTranslation.get(); | 51 return m_paintOffsetTranslation.get(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 const ClipPaintPropertyNode* cssClipFixedPosition() const { | 83 const ClipPaintPropertyNode* cssClipFixedPosition() const { |
127 return m_cssClipFixedPosition.get(); | 84 return m_cssClipFixedPosition.get(); |
128 } | 85 } |
129 const ClipPaintPropertyNode* innerBorderRadiusClip() const { | 86 const ClipPaintPropertyNode* innerBorderRadiusClip() const { |
130 return m_innerBorderRadiusClip.get(); | 87 return m_innerBorderRadiusClip.get(); |
131 } | 88 } |
132 const ClipPaintPropertyNode* overflowClip() const { | 89 const ClipPaintPropertyNode* overflowClip() const { |
133 return m_overflowClip.get(); | 90 return m_overflowClip.get(); |
134 } | 91 } |
135 | 92 |
136 // This is a complete set of property nodes that should be used as a starting
point to paint | 93 // The complete set of property tree nodes (inherited, or created locally) and
paint offset that |
137 // this layout object. It is needed becauase some property inherits from the c
ontaining block, | 94 // can be used to paint. |paintOffset| is relative to the propertyTreeState's
transform space. |
138 // not painting parent, thus can't be derived in O(1) during paint walk. | 95 // See: localBorderBoxProperties and contentsProperties. |
139 // Note: If this layout object has transform or stacking-context effects, thos
e are already | 96 struct PropertyTreeStateWithOffset { |
140 // baked into in the context here. However for properties that affects only ch
ildren, | 97 PropertyTreeStateWithOffset(LayoutPoint offset, PropertyTreeState treeState) |
141 // for example, perspective and overflow clip, those should be applied by the
painter | 98 : paintOffset(offset), propertyTreeState(treeState) {} |
142 // at the right painting step. | |
143 // TODO(pdr): Refactor this to use PropertyTreeState. | |
144 struct LocalBorderBoxProperties { | |
145 LayoutPoint paintOffset; | 99 LayoutPoint paintOffset; |
146 GeometryPropertyTreeState geometryPropertyTreeState; | 100 PropertyTreeState propertyTreeState; |
147 const ScrollPaintPropertyNode* scroll; | |
148 }; | 101 }; |
149 const LocalBorderBoxProperties* localBorderBoxProperties() const { | 102 |
| 103 // This is a complete set of property nodes and paint offset that should be us
ed as a starting |
| 104 // point to paint this layout object. This is cached because some properties i
nherit from the |
| 105 // containing block chain instead of the painting parent and cannot be derived
in O(1) during |
| 106 // the paint walk. |
| 107 // For example, <div style='opacity: 0.3; position: relative; margin: 11px;'/>
would have a |
| 108 // paint offset of (11px, 11px) and propertyTreeState.effect() would be an eff
ect node with |
| 109 // opacity of 0.3 which was created by the div itself. Note that propertyTreeS
tate.transform() |
| 110 // would not be null but would instead point to the transform space setup by d
iv's ancestors. |
| 111 const PropertyTreeStateWithOffset* localBorderBoxProperties() const { |
150 return m_localBorderBoxProperties.get(); | 112 return m_localBorderBoxProperties.get(); |
151 } | 113 } |
152 // ContentsPropertyTreeState is the GeometryPropertyTreeState that is the same
as in | 114 void setLocalBorderBoxProperties( |
153 // localBorderBoxProperties, except that it is inside any clips and scrolls ca
used by this | 115 std::unique_ptr<PropertyTreeStateWithOffset> properties) { |
154 // object. This GeometryPropertyTreeState is suitable as the destination for p
aint invalidation. | 116 m_localBorderBoxProperties = std::move(properties); |
155 // |paintOffsetFromState| is the offset from the GeometryPropertyTreeState to
this object's | 117 } |
156 // contents space. | 118 |
157 void getContentsPropertyTreeState(GeometryPropertyTreeState&, | 119 // This is the complete set of property nodes and paint offset that can be use
d to paint the |
158 LayoutPoint& paintOffsetFromState) const; | 120 // contents of this object. It is similar to localBorderBoxProperties but incl
udes properties |
| 121 // (e.g., overflow clip, scroll translation) that apply to contents. This is s
uitable for paint |
| 122 // invalidation. |
| 123 ObjectPaintProperties::PropertyTreeStateWithOffset contentsProperties() const; |
159 | 124 |
160 void clearPaintOffsetTranslation() { m_paintOffsetTranslation = nullptr; } | 125 void clearPaintOffsetTranslation() { m_paintOffsetTranslation = nullptr; } |
161 void clearTransform() { m_transform = nullptr; } | 126 void clearTransform() { m_transform = nullptr; } |
162 void clearEffect() { m_effect = nullptr; } | 127 void clearEffect() { m_effect = nullptr; } |
163 void clearCssClip() { m_cssClip = nullptr; } | 128 void clearCssClip() { m_cssClip = nullptr; } |
164 void clearCssClipFixedPosition() { m_cssClipFixedPosition = nullptr; } | 129 void clearCssClipFixedPosition() { m_cssClipFixedPosition = nullptr; } |
165 void clearInnerBorderRadiusClip() { m_innerBorderRadiusClip = nullptr; } | 130 void clearInnerBorderRadiusClip() { m_innerBorderRadiusClip = nullptr; } |
166 void clearOverflowClip() { m_overflowClip = nullptr; } | 131 void clearOverflowClip() { m_overflowClip = nullptr; } |
167 void clearPerspective() { m_perspective = nullptr; } | 132 void clearPerspective() { m_perspective = nullptr; } |
168 void clearSvgLocalToBorderBoxTransform() { | 133 void clearSvgLocalToBorderBoxTransform() { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 template <typename... Args> | 194 template <typename... Args> |
230 ClipPaintPropertyNode* createOrUpdateInnerBorderRadiusClip(Args&&... args) { | 195 ClipPaintPropertyNode* createOrUpdateInnerBorderRadiusClip(Args&&... args) { |
231 return createOrUpdateProperty(m_innerBorderRadiusClip, | 196 return createOrUpdateProperty(m_innerBorderRadiusClip, |
232 std::forward<Args>(args)...); | 197 std::forward<Args>(args)...); |
233 } | 198 } |
234 template <typename... Args> | 199 template <typename... Args> |
235 ClipPaintPropertyNode* createOrUpdateOverflowClip(Args&&... args) { | 200 ClipPaintPropertyNode* createOrUpdateOverflowClip(Args&&... args) { |
236 return createOrUpdateProperty(m_overflowClip, std::forward<Args>(args)...); | 201 return createOrUpdateProperty(m_overflowClip, std::forward<Args>(args)...); |
237 } | 202 } |
238 | 203 |
239 void setLocalBorderBoxProperties( | |
240 std::unique_ptr<LocalBorderBoxProperties> properties) { | |
241 m_localBorderBoxProperties = std::move(properties); | |
242 } | |
243 | |
244 private: | 204 private: |
245 ObjectPaintProperties() {} | 205 ObjectPaintProperties() {} |
246 | 206 |
247 template <typename PaintPropertyNode, typename... Args> | 207 template <typename PaintPropertyNode, typename... Args> |
248 PaintPropertyNode* createOrUpdateProperty(RefPtr<PaintPropertyNode>& field, | 208 PaintPropertyNode* createOrUpdateProperty(RefPtr<PaintPropertyNode>& field, |
249 Args&&... args) { | 209 Args&&... args) { |
250 if (field) | 210 if (field) |
251 field->update(std::forward<Args>(args)...); | 211 field->update(std::forward<Args>(args)...); |
252 else | 212 else |
253 field = PaintPropertyNode::create(std::forward<Args>(args)...); | 213 field = PaintPropertyNode::create(std::forward<Args>(args)...); |
254 return field.get(); | 214 return field.get(); |
255 } | 215 } |
256 | 216 |
257 RefPtr<TransformPaintPropertyNode> m_paintOffsetTranslation; | 217 RefPtr<TransformPaintPropertyNode> m_paintOffsetTranslation; |
258 RefPtr<TransformPaintPropertyNode> m_transform; | 218 RefPtr<TransformPaintPropertyNode> m_transform; |
259 RefPtr<EffectPaintPropertyNode> m_effect; | 219 RefPtr<EffectPaintPropertyNode> m_effect; |
260 RefPtr<ClipPaintPropertyNode> m_cssClip; | 220 RefPtr<ClipPaintPropertyNode> m_cssClip; |
261 RefPtr<ClipPaintPropertyNode> m_cssClipFixedPosition; | 221 RefPtr<ClipPaintPropertyNode> m_cssClipFixedPosition; |
262 RefPtr<ClipPaintPropertyNode> m_innerBorderRadiusClip; | 222 RefPtr<ClipPaintPropertyNode> m_innerBorderRadiusClip; |
263 RefPtr<ClipPaintPropertyNode> m_overflowClip; | 223 RefPtr<ClipPaintPropertyNode> m_overflowClip; |
264 RefPtr<TransformPaintPropertyNode> m_perspective; | 224 RefPtr<TransformPaintPropertyNode> m_perspective; |
265 // TODO(pdr): Only LayoutSVGRoot needs this and it should be moved there. | 225 // TODO(pdr): Only LayoutSVGRoot needs this and it should be moved there. |
266 RefPtr<TransformPaintPropertyNode> m_svgLocalToBorderBoxTransform; | 226 RefPtr<TransformPaintPropertyNode> m_svgLocalToBorderBoxTransform; |
267 RefPtr<TransformPaintPropertyNode> m_scrollTranslation; | 227 RefPtr<TransformPaintPropertyNode> m_scrollTranslation; |
268 RefPtr<TransformPaintPropertyNode> m_scrollbarPaintOffset; | 228 RefPtr<TransformPaintPropertyNode> m_scrollbarPaintOffset; |
269 RefPtr<ScrollPaintPropertyNode> m_scroll; | 229 RefPtr<ScrollPaintPropertyNode> m_scroll; |
270 | 230 |
271 std::unique_ptr<LocalBorderBoxProperties> m_localBorderBoxProperties; | 231 std::unique_ptr<PropertyTreeStateWithOffset> m_localBorderBoxProperties; |
272 }; | 232 }; |
273 | 233 |
274 } // namespace blink | 234 } // namespace blink |
275 | 235 |
276 #endif // ObjectPaintProperties_h | 236 #endif // ObjectPaintProperties_h |
OLD | NEW |