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