Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : /*
8 : * Inlined methods for nsStyleContext. Will just redirect to
9 : * GeckoStyleContext methods when compiled without stylo, but will do
10 : * virtual dispatch (by checking which kind of container it is)
11 : * in stylo mode.
12 : */
13 :
14 : #ifndef nsStyleContextInlines_h
15 : #define nsStyleContextInlines_h
16 :
17 : #include "nsStyleContext.h"
18 : #include "mozilla/ServoStyleContext.h"
19 : #include "mozilla/GeckoStyleContext.h"
20 : #include "mozilla/ServoUtils.h"
21 :
22 1167958 : MOZ_DEFINE_STYLO_METHODS(nsStyleContext,
23 : mozilla::GeckoStyleContext,
24 : mozilla::ServoStyleContext);
25 :
26 : nsRuleNode*
27 8456 : nsStyleContext::RuleNode()
28 : {
29 8456 : MOZ_RELEASE_ASSERT(IsGecko());
30 8456 : return AsGecko()->RuleNode();
31 : }
32 :
33 : ServoComputedValues*
34 0 : nsStyleContext::ComputedValues()
35 : {
36 0 : MOZ_RELEASE_ASSERT(IsServo());
37 0 : return AsServo()->ComputedValues();
38 : }
39 :
40 : #define STYLE_STRUCT(name_, checkdata_cb_) \
41 : const nsStyle##name_ * \
42 : nsStyleContext::Style##name_() { \
43 : return DoGetStyle##name_<true>(); \
44 : } \
45 : const nsStyle##name_ * \
46 : nsStyleContext::ThreadsafeStyle##name_() { \
47 : if (mozilla::ServoStyleSet::IsInServoTraversal()) { \
48 : return Servo_GetStyle##name_(AsServo()->ComputedValues()); \
49 : } \
50 : return Style##name_(); \
51 : } \
52 : const nsStyle##name_ * nsStyleContext::PeekStyle##name_() { \
53 : return DoGetStyle##name_<false>(); \
54 : }
55 : #include "nsStyleStructList.h"
56 : #undef STYLE_STRUCT
57 :
58 : // Helper functions for GetStyle* and PeekStyle*
59 : #define STYLE_STRUCT_INHERITED(name_, checkdata_cb_) \
60 : template<bool aComputeData> \
61 : const nsStyle##name_ * nsStyleContext::DoGetStyle##name_() { \
62 : if (auto gecko = GetAsGecko()) { \
63 : const nsStyle##name_ * cachedData = \
64 : static_cast<nsStyle##name_*>( \
65 : gecko->mCachedInheritedData \
66 : .mStyleStructs[eStyleStruct_##name_]); \
67 : if (cachedData) /* Have it cached already, yay */ \
68 : return cachedData; \
69 : if (!aComputeData) { \
70 : /* We always cache inherited structs on the context when we */\
71 : /* compute them. */ \
72 : return nullptr; \
73 : } \
74 : /* Have the rulenode deal */ \
75 : AUTO_CHECK_DEPENDENCY(gecko, eStyleStruct_##name_); \
76 : const nsStyle##name_ * newData = \
77 : gecko->RuleNode()-> \
78 : GetStyle##name_<aComputeData>(this->AsGecko(), mBits); \
79 : /* always cache inherited data on the style context; the rule */\
80 : /* node set the bit in mBits for us if needed. */ \
81 : gecko->mCachedInheritedData \
82 : .mStyleStructs[eStyleStruct_##name_] = \
83 : const_cast<nsStyle##name_ *>(newData); \
84 : return newData; \
85 : } \
86 : auto servo = AsServo(); \
87 : /** \
88 : * Also (conservatively) set the owning bit in the parent style \
89 : * context if we're a text node. \
90 : * \
91 : * This causes the parent element's style context to cache any \
92 : * inherited structs we request for a text node, which means we \
93 : * don't have to compute change hints for the text node, as \
94 : * handling the change on the parent element is sufficient. \
95 : * \
96 : * Note, however, that we still need to request the style struct \
97 : * of the text node itself, since we may run some fixups on it, \
98 : * like for text-combine. \
99 : * \
100 : * This model is sound because for the fixed-up values to change, \
101 : * other properties on the parent need to change too, and we'll \
102 : * handle those change hints correctly. \
103 : * \
104 : * TODO(emilio): Perhaps we should remove those fixups and handle \
105 : * those in layout instead. Those fixups are kind of expensive \
106 : * for style sharing, and computed style of text nodes is not \
107 : * observable. If we do that, we could assert here that the \
108 : * inherited structs of both are the same. \
109 : */ \
110 : if (mPseudoTag == nsCSSAnonBoxes::mozText && aComputeData) { \
111 : MOZ_ASSERT(mParent); \
112 : mParent->AddStyleBit(NS_STYLE_INHERIT_BIT(name_)); \
113 : } \
114 : \
115 : const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_));\
116 : if (!aComputeData && needToCompute) { \
117 : return nullptr; \
118 : } \
119 : \
120 : const nsStyle##name_* data = \
121 : Servo_GetStyle##name_(servo->ComputedValues()); \
122 : /* perform any remaining main thread work on the struct */ \
123 : if (needToCompute) { \
124 : MOZ_ASSERT(NS_IsMainThread()); \
125 : MOZ_ASSERT(!mozilla::ServoStyleSet::IsInServoTraversal()); \
126 : const_cast<nsStyle##name_*>(data)->FinishStyle(PresContext()); \
127 : /* the ServoStyleContext owns the struct */ \
128 : AddStyleBit(NS_STYLE_INHERIT_BIT(name_)); \
129 : } \
130 : return data; \
131 : }
132 :
133 : #define STYLE_STRUCT_RESET(name_, checkdata_cb_) \
134 : template<bool aComputeData> \
135 : const nsStyle##name_ * nsStyleContext::DoGetStyle##name_() { \
136 : if (auto gecko = GetAsGecko()) { \
137 : if (gecko->mCachedResetData) { \
138 : const nsStyle##name_ * cachedData = \
139 : static_cast<nsStyle##name_*>( \
140 : gecko->mCachedResetData->mStyleStructs[eStyleStruct_##name_]); \
141 : if (cachedData) /* Have it cached already, yay */ \
142 : return cachedData; \
143 : } \
144 : /* Have the rulenode deal */ \
145 : AUTO_CHECK_DEPENDENCY(gecko, eStyleStruct_##name_); \
146 : return gecko->RuleNode()->GetStyle##name_<aComputeData>(this->AsGecko()); \
147 : } \
148 : auto servo = AsServo(); \
149 : const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_)); \
150 : if (!aComputeData && needToCompute) { \
151 : return nullptr; \
152 : } \
153 : const nsStyle##name_* data = \
154 : Servo_GetStyle##name_(servo->ComputedValues()); \
155 : /* perform any remaining main thread work on the struct */ \
156 : if (needToCompute) { \
157 : const_cast<nsStyle##name_*>(data)->FinishStyle(PresContext()); \
158 : /* the ServoStyleContext owns the struct */ \
159 : AddStyleBit(NS_STYLE_INHERIT_BIT(name_)); \
160 : } \
161 : return data; \
162 : }
163 : #include "nsStyleStructList.h"
164 : #undef STYLE_STRUCT_RESET
165 : #undef STYLE_STRUCT_INHERITED
166 :
167 :
168 : nsPresContext*
169 74956 : nsStyleContext::PresContext() const
170 : {
171 74956 : MOZ_STYLO_FORWARD(PresContext, ())
172 : }
173 :
174 : mozilla::GeckoStyleContext*
175 11817 : nsStyleContext::GetParent() const
176 : {
177 11817 : MOZ_ASSERT(IsGecko(),
178 : "This should be used only in Gecko-backed style system!");
179 11817 : if (mParent) {
180 10830 : return mParent->AsGecko();
181 : } else {
182 987 : return nullptr;
183 : }
184 : }
185 :
186 : bool
187 745 : nsStyleContext::IsLinkContext() const
188 : {
189 745 : return GetStyleIfVisited() && GetStyleIfVisited()->GetParent() == GetParent();
190 : }
191 :
192 : void
193 493 : nsStyleContext::StartBackgroundImageLoads()
194 : {
195 : // Just get our background struct; that should do the trick
196 493 : StyleBackground();
197 493 : }
198 :
199 : #endif // nsStyleContextInlines_h
|