From 0b60039322687efec11084554de4a33c07c96916 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Thu, 1 Jun 2017 09:17:17 -0400 Subject: [PATCH] Bug 1368551 - Don't send transforms to WR in push_stacking_context if they are identity. r=pchang If we set a transform in push_stacking_context, it changes the internal WebRender behaviour to make that stacking context a reference frame, and things inside it are positioned differently. This is true even if the transform is an identity transform. In most cases we are hitting this and sending an identity transform through, when in fact we want to be sending a None value to WebRender so that it doesn't create reference frames. This is a partial fix, a proper fix will be done in bug 1345577 by separating the CSS transform from the other transforms that FrameLayerBuilder invents. MozReview-Commit-ID: ElSs3hFMD2D --- gfx/layers/wr/StackingContextHelper.cpp | 3 ++- gfx/layers/wr/WebRenderContainerLayer.cpp | 7 +++++++ gfx/webrender_bindings/src/bindings.rs | 11 +++++++---- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/gfx/layers/wr/StackingContextHelper.cpp b/gfx/layers/wr/StackingContextHelper.cpp index fa79bd6063f9..df3f60de7c14 100644 --- a/gfx/layers/wr/StackingContextHelper.cpp +++ b/gfx/layers/wr/StackingContextHelper.cpp @@ -27,7 +27,8 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen Layer* layer = aLayer->GetLayer(); mTransform = aTransform.valueOr(layer->GetTransform()); float opacity = 1.0f; - mBuilder->PushStackingContext(scBounds, 0, &opacity, &mTransform, + mBuilder->PushStackingContext(scBounds, 0, &opacity, + mTransform.IsIdentity() ? nullptr : &mTransform, wr::ToWrMixBlendMode(layer->GetMixBlendMode())); mOrigin = aLayer->Bounds().TopLeft(); } diff --git a/gfx/layers/wr/WebRenderContainerLayer.cpp b/gfx/layers/wr/WebRenderContainerLayer.cpp index 408f40cee977..611b04f63d3a 100644 --- a/gfx/layers/wr/WebRenderContainerLayer.cpp +++ b/gfx/layers/wr/WebRenderContainerLayer.cpp @@ -107,6 +107,13 @@ WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder, transformForSC = nullptr; } + if (transformForSC && transform.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; + } + ScrollingLayersHelper scroller(this, aBuilder, aSc); StackingContextHelper sc(aSc, aBuilder, this, animationsId, opacityForSC, transformForSC); diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index 4ecfe141cf56..027284e417fd 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -1261,16 +1261,19 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState, } let transform = unsafe { transform.as_ref() }; - let transform_binding = match transform { - Some(transform) => PropertyBinding::Value(transform.into()), - None => PropertyBinding::Binding(PropertyBindingKey::new(animation_id)), + let transform_binding = match animation_id { + 0 => match transform { + Some(transform) => Some(PropertyBinding::Value(transform.into())), + None => None, + }, + _ => Some(PropertyBinding::Binding(PropertyBindingKey::new(animation_id))), }; state.frame_builder .dl_builder .push_stacking_context(webrender_traits::ScrollPolicy::Scrollable, bounds, - Some(transform_binding), + transform_binding, TransformStyle::Flat, None, mix_blend_mode,