This assertion was originally added in bug 1353208 because in that bug we
changed the type of nsSMILCompositor::mCachedBaseValue from
nsAutoPtr<nsSMILValue> to just nsSMILValue. When using nsAutoPtr,
mCachedBaseValue had two null states: one where the pointer is null, and one
where the pointed-to nsSMILValue is null. Coalescing these two states simplifies
the code but there is one case where the difference is significant as described
in the commit message for that changeset (mozilla-central changeset
ad7060dae117):
"There's a subtle difference in behavior with regards to the first sample.
Previously we would compare the (initially) null mCachedBaseValue pointer with
the passed-in nsSMILValue and set mForceCompositing to true. With this patch,
however, we will only set mForceCompositing to true if the passed-in
mCachedBaseValue is not null."
That is, if the base value we get back is a null nsSMILValue, previously we
would set mForceCompositing to true unconditionally, but with the changes in bug
1353208 we would only set that to true if the passed-in nsSMILValue was not
null.
We believed that would never matter since the passed-in nsSMILValue would never
be null if we called GetBaseValue. Quoting from that same commit message:
"... if we do call GetBaseValue the result should not be a null nsSMILValue
(except in some OOM cases where we don't really care if we miss a sample).
This patch adds an assertion to check that GetBaseValue does, in fact, return
a non-null value. (I checked the code and this appears to be the case. Even in
error cases we typically return an empty nsSMILValue of a non-null type. For
example, the early return in nsSMILCSSProperty::GetBaseValue() does this.)"
We added an assertion to validate that assumption but the crashtest included in
this patch demonstrates a case where it does not hold (specifically, when
nsStyleUtil::CSPAllowsInlineStyle returns false, nsCSSProperty::GetBaseValue
will return a null nsSMILValue).
That would seem to suggest that there is at least one case where we might fail
to set mForceIsCompositing to true and hence fail to update style on this first
sample (and presumably thereonwards too since future comparisons of
mCachedBaseValue will compare equal). However, for the case of an initial sample
mForceCompositing should already be set to true since set we update
mForceCompositing in nsSMILCompositor::GetFirstFuncToAffectSandwich() and will
make it true if *anything* in the animation function has changed and at this
point, the initial sample, *everything* will have changed. Hence, I believe
dropping this assertion is acceptable.
I have confirmed that in the crashtest in this patch, during the first sample
mForceCompositing is set to true.
I would create a reftest to test the behavior on the first sample but, at least
for the specific case where inline style is disabled due to CSP, not updating
style *is* the expected behavior so there will be no difference in behavior
regardless of whether or not the mForceCompositing flag is set.
MozReview-Commit-ID: Li0pZEH2PNl
--HG--
extra : rebase_source : a1c12a019b8481600afa4295447dc1e6fb281b22
In some circumstances it is possible to sample a timed element in the active
state with a time that precedes is current interval.
One possible sequence of steps leading to this situation is as follows:
1. A timed element (e.g. <set>, <animate>) with a non-zero begin time is the
child of <svg> element A (its "time container") but has yet to be sampled.
2. In order to resolve its initial interval, the timed element registers a
startup milestone with its time container at time 0.
3. However, before the sample is performed where the timed element's initial
current interval is resolved, <svg> element A is detached from the document
tree.
4. The timed element is then attached to a different <svg> element B that has
a current time greater than the begin time of the timed element and less than
that of <svg> element A.
5. Since the timed element is still in its startup state it registers its
startup milestone again, this time with its new time container, i.e. <svg>
element B.
6. A tick occurs or the document has its style flushed such that a sample is
performed.
This includes running the milestone sample which causes the timed element to
resolve its initial current interval. Furthermore the subsequent regular
sample of the timed element causes it to transition into its active state
because the current time of <svg> element B is greater than the begin time of
the timed element.
7. <svg> element A is re-attached to the document.
8. When we go to run the next sample, we iterate through all time containers
associated with the document's animation controller which includes both <svg>
element A, and <svg> element B.
9. <svg> element A renders up its 0 milestone from step (2) since it has yet to
run it. It converts this to parent time, i.e. the time space of the animation
controller, which will be zero or less depending on the current time of <svg>
element A when it was re-attached.
10. Since the milestone from <svg> element A will be the earliest milestone
time, it will be used as the next milestone sample time.
11. The timed element is then sampled using this time, but first it is converted
to a time in the time space of the timed element's time container, which is
now <svg> element B.
As a result of this conversion, the sample time may end up being *before*
the beginning of the timed element's current interval. Since timed elements
never expect the time to go backwards an assertion fails when it detects
that it is active, but is being sampled before its current interval.
For this particular case, ignoring the "early" sample seems to be the most
appropriate action.
More generally, however, we can anticipate other cases similar to this where
milestones are registered that cause the sample time to temporarily go
backwards. A quick audit of nsSMILTimedElement::DoSampleAt suggests that, with
the code changes from this patch, that is probably ok.
As an alternative we could, perhaps, try to drop and re-create all milestones
when time containers are re-attached to the document tree but that would add
more complexity and would not necessarily cover other similar cases of this
situation.
I have verified that the crashtest included in this changeset fails without the
code changes also in this changeset.
MozReview-Commit-ID: KKGYRayNkpo
--HG--
extra : rebase_source : 832d4b357a2a2fe07abf9eab3a6046599aff3ef5
Using a copy constructor here means that reallocating hashtables
containing nsSMILCompositor does a bunch of unnecessary work; we can use
a move constructor to avoid a lot of that unnecessary work.
Defining Singleton() in the declaration of nsSMILNullType implicitly
sticks an "inline" on the function, which is not what we want: inlining
it spreads around a lot of static initialization code. Providing an
out-of-line definition is much better in terms of code size.
(Path is actually r=froydnj.)
Bug 1400459 devirtualized nsIAtom so that it is no longer a subclass of
nsISupports. This means that nsAtom is now a better name for it than nsIAtom.
MozReview-Commit-ID: 91U22X2NydP
--HG--
rename : xpcom/ds/nsIAtom.h => xpcom/ds/nsAtom.h
extra : rebase_source : ac3e904a21b8b48e74534fff964f1623ee937c67
I have verified that this fails without the code changes from the previous patch
in this series, and passes with them.
MozReview-Commit-ID: 1respvNVQaC
--HG--
extra : rebase_source : 82007792f23465edb1d286b721edeea850e2aaa3
In some rare cases we can end up with both arguments passed to
nsSMILCSSValueType::SandwichAdd being "empty", that is, having the type
nsSMILCSSValueType but a null pointer.
This can happen, for example, when we have a two by-animations and linear
interpolation causing us to pass the "empty" from-value up as the underlying
value from the first by-animation to the second by-animation (which it will try
to add with its empty from-value).
In this case the result of adding "empty" to "empty" should just be "empty"
which we achieve by just doing an early return (since the fallback behavior for
failed addition is to just use the second argument as the result; note that if
we return true though the result would also be the same).
We don't currently have a test case that produces this for interpolate but it
makes sense that trying to interpolate "empty" to "empty" should likewise fail
and just produce "empty". In this case failing will make us fall back to
discrete animation and just use the "empty" values as-is. Indicating failure,
however, has the additional effect of making us use the special keyTimes
behavior defined for discrete animation.
MozReview-Commit-ID: IZ5qg0Mk5Uy
--HG--
extra : rebase_source : 402e881cd8639885568e0a32fb49aa4dfa7cbbde
Normally when we interpolate values for CSS properties we convert empty values
(such as the empty "from" value created for a by-animation) to a suitable zero
value. However, when we use discrete interpolation that step never occurs and in
some rare cases that means we end up setting the empty value on the target
attribute directly which will have an incorrect result (e.g. setting "" for the
height property will have no effect, whereas setting "0px" will).
This patch makes us perform the empty value to zero value conversion when
performing discrete animation.
Unfortunately it is not possible to test this behavior with shorthands since
there are currently no shorthand properties that are additive.
MozReview-Commit-ID: JFT1tis1RAR
--HG--
extra : rebase_source : cc444b6d4d5571c8ab231d88c4d349ea0713baaa
This patch merges nsAtom into nsIAtom. For the moment, both names can be used
interchangeably due to a typedef. The patch also devirtualizes nsIAtom, by
making it not inherit from nsISupports, removing NS_DECL_NSIATOM, and dropping
the use of NS_IMETHOD_. It also removes nsIAtom's IIDs.
These changes trigger knock-on changes throughout the codebase, changing the
types of lots of things as follows.
- nsCOMPtr<nsIAtom> --> RefPtr<nsIAtom>
- nsCOMArray<nsIAtom> --> nsTArray<RefPtr<nsIAtom>>
- Count() --> Length()
- ObjectAt() --> ElementAt()
- AppendObject() --> AppendElement()
- RemoveObjectAt() --> RemoveElementAt()
- ns*Hashtable<nsISupportsHashKey, ...> -->
ns*Hashtable<nsRefPtrHashKey<nsIAtom>, ...>
- nsInterfaceHashtable<T, nsIAtom> --> nsRefPtrHashtable<T, nsIAtom>
- This requires adding a Get() method to nsRefPtrHashtable that it lacks but
nsInterfaceHashtable has.
- nsCOMPtr<nsIMutableArray> --> nsTArray<RefPtr<nsIAtom>>
- nsArrayBase::Create() --> nsTArray()
- GetLength() --> Length()
- do_QueryElementAt() --> operator[]
The patch also has some changes to Rust code that manipulates nsIAtom.
MozReview-Commit-ID: DykOl8aEnUJ
--HG--
extra : rebase_source : 254404e318e94b4c93ec8d4081ff0f0fda8aa7d1
I'm not sure exactly how this works, but test_smilTextZoom.xhtml passes so this
appears to be taken care of.
MozReview-Commit-ID: C04XjX2rtZw
--HG--
extra : rebase_source : 19c08a1267f8764f83e9e7b31731bb82e52df9e6
Currently, Gecko converts lengths in stroke-* properties to numbers when
creating animation values and hence the result of animation is always a unitless
value for these properties.
Servo, on the other hand, converts lengths for these properties to numbers
during interpolation and hence sometimes the result of animation is a unitless
value, and other times (such as when skipping interpolation) it is not.
Other browsers produce lengths with px units and ultimately we should align
with that behavior. As a result, this patch updates various SMIL mochitests to:
* Expect animation values with px unit
* Compare values by stripping px units as a temporary measure until we
correctly serialize these values with px (bug 1379908).
MozReview-Commit-ID: IsT26DKkgiP
--HG--
extra : rebase_source : 8d8dee6ad53d29801096d3affe996e4df1a9388c
We need to check whether the function fails or not in order to check whether
we support the specified paced animation values.
Current servo returns 0.0 when failed computing distance, so servo doesn't
distinguish its failure. This patch makes Servo_AnimationValue_ComputeDistance
return a negative value when the function fails.
MozReview-Commit-ID: 43Q4gu4xwHc
--HG--
extra : rebase_source : fa159b4b03e2e84c0a365455de4c0d2cf5d4f2ce
Replace it with NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION, because it
has been the same for a while.
MozReview-Commit-ID: 5agRGFyUry1
--HG--
extra : rebase_source : 5388c56b2f6905c6ef969150f0c5b77bf247624d
We should not be declaring forward declarations for nsString classes directly,
instead we should use nsStringFwd.h. This will make changing the underlying
types easier.
--HG--
extra : rebase_source : b2c7554e8632f078167ff2f609392e63a136c299
In SMIL if a discrete calcMode is used, the keyTimes attribute may be used to
specify the times at which the various animation values are used, overriding the
regular 50% flip behavior (see nsSMILAnimationFunction::ScaleSimpleProgress).
However, this behavior is only applied when the calcMode is known to be
discrete. If the author specifies calcMode="linear" but
attributeType="stroke-linecap" then SMIL should fall back to discrete calcMode
including applying the special keyTimes behavior.
For the Servo backend, Servo_AnimationValues_Interpolate does not return an
error for discretely animated properties so SMIL does not recognize when we fall
back to discrete calcMode. This patch adds a check before performing
interpolation that tests if the property is a discretely interpolable one and,
if it is, returns an error so that we run SMIL's special discrete calcMode
handling.
MozReview-Commit-ID: FOp8XcNbvdu
--HG--
extra : rebase_source : 57ddb333855de111aa585fe894e99937681e5cd2
When display style is changed from 'none' to other in animation-only restyle
we need to resolve descendant elements' style that were in the display:none
subtree.
Three possible ways to resolve the descendant elements' style;
1) Traversing unstyled elements in animation-only restyle
We can't simply traverse unstyled elements in the animation-only restyle
since when we decided to traverse the unstyled elements we don't know yet
the elements will be initially styled or are in display:none subtree. It
will result that the new elements are styled in animation-only restyle,
it's undesirable.
2) Creating a SequentialTask and resolve the descendants' style with
ServoStyleSet::StyleNewSubtree()
We can't resolve the descendants' styles with ServoStyleSet::StyleNewSubtree()
in SequentialTask since at the moment we are still in servo traversal (i.e.
sInServoTraversal is true). That means AutoSetInServoTraversal fails
in PrepareAndTraverseSubtree().
3) Creating a SequentialTask and set restyle subtree hint and defer descendants'
restyle in a subsequent normal traversal
Note that, when we process throttled animations flush, we don't process
normal traversal so the descendants will not be traversed until normal
restyle happens but it will not be a big problem since it's really rare
that user clicks display animation element just at the right moment when
display property changes from none to other. Also, if it will be really
a problem, we should process *only* transform animations on the compositor,
it's ideally right thing to do. Display property never runs on the
compositor.
This patch takes the third approach.
MozReview-Commit-ID: Krxa3kkdIq4
--HG--
extra : rebase_source : 33e9db953f21168c76716329568191625bd15896
AddOrAccumulate in nsSMILCSSValueType.cpp sets initializes |valueToAdd| to
either &valueToAddWrapper->mGeckoValue or nullptr. It then asks
FinalizeStyleAnimationValues to fill it in. FinalizeStyleAnimationValues will
return false if it could not fill it in, in which case AddOrAccumulate returns
early. As a result, after the early return we can be assured that |valueToAdd|
is not null. However, valueToAddWrapper may still be null.
Changeset 4d87f2bf4b10369af0dd83a2ef962a23299ee8d9 from bug 1358966 changed this
code such that we pass a member of valueToAddWrapper to StyleAnimationValue::Add
where we used to pass a member of valueToAdd. As a result, we can end up passing
0x20 (since valueToAddWrapper is nullptr) to Add() and then trying to read from
it.
This patch makes us pass, instead, |valueToAdd| since we know that is guaranteed
to be non-null here.
MozReview-Commit-ID: 1YwT1lBHnUe
--HG--
extra : rebase_source : abec6995af68de13eacaccf7eca7b2d121eaedf3