зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1383825 - limit the growth of scaling for animated nsDisplayTransform in fallback case. r=mattwoodrow
MozReview-Commit-ID: 25NNa1CKMEM
This commit is contained in:
Родитель
fc0b3076bb
Коммит
93a171958a
|
@ -652,7 +652,7 @@ gfxUtils::ClipToRegion(DrawTarget* aTarget, const nsIntRegion& aRegion)
|
|||
}
|
||||
|
||||
/*static*/ gfxFloat
|
||||
gfxUtils::ClampToScaleFactor(gfxFloat aVal)
|
||||
gfxUtils::ClampToScaleFactor(gfxFloat aVal, bool aRoundDown)
|
||||
{
|
||||
// Arbitary scale factor limitation. We can increase this
|
||||
// for better scaling performance at the cost of worse
|
||||
|
@ -678,8 +678,12 @@ gfxUtils::ClampToScaleFactor(gfxFloat aVal)
|
|||
// next integer value.
|
||||
if (fabs(power - NS_round(power)) < 1e-5) {
|
||||
power = NS_round(power);
|
||||
} else if (inverse) {
|
||||
// Use floor when we are either inverted or rounding down, but
|
||||
// not both.
|
||||
} else if (inverse != aRoundDown) {
|
||||
power = floor(power);
|
||||
// Otherwise, ceil when we are not inverted and not rounding
|
||||
// down, or we are inverted and rounding down.
|
||||
} else {
|
||||
power = ceil(power);
|
||||
}
|
||||
|
|
|
@ -146,9 +146,10 @@ public:
|
|||
|
||||
/**
|
||||
* Return the smallest power of kScaleResolution (2) greater than or equal to
|
||||
* aVal.
|
||||
* aVal. If aRoundDown is specified, the power of 2 will rather be less than
|
||||
* or equal to aVal.
|
||||
*/
|
||||
static gfxFloat ClampToScaleFactor(gfxFloat aVal);
|
||||
static gfxFloat ClampToScaleFactor(gfxFloat aVal, bool aRoundDown = false);
|
||||
|
||||
/**
|
||||
* Clears surface to aColor (which defaults to transparent black).
|
||||
|
|
|
@ -5391,6 +5391,23 @@ static void RestrictScaleToMaxLayerSize(gfxSize& aScale,
|
|||
aScale.height /= scale;
|
||||
}
|
||||
}
|
||||
|
||||
static nsSize
|
||||
ComputeDesiredDisplaySizeForAnimation(nsIFrame* aContainerFrame)
|
||||
{
|
||||
// Use the size of the nearest widget as the maximum size. This
|
||||
// is important since it might be a popup that is bigger than the
|
||||
// pres context's size.
|
||||
nsPresContext* presContext = aContainerFrame->PresContext();
|
||||
nsIWidget* widget = aContainerFrame->GetNearestWidget();
|
||||
if (widget) {
|
||||
return LayoutDevicePixel::ToAppUnits(widget->GetClientSize(),
|
||||
presContext->AppUnitsPerDevPixel());
|
||||
} else {
|
||||
return presContext->GetVisibleArea().Size();
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
||||
nsDisplayListBuilder* aDisplayListBuilder,
|
||||
|
@ -5455,20 +5472,7 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
|||
aContainerItem->GetType() == nsDisplayItem::TYPE_TRANSFORM &&
|
||||
EffectCompositor::HasAnimationsForCompositor(
|
||||
aContainerFrame, eCSSProperty_transform)) {
|
||||
// Use the size of the nearest widget as the maximum size. This
|
||||
// is important since it might be a popup that is bigger than the
|
||||
// pres context's size.
|
||||
nsPresContext* presContext = aContainerFrame->PresContext();
|
||||
nsIWidget* widget = aContainerFrame->GetNearestWidget();
|
||||
nsSize displaySize;
|
||||
if (widget) {
|
||||
LayoutDeviceIntSize widgetSize = widget->GetClientSize();
|
||||
int32_t p2a = presContext->AppUnitsPerDevPixel();
|
||||
displaySize.width = NSIntPixelsToAppUnits(widgetSize.width, p2a);
|
||||
displaySize.height = NSIntPixelsToAppUnits(widgetSize.height, p2a);
|
||||
} else {
|
||||
displaySize = presContext->GetVisibleArea().Size();
|
||||
}
|
||||
nsSize displaySize = ComputeDesiredDisplaySizeForAnimation(aContainerFrame);
|
||||
// compute scale using the animation on the container (ignoring
|
||||
// its ancestors)
|
||||
scale = nsLayoutUtils::ComputeSuitableScaleForAnimation(
|
||||
|
@ -5505,6 +5509,19 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
|||
if (clamp) {
|
||||
scale.width = gfxUtils::ClampToScaleFactor(scale.width);
|
||||
scale.height = gfxUtils::ClampToScaleFactor(scale.height);
|
||||
|
||||
// Limit animated scale factors to not grow excessively beyond the display size.
|
||||
nsSize maxScale(4, 4);
|
||||
if (!aVisibleRect.IsEmpty()) {
|
||||
nsSize displaySize = ComputeDesiredDisplaySizeForAnimation(aContainerFrame);
|
||||
maxScale = Max(maxScale, displaySize / aVisibleRect.Size());
|
||||
}
|
||||
if (scale.width > maxScale.width) {
|
||||
scale.width = gfxUtils::ClampToScaleFactor(maxScale.width, true);
|
||||
}
|
||||
if (scale.height > maxScale.height) {
|
||||
scale.height = gfxUtils::ClampToScaleFactor(maxScale.height, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// XXX Do we need to move nearly-integer values to integers here?
|
||||
|
|
Загрузка…
Ссылка в новой задаче