Bug 1324591 - Store PrerenderDecision in nsDisplayTransform. r=botond

Depends on D75728

Differential Revision: https://phabricator.services.mozilla.com/D75729
This commit is contained in:
Hiroyuki Ikezoe 2020-07-05 11:43:07 +00:00
Родитель 1c1e6e4963
Коммит cb8a5d8210
3 изменённых файлов: 40 добавлений и 27 удалений

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

@ -3260,17 +3260,15 @@ void nsIFrame::BuildDisplayListForStackingContext(
aBuilder->SetContainsBackdropFilter(false);
nsRect visibleRectOutsideTransform = visibleRect;
bool allowAsyncAnimation = false;
nsDisplayTransform::PrerenderInfo prerenderInfo;
bool inTransform = aBuilder->IsInTransform();
if (isTransformed) {
nsDisplayTransform::PrerenderInfo decision =
nsDisplayTransform::ShouldPrerenderTransformedContent(aBuilder, this,
&dirtyRect);
prerenderInfo = nsDisplayTransform::ShouldPrerenderTransformedContent(
aBuilder, this, &dirtyRect);
switch (decision.mDecision) {
switch (prerenderInfo.mDecision) {
case nsDisplayTransform::PrerenderDecision::Full:
case nsDisplayTransform::PrerenderDecision::Partial:
allowAsyncAnimation = true;
visibleRect = dirtyRect;
break;
case nsDisplayTransform::PrerenderDecision::No: {
@ -3278,7 +3276,7 @@ void nsIFrame::BuildDisplayListForStackingContext(
// then we want disable async animations for the rest of the preserve-3d
// (especially ancestors).
if ((extend3DContext || combines3DTransformWithAncestors) &&
decision.mHasAnimations) {
prerenderInfo.mHasAnimations) {
aBuilder->SavePreserves3DAllowAsyncAnimation(false);
}
@ -3768,14 +3766,15 @@ void nsIFrame::BuildDisplayListForStackingContext(
// Alternatively we could not block animations for later siblings, and only
// block them for ancestors of a blocked one.
if ((extend3DContext || combines3DTransformWithAncestors) &&
allowAsyncAnimation) {
prerenderInfo.CanUseAsyncAnimations() &&
!aBuilder->GetPreserves3DAllowAsyncAnimation()) {
// aBuilder->GetPreserves3DAllowAsyncAnimation() means the inner or
// previous silbing frames are allowed/disallowed for async animations.
allowAsyncAnimation = aBuilder->GetPreserves3DAllowAsyncAnimation();
prerenderInfo.mDecision = nsDisplayTransform::PrerenderDecision::No;
}
nsDisplayTransform* transformItem = MakeDisplayItem<nsDisplayTransform>(
aBuilder, this, &resultList, visibleRect, allowAsyncAnimation);
aBuilder, this, &resultList, visibleRect, prerenderInfo.mDecision);
if (transformItem) {
resultList.AppendToTop(transformItem);
ct.TrackContainer(transformItem);

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

@ -7287,8 +7287,8 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot),
mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot),
mChildrenBuildingRect(aChildrenBuildingRect),
mIsTransformSeparator(true),
mAllowAsyncAnimation(false) {
mPrerenderDecision(PrerenderDecision::No),
mIsTransformSeparator(true) {
MOZ_COUNT_CTOR(nsDisplayTransform);
MOZ_ASSERT(aFrame, "Must have a frame!");
Init(aBuilder, aList);
@ -7297,14 +7297,14 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList,
const nsRect& aChildrenBuildingRect,
bool aAllowAsyncAnimation)
PrerenderDecision aPrerenderDecision)
: nsDisplayHitTestInfoBase(aBuilder, aFrame),
mTransformGetter(nullptr),
mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot),
mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot),
mChildrenBuildingRect(aChildrenBuildingRect),
mIsTransformSeparator(false),
mAllowAsyncAnimation(aAllowAsyncAnimation) {
mPrerenderDecision(aPrerenderDecision),
mIsTransformSeparator(false) {
MOZ_COUNT_CTOR(nsDisplayTransform);
MOZ_ASSERT(aFrame, "Must have a frame!");
SetReferenceFrameToAncestor(aBuilder);
@ -7320,8 +7320,8 @@ nsDisplayTransform::nsDisplayTransform(
mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot),
mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot),
mChildrenBuildingRect(aChildrenBuildingRect),
mIsTransformSeparator(false),
mAllowAsyncAnimation(false) {
mPrerenderDecision(PrerenderDecision::No),
mIsTransformSeparator(false) {
MOZ_COUNT_CTOR(nsDisplayTransform);
MOZ_ASSERT(aFrame, "Must have a frame!");
Init(aBuilder, aList);
@ -7640,7 +7640,7 @@ bool nsDisplayOpacity::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) {
}
bool nsDisplayTransform::CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) {
return mAllowAsyncAnimation;
return mPrerenderDecision != PrerenderDecision::No;
}
bool nsDisplayBackgroundColor::CanUseAsyncAnimations(
@ -8044,7 +8044,7 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(
~Layer::CONTENT_EXTEND_3D_CONTEXT);
}
if (mAllowAsyncAnimation) {
if (CanUseAsyncAnimations(aBuilder)) {
mFrame->SetProperty(nsIFrame::RefusedAsyncAnimationProperty(), false);
}
@ -8054,7 +8054,7 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(
container, aBuilder, this, mFrame, GetType());
}
if (mAllowAsyncAnimation && MayBeAnimated(aBuilder)) {
if (CanUseAsyncAnimations(aBuilder) && MayBeAnimated(aBuilder)) {
// Only allow async updates to the transform if we're an animated layer,
// since that's what triggers us to set the correct AGR in the constructor
// and makes sure FrameLayerBuilder won't compute occlusions for this layer.
@ -8531,7 +8531,19 @@ void nsDisplayTransform::WriteDebugInfo(std::stringstream& aStream) {
aStream << " combines-3d-with-ancestors";
}
aStream << " allowAsync(" << (mAllowAsyncAnimation ? "true" : "false") << ")";
aStream << " prerender(";
switch (mPrerenderDecision) {
case PrerenderDecision::No:
aStream << "no";
break;
case PrerenderDecision::Partial:
aStream << "partial";
break;
case PrerenderDecision::Full:
aStream << "full";
break;
}
aStream << ")";
aStream << " childrenBuildingRect" << mChildrenBuildingRect;
}

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

@ -6727,7 +6727,7 @@ class nsDisplayTransform : public nsDisplayHitTestInfoBase {
using TransformReferenceBox = nsStyleTransformMatrix::TransformReferenceBox;
public:
enum class PrerenderDecision { No, Full, Partial };
enum class PrerenderDecision : uint8_t { No, Full, Partial };
/**
* Returns a matrix (in pixels) for the current frame. The matrix should be
@ -6747,7 +6747,7 @@ class nsDisplayTransform : public nsDisplayHitTestInfoBase {
nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, const nsRect& aChildrenBuildingRect,
bool aAllowAsyncAnimation);
PrerenderDecision aPrerenderDecision);
nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, const nsRect& aChildrenBuildingRect,
@ -7006,6 +7006,9 @@ class nsDisplayTransform : public nsDisplayHitTestInfoBase {
float aAppUnitsPerPixel);
struct PrerenderInfo {
bool CanUseAsyncAnimations() const {
return mDecision != PrerenderDecision::No && mHasAnimations;
}
PrerenderDecision mDecision = PrerenderDecision::No;
bool mHasAnimations = true;
};
@ -7082,6 +7085,7 @@ class nsDisplayTransform : public nsDisplayHitTestInfoBase {
nsRect mChildBounds;
// The transformed bounds of this display item.
nsRect mBounds;
PrerenderDecision mPrerenderDecision : 8;
// This item is a separator between 3D rendering contexts, and
// mTransform have been presetted by the constructor.
// This also forces us not to extend the 3D context. Since we don't create a
@ -7089,11 +7093,9 @@ class nsDisplayTransform : public nsDisplayHitTestInfoBase {
// context, the transform items of a child preserves3d context may extend the
// parent context unintendedly if the root of the child preserves3d context
// doesn't create a transform item.
bool mIsTransformSeparator;
// True if async animation of the transform is allowed.
bool mAllowAsyncAnimation;
bool mIsTransformSeparator : 1;
// True if this nsDisplayTransform should get flattened
bool mShouldFlatten;
bool mShouldFlatten : 1;
};
/* A display item that applies a perspective transformation to a single