will-change should sometimes trigger compositing
[WebKit-https.git] / Source / WebCore / rendering / style / WillChangeData.h
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 #ifndef WillChangeData_h
27 #define WillChangeData_h
28
29 #include "CSSPropertyNames.h"
30 #include "RenderStyleConstants.h"
31 #include <wtf/RefCounted.h>
32 #include <wtf/Vector.h>
33
34 namespace WebCore {
35
36 class WillChangeData : public RefCounted<WillChangeData> {
37     WTF_MAKE_FAST_ALLOCATED;
38 public:
39     static Ref<WillChangeData> create()
40     {
41         return adoptRef(*new WillChangeData);
42     }
43     
44     bool operator==(const WillChangeData&) const;
45     bool operator!=(const WillChangeData& o) const
46     {
47         return !(*this == o);
48     }
49
50     bool isAuto() const { return m_animatableFeatures.isEmpty(); }
51     size_t numFeatures() const { return m_animatableFeatures.size(); }
52
53     bool containsScrollPosition() const;
54     bool containsContents() const;
55     bool containsProperty(CSSPropertyID) const;
56
57     bool canCreateStackingContext() const { return m_canCreateStackingContext; }
58     bool canCreateStackingContextOnInline() const { return m_canCreateStackingContextOnInline; }
59
60     bool canTriggerCompositing() const { return m_canTriggerCompositing; }
61     bool canTriggerCompositingOnInline() const { return m_canTriggerCompositingOnInline; }
62
63     enum Feature {
64         ScrollPosition,
65         Contents,
66         Property,
67         Invalid
68     };
69
70     void addFeature(Feature, CSSPropertyID = CSSPropertyInvalid);
71     
72     typedef std::pair<Feature, CSSPropertyID> FeaturePropertyPair;
73     FeaturePropertyPair featureAt(size_t) const;
74
75 private:
76     WillChangeData()
77     {
78     }
79
80     struct AnimatableFeature {
81         static const int numCSSPropertyIDBits = 14;
82         COMPILE_ASSERT(numCSSProperties < (1 << numCSSPropertyIDBits), CSSPropertyID_should_fit_in_14_bits);
83
84         unsigned m_feature : 2;
85         unsigned m_cssPropertyID : numCSSPropertyIDBits;
86
87         Feature feature() const
88         {
89             return static_cast<Feature>(m_feature);
90         }
91
92         CSSPropertyID property() const
93         {
94             return feature() == Property ? static_cast<CSSPropertyID>(m_cssPropertyID) : CSSPropertyInvalid;
95         }
96         
97         FeaturePropertyPair featurePropertyPair() const
98         {
99             return FeaturePropertyPair(feature(), property());
100         }
101
102         AnimatableFeature(Feature willChange, CSSPropertyID willChangeProperty = CSSPropertyInvalid)
103         {
104             switch (willChange) {
105             case Property:
106                 ASSERT(willChangeProperty != CSSPropertyInvalid);
107                 m_cssPropertyID = willChangeProperty;
108                 FALLTHROUGH;
109             case ScrollPosition:
110             case Contents:
111                 m_feature = static_cast<unsigned>(willChange);
112                 break;
113             case Invalid:
114                 ASSERT_NOT_REACHED();
115                 break;
116             }
117         }
118         
119         bool operator==(const AnimatableFeature& other) const
120         {
121             return m_feature == other.m_feature && m_cssPropertyID == other.m_cssPropertyID;
122         }
123     };
124
125     Vector<AnimatableFeature, 1> m_animatableFeatures;
126     bool m_canCreateStackingContext { false };
127     bool m_canCreateStackingContextOnInline { false };
128     bool m_canTriggerCompositing { false };
129     bool m_canTriggerCompositingOnInline { false };
130 };
131
132
133 } // namespace WebCore
134
135 #endif // WillChangeData_h