Bug 1367904 - Part 10: stylo: Switch Gecko over to ServoStyleContext; r=bholley

MozReview-Commit-ID: EmopKVjEzlz
This commit is contained in:
Manish Goregaokar 2017-07-17 11:42:00 -07:00
parent ead2d89220
commit f33beecc59
26 changed files with 392 additions and 273 deletions

View File

@ -1284,14 +1284,14 @@ EffectCompositor::AnimationStyleRuleProcessor::SizeOfIncludingThis(
template
void
EffectCompositor::UpdateEffectProperties(
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
Element* aElement,
CSSPseudoElementType aPseudoType);
template
void
EffectCompositor::UpdateEffectProperties(
const ServoComputedValues* aServoValues,
const ServoStyleContext* aStyleContext,
Element* aElement,
CSSPseudoElementType aPseudoType);

View File

@ -186,12 +186,22 @@ KeyframeEffectReadOnly::SetKeyframes(JSContext* aContext,
}
RefPtr<nsStyleContext> styleContext = GetTargetStyleContext();
SetKeyframes(Move(keyframes), styleContext);
if (styleContext) {
if (auto gecko = styleContext->GetAsGecko()) {
SetKeyframes(Move(keyframes), gecko);
} else {
SetKeyframes(Move(keyframes), styleContext->AsServo());
}
} else {
// SetKeyframes has the same behavior for null StyleType* for
// both backends, just pick one and use it.
SetKeyframes(Move(keyframes), (GeckoStyleContext*) nullptr);
}
}
void
KeyframeEffectReadOnly::SetKeyframes(nsTArray<Keyframe>&& aKeyframes,
nsStyleContext* aStyleContext)
GeckoStyleContext* aStyleContext)
{
DoSetKeyframes(Move(aKeyframes), Move(aStyleContext));
}
@ -199,7 +209,7 @@ KeyframeEffectReadOnly::SetKeyframes(nsTArray<Keyframe>&& aKeyframes,
void
KeyframeEffectReadOnly::SetKeyframes(
nsTArray<Keyframe>&& aKeyframes,
const ServoComputedValues* aComputedValues)
const ServoStyleContext* aComputedValues)
{
DoSetKeyframes(Move(aKeyframes), aComputedValues);
}
@ -209,10 +219,10 @@ void
KeyframeEffectReadOnly::DoSetKeyframes(nsTArray<Keyframe>&& aKeyframes,
StyleType* aStyle)
{
static_assert(IsSame<StyleType, nsStyleContext>::value ||
IsSame<StyleType, const ServoComputedValues>::value,
"StyleType should be nsStyleContext* or "
"const ServoComputedValues*");
static_assert(IsSame<StyleType, GeckoStyleContext>::value ||
IsSame<StyleType, const ServoStyleContext>::value,
"StyleType should be GeckoStyleContext* or "
"const ServoStyleContext*");
if (KeyframesEqualIgnoringComputedOffsets(aKeyframes, mKeyframes)) {
return;
@ -296,21 +306,19 @@ KeyframeEffectReadOnly::UpdateProperties(nsStyleContext* aStyleContext)
{
MOZ_ASSERT(aStyleContext);
if (!mDocument->IsStyledByServo()) {
DoUpdateProperties(Move(aStyleContext));
if (auto gecko = aStyleContext->GetAsGecko()) {
DoUpdateProperties(Move(gecko));
return;
}
const ServoComputedValues* currentStyle = aStyleContext->ComputedValues();
DoUpdateProperties(currentStyle);
UpdateProperties(aStyleContext->AsServo());
}
void
KeyframeEffectReadOnly::UpdateProperties(
const ServoComputedValues* aComputedValues)
const ServoStyleContext* aStyleContext)
{
DoUpdateProperties(aComputedValues);
DoUpdateProperties(aStyleContext);
}
template<typename StyleType>
@ -440,7 +448,7 @@ KeyframeEffectReadOnly::CompositeValue(
void
KeyframeEffectReadOnly::EnsureBaseStyles(
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
const nsTArray<AnimationProperty>& aProperties)
{
if (!mTarget) {
@ -468,7 +476,7 @@ KeyframeEffectReadOnly::EnsureBaseStyles(
void
KeyframeEffectReadOnly::EnsureBaseStyle(
nsCSSPropertyID aProperty,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
RefPtr<nsStyleContext>& aCachedBaseStyleContext)
{
if (mBaseStyleValues.Contains(aProperty)) {
@ -497,7 +505,7 @@ KeyframeEffectReadOnly::EnsureBaseStyle(
void
KeyframeEffectReadOnly::EnsureBaseStyles(
const ServoComputedValues* aComputedValues,
const ServoStyleContext* aComputedValues,
const nsTArray<AnimationProperty>& aProperties)
{
if (!mTarget) {
@ -528,7 +536,7 @@ KeyframeEffectReadOnly::EnsureBaseStyle(
const AnimationProperty& aProperty,
CSSPseudoElementType aPseudoType,
nsPresContext* aPresContext,
const ServoComputedValues* aComputedStyle,
const ServoStyleContext* aComputedStyle,
RefPtr<ServoStyleContext>& aBaseStyleContext)
{
bool hasAdditiveValues = false;
@ -909,10 +917,10 @@ template<typename StyleType>
nsTArray<AnimationProperty>
KeyframeEffectReadOnly::BuildProperties(StyleType* aStyle)
{
static_assert(IsSame<StyleType, nsStyleContext>::value ||
IsSame<StyleType, const ServoComputedValues>::value,
"StyleType should be nsStyleContext* or "
"const ServoComputedValues*");
static_assert(IsSame<StyleType, GeckoStyleContext>::value ||
IsSame<StyleType, const ServoStyleContext>::value,
"StyleType should be GeckoStyleContext* or "
"const ServoStyleContext*");
MOZ_ASSERT(aStyle);

View File

@ -46,6 +46,7 @@ struct AnimationRule;
struct TimingParams;
class EffectSet;
class ServoStyleContext;
class GeckoStyleContext;
namespace dom {
class ElementOrCSSPseudoElement;
@ -165,9 +166,9 @@ public:
void SetKeyframes(JSContext* aContext, JS::Handle<JSObject*> aKeyframes,
ErrorResult& aRv);
void SetKeyframes(nsTArray<Keyframe>&& aKeyframes,
nsStyleContext* aStyleContext);
GeckoStyleContext* aStyleContext);
void SetKeyframes(nsTArray<Keyframe>&& aKeyframes,
const ServoComputedValues* aComputedValues);
const ServoStyleContext* aComputedValues);
// Returns true if the effect includes |aProperty| regardless of whether the
// property is overridden by !important rule.
@ -196,7 +197,7 @@ public:
// |aStyleContext| to resolve specified values.
void UpdateProperties(nsStyleContext* aStyleContext);
// Servo version of the above function.
void UpdateProperties(const ServoComputedValues* aComputedValues);
void UpdateProperties(const ServoStyleContext* aComputedValues);
// Update various bits of state related to running ComposeStyle().
// We need to update this outside ComposeStyle() because we should avoid
@ -259,7 +260,7 @@ public:
// Cumulative change hint on each segment for each property.
// This is used for deciding the animation is paint-only.
void CalculateCumulativeChangeHint(nsStyleContext* aStyleContext);
void CalculateCumulativeChangeHint(const ServoComputedValues* aComputedValues)
void CalculateCumulativeChangeHint(const ServoStyleContext* aComputedValues)
{
}
@ -367,9 +368,9 @@ protected:
const RefPtr<AnimValuesStyleRule>& aAnimationRule);
// Ensure the base styles is available for any properties in |aProperties|.
void EnsureBaseStyles(nsStyleContext* aStyleContext,
void EnsureBaseStyles(GeckoStyleContext* aStyleContext,
const nsTArray<AnimationProperty>& aProperties);
void EnsureBaseStyles(const ServoComputedValues* aComputedValues,
void EnsureBaseStyles(const ServoStyleContext* aComputedValues,
const nsTArray<AnimationProperty>& aProperties);
// If no base style is already stored for |aProperty|, resolves the base style
@ -378,14 +379,14 @@ protected:
// base style context will be resolved and stored in
// |aCachedBaseStyleContext|.
void EnsureBaseStyle(nsCSSPropertyID aProperty,
nsStyleContext* aStyleContext,
GeckoStyleContext* aStyleContext,
RefPtr<nsStyleContext>& aCachedBaseStyleContext);
// Stylo version of the above function that also first checks for an additive
// value in |aProperty|'s list of segments.
void EnsureBaseStyle(const AnimationProperty& aProperty,
CSSPseudoElementType aPseudoType,
nsPresContext* aPresContext,
const ServoComputedValues* aComputedValues,
const ServoStyleContext* aComputedValues,
RefPtr<mozilla::ServoStyleContext>& aBaseComputedValues);
Maybe<OwningAnimationTarget> mTarget;

View File

@ -368,12 +368,12 @@ IsComputeValuesFailureKey(const PropertyValuePair& aPair);
static nsTArray<ComputedKeyframeValues>
GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
nsStyleContext* aStyleContext);
GeckoStyleContext* aStyleContext);
static nsTArray<ComputedKeyframeValues>
GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
const ServoComputedValues* aComputedValues);
const ServoStyleContext* aComputedValues);
static void
BuildSegmentsFromValueEntries(nsTArray<KeyframeValueEntry>& aEntries,
@ -1012,7 +1012,7 @@ IsComputeValuesFailureKey(const PropertyValuePair& aPair)
static nsTArray<ComputedKeyframeValues>
GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
nsStyleContext* aStyleContext)
GeckoStyleContext* aStyleContext)
{
MOZ_ASSERT(aStyleContext);
MOZ_ASSERT(aElement);
@ -1087,7 +1087,7 @@ GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
static nsTArray<ComputedKeyframeValues>
GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
const ServoComputedValues* aComputedValues)
const ServoStyleContext* aStyleContext)
{
MOZ_ASSERT(aElement);
MOZ_ASSERT(aElement->IsStyledByServo());
@ -1096,7 +1096,7 @@ GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
MOZ_ASSERT(presContext);
return presContext->StyleSet()->AsServo()
->GetComputedKeyframeValuesFor(aKeyframes, aElement, aComputedValues);
->GetComputedKeyframeValuesFor(aKeyframes, aElement, aStyleContext->ComputedValues());
}
static void

View File

@ -2844,7 +2844,7 @@ CreateFontDeclarationForServo(const nsAString& aFont,
return CreateDeclarationForServo(eCSSProperty_font, aFont, aDocument);
}
static already_AddRefed<ServoComputedValues>
static already_AddRefed<ServoStyleContext>
GetFontStyleForServo(Element* aElement, const nsAString& aFont,
nsIPresShell* aPresShell,
nsAString& aOutUsedFont,
@ -2869,7 +2869,7 @@ GetFontStyleForServo(Element* aElement, const nsAString& aFont,
ServoStyleSet* styleSet = aPresShell->StyleSet()->AsServo();
RefPtr<ServoComputedValues> parentStyle;
RefPtr<ServoStyleContext> parentStyle;
// have to get a parent style context for inherit-like relative
// values (2em, bolder, etc.)
if (aElement && aElement->IsInUncomposedDoc()) {
@ -2880,7 +2880,8 @@ GetFontStyleForServo(Element* aElement, const nsAString& aFont,
// the canvas element is display:none.
parentStyle =
styleSet->ResolveTransientServoStyle(aElement,
CSSPseudoElementType::NotPseudo);
CSSPseudoElementType::NotPseudo,
nullptr);
} else {
RefPtr<RawServoDeclarationBlock> declarations =
CreateFontDeclarationForServo(NS_LITERAL_STRING("10px sans-serif"),
@ -2896,7 +2897,7 @@ GetFontStyleForServo(Element* aElement, const nsAString& aFont,
MOZ_ASSERT(!aPresShell->IsDestroying(),
"GetFontParentStyleContext should have returned an error if the presshell is being destroyed.");
RefPtr<ServoComputedValues> sc =
RefPtr<ServoStyleContext> sc =
styleSet->ResolveForDeclarations(parentStyle, declarations);
// The font getter is required to be reserialized based on what we
@ -2960,9 +2961,9 @@ CreateFilterDeclarationForServo(const nsAString& aFilter,
return CreateDeclarationForServo(eCSSProperty_filter, aFilter, aDocument);
}
static already_AddRefed<ServoComputedValues>
static already_AddRefed<ServoStyleContext>
ResolveFilterStyleForServo(const nsAString& aFilterString,
const ServoComputedValues* aParentStyle,
const ServoStyleContext* aParentStyle,
nsIPresShell* aPresShell,
ErrorResult& aError)
{
@ -2983,7 +2984,7 @@ ResolveFilterStyleForServo(const nsAString& aFilterString,
}
ServoStyleSet* styleSet = aPresShell->StyleSet()->AsServo();
RefPtr<ServoComputedValues> computedValues =
RefPtr<ServoStyleContext> computedValues =
styleSet->ResolveForDeclarations(aParentStyle, declarations);
return computedValues.forget();
@ -3028,7 +3029,7 @@ CanvasRenderingContext2D::ParseFilter(const nsAString& aString,
// For stylo
MOZ_ASSERT(presShell->StyleSet()->IsServo());
RefPtr<ServoComputedValues> parentStyle =
RefPtr<ServoStyleContext> parentStyle =
GetFontStyleForServo(mCanvasElement,
GetFont(),
presShell,
@ -3038,7 +3039,7 @@ CanvasRenderingContext2D::ParseFilter(const nsAString& aString,
return false;
}
RefPtr<ServoComputedValues> computedValues =
RefPtr<ServoStyleContext> computedValues =
ResolveFilterStyleForServo(aString,
parentStyle,
presShell,
@ -3047,7 +3048,7 @@ CanvasRenderingContext2D::ParseFilter(const nsAString& aString,
return false;
}
const nsStyleEffects* effects = Servo_GetStyleEffects(computedValues);
const nsStyleEffects* effects = Servo_GetStyleEffects(computedValues->ComputedValues());
// XXX: This mFilters is a one shot object, we probably could avoid copying.
aFilterChain = effects->mFilters;
return true;
@ -3955,7 +3956,7 @@ CanvasRenderingContext2D::SetFontInternal(const nsAString& aFont,
}
RefPtr<nsStyleContext> sc;
RefPtr<ServoComputedValues> computedValues;
RefPtr<ServoStyleContext> computedValues;
nsString usedFont;
const nsStyleFont* fontStyle;
if (presShell->StyleSet()->IsServo()) {
@ -3967,7 +3968,7 @@ CanvasRenderingContext2D::SetFontInternal(const nsAString& aFont,
if (!computedValues) {
return false;
}
fontStyle = Servo_GetStyleFont(computedValues);
fontStyle = Servo_GetStyleFont(computedValues->ComputedValues());
} else {
sc = GetFontStyleContext(mCanvasElement,
aFont,

View File

@ -11,6 +11,7 @@
#include "mozilla/DocumentStyleRootIterator.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/ServoStyleSet.h"
#include "mozilla/ServoStyleContext.h"
#include "mozilla/Unused.h"
#include "mozilla/ViewportFrame.h"
#include "mozilla/dom/ChildIterator.h"
@ -459,6 +460,7 @@ ServoRestyleManager::ProcessPostTraversal(
TraversalRestyleBehavior aRestyleBehavior)
{
nsIFrame* styleFrame = nsLayoutUtils::GetStyleFrame(aElement);
ServoStyleContext* parent = aParentContext ? aParentContext->AsServo() : nullptr;
// NOTE(emilio): This is needed because for table frames the bit is set on the
// table wrapper (which is the primary frame), not on the table itself.
@ -549,16 +551,20 @@ ServoRestyleManager::ProcessPostTraversal(
RefPtr<ServoStyleContext> newContext = nullptr;
if (wasRestyled && oldStyleContext) {
MOZ_ASSERT(styleFrame || displayContentsNode);
RefPtr<ServoComputedValues> computedValues =
RefPtr<ServoStyleContext> currentContext =
aRestyleState.StyleSet().ResolveServoStyle(aElement);
MOZ_ASSERT(oldStyleContext->ComputedValues() != computedValues);
MOZ_ASSERT(oldStyleContext->ComputedValues() != currentContext->ComputedValues());
auto pseudo = aElement->GetPseudoElementType();
nsIAtom* pseudoTag = pseudo == CSSPseudoElementType::NotPseudo
? nullptr : nsCSSPseudoElements::GetPseudoAtom(pseudo);
newContext = aRestyleState.StyleSet().GetContext(
computedValues.forget(), aParentContext, pseudoTag, pseudo, aElement);
// XXXManishearth we should just reuse the old one here
RefPtr<ServoStyleContext> tempContext =
Servo_StyleContext_NewContext(currentContext->ComputedValues(), parent,
PresContext(), pseudo, pseudoTag).Consume();
newContext = aRestyleState.StyleSet().GetContext(tempContext.forget(), aParentContext,
pseudoTag, pseudo, aElement);
newContext->ResolveSameStructsAs(PresContext(), oldStyleContext);

View File

@ -1925,11 +1925,11 @@ nsCSSFrameConstructor::CreateGeneratedContentItem(nsFrameConstructorState& aStat
//
// We don't do this for pseudos that may trigger animations or transitions,
// since those need to be kicked off by the traversal machinery.
bool isServo = pseudoStyleContext->IsServo();
bool hasServoAnimations = false;
if (isServo) {
ServoComputedValues* servoStyle = pseudoStyleContext->ComputedValues();
hasServoAnimations = Servo_ComputedValues_SpecifiesAnimationsOrTransitions(servoStyle);
ServoStyleContext* servoStyle = pseudoStyleContext->GetAsServo();
if (servoStyle) {
hasServoAnimations =
Servo_ComputedValues_SpecifiesAnimationsOrTransitions(servoStyle->ComputedValues());
if (!hasServoAnimations) {
Servo_SetExplicitStyle(container, servoStyle);
}
@ -1971,7 +1971,7 @@ nsCSSFrameConstructor::CreateGeneratedContentItem(nsFrameConstructorState& aStat
}
// We may need to do a synchronous servo traversal in various uncommon cases.
if (isServo) {
if (servoStyle) {
if (hasServoAnimations) {
// If animations are involved, we avoid the SetExplicitStyle optimization
// above.
@ -5886,8 +5886,10 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState
// styling descendants of elements with a -moz-binding the
// first time. Thus call StyleNewChildren() again.
styleSet->StyleNewChildren(element);
styleContext =
styleSet->ResolveStyleFor(element, nullptr, LazyComputeBehavior::Assert);
styleSet->ResolveStyleFor(element, styleContext->GetParentAllowServo()->AsServo(),
LazyComputeBehavior::Assert);
} else {
styleContext =
ResolveStyleContext(styleContext->GetParent(), aContent, &aState);

View File

@ -110,6 +110,30 @@ public:
return mRuleNode;
}
void AddRef() {
if (mRefCnt == UINT32_MAX) {
NS_WARNING("refcount overflow, leaking object");
return;
}
++mRefCnt;
NS_LOG_ADDREF(this, mRefCnt, "nsStyleContext", sizeof(nsStyleContext));
return;
}
void Release() {
if (mRefCnt == UINT32_MAX) {
NS_WARNING("refcount overflow, leaking object");
return;
}
--mRefCnt;
NS_LOG_RELEASE(this, mRefCnt, "nsStyleContext");
if (mRefCnt == 0) {
Destroy();
return;
}
return;
}
~GeckoStyleContext() {
Destructor();
}

View File

@ -80,9 +80,9 @@ SERVO_BINDING_FUNC(Servo_StyleSet_GetFontFaceRules, void,
SERVO_BINDING_FUNC(Servo_StyleSet_GetCounterStyleRule, nsCSSCounterStyleRule*,
RawServoStyleSetBorrowed set, nsIAtom* name)
SERVO_BINDING_FUNC(Servo_StyleSet_ResolveForDeclarations,
ServoComputedValuesStrong,
ServoStyleContextStrong,
RawServoStyleSetBorrowed set,
ServoComputedValuesBorrowedOrNull parent_style,
ServoStyleContextBorrowedOrNull parent_style,
RawServoDeclarationBlockBorrowed declarations)
SERVO_BINDING_FUNC(Servo_StyleSet_MightHaveAttributeDependency, bool,
RawServoStyleSetBorrowed set,
@ -459,16 +459,19 @@ SERVO_BINDING_FUNC(Servo_CSSSupports, bool,
// Computed style data
SERVO_BINDING_FUNC(Servo_ComputedValues_GetForAnonymousBox,
ServoComputedValuesStrong,
ServoComputedValuesBorrowedOrNull parent_style_or_null,
ServoStyleContextStrong,
ServoStyleContextBorrowedOrNull parent_style_or_null,
mozilla::CSSPseudoElementType pseudo_type,
nsIAtom* pseudo_tag,
RawServoStyleSetBorrowed set)
SERVO_BINDING_FUNC(Servo_ComputedValues_Inherit, ServoComputedValuesStrong,
SERVO_BINDING_FUNC(Servo_ComputedValues_Inherit, ServoStyleContextStrong,
RawServoStyleSetBorrowed set,
ServoComputedValuesBorrowedOrNull parent_style,
mozilla::CSSPseudoElementType pseudo_type,
nsIAtom* pseudo_tag,
ServoStyleContextBorrowedOrNull parent_style,
mozilla::InheritTarget target)
SERVO_BINDING_FUNC(Servo_ComputedValues_GetVisitedStyle,
ServoComputedValuesStrong,
ServoStyleContextStrong,
ServoComputedValuesBorrowed values)
SERVO_BINDING_FUNC(Servo_ComputedValues_GetStyleBits, uint64_t,
ServoComputedValuesBorrowed values)
@ -482,6 +485,15 @@ SERVO_BINDING_FUNC(Servo_ComputedValues_GetStyleRuleList, void,
ServoComputedValuesBorrowed values,
RawGeckoServoStyleRuleListBorrowedMut rules)
SERVO_BINDING_FUNC(Servo_StyleContext_NewContext,
ServoStyleContextStrong,
ServoComputedValuesBorrowed values,
ServoStyleContextBorrowedOrNull parent,
RawGeckoPresContextBorrowed pres_context,
mozilla::CSSPseudoElementType pseudo_type,
nsIAtom* pseudo_tag)
// Initialize Servo components. Should be called exactly once at startup.
SERVO_BINDING_FUNC(Servo_Initialize, void,
RawGeckoURLExtraData* dummy_url_data)
@ -496,18 +508,20 @@ SERVO_BINDING_FUNC(Servo_TakeChangeHint,
RawGeckoElementBorrowed element,
mozilla::TraversalRestyleBehavior restyle_behavior,
bool* was_restyled)
SERVO_BINDING_FUNC(Servo_ResolveStyle, ServoComputedValuesStrong,
SERVO_BINDING_FUNC(Servo_ResolveStyle, ServoStyleContextStrong,
RawGeckoElementBorrowed element,
RawServoStyleSetBorrowed set)
SERVO_BINDING_FUNC(Servo_ResolvePseudoStyle, ServoComputedValuesStrong,
SERVO_BINDING_FUNC(Servo_ResolvePseudoStyle, ServoStyleContextStrong,
RawGeckoElementBorrowed element,
mozilla::CSSPseudoElementType pseudo_type,
nsIAtom* pseudo_tag,
bool is_probe,
ServoComputedValuesBorrowedOrNull inherited_style,
ServoStyleContextBorrowedOrNull parent_style_context,
RawServoStyleSetBorrowed set)
SERVO_BINDING_FUNC(Servo_SetExplicitStyle, void,
RawGeckoElementBorrowed element,
ServoComputedValuesBorrowed primary_style)
ServoStyleContextBorrowed primary_style)
SERVO_BINDING_FUNC(Servo_HasAuthorSpecifiedRules, bool,
RawGeckoElementBorrowed element,
uint32_t rule_type_mask,
@ -521,9 +535,11 @@ SERVO_BINDING_FUNC(Servo_HasAuthorSpecifiedRules, bool,
//
// The tree must be in a consistent state such that a normal traversal could be
// performed, and this function maintains that invariant.
SERVO_BINDING_FUNC(Servo_ResolveStyleLazily, ServoComputedValuesStrong,
SERVO_BINDING_FUNC(Servo_ResolveStyleLazily, ServoStyleContextStrong,
RawGeckoElementBorrowed element,
mozilla::CSSPseudoElementType pseudo_type,
nsIAtom* pseudo_tag,
ServoStyleContextBorrowedOrNull parent_style_context,
mozilla::StyleRuleInclusion rule_inclusion,
const mozilla::ServoElementSnapshotTable* snapshots,
RawServoStyleSetBorrowed set)
@ -547,10 +563,10 @@ SERVO_BINDING_FUNC(Servo_MaybeGCRuleTree, void, RawServoStyleSetBorrowed set)
// Returns computed values for the given element without any animations rules.
SERVO_BINDING_FUNC(Servo_StyleSet_GetBaseComputedValuesForElement,
ServoComputedValuesStrong,
ServoStyleContextStrong,
RawServoStyleSetBorrowed set,
RawGeckoElementBorrowed element,
ServoComputedValuesBorrowed existing_style,
ServoStyleContextBorrowed existing_style,
const mozilla::ServoElementSnapshotTable* snapshots,
mozilla::CSSPseudoElementType pseudo_type)
@ -574,7 +590,7 @@ SERVO_BINDING_FUNC(Servo_GetCustomPropertyNameAt, bool,
// Style-struct management.
#define STYLE_STRUCT(name, checkdata_cb) \
struct nsStyle##name; \
SERVO_BINDING_FUNC(Servo_GetStyle##name, const nsStyle##name*, \
SERVO_BINDING_FUNC(Servo_GetStyle##name, const nsStyle##name*, \
ServoComputedValuesBorrowedOrNull computed_values)
#include "nsStyleStructList.h"
#undef STYLE_STRUCT

View File

@ -24,6 +24,7 @@ struct RawServoAnimationValueMap;
namespace mozilla {
class ServoElementSnapshot;
class ServoStyleContext;
struct StyleAnimation;
struct URLExtraData;
namespace dom {
@ -102,6 +103,14 @@ typedef mozilla::dom::StyleChildrenIterator RawGeckoStyleChildrenIterator;
#include "mozilla/ServoArcTypeList.h"
#undef SERVO_ARC_TYPE
typedef mozilla::ServoStyleContext const* ServoStyleContextBorrowed;
typedef mozilla::ServoStyleContext const* ServoStyleContextBorrowedOrNull;
struct MOZ_MUST_USE_TYPE ServoStyleContextStrong
{
mozilla::ServoStyleContext* mPtr;
already_AddRefed<mozilla::ServoStyleContext> Consume();
};
#define DECL_OWNED_REF_TYPE_FOR(type_) \
typedef type_* type_##Owned; \
DECL_BORROWED_REF_TYPE_FOR(type_) \

View File

@ -83,9 +83,9 @@ using namespace mozilla::dom;
return result.forget(); \
}
#include "mozilla/ServoArcTypeList.h"
SERVO_ARC_TYPE(StyleContext, ServoStyleContext)
#undef SERVO_ARC_TYPE
static Mutex* sServoFontMetricsLock = nullptr;
static RWLock* sServoLangFontPrefsLock = nullptr;
@ -208,6 +208,26 @@ Gecko_DestroyAnonymousContentList(nsTArray<nsIContent*>* aAnonContent)
delete aAnonContent;
}
void
Gecko_ServoStyleContext_Init(ServoStyleContext* aContext,
const ServoStyleContext* aParentContext,
RawGeckoPresContextBorrowed aPresContext, ServoComputedValuesStrong aValues,
mozilla::CSSPseudoElementType aPseudoType, nsIAtom* aPseudoTag)
{
// because it is within an Arc it is unsafe for the Rust side to ever
// carry around a mutable non opaque reference to the context, so we
// cast it here.
ServoStyleContext* parent = const_cast<ServoStyleContext*>(aParentContext);
nsPresContext* pres = const_cast<nsPresContext*>(aPresContext);
new (KnownNotNull, aContext) ServoStyleContext(parent, pres, aPseudoTag, aPseudoType, aValues.Consume());
}
void
Gecko_ServoStyleContext_Destroy(ServoStyleContext* aContext)
{
aContext->~ServoStyleContext();
}
void
Gecko_ConstructStyleChildrenIterator(
RawGeckoElementBorrowed aElement,
@ -605,8 +625,8 @@ Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed aA,
void
Gecko_UpdateAnimations(RawGeckoElementBorrowed aElement,
ServoComputedValuesBorrowedOrNull aOldComputedValues,
ServoComputedValuesBorrowedOrNull aComputedValues,
ServoStyleContextBorrowedOrNull aOldComputedValues,
ServoStyleContextBorrowedOrNull aComputedValues,
UpdateAnimationsTasks aTasks)
{
MOZ_ASSERT(NS_IsMainThread());
@ -644,7 +664,8 @@ Gecko_UpdateAnimations(RawGeckoElementBorrowed aElement,
MOZ_ASSERT(aOldComputedValues);
presContext->TransitionManager()->
UpdateTransitions(const_cast<dom::Element*>(aElement), pseudoType,
aOldComputedValues, aComputedValues);
aOldComputedValues,
aComputedValues);
}
if (aTasks & UpdateAnimationsTasks::EffectProperties) {

View File

@ -50,6 +50,7 @@ namespace mozilla {
};
enum class UpdateAnimationsTasks : uint8_t;
struct LangGroupFontPrefs;
class ServoStyleContext;
class ServoStyleSheet;
class ServoElementSnapshotTable;
}
@ -140,6 +141,12 @@ RawGeckoElementBorrowedOrNull Gecko_GetBeforeOrAfterPseudo(RawGeckoElementBorrow
nsTArray<nsIContent*>* Gecko_GetAnonymousContentForElement(RawGeckoElementBorrowed element);
void Gecko_DestroyAnonymousContentList(nsTArray<nsIContent*>* anon_content);
void Gecko_ServoStyleContext_Init(mozilla::ServoStyleContext* context,
ServoStyleContextBorrowedOrNull parent_context,
RawGeckoPresContextBorrowed pres_context, ServoComputedValuesStrong values,
mozilla::CSSPseudoElementType pseudo_type, nsIAtom* pseudo_tag);
void Gecko_ServoStyleContext_Destroy(mozilla::ServoStyleContext* context);
// By default, Servo walks the DOM by traversing the siblings of the DOM-view
// first child. This generally works, but misses anonymous children, which we
// want to traverse during styling. To support these cases, we create an
@ -225,8 +232,8 @@ Gecko_GetSMILOverrideDeclarationBlock(RawGeckoElementBorrowed element);
bool Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed,
RawGeckoStyleAnimationListBorrowed);
void Gecko_UpdateAnimations(RawGeckoElementBorrowed aElementOrPseudo,
ServoComputedValuesBorrowedOrNull aOldComputedValues,
ServoComputedValuesBorrowedOrNull aComputedValues,
ServoStyleContextBorrowedOrNull aOldComputedValues,
ServoStyleContextBorrowedOrNull aComputedValues,
mozilla::UpdateAnimationsTasks aTasks);
bool Gecko_ElementHasAnimations(RawGeckoElementBorrowed aElementOrPseudo);
bool Gecko_ElementHasCSSAnimations(RawGeckoElementBorrowed aElementOrPseudo);

View File

@ -63,6 +63,7 @@ headers = [
"mozilla/LookAndFeel.h",
"mozilla/ServoBindings.h",
"mozilla/ServoMediaList.h",
"mozilla/ServoStyleContext.h",
"nsCSSCounterStyleRule.h",
"nsCSSFontFaceRule.h",
"nsMediaFeatures.h",
@ -120,8 +121,8 @@ whitelist-types = [
"mozilla::ComputedTiming",
"mozilla::ComputedTimingFunction",
"mozilla::ComputedTimingFunction::BeforeFlag",
"mozilla::ServoComputedValues2",
"mozilla::ServoElementSnapshot.*",
"mozilla::ServoStyleContext",
"mozilla::ServoStyleSheetInner",
"mozilla::CSSPseudoClassType",
"mozilla::css::ErrorReporter",
@ -246,7 +247,11 @@ whitelist-types = [
"Runnable",
"ServoAttrSnapshot",
"ServoBundledURI",
"ServoComputedValues",
"ServoElementSnapshot",
"ServoStyleContextStrong",
"ServoStyleContextBorrowed",
"ServoStyleContextBorrowedOrNull",
"SheetParsingMode",
"StaticRefPtr",
"StyleAnimation",
@ -318,6 +323,7 @@ mapped-generic-types = [
{ generic = false, gecko = "mozilla::ServoVisitedStyle", servo = "Option<::stylearc::Arc<::properties::ComputedValues>>" },
{ generic = false, gecko = "mozilla::ServoComputedValueFlags", servo = "::properties::computed_value_flags::ComputedValueFlags" },
{ generic = true, gecko = "mozilla::ServoRawOffsetArc", servo = "::stylearc::RawOffsetArc" },
{ generic = false, gecko = "ServoStyleContextStrong", servo = "::gecko_bindings::sugar::ownership::Strong<ServoStyleContext>" },
]
fixups = [
{ pat = "root::nsString", rep = "::nsstring::nsStringRepr" },
@ -328,6 +334,8 @@ headers = ["mozilla/ServoBindings.h"]
hide-types = [
"nsACString_internal",
"nsAString_internal",
"ServoStyleContextBorrowed",
"ServoStyleContextBorrowedOrNull",
]
raw-lines = [
"pub use nsstring::{nsACString, nsAString, nsString, nsStringRepr};",
@ -335,6 +343,8 @@ raw-lines = [
"use gecko_bindings::structs::nsTArray;",
"type nsACString_internal = nsACString;",
"type nsAString_internal = nsAString;",
"pub type ServoStyleContextBorrowed<'a> = &'a ServoStyleContext;",
"pub type ServoStyleContextBorrowedOrNull<'a> = Option<&'a ::properties::ComputedValues>;",
]
whitelist-functions = ["Servo_.*", "Gecko_.*"]
structs-types = [
@ -460,6 +470,9 @@ structs-types = [
"Loader",
"LoaderReusableStyleSheets",
"ServoStyleSheet",
"ServoComputedValues",
"ServoStyleContext",
"ServoStyleContextStrong",
"EffectCompositor_CascadeLevel",
"UpdateAnimationsTasks",
"ParsingMode",

View File

@ -13,14 +13,6 @@ namespace mozilla {
class ServoStyleContext final : public nsStyleContext {
public:
static already_AddRefed<ServoStyleContext>
Create(nsStyleContext* aParentContext,
nsPresContext* aPresContext,
nsIAtom* aPseudoTag,
mozilla::CSSPseudoElementType aPseudoType,
already_AddRefed<ServoComputedValues> aComputedValues);
ServoStyleContext(nsStyleContext* aParent,
nsPresContext* aPresContext,
nsIAtom* aPseudoTag,
@ -34,6 +26,15 @@ public:
ServoComputedValues* ComputedValues() const {
return mSource;
}
void AddRef() {
Servo_StyleContext_AddRef(this);
}
void Release() {
Servo_StyleContext_Release(this);
}
~ServoStyleContext() {
Destructor();
}
@ -42,23 +43,19 @@ public:
* Makes this context match |aOther| in terms of which style structs have
* been resolved.
*/
void ResolveSameStructsAs(nsPresContext* aPresContext, ServoStyleContext* aOther) {
// NB: This function is only called on newly-minted style contexts, but
// those may already have resolved style structs given the SetStyleBits call
// in FinishConstruction. So we carefully xor out the bits that are new so
// that we don't call FinishStyle twice.
void ResolveSameStructsAs(nsPresContext* aPresContext, const ServoStyleContext* aOther) {
// Only resolve structs that are not already resolved in this struct.
uint64_t ourBits = mBits & NS_STYLE_INHERIT_MASK;
uint64_t otherBits = aOther->mBits & NS_STYLE_INHERIT_MASK;
MOZ_ASSERT((otherBits | ourBits) == otherBits, "otherBits should be a superset");
uint64_t newBits = (ourBits ^ otherBits) & NS_STYLE_INHERIT_MASK;
uint64_t newBits = otherBits & ~ourBits & NS_STYLE_INHERIT_MASK;
#define STYLE_STRUCT(name_, checkdata_cb) \
#define STYLE_STRUCT(name_, checkdata_cb) \
if (nsStyle##name_::kHasFinishStyle && newBits & NS_STYLE_INHERIT_BIT(name_)) { \
const nsStyle##name_* data = Servo_GetStyle##name_(ComputedValues()); \
const_cast<nsStyle##name_*>(data)->FinishStyle(aPresContext); \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
mBits |= newBits;
}

View File

@ -189,22 +189,24 @@ ServoStyleSet::GetContext(nsIContent* aContent,
MOZ_ASSERT(aContent->IsElement());
Element* element = aContent->AsElement();
RefPtr<ServoComputedValues> computedValues;
RefPtr<ServoStyleContext> computedValues;
ServoStyleContext* parent = aParentContext ? aParentContext->AsServo() : nullptr;
if (aMayCompute == LazyComputeBehavior::Allow) {
PreTraverseSync();
computedValues =
ResolveStyleLazily(element, CSSPseudoElementType::NotPseudo);
RefPtr<ServoStyleContext> tmp =
ResolveStyleLazily(element, CSSPseudoElementType::NotPseudo, aPseudoTag, parent);
computedValues = GetContext(tmp.forget(), parent, aPseudoTag, aPseudoType,
element);
} else {
computedValues = ResolveServoStyle(element);
}
MOZ_ASSERT(computedValues);
return GetContext(computedValues.forget(), aParentContext, aPseudoTag, aPseudoType,
element);
return computedValues.forget();
}
already_AddRefed<ServoStyleContext>
ServoStyleSet::GetContext(already_AddRefed<ServoComputedValues> aComputedValues,
ServoStyleSet::GetContext(already_AddRefed<ServoStyleContext> aComputedValues,
nsStyleContext* aParentContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
@ -220,11 +222,16 @@ ServoStyleSet::GetContext(already_AddRefed<ServoComputedValues> aComputedValues,
.HasState(NS_EVENT_STATE_VISITED);
}
RefPtr<ServoComputedValues> computedValues = Move(aComputedValues);
RefPtr<ServoComputedValues> visitedComputedValues =
RefPtr<ServoStyleContext> result = Move(aComputedValues);
RefPtr<ServoComputedValues> computedValues = result->ComputedValues();
MOZ_ASSERT(result->GetPseudoType() == aPseudoType);
MOZ_ASSERT(result->GetPseudo() == aPseudoTag);
RefPtr<ServoStyleContext> resultIfVisited =
Servo_ComputedValues_GetVisitedStyle(computedValues).Consume();
// If `visitedComputedValues` is non-null, then there was a relevant link and
// If `resultIfVisited` is non-null, then there was a relevant link and
// visited styles were computed. This corresponds to the cases where Gecko's
// style system produces `aVisitedRuleNode`.
// Set up `parentIfVisited` depending on whether our parent context has a
@ -233,26 +240,24 @@ ServoStyleSet::GetContext(already_AddRefed<ServoComputedValues> aComputedValues,
nsStyleContext *parentIfVisited =
aParentContext ? aParentContext->GetStyleIfVisited() : nullptr;
if (!parentIfVisited) {
if (visitedComputedValues) {
if (resultIfVisited) {
parentIfVisited = aParentContext;
}
}
ServoStyleContext* parentIfVisitedServo = parentIfVisited ? parentIfVisited->AsServo() : nullptr;
// The true visited state of the relevant link is used to decided whether
// visited styles should be consulted for all visited dependent properties.
bool relevantLinkVisited = isLink ? isVisitedLink :
(aParentContext && aParentContext->RelevantLinkVisited());
RefPtr<ServoStyleContext> result =
ServoStyleContext::Create(aParentContext, mPresContext, aPseudoTag, aPseudoType,
computedValues.forget());
if (visitedComputedValues) {
RefPtr<ServoStyleContext> resultIfVisited =
ServoStyleContext::Create(parentIfVisited, mPresContext, aPseudoTag, aPseudoType,
visitedComputedValues.forget());
resultIfVisited->SetIsStyleIfVisited();
result->SetStyleIfVisited(resultIfVisited.forget());
if (resultIfVisited) {
RefPtr<ServoStyleContext> visitedContext =
Servo_StyleContext_NewContext(resultIfVisited->ComputedValues(), parentIfVisitedServo,
mPresContext, aPseudoType, aPseudoTag).Consume();
visitedContext->SetIsStyleIfVisited();
result->SetStyleIfVisited(visitedContext.forget());
if (relevantLinkVisited) {
result->AddStyleBit(NS_STYLE_RELEVANT_LINK_VISITED);
@ -447,13 +452,12 @@ ServoStyleSet::ResolveStyleForText(nsIContent* aTextNode,
// rules: inherit the inherit structs, reset the reset structs. This is cheap
// enough to do on the main thread, which means that the parallel style system
// can avoid worrying about text nodes.
const ServoComputedValues* parentComputedValues =
aParentContext->ComputedValues();
RefPtr<ServoComputedValues> computedValues =
RefPtr<ServoStyleContext> computedValues =
Servo_ComputedValues_Inherit(mRawSet.get(),
parentComputedValues,
CSSPseudoElementType::InheritingAnonBox,
nsCSSAnonBoxes::mozText,
aParentContext->AsServo(),
InheritTarget::Text).Consume();
return GetContext(computedValues.forget(), aParentContext,
nsCSSAnonBoxes::mozText,
CSSPseudoElementType::InheritingAnonBox,
@ -463,10 +467,11 @@ ServoStyleSet::ResolveStyleForText(nsIContent* aTextNode,
already_AddRefed<nsStyleContext>
ServoStyleSet::ResolveStyleForFirstLetterContinuation(nsStyleContext* aParentContext)
{
const ServoComputedValues* parent =
aParentContext->ComputedValues();
RefPtr<ServoComputedValues> computedValues =
ServoStyleContext* parent = aParentContext ? aParentContext->AsServo() : nullptr;
RefPtr<ServoStyleContext> computedValues =
Servo_ComputedValues_Inherit(mRawSet.get(),
CSSPseudoElementType::InheritingAnonBox,
nsCSSAnonBoxes::firstLetterContinuation,
parent,
InheritTarget::FirstLetterContinuation)
.Consume();
@ -488,8 +493,10 @@ ServoStyleSet::ResolveStyleForPlaceholder()
return retval.forget();
}
RefPtr<ServoComputedValues> computedValues =
RefPtr<ServoStyleContext> computedValues =
Servo_ComputedValues_Inherit(mRawSet.get(),
CSSPseudoElementType::NonInheritingAnonBox,
nsCSSAnonBoxes::oofPlaceholder,
nullptr,
InheritTarget::PlaceholderFrame)
.Consume();
@ -514,7 +521,9 @@ ServoStyleSet::ResolvePseudoElementStyle(Element* aOriginatingElement,
MOZ_ASSERT(aType < CSSPseudoElementType::Count);
RefPtr<ServoComputedValues> computedValues;
RefPtr<ServoStyleContext> computedValues;
nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
if (aPseudoElement) {
MOZ_ASSERT(aType == aPseudoElement->GetPseudoElementType());
computedValues = Servo_ResolveStyle(aPseudoElement,
@ -522,11 +531,14 @@ ServoStyleSet::ResolvePseudoElementStyle(Element* aOriginatingElement,
} else {
const ServoComputedValues* parentStyle =
aParentContext ? aParentContext->ComputedValues() : nullptr;
ServoStyleContext* parent = aParentContext ? aParentContext->AsServo() : nullptr;
computedValues =
Servo_ResolvePseudoStyle(aOriginatingElement,
aType,
pseudoTag,
/* is_probe = */ false,
parentStyle,
parent,
mRawSet.get()).Consume();
}
@ -535,34 +547,33 @@ ServoStyleSet::ResolvePseudoElementStyle(Element* aOriginatingElement,
bool isBeforeOrAfter = aType == CSSPseudoElementType::before ||
aType == CSSPseudoElementType::after;
nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
return GetContext(computedValues.forget(), aParentContext, pseudoTag, aType,
isBeforeOrAfter ? aOriginatingElement : nullptr);
}
already_AddRefed<nsStyleContext>
ServoStyleSet::ResolveTransientStyle(Element* aElement,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
nsIAtom* aPseudoTag,
StyleRuleInclusion aRuleInclusion)
{
RefPtr<ServoComputedValues> computedValues =
ResolveTransientServoStyle(aElement, aPseudoType, aRuleInclusion);
return GetContext(computedValues.forget(),
RefPtr<ServoStyleContext> result =
ResolveTransientServoStyle(aElement, aPseudoType, aPseudoTag, aRuleInclusion);
return GetContext(result.forget(),
nullptr,
aPseudoTag,
aPseudoType, nullptr);
}
already_AddRefed<ServoComputedValues>
already_AddRefed<ServoStyleContext>
ServoStyleSet::ResolveTransientServoStyle(
Element* aElement,
CSSPseudoElementType aPseudoType,
nsIAtom* aPseudoTag,
StyleRuleInclusion aRuleInclusion)
{
PreTraverseSync();
return ResolveStyleLazily(aElement, aPseudoType, aRuleInclusion);
return ResolveStyleLazily(aElement, aPseudoType, aPseudoTag, nullptr, aRuleInclusion);
}
already_AddRefed<ServoStyleContext>
@ -574,11 +585,10 @@ ServoStyleSet::ResolveInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag,
UpdateStylistIfNeeded();
const ServoComputedValues* parentStyle =
aParentContext ? aParentContext->ComputedValues()
: nullptr;
RefPtr<ServoComputedValues> computedValues =
Servo_ComputedValues_GetForAnonymousBox(parentStyle, aPseudoTag,
ServoStyleContext* parent = aParentContext ? aParentContext->AsServo() : nullptr;
RefPtr<ServoStyleContext> computedValues =
Servo_ComputedValues_GetForAnonymousBox(parent, CSSPseudoElementType::InheritingAnonBox,
aPseudoTag,
mRawSet.get()).Consume();
#ifdef DEBUG
if (!computedValues) {
@ -621,8 +631,9 @@ ServoStyleSet::ResolveNonInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag)
// are indeed annotated as skipping this fixup.)
MOZ_ASSERT(!nsCSSAnonBoxes::IsNonInheritingAnonBox(nsCSSAnonBoxes::viewport),
"viewport needs fixup to handle blockifying it");
RefPtr<ServoComputedValues> computedValues =
Servo_ComputedValues_GetForAnonymousBox(nullptr, aPseudoTag,
RefPtr<ServoStyleContext> computedValues =
Servo_ComputedValues_GetForAnonymousBox(nullptr, CSSPseudoElementType::NonInheritingAnonBox,
aPseudoTag,
mRawSet.get()).Consume();
#ifdef DEBUG
if (!computedValues) {
@ -851,10 +862,13 @@ ServoStyleSet::ProbePseudoElementStyle(Element* aOriginatingElement,
// aOriginatingElement's styles anyway.
MOZ_ASSERT(aType < CSSPseudoElementType::Count);
RefPtr<ServoComputedValues> computedValues =
Servo_ResolvePseudoStyle(aOriginatingElement, aType,
nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
ServoStyleContext* parent = aParentContext ? aParentContext->AsServo() : nullptr;
RefPtr<ServoStyleContext> computedValues =
Servo_ResolvePseudoStyle(aOriginatingElement, aType, pseudoTag,
/* is_probe = */ true,
nullptr,
parent,
mRawSet.get()).Consume();
if (!computedValues) {
return nullptr;
@ -866,8 +880,8 @@ ServoStyleSet::ProbePseudoElementStyle(Element* aOriginatingElement,
bool isBeforeOrAfter = aType == CSSPseudoElementType::before ||
aType == CSSPseudoElementType::after;
if (isBeforeOrAfter) {
const nsStyleDisplay* display = Servo_GetStyleDisplay(computedValues);
const nsStyleContent* content = Servo_GetStyleContent(computedValues);
const nsStyleDisplay* display = Servo_GetStyleDisplay(computedValues->ComputedValues());
const nsStyleContent* content = Servo_GetStyleContent(computedValues->ComputedValues());
// XXXldb What is contentCount for |content: ""|?
if (display->mDisplay == StyleDisplay::None ||
content->ContentCount() == 0) {
@ -875,7 +889,6 @@ ServoStyleSet::ProbePseudoElementStyle(Element* aOriginatingElement,
}
}
nsIAtom* pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
return GetContext(computedValues.forget(), aParentContext, pseudoTag, aType,
isBeforeOrAfter ? aOriginatingElement : nullptr);
}
@ -1100,15 +1113,13 @@ ServoStyleSet::GetBaseContextForElement(
nsPresContext* aPresContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
ServoComputedValuesBorrowed aStyle)
const ServoStyleContext* aStyle)
{
RefPtr<ServoComputedValues> cv = Servo_StyleSet_GetBaseComputedValuesForElement(mRawSet.get(),
return Servo_StyleSet_GetBaseComputedValuesForElement(mRawSet.get(),
aElement,
aStyle,
&Snapshots(),
aPseudoType).Consume();
return ServoStyleContext::Create(nullptr, aPresContext, aPseudoTag,
aPseudoType, cv.forget());
}
already_AddRefed<RawServoAnimationValue>
@ -1175,7 +1186,7 @@ ServoStyleSet::CompatibilityModeChanged()
Servo_StyleSet_CompatModeChanged(mRawSet.get());
}
already_AddRefed<ServoComputedValues>
already_AddRefed<ServoStyleContext>
ServoStyleSet::ResolveServoStyle(Element* aElement)
{
UpdateStylistIfNeeded();
@ -1190,9 +1201,11 @@ ServoStyleSet::ClearNonInheritingStyleContexts()
}
}
already_AddRefed<ServoComputedValues>
already_AddRefed<ServoStyleContext>
ServoStyleSet::ResolveStyleLazily(Element* aElement,
CSSPseudoElementType aPseudoType,
nsIAtom* aPseudoTag,
const ServoStyleContext* aParentContext,
StyleRuleInclusion aRuleInclusion)
{
mPresContext->EffectCompositor()->PreTraverse(aElement, aPseudoType);
@ -1225,9 +1238,11 @@ ServoStyleSet::ResolveStyleLazily(Element* aElement,
}
}
RefPtr<ServoComputedValues> computedValues =
RefPtr<ServoStyleContext> computedValues =
Servo_ResolveStyleLazily(elementForStyleResolution,
pseudoTypeForStyleResolution,
aPseudoTag,
aParentContext,
aRuleInclusion,
&Snapshots(),
mRawSet.get()).Consume();
@ -1236,6 +1251,8 @@ ServoStyleSet::ResolveStyleLazily(Element* aElement,
computedValues =
Servo_ResolveStyleLazily(elementForStyleResolution,
pseudoTypeForStyleResolution,
aPseudoTag,
aParentContext,
aRuleInclusion,
&Snapshots(),
mRawSet.get()).Consume();
@ -1258,9 +1275,9 @@ ServoStyleSet::CounterStyleRuleForName(nsIAtom* aName)
return Servo_StyleSet_GetCounterStyleRule(mRawSet.get(), aName);
}
already_AddRefed<ServoComputedValues>
already_AddRefed<ServoStyleContext>
ServoStyleSet::ResolveForDeclarations(
ServoComputedValuesBorrowedOrNull aParentOrNull,
const ServoStyleContext* aParentOrNull,
RawServoDeclarationBlockBorrowed aDeclarations)
{
UpdateStylistIfNeeded();

View File

@ -188,16 +188,17 @@ public:
// |aPeudoTag| and |aPseudoType| must match.
already_AddRefed<nsStyleContext>
ResolveTransientStyle(dom::Element* aElement,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
nsIAtom* aPseudoTag,
StyleRuleInclusion aRules =
StyleRuleInclusion::All);
// Similar to ResolveTransientStyle() but returns ServoComputedValues.
// Unlike ResolveServoStyle() this function calls PreTraverseSync().
already_AddRefed<ServoComputedValues>
already_AddRefed<ServoStyleContext>
ResolveTransientServoStyle(dom::Element* aElement,
CSSPseudoElementType aPseudoTag,
CSSPseudoElementType aPseudoType,
nsIAtom* aPseudoTag,
StyleRuleInclusion aRules =
StyleRuleInclusion::All);
@ -361,7 +362,7 @@ public:
* Resolve style for the given element, and return it as a
* ServoComputedValues, not an nsStyleContext.
*/
already_AddRefed<ServoComputedValues> ResolveServoStyle(dom::Element* aElement);
already_AddRefed<ServoStyleContext> ResolveServoStyle(dom::Element* aElement);
bool GetKeyframesForName(const nsString& aName,
const nsTimingFunction& aTimingFunction,
@ -388,15 +389,15 @@ public:
nsPresContext* aPresContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
ServoComputedValuesBorrowed aStyle);
const ServoStyleContext* aStyle);
/**
* Resolve style for a given declaration block with/without the parent style.
* If the parent style is not specified, the document default computed values
* is used.
*/
already_AddRefed<ServoComputedValues>
ResolveForDeclarations(ServoComputedValuesBorrowedOrNull aParentOrNull,
already_AddRefed<ServoStyleContext>
ResolveForDeclarations(const ServoStyleContext* aParentOrNull,
RawServoDeclarationBlockBorrowed aDeclarations);
already_AddRefed<RawServoAnimationValue>
@ -477,7 +478,7 @@ private:
ServoStyleSet* mSet;
};
already_AddRefed<ServoStyleContext> GetContext(already_AddRefed<ServoComputedValues>,
already_AddRefed<ServoStyleContext> GetContext(already_AddRefed<ServoStyleContext>,
nsStyleContext* aParentContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
@ -559,9 +560,11 @@ private:
*/
void UpdateStylist();
already_AddRefed<ServoComputedValues>
already_AddRefed<ServoStyleContext>
ResolveStyleLazily(dom::Element* aElement,
CSSPseudoElementType aPseudoType,
nsIAtom* aPseudoTag,
const ServoStyleContext* aParentContext,
StyleRuleInclusion aRules =
StyleRuleInclusion::All);

View File

@ -169,6 +169,8 @@ struct ServoComputedValueFlags {
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
} // namespace mozilla
/**
* We want C++ to be abe to read the style struct fields of ComputedValues
@ -180,27 +182,25 @@ struct ServoComputedValueFlags {
*
* <div rustbindgen nocopy></div>
*/
struct ServoComputedValues2 {
#define STYLE_STRUCT(name_, checkdata_cb_) ServoRawOffsetArc<Gecko##name_> name_;
struct ServoComputedValues {
#define STYLE_STRUCT(name_, checkdata_cb_) mozilla::ServoRawOffsetArc<mozilla::Gecko##name_> name_;
#define STYLE_STRUCT_LIST_IGNORE_VARIABLES
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#undef STYLE_STRUCT_LIST_IGNORE_VARIABLES
ServoCustomPropertiesMap custom_properties;
ServoWritingMode writing_mode;
ServoFontComputationData font_computation_data;
mozilla::ServoCustomPropertiesMap custom_properties;
mozilla::ServoWritingMode writing_mode;
mozilla::ServoFontComputationData font_computation_data;
/// The rule node representing the ordered list of rules matched for this
/// node. Can be None for default values and text nodes. This is
/// essentially an optimization to avoid referencing the root rule node.
ServoRuleNode rules;
mozilla::ServoRuleNode rules;
/// The element's computed values if visited, only computed if there's a
/// relevant link for this element. A element's "relevant link" is the
/// element being matched if it is a link or the nearest ancestor link.
ServoVisitedStyle visited_style;
ServoComputedValueFlags flags;
~ServoComputedValues2() {} // do nothing, but prevent Copy from being impl'd by bindgen
mozilla::ServoVisitedStyle visited_style;
mozilla::ServoComputedValueFlags flags;
~ServoComputedValues() {} // do nothing, but prevent Copy from being impl'd by bindgen
};
} // namespace mozilla
#endif // mozilla_ServoTypes_h

View File

@ -404,10 +404,10 @@ ResolvedStyleCache::Get(nsPresContext *aPresContext,
class MOZ_STACK_CLASS ServoCSSAnimationBuilder final {
public:
explicit ServoCSSAnimationBuilder(const ServoComputedValues* aComputedValues)
: mComputedValues(aComputedValues)
explicit ServoCSSAnimationBuilder(const ServoStyleContext* aStyleContext)
: mStyleContext(aStyleContext)
{
MOZ_ASSERT(aComputedValues);
MOZ_ASSERT(aStyleContext);
}
bool BuildKeyframes(nsPresContext* aPresContext,
@ -424,11 +424,11 @@ public:
void SetKeyframes(KeyframeEffectReadOnly& aEffect,
nsTArray<Keyframe>&& aKeyframes)
{
aEffect.SetKeyframes(Move(aKeyframes), mComputedValues);
aEffect.SetKeyframes(Move(aKeyframes), mStyleContext);
}
private:
const ServoComputedValues* mComputedValues;
const ServoStyleContext* mStyleContext;
};
class MOZ_STACK_CLASS GeckoCSSAnimationBuilder final {
@ -448,7 +448,7 @@ public:
void SetKeyframes(KeyframeEffectReadOnly& aEffect,
nsTArray<Keyframe>&& aKeyframes)
{
aEffect.SetKeyframes(Move(aKeyframes), mStyleContext);
aEffect.SetKeyframes(Move(aKeyframes), mStyleContext->AsGecko());
}
private:
@ -990,7 +990,7 @@ BuildAnimations(nsPresContext* aPresContext,
}
void
nsAnimationManager::UpdateAnimations(nsStyleContext* aStyleContext,
nsAnimationManager::UpdateAnimations(GeckoStyleContext* aStyleContext,
mozilla::dom::Element* aElement)
{
MOZ_ASSERT(mPresContext->IsDynamic(),
@ -1015,7 +1015,7 @@ void
nsAnimationManager::UpdateAnimations(
dom::Element* aElement,
CSSPseudoElementType aPseudoType,
const ServoComputedValues* aComputedValues)
const ServoStyleContext* aStyleContext)
{
MOZ_ASSERT(mPresContext->IsDynamic(),
"Should not update animations for print or print preview");
@ -1023,7 +1023,7 @@ nsAnimationManager::UpdateAnimations(
"Should not update animations that are not attached to the "
"document tree");
if (!aComputedValues) {
if (!aStyleContext) {
// If we are in a display:none subtree we will have no computed values.
// Since CSS animations should not run in display:none subtrees we should
// stop (actually, destroy) any animations on this element here.
@ -1032,10 +1032,10 @@ nsAnimationManager::UpdateAnimations(
}
NonOwningAnimationTarget target(aElement, aPseudoType);
ServoCSSAnimationBuilder builder(aComputedValues);
ServoCSSAnimationBuilder builder(aStyleContext);
const nsStyleDisplay *disp =
Servo_GetStyleDisplay(aComputedValues);
Servo_GetStyleDisplay(aStyleContext->ComputedValues());
DoUpdateAnimations(target, *disp, builder);
}

View File

@ -32,6 +32,9 @@ class Promise;
enum class CSSPseudoElementType : uint8_t;
struct NonOwningAnimationTarget;
class GeckoStyleContext;
class ServoStyleContext;
struct AnimationEventInfo {
RefPtr<dom::Element> mElement;
RefPtr<dom::Animation> mAnimation;
@ -323,7 +326,7 @@ public:
* aStyleContext may be a style context for aElement or for its
* :before or :after pseudo-element.
*/
void UpdateAnimations(nsStyleContext* aStyleContext,
void UpdateAnimations(mozilla::GeckoStyleContext* aStyleContext,
mozilla::dom::Element* aElement);
/**
@ -333,7 +336,7 @@ public:
void UpdateAnimations(
mozilla::dom::Element* aElement,
mozilla::CSSPseudoElementType aPseudoType,
const ServoComputedValues* aComputedValues);
const mozilla::ServoStyleContext* aComputedValues);
/**
* Add a pending event.

View File

@ -642,7 +642,7 @@ nsComputedDOMStyle::DoGetStyleContextNoFlush(Element* aElement,
} else {
return presContext->StyleSet()->AsServo()->
GetBaseContextForElement(aElement, nullptr, presContext,
aPseudo, pseudoType, result->ComputedValues());
aPseudo, pseudoType, result->AsServo());
}
}
@ -669,13 +669,13 @@ nsComputedDOMStyle::DoGetStyleContextNoFlush(Element* aElement,
? StyleRuleInclusion::DefaultOnly
: StyleRuleInclusion::All;
RefPtr<nsStyleContext> result =
servoSet->ResolveTransientStyle(aElement, aPseudo, pseudoType, rules);
servoSet->ResolveTransientStyle(aElement, pseudoType, aPseudo, rules);
if (aAnimationFlag == eWithAnimation) {
return result.forget();
}
return servoSet->GetBaseContextForElement(aElement, nullptr, presContext,
aPseudo, pseudoType, result->ComputedValues());
aPseudo, pseudoType, result->AsServo());
}
RefPtr<nsStyleContext> parentContext;

View File

@ -165,13 +165,12 @@ nsStyleContext::Destructor()
presContext->StyleSet()->RootStyleContextRemoved();
}
// Free up our data structs.
// Free up our caches.
if (gecko) {
gecko->DestroyCachedStructs(presContext);
// Servo doesn't store things here, and it's not threadsafe
CSSVariableImageTable::RemoveAll(this);
}
// Free any ImageValues we were holding on to for CSS variable values.
CSSVariableImageTable::RemoveAll(this);
}
void nsStyleContext::AddChild(nsStyleContext* aChild)
@ -492,6 +491,44 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aNewContext,
aSamePointerStructs);
}
void
nsStyleContext::SetStyleIfVisited(already_AddRefed<nsStyleContext> aStyleIfVisited)
{
MOZ_ASSERT(!IsStyleIfVisited(), "this context is not visited data");
// XXXManishearth
// Servo currently mints fresh visited contexts on calls to GetContext()
// in line with the previous behavior.
// This is suboptimal and should be phased out when we phase out GetContext()
NS_ASSERTION(IsServo() || !mStyleIfVisited, "should only be set once");
mStyleIfVisited = aStyleIfVisited;
MOZ_ASSERT(mStyleIfVisited->IsStyleIfVisited(),
"other context is visited data");
MOZ_ASSERT(!mStyleIfVisited->GetStyleIfVisited(),
"other context does not have visited data");
NS_ASSERTION(GetStyleIfVisited()->GetPseudo() == GetPseudo(),
"pseudo tag mismatch");
// XXXManishearth In Servo mode this can be called during ResolveTransientServoStyle
// in which case we may already have a visited style context but the
// expected parent is gone. Will be fixed when the aforementioned suboptimal
// behavior is removed
if (IsGecko()) {
if (GetParent() && GetParent()->GetStyleIfVisited()) {
MOZ_ASSERT(GetStyleIfVisited()->GetParent() ==
GetParent()->GetStyleIfVisited() ||
GetStyleIfVisited()->GetParent() ==
GetParent(),
"parent mismatch");
} else {
MOZ_ASSERT(GetStyleIfVisited()->GetParent() ==
GetParent(),
"parent mismatch");
}
}
}
class MOZ_STACK_CLASS FakeStyleContext
{
public:
@ -637,23 +674,6 @@ NS_NewStyleContext(nsStyleContext* aParentContext,
return context.forget();
}
namespace mozilla {
already_AddRefed<ServoStyleContext>
ServoStyleContext::Create(nsStyleContext* aParentContext,
nsPresContext* aPresContext,
nsIAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
already_AddRefed<ServoComputedValues> aComputedValues)
{
RefPtr<ServoStyleContext> context =
new ServoStyleContext(aParentContext, aPresContext, aPseudoTag, aPseudoType,
Move(aComputedValues));
return context.forget();
}
} // namespace mozilla
nsIPresShell*
nsStyleContext::Arena()
{

View File

@ -26,6 +26,8 @@ class ServoStyleContext;
} // namespace mozilla
extern "C" {
void Servo_StyleContext_AddRef(mozilla::ServoStyleContext* aContext);
void Servo_StyleContext_Release(mozilla::ServoStyleContext* aContext);
#define STYLE_STRUCT(name_, checkdata_cb_) \
struct nsStyle##name_; \
const nsStyle##name_* Servo_GetStyle##name_( \
@ -82,29 +84,8 @@ public:
static void Initialize();
#endif
nsrefcnt AddRef() {
if (mRefCnt == UINT32_MAX) {
NS_WARNING("refcount overflow, leaking object");
return mRefCnt;
}
++mRefCnt;
NS_LOG_ADDREF(this, mRefCnt, "nsStyleContext", sizeof(nsStyleContext));
return mRefCnt;
}
nsrefcnt Release() {
if (mRefCnt == UINT32_MAX) {
NS_WARNING("refcount overflow, leaking object");
return mRefCnt;
}
--mRefCnt;
NS_LOG_RELEASE(this, mRefCnt, "nsStyleContext");
if (mRefCnt == 0) {
Destroy();
return 0;
}
return mRefCnt;
}
inline void AddRef();
inline void Release();
#ifdef DEBUG
void FrameAddRef() {
@ -222,31 +203,7 @@ public:
{ return mStyleIfVisited; }
// To be called only from nsStyleSet / ServoStyleSet.
void SetStyleIfVisited(already_AddRefed<nsStyleContext> aStyleIfVisited)
{
MOZ_ASSERT(!IsStyleIfVisited(), "this context is not visited data");
NS_ASSERTION(!mStyleIfVisited, "should only be set once");
mStyleIfVisited = aStyleIfVisited;
MOZ_ASSERT(mStyleIfVisited->IsStyleIfVisited(),
"other context is visited data");
MOZ_ASSERT(!mStyleIfVisited->GetStyleIfVisited(),
"other context does not have visited data");
NS_ASSERTION(GetStyleIfVisited()->GetPseudo() == GetPseudo(),
"pseudo tag mismatch");
if (GetParentAllowServo() && GetParentAllowServo()->GetStyleIfVisited()) {
NS_ASSERTION(GetStyleIfVisited()->GetParentAllowServo() ==
GetParentAllowServo()->GetStyleIfVisited() ||
GetStyleIfVisited()->GetParentAllowServo() ==
GetParentAllowServo(),
"parent mismatch");
} else {
NS_ASSERTION(GetStyleIfVisited()->GetParentAllowServo() ==
GetParentAllowServo(),
"parent mismatch");
}
}
void SetStyleIfVisited(already_AddRefed<nsStyleContext> aStyleIfVisited);
// Does any descendant of this style context have any style values
// that were computed based on this style context's ancestors?

View File

@ -37,6 +37,18 @@ nsStyleContext::ComputedValues()
return AsServo()->ComputedValues();
}
void
nsStyleContext::AddRef()
{
MOZ_STYLO_FORWARD(AddRef, ())
}
void
nsStyleContext::Release()
{
MOZ_STYLO_FORWARD(Release, ())
}
#define STYLE_STRUCT(name_, checkdata_cb_) \
const nsStyle##name_ * \
nsStyleContext::Style##name_() { \
@ -196,4 +208,5 @@ nsStyleContext::StartBackgroundImageLoads()
StyleBackground();
}
#endif // nsStyleContextInlines_h

View File

@ -962,10 +962,10 @@ nsStyleSet::GetContext(nsStyleContext* aParentContext,
if (PresContext()->IsDynamic() &&
aElementForAnimation->IsInComposedDoc()) {
// Update CSS animations in case the animation-name has just changed.
PresContext()->AnimationManager()->UpdateAnimations(result,
PresContext()->AnimationManager()->UpdateAnimations(result->AsGecko(),
aElementForAnimation);
PresContext()->EffectCompositor()->UpdateEffectProperties(
result.get(), aElementForAnimation, result->GetPseudoType());
result->AsGecko(), aElementForAnimation, result->GetPseudoType());
animRule = PresContext()->EffectCompositor()->
GetAnimationRule(aElementForAnimation,

View File

@ -445,7 +445,7 @@ ExtractNonDiscreteComputedValue(nsCSSPropertyID aProperty,
static inline bool
ExtractNonDiscreteComputedValue(nsCSSPropertyID aProperty,
const ServoComputedValues* aComputedStyle,
const ServoStyleContext* aComputedStyle,
AnimationValue& aAnimationValue)
{
if (Servo_Property_IsDiscreteAnimatable(aProperty) &&
@ -454,7 +454,7 @@ ExtractNonDiscreteComputedValue(nsCSSPropertyID aProperty,
}
aAnimationValue.mServo =
Servo_ComputedValues_ExtractAnimationValue(aComputedStyle,
Servo_ComputedValues_ExtractAnimationValue(aComputedStyle->ComputedValues(),
aProperty).Consume();
return !!aAnimationValue.mServo;
}
@ -589,8 +589,8 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
aElement,
afterChangeStyle->GetPseudoType(),
collection,
aOldStyleContext,
afterChangeStyle.get());
aOldStyleContext->AsGecko(),
afterChangeStyle->AsGecko());
}
MOZ_ASSERT(!startedAny || collection,
@ -624,8 +624,8 @@ bool
nsTransitionManager::UpdateTransitions(
dom::Element *aElement,
CSSPseudoElementType aPseudoType,
const ServoComputedValues* aOldStyle,
const ServoComputedValues* aNewStyle)
const ServoStyleContext* aOldStyle,
const ServoStyleContext* aNewStyle)
{
if (!mPresContext->IsDynamic()) {
// For print or print preview, ignore transitions.
@ -634,7 +634,7 @@ nsTransitionManager::UpdateTransitions(
CSSTransitionCollection* collection =
CSSTransitionCollection::GetAnimationCollection(aElement, aPseudoType);
const nsStyleDisplay *disp = Servo_GetStyleDisplay(aNewStyle);
const nsStyleDisplay *disp = Servo_GetStyleDisplay(aNewStyle->ComputedValues());
return DoUpdateTransitions(disp,
aElement, aPseudoType,
collection,

View File

@ -26,6 +26,7 @@ namespace mozilla {
enum class CSSPseudoElementType : uint8_t;
struct Keyframe;
struct StyleTransition;
class ServoStyleContext;
} // namespace mozilla
/*****************************************************************************
@ -377,8 +378,8 @@ public:
bool UpdateTransitions(
mozilla::dom::Element *aElement,
mozilla::CSSPseudoElementType aPseudoType,
const ServoComputedValues* aOldStyle,
const ServoComputedValues* aNewStyle);
const mozilla::ServoStyleContext* aOldStyle,
const mozilla::ServoStyleContext* aNewStyle);
/**
* When we're resolving style for an element that previously didn't have