Bug 1634616 - Unscale pre-render area for transform animations too. r=botond

Differential Revision: https://phabricator.services.mozilla.com/D74520
This commit is contained in:
Hiroyuki Ikezoe 2020-05-12 08:32:15 +00:00
Родитель 90668a72e5
Коммит d611690078
4 изменённых файлов: 21 добавлений и 15 удалений

Просмотреть файл

@ -9810,13 +9810,19 @@ CSSPoint nsLayoutUtils::GetCumulativeApzCallbackTransform(nsIFrame* aFrame) {
/* static */
nsRect nsLayoutUtils::ComputePartialPrerenderArea(
const nsRect& aDirtyRect, const nsRect& aOverflow,
nsIFrame* aFrame, const nsRect& aDirtyRect, const nsRect& aOverflow,
const nsSize& aPrerenderSize) {
const gfxSize scale = GetTransformToAncestorScale(aFrame);
nsSize prerenderSize = aPrerenderSize;
if (scale.width != 0 && scale.height != 0) {
prerenderSize.width /= scale.width;
prerenderSize.height /= scale.height;
}
// Simple calculation for now: center the pre-render area on the dirty rect,
// and clamp to the overflow area. Later we can do more advanced things like
// redistributing from one axis to another, or from one side to another.
nscoord xExcess = std::max(aPrerenderSize.width - aDirtyRect.width, 0);
nscoord yExcess = std::max(aPrerenderSize.height - aDirtyRect.height, 0);
nscoord xExcess = std::max(prerenderSize.width - aDirtyRect.width, 0);
nscoord yExcess = std::max(prerenderSize.height - aDirtyRect.height, 0);
nsRect result = aDirtyRect;
result.Inflate(xExcess / 2, yExcess / 2);
return result.MoveInsideAndClamp(aOverflow);

Просмотреть файл

@ -2970,16 +2970,21 @@ class nsLayoutUtils {
/**
* Compute a rect to pre-render in cases where we want to render more of
* something than what is visible (usually to support async transformation).
* @param aDirtyRect the area that's visible
* @param aOverflow the total size of the thing we're rendering
* @param aPrerenderSize how large of an area we're willing to render
* @param aFrame the target frame to be pre-rendered
* @param aDirtyRect the area that's visible in the coordinate system of
* |aFrame|.
* @param aOverflow the total size of the thing we're rendering in the
* coordinate system of |aFrame|.
* @param aPrerenderSize how large of an area we're willing to render in the
* coordinate system of the root frame.
* @return A rectangle that includes |aDirtyRect|, is clamped to |aOverflow|,
* and is no larger than |aPrerenderSize| (unless |aPrerenderSize|
* is smaller than |aDirtyRect|, in which case the returned rect
* will still include |aDirtyRect| and thus be larger than
* |aPrerenderSize|).
*/
static nsRect ComputePartialPrerenderArea(const nsRect& aDirtyRect,
static nsRect ComputePartialPrerenderArea(nsIFrame* aFrame,
const nsRect& aDirtyRect,
const nsRect& aOverflow,
const nsSize& aPrerenderSize);

Просмотреть файл

@ -7827,8 +7827,8 @@ auto nsDisplayTransform::ShouldPrerenderTransformedContent(
}
if (StaticPrefs::layout_animation_prerender_partial()) {
*aDirtyRect = nsLayoutUtils::ComputePartialPrerenderArea(*aDirtyRect,
overflow, maxSize);
*aDirtyRect = nsLayoutUtils::ComputePartialPrerenderArea(
aFrame, *aDirtyRect, overflow, maxSize);
result.mDecision = PrerenderDecision::Partial;
return result;
}

Просмотреть файл

@ -313,14 +313,9 @@ void nsSliderFrame::BuildDisplayListForChildren(
const nsRect overflow = thumb->GetVisualOverflowRectRelativeToParent();
nsSize refSize = aBuilder->RootReferenceFrame()->GetSize();
const gfxSize scale = nsLayoutUtils::GetTransformToAncestorScale(thumb);
if (scale.width != 0 && scale.height != 0) {
refSize.width /= scale.width;
refSize.height /= scale.height;
}
nsRect dirty = aBuilder->GetVisibleRect().Intersect(thumbRect);
dirty = nsLayoutUtils::ComputePartialPrerenderArea(
aBuilder->GetVisibleRect(), overflow, refSize);
thumb, aBuilder->GetVisibleRect(), overflow, refSize);
nsDisplayListBuilder::AutoBuildingDisplayList buildingDisplayList(
aBuilder, this, dirty, dirty);