mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-04 06:48:38 +09:00
Issue #2364 - Limit the growth of scaling for animated nsDisplayTransform in the fallback case.
This ensures we don't scale the underlying size of the layer beyond what is close to the current display size. When box shadows get much larger than this, they start taking so much time to render that successive frames grow in scale too fast for any inter-frame reuse to be possible. With this, we avoid that and no longer get crushed by re-rendering gigantic box shadows every single frame. See BZ 1383825
This commit is contained in:
parent
d4cdecec81
commit
0db18745f4
3 changed files with 42 additions and 21 deletions
|
|
@ -5245,6 +5245,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,
|
||||
|
|
@ -5309,20 +5326,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(
|
||||
|
|
@ -5359,6 +5363,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?
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue