mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 21:00:50 +00:00
Bug 972310 - Set a suitable layer size for css scale animation/transition. r=roc
This commit is contained in:
parent
56f7c1ed2b
commit
cbf26b902d
@ -2994,12 +2994,12 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
||||
gfxSize scale;
|
||||
// XXX Should we do something for 3D transforms?
|
||||
if (canDraw2D) {
|
||||
// // If the container's transform is animated off main thread, then use the
|
||||
// maximum scale.
|
||||
// If the container's transform is animated off main thread, fix a suitable scale size
|
||||
// for animation
|
||||
if (aContainerFrame->GetContent() &&
|
||||
nsLayoutUtils::HasAnimationsForCompositor(
|
||||
aContainerFrame->GetContent(), eCSSProperty_transform)) {
|
||||
scale = nsLayoutUtils::GetMaximumAnimatedScale(aContainerFrame->GetContent());
|
||||
scale = nsLayoutUtils::ComputeSuitableScaleForAnimation(aContainerFrame->GetContent());
|
||||
} else {
|
||||
// Scale factors are normalized to a power of 2 to reduce the number of resolution changes
|
||||
scale = RoundToFloatPrecision(transform2d.ScaleFactors(true));
|
||||
|
@ -309,10 +309,27 @@ GetScaleForValue(const nsStyleAnimation::Value& aValue,
|
||||
return transform2d.ScaleFactors(true);
|
||||
}
|
||||
|
||||
gfxSize
|
||||
nsLayoutUtils::GetMaximumAnimatedScale(nsIContent* aContent)
|
||||
float
|
||||
GetSuitableScale(float aMaxScale, float aMinScale)
|
||||
{
|
||||
gfxSize result;
|
||||
// If the minimum scale >= 1.0f, use it; if the maximum <= 1.0f, use it;
|
||||
// otherwise use 1.0f.
|
||||
if (aMinScale >= 1.0f) {
|
||||
return aMinScale;
|
||||
}
|
||||
else if (aMaxScale <= 1.0f) {
|
||||
return aMaxScale;
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
gfxSize
|
||||
nsLayoutUtils::ComputeSuitableScaleForAnimation(nsIContent* aContent)
|
||||
{
|
||||
gfxSize maxScale(1.0f, 1.0f);
|
||||
gfxSize minScale(1.0f, 1.0f);
|
||||
|
||||
ElementAnimations* animations = HasAnimationOrTransitionForCompositor<ElementAnimations>
|
||||
(aContent, nsGkAtoms::animationsProperty, eCSSProperty_transform);
|
||||
if (animations) {
|
||||
@ -325,47 +342,50 @@ nsLayoutUtils::GetMaximumAnimatedScale(nsIContent* aContent)
|
||||
AnimationPropertySegment& segment = prop.mSegments[segIdx];
|
||||
gfxSize from = GetScaleForValue(segment.mFromValue,
|
||||
aContent->GetPrimaryFrame());
|
||||
result.width = std::max<float>(result.width, from.width);
|
||||
result.height = std::max<float>(result.height, from.height);
|
||||
maxScale.width = std::max<float>(maxScale.width, from.width);
|
||||
maxScale.height = std::max<float>(maxScale.height, from.height);
|
||||
minScale.width = std::min<float>(minScale.width, from.width);
|
||||
minScale.height = std::min<float>(minScale.height, from.height);
|
||||
gfxSize to = GetScaleForValue(segment.mToValue,
|
||||
aContent->GetPrimaryFrame());
|
||||
result.width = std::max<float>(result.width, to.width);
|
||||
result.height = std::max<float>(result.height, to.height);
|
||||
maxScale.width = std::max<float>(maxScale.width, to.width);
|
||||
maxScale.height = std::max<float>(maxScale.height, to.height);
|
||||
minScale.width = std::min<float>(minScale.width, to.width);
|
||||
minScale.height = std::min<float>(minScale.height, to.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ElementTransitions* transitions = HasAnimationOrTransitionForCompositor<ElementTransitions>
|
||||
(aContent, nsGkAtoms::transitionsProperty, eCSSProperty_transform);
|
||||
if (transitions) {
|
||||
for (uint32_t i = 0, i_end = transitions->mPropertyTransitions.Length();
|
||||
i < i_end; ++i)
|
||||
{
|
||||
i < i_end; ++i){
|
||||
ElementPropertyTransition &pt = transitions->mPropertyTransitions[i];
|
||||
if (pt.IsRemovedSentinel()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pt.mProperty == eCSSProperty_transform) {
|
||||
gfxSize start = GetScaleForValue(pt.mStartValue,
|
||||
aContent->GetPrimaryFrame());
|
||||
result.width = std::max<float>(result.width, start.width);
|
||||
result.height = std::max<float>(result.height, start.height);
|
||||
maxScale.width = std::max<float>(maxScale.width, start.width);
|
||||
maxScale.height = std::max<float>(maxScale.height, start.height);
|
||||
minScale.width = std::min<float>(minScale.width, start.width);
|
||||
minScale.height = std::min<float>(minScale.height, start.height);
|
||||
gfxSize end = GetScaleForValue(pt.mEndValue,
|
||||
aContent->GetPrimaryFrame());
|
||||
result.width = std::max<float>(result.width, end.width);
|
||||
result.height = std::max<float>(result.height, end.height);
|
||||
maxScale.width = std::max<float>(maxScale.width, end.width);
|
||||
maxScale.height = std::max<float>(maxScale.height, end.height);
|
||||
minScale.width = std::min<float>(minScale.width, end.width);
|
||||
minScale.height = std::min<float>(minScale.height, end.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't manage to find a max scale, use no scale rather than 0,0
|
||||
if (result == gfxSize()) {
|
||||
return gfxSize(1, 1);
|
||||
}
|
||||
|
||||
return result;
|
||||
return gfxSize(GetSuitableScale(maxScale.width, minScale.width),
|
||||
GetSuitableScale(maxScale.height, minScale.height));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1728,11 +1728,14 @@ public:
|
||||
static bool IsAnimationLoggingEnabled();
|
||||
|
||||
/**
|
||||
* Find the maximum scale for an element (aContent) over the course of any
|
||||
* animations and transitions on the element. Will return 1,1 if there is no
|
||||
* animated scaling.
|
||||
* Find a suitable scale for an element (aContent) over the course of any
|
||||
* animations and transitions on the element.
|
||||
* It will check the maximum and minimum scale during the animations and
|
||||
* transitions and return a suitable value for performance and quality.
|
||||
* Will return scale(1,1) if there is no animated scaling.
|
||||
* Always return positive value.
|
||||
*/
|
||||
static gfxSize GetMaximumAnimatedScale(nsIContent* aContent);
|
||||
static gfxSize ComputeSuitableScaleForAnimation(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Checks if we should forcibly use nearest pixel filtering for the
|
||||
|
Loading…
x
Reference in New Issue
Block a user