1 | /* |
2 | * Copyright (C) 2015 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include "config.h" |
27 | #include "WillChangeData.h" |
28 | |
29 | namespace WebCore { |
30 | |
31 | bool WillChangeData::operator==(const WillChangeData& other) const |
32 | { |
33 | return m_animatableFeatures == other.m_animatableFeatures; |
34 | } |
35 | |
36 | bool WillChangeData::containsScrollPosition() const |
37 | { |
38 | for (const auto& feature : m_animatableFeatures) { |
39 | if (feature.feature() == ScrollPosition) |
40 | return true; |
41 | } |
42 | return false; |
43 | } |
44 | |
45 | bool WillChangeData::containsContents() const |
46 | { |
47 | for (const auto& feature : m_animatableFeatures) { |
48 | if (feature.feature() == Contents) |
49 | return true; |
50 | } |
51 | return false; |
52 | } |
53 | |
54 | bool WillChangeData::containsProperty(CSSPropertyID property) const |
55 | { |
56 | for (const auto& feature : m_animatableFeatures) { |
57 | if (feature.property() == property) |
58 | return true; |
59 | } |
60 | return false; |
61 | } |
62 | |
63 | // "If any non-initial value of a property would create a stacking context on the element, |
64 | // specifying that property in will-change must create a stacking context on the element." |
65 | bool WillChangeData::propertyCreatesStackingContext(CSSPropertyID property) |
66 | { |
67 | switch (property) { |
68 | case CSSPropertyPerspective: |
69 | case CSSPropertyTransform: |
70 | case CSSPropertyTransformStyle: |
71 | case CSSPropertyWebkitTransformStyle: |
72 | case CSSPropertyClipPath: |
73 | case CSSPropertyWebkitClipPath: |
74 | case CSSPropertyMask: |
75 | case CSSPropertyOpacity: |
76 | case CSSPropertyPosition: |
77 | case CSSPropertyZIndex: |
78 | case CSSPropertyWebkitBoxReflect: |
79 | #if ENABLE(CSS_COMPOSITING) |
80 | case CSSPropertyMixBlendMode: |
81 | case CSSPropertyIsolation: |
82 | #endif |
83 | case CSSPropertyFilter: |
84 | #if ENABLE(FILTERS_LEVEL_2) |
85 | case CSSPropertyWebkitBackdropFilter: |
86 | #endif |
87 | case CSSPropertyWebkitMask: |
88 | case CSSPropertyWebkitMaskImage: |
89 | case CSSPropertyWebkitMaskBoxImage: |
90 | #if ENABLE(OVERFLOW_SCROLLING_TOUCH) |
91 | case CSSPropertyWebkitOverflowScrolling: |
92 | #endif |
93 | return true; |
94 | default: |
95 | return false; |
96 | } |
97 | } |
98 | |
99 | static bool propertyTriggersCompositing(CSSPropertyID property) |
100 | { |
101 | switch (property) { |
102 | case CSSPropertyOpacity: |
103 | case CSSPropertyFilter: |
104 | #if ENABLE(FILTERS_LEVEL_2) |
105 | case CSSPropertyWebkitBackdropFilter: |
106 | #endif |
107 | return true; |
108 | default: |
109 | return false; |
110 | } |
111 | } |
112 | |
113 | static bool propertyTriggersCompositingOnBoxesOnly(CSSPropertyID property) |
114 | { |
115 | // Don't trigger for perspective and transform-style, because those |
116 | // only do compositing if they have a 3d-transformed descendant and |
117 | // we don't want to do compositing all the time. |
118 | // Similarly, we don't want -webkit-overflow-scrolling-touch to |
119 | // always composite if there's no scrollable overflow. |
120 | switch (property) { |
121 | case CSSPropertyTransform: |
122 | return true; |
123 | default: |
124 | return false; |
125 | } |
126 | } |
127 | |
128 | void WillChangeData::addFeature(Feature feature, CSSPropertyID propertyID) |
129 | { |
130 | ASSERT(feature == Property || propertyID == CSSPropertyInvalid); |
131 | m_animatableFeatures.append(AnimatableFeature(feature, propertyID)); |
132 | |
133 | m_canCreateStackingContext |= propertyCreatesStackingContext(propertyID); |
134 | |
135 | m_canTriggerCompositingOnInline |= propertyTriggersCompositing(propertyID); |
136 | m_canTriggerCompositing |= m_canTriggerCompositingOnInline | propertyTriggersCompositingOnBoxesOnly(propertyID); |
137 | } |
138 | |
139 | WillChangeData::FeaturePropertyPair WillChangeData::featureAt(size_t index) const |
140 | { |
141 | if (index >= m_animatableFeatures.size()) |
142 | return FeaturePropertyPair(Invalid, CSSPropertyInvalid); |
143 | |
144 | return m_animatableFeatures[index].featurePropertyPair(); |
145 | } |
146 | |
147 | } // namespace WebCore |
148 | |