mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 10:00:54 +00:00
Bug 828173 patch 4: Expose AddAnimationsAndTransitionsToLayer and allow it to be called from style change handling. r=mattwoodrow
This commit is contained in:
parent
1c6ed806fe
commit
143d4b266e
@ -314,7 +314,7 @@ ToTimingFunction(css::ComputedTimingFunction& aCTF)
|
||||
static void
|
||||
AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
|
||||
ElementAnimation* ea, Layer* aLayer,
|
||||
AnimationData& aData)
|
||||
AnimationData& aData, bool aPending)
|
||||
{
|
||||
NS_ASSERTION(aLayer->AsContainerLayer(), "Should only animate ContainerLayer");
|
||||
nsStyleContext* styleContext = aFrame->StyleContext();
|
||||
@ -323,7 +323,8 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
|
||||
// all data passed directly to the compositor should be in css pixels
|
||||
float scale = nsDeviceContext::AppUnitsPerCSSPixel();
|
||||
|
||||
Animation* animation = aLayer->AddAnimation();
|
||||
Animation* animation = aPending ? aLayer->AddAnimationForNextTransaction()
|
||||
: aLayer->AddAnimation();
|
||||
|
||||
animation->startTime() = ea->mStartTime + ea->mDelay;
|
||||
animation->duration() = ea->mIterationDuration;
|
||||
@ -367,15 +368,31 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
AddAnimationsAndTransitionsToLayer(Layer* aLayer, nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aItem, nsCSSProperty aProperty)
|
||||
/* static */ void
|
||||
nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aItem,
|
||||
nsIFrame* aFrame,
|
||||
nsCSSProperty aProperty)
|
||||
{
|
||||
aLayer->ClearAnimations();
|
||||
// This function can be called in two ways: from
|
||||
// nsDisplay*::BuildLayer while constructing a layer (with all
|
||||
// pointers non-null), or from RestyleManager's handling of
|
||||
// UpdateOpacityLayer/UpdateTransformLayer hints.
|
||||
MOZ_ASSERT(!aBuilder == !aItem,
|
||||
"should only be called in two configurations, with both "
|
||||
"aBuilder and aItem, or with neither");
|
||||
MOZ_ASSERT(!aItem || aFrame == aItem->Frame(), "frame mismatch");
|
||||
|
||||
nsIFrame* frame = aItem->Frame();
|
||||
bool pending = !aBuilder;
|
||||
|
||||
nsIContent* content = frame->GetContent();
|
||||
if (pending) {
|
||||
aLayer->ClearAnimationsForNextTransaction();
|
||||
} else {
|
||||
aLayer->ClearAnimations();
|
||||
}
|
||||
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
@ -390,43 +407,54 @@ AddAnimationsAndTransitionsToLayer(Layer* aLayer, nsDisplayListBuilder* aBuilder
|
||||
}
|
||||
|
||||
// If the frame is not prerendered, bail out.
|
||||
if (!aItem->CanUseAsyncAnimations(aBuilder)) {
|
||||
// Do this check only during layer construction; during updating the
|
||||
// caller is required to check it appropriately.
|
||||
if (aItem && !aItem->CanUseAsyncAnimations(aBuilder)) {
|
||||
// AnimationManager or TransitionManager need to know that we refused to
|
||||
// run this animation asynchronously so that they will not throttle the
|
||||
// main thread animation.
|
||||
frame->Properties().Set(nsIFrame::RefusedAsyncAnimation(),
|
||||
aFrame->Properties().Set(nsIFrame::RefusedAsyncAnimation(),
|
||||
reinterpret_cast<void*>(intptr_t(true)));
|
||||
|
||||
// We need to schedule another refresh driver run so that AnimationManager
|
||||
// or TransitionManager get a chance to unthrottle the animation.
|
||||
frame->SchedulePaint();
|
||||
aFrame->SchedulePaint();
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::TimeStamp currentTime =
|
||||
frame->PresContext()->RefreshDriver()->MostRecentRefresh();
|
||||
aFrame->PresContext()->RefreshDriver()->MostRecentRefresh();
|
||||
AnimationData data;
|
||||
if (aProperty == eCSSProperty_transform) {
|
||||
nsRect bounds = nsDisplayTransform::GetFrameBoundsForTransform(frame);
|
||||
nsRect bounds = nsDisplayTransform::GetFrameBoundsForTransform(aFrame);
|
||||
// all data passed directly to the compositor should be in css pixels
|
||||
float scale = nsDeviceContext::AppUnitsPerCSSPixel();
|
||||
gfxPoint3D offsetToTransformOrigin =
|
||||
nsDisplayTransform::GetDeltaToTransformOrigin(frame, scale, &bounds);
|
||||
nsDisplayTransform::GetDeltaToTransformOrigin(aFrame, scale, &bounds);
|
||||
gfxPoint3D offsetToPerspectiveOrigin =
|
||||
nsDisplayTransform::GetDeltaToPerspectiveOrigin(frame, scale);
|
||||
nsDisplayTransform::GetDeltaToPerspectiveOrigin(aFrame, scale);
|
||||
nscoord perspective = 0.0;
|
||||
nsStyleContext* parentStyleContext = frame->StyleContext()->GetParent();
|
||||
nsStyleContext* parentStyleContext = aFrame->StyleContext()->GetParent();
|
||||
if (parentStyleContext) {
|
||||
const nsStyleDisplay* disp = parentStyleContext->StyleDisplay();
|
||||
if (disp && disp->mChildPerspective.GetUnit() == eStyleUnit_Coord) {
|
||||
perspective = disp->mChildPerspective.GetCoordValue();
|
||||
}
|
||||
}
|
||||
nsPoint origin = aItem->ToReferenceFrame();
|
||||
nsPoint origin;
|
||||
if (aItem) {
|
||||
origin = aItem->ToReferenceFrame();
|
||||
} else {
|
||||
// transform display items used a reference frame computed from
|
||||
// their GetTransformRootFrame().
|
||||
nsIFrame* referenceFrame =
|
||||
nsLayoutUtils::GetReferenceFrame(GetTransformRootFrame(aFrame));
|
||||
origin = aFrame->GetOffsetToCrossDoc(referenceFrame);
|
||||
}
|
||||
|
||||
data = TransformData(origin, offsetToTransformOrigin,
|
||||
offsetToPerspectiveOrigin, bounds, perspective,
|
||||
frame->PresContext()->AppUnitsPerDevPixel());
|
||||
aFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
} else if (aProperty == eCSSProperty_opacity) {
|
||||
data = null_t();
|
||||
}
|
||||
@ -458,8 +486,8 @@ AddAnimationsAndTransitionsToLayer(Layer* aLayer, nsDisplayListBuilder* aBuilder
|
||||
segment.mToValue = pt->mEndValue;
|
||||
segment.mTimingFunction = pt->mTimingFunction;
|
||||
|
||||
AddAnimationsForProperty(frame, aProperty, &anim,
|
||||
aLayer, data);
|
||||
AddAnimationsForProperty(aFrame, aProperty, &anim,
|
||||
aLayer, data, pending);
|
||||
|
||||
pt->mIsRunningOnCompositor = true;
|
||||
}
|
||||
@ -473,8 +501,8 @@ AddAnimationsAndTransitionsToLayer(Layer* aLayer, nsDisplayListBuilder* aBuilder
|
||||
anim->IsRunningAt(currentTime))) {
|
||||
continue;
|
||||
}
|
||||
AddAnimationsForProperty(frame, aProperty, anim,
|
||||
aLayer, data);
|
||||
AddAnimationsForProperty(aFrame, aProperty, anim,
|
||||
aLayer, data, pending);
|
||||
}
|
||||
aLayer->SetAnimationGeneration(ea->mAnimationGeneration);
|
||||
}
|
||||
@ -3195,8 +3223,9 @@ nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
return nullptr;
|
||||
|
||||
container->SetOpacity(mFrame->StyleDisplay()->mOpacity);
|
||||
AddAnimationsAndTransitionsToLayer(container, aBuilder,
|
||||
this, eCSSProperty_opacity);
|
||||
nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(container, aBuilder,
|
||||
this, mFrame,
|
||||
eCSSProperty_opacity);
|
||||
return container.forget();
|
||||
}
|
||||
|
||||
@ -4662,8 +4691,9 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
|
||||
container->SetContentFlags(container->GetContentFlags() & ~Layer::CONTENT_PRESERVE_3D);
|
||||
}
|
||||
|
||||
AddAnimationsAndTransitionsToLayer(container, aBuilder,
|
||||
this, eCSSProperty_transform);
|
||||
nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(container, aBuilder,
|
||||
this, mFrame,
|
||||
eCSSProperty_transform);
|
||||
if (ShouldPrerenderTransformedContent(aBuilder, mFrame, false)) {
|
||||
container->SetUserData(nsIFrame::LayerIsPrerenderedDataKey(),
|
||||
/*the value is irrelevant*/nullptr);
|
||||
|
@ -39,6 +39,7 @@ class nsDisplayLayerEventRegions;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class Layer;
|
||||
class ImageLayer;
|
||||
class ImageContainer;
|
||||
} //namepsace
|
||||
@ -112,6 +113,7 @@ public:
|
||||
typedef mozilla::DisplayItemClip DisplayItemClip;
|
||||
typedef mozilla::DisplayListClipState DisplayListClipState;
|
||||
typedef nsIWidget::ThemeGeometry ThemeGeometry;
|
||||
typedef mozilla::layers::Layer Layer;
|
||||
|
||||
/**
|
||||
* @param aReferenceFrame the frame at the root of the subtree; its origin
|
||||
@ -481,6 +483,18 @@ public:
|
||||
*/
|
||||
const DisplayItemClip* AllocateDisplayItemClip(const DisplayItemClip& aOriginal);
|
||||
|
||||
/**
|
||||
* Transfer off main thread animations to the layer. May be called
|
||||
* with aBuilder and aItem both null, but only if the caller has
|
||||
* already checked that off main thread animations should be sent to
|
||||
* the layer. When they are both null, the animations are added to
|
||||
* the layer as pending animations.
|
||||
*/
|
||||
static void AddAnimationsAndTransitionsToLayer(Layer* aLayer,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aItem,
|
||||
nsIFrame* aFrame,
|
||||
nsCSSProperty aProperty);
|
||||
/**
|
||||
* A helper class to temporarily set the value of
|
||||
* mIsAtRootOfPseudoStackingContext, and temporarily
|
||||
|
Loading…
Reference in New Issue
Block a user