--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -605,17 +605,18 @@ AddAnimationForProperty(nsIFrame* aFrame
static_cast<uint8_t>(segment.mToComposite);
animSegment->sampleFn() = ToTimingFunction(segment.mTimingFunction);
}
}
static void
AddAnimationsForProperty(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem, nsCSSPropertyID aProperty,
- AnimationInfo& aAnimationInfo, bool aPending)
+ AnimationInfo& aAnimationInfo, bool aPending,
+ bool aIsForWebRender)
{
if (aPending) {
aAnimationInfo.ClearAnimationsForNextTransaction();
} else {
aAnimationInfo.ClearAnimations();
}
// Update the animation generation on the layer. We need to do this before
@@ -662,17 +663,21 @@ AddAnimationsForProperty(nsIFrame* aFram
int32_t devPixelsToAppUnits = aFrame->PresContext()->AppUnitsPerDevPixel();
float scale = devPixelsToAppUnits;
Point3D offsetToTransformOrigin =
nsDisplayTransform::GetDeltaToTransformOrigin(aFrame, scale, &bounds);
nsPoint origin;
float scaleX = 1.0f;
float scaleY = 1.0f;
bool hasPerspectiveParent = false;
- if (aItem) {
+ if (aIsForWebRender) {
+ // leave origin empty, because we are sending it separately on the stacking
+ // context that we are pushing to WR, and WR will automatically include
+ // it when picking up the animated transform values
+ } else if (aItem) {
// This branch is for display items to leverage the cache of
// nsDisplayListBuilder.
origin = aItem->ToReferenceFrame();
} else {
// This branch is running for restyling.
// Animations are animated at the coordination of the reference
// frame outside, not the given frame itself. The given frame
// is also reference frame too, so the parent's reference frame
@@ -840,17 +845,17 @@ nsDisplayListBuilder::AddAnimationsAndTr
if (!(backend == layers::LayersBackend::LAYERS_CLIENT ||
backend == layers::LayersBackend::LAYERS_WR)) {
return;
}
bool pending = !aBuilder;
AnimationInfo& animationInfo = aLayer->GetAnimationInfo();
AddAnimationsForProperty(aFrame, aBuilder, aItem, aProperty,
- animationInfo, pending);
+ animationInfo, pending, false);
animationInfo.TransferMutatedFlagToLayer(aLayer);
}
nsDisplayItem*
nsDisplayListBuilder::MergeItems(nsTArray<nsDisplayItem*>& aMergedItems)
{
// For merging, we create a temporary item by cloning the last item of the
// mergeable items list. This ensures that the temporary item will have the
@@ -6667,17 +6672,17 @@ nsDisplayOpacity::CreateWebRenderCommand
nsDisplayListBuilder* aDisplayListBuilder)
{
float* opacityForSC = &mOpacity;
RefPtr<WebRenderAnimationData> animationData = aManager->CommandBuilder().CreateOrRecycleWebRenderUserData<WebRenderAnimationData>(this);
AnimationInfo& animationInfo = animationData->GetAnimationInfo();
AddAnimationsForProperty(Frame(), aDisplayListBuilder,
this, eCSSProperty_opacity,
- animationInfo, false);
+ animationInfo, false, true);
animationInfo.StartPendingAnimations(aManager->GetAnimationReadyTime());
// Note that animationsId can be 0 (uninitialized in AnimationInfo) if there
// are no active animations.
uint64_t animationsId = animationInfo.GetCompositorAnimationsId();
wr::WrAnimationProperty prop;
if (!animationInfo.GetAnimations().IsEmpty()) {
@@ -8418,19 +8423,28 @@ nsDisplayTransform::GetTransform() const
GetResultingTransformMatrix(mFrame, ToReferenceFrame(),
scale, INCLUDE_PERSPECTIVE|OFFSET_BY_ORIGIN);
}
}
return mTransform;
}
Matrix4x4
-nsDisplayTransform::GetTransformForRendering()
+nsDisplayTransform::GetTransformForRendering(LayoutDevicePoint* aOutOrigin)
{
if (!mFrame->HasPerspective() || mTransformGetter || mIsTransformSeparator) {
+ if (!mTransformGetter && !mIsTransformSeparator && aOutOrigin) {
+ // If aOutOrigin is provided, put the offset to origin into it, because
+ // we need to keep it separate for webrender. The combination of
+ // *aOutOrigin and the returned matrix here should always be equivalent
+ // to what GetTransform() would have returned.
+ float scale = mFrame->PresContext()->AppUnitsPerDevPixel();
+ *aOutOrigin = LayoutDevicePoint::FromAppUnits(ToReferenceFrame(), scale);
+ return GetResultingTransformMatrix(mFrame, nsPoint(0, 0), scale, INCLUDE_PERSPECTIVE);
+ }
return GetTransform();
}
MOZ_ASSERT(!mTransformGetter);
float scale = mFrame->PresContext()->AppUnitsPerDevPixel();
// Don't include perspective transform, or the offset to origin, since
// nsDisplayPerspective will handle both of those.
return GetResultingTransformMatrix(mFrame, ToReferenceFrame(), scale, 0);
@@ -8476,31 +8490,38 @@ nsDisplayTransform::ShouldBuildLayerEven
bool
nsDisplayTransform::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
- Matrix4x4 newTransformMatrix = GetTransformForRendering();
+ // We want to make sure we don't pollute the transform property in the WR
+ // stacking context by including the position of this frame (relative to the
+ // parent reference frame). We need to keep those separate; the position of
+ // this frame goes into the stacking context bounds while the transform goes
+ // into the transform.
+ LayoutDevicePoint position;
+ Matrix4x4 newTransformMatrix = GetTransformForRendering(&position);
+
gfx::Matrix4x4* transformForSC = &newTransformMatrix;
if (newTransformMatrix.IsIdentity()) {
// If the transform is an identity transform, strip it out so that WR
// doesn't turn this stacking context into a reference frame, as it
// affects positioning. Bug 1345577 tracks a better fix.
transformForSC = nullptr;
}
RefPtr<WebRenderAnimationData> animationData = aManager->CommandBuilder().CreateOrRecycleWebRenderUserData<WebRenderAnimationData>(this);
AnimationInfo& animationInfo = animationData->GetAnimationInfo();
AddAnimationsForProperty(Frame(), aDisplayListBuilder,
this, eCSSProperty_transform,
- animationInfo, false);
+ animationInfo, false, true);
animationInfo.StartPendingAnimations(aManager->GetAnimationReadyTime());
// Note that animationsId can be 0 (uninitialized in AnimationInfo) if there
// are no active animations.
uint64_t animationsId = animationInfo.GetCompositorAnimationsId();
wr::WrAnimationProperty prop;
if (!animationInfo.GetAnimations().IsEmpty()) {
// Update transfrom as nullptr in stacking context if there exists
@@ -8524,17 +8545,17 @@ nsDisplayTransform::CreateWebRenderComma
aManager->AddCompositorAnimationsIdForDiscard(animationsId);
animationsId = 0;
}
nsTArray<mozilla::wr::WrFilterOp> filters;
StackingContextHelper sc(aSc,
aBuilder,
filters,
- LayoutDeviceRect(),
+ LayoutDeviceRect(position, LayoutDeviceSize()),
&newTransformMatrix,
animationsId ? &prop : nullptr,
nullptr,
transformForSC,
nullptr,
gfx::CompositionOp::OP_OVER,
!BackfaceIsHidden(),
mFrame->Extend3DContext() && !mNoExtendContext);