diff --git a/gfx/layers/wr/AsyncImagePipelineManager.cpp b/gfx/layers/wr/AsyncImagePipelineManager.cpp index cf7121a51f57..24be3bb0523a 100644 --- a/gfx/layers/wr/AsyncImagePipelineManager.cpp +++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp @@ -320,18 +320,19 @@ AsyncImagePipelineManager::ApplyAsyncImages(wr::TransactionBuilder& aTxn) wr::DisplayListBuilder builder(pipelineId, contentSize); float opacity = 1.0f; - builder.PushStackingContext(wr::ToLayoutRect(pipeline->mScBounds), - nullptr, - nullptr, - &opacity, - pipeline->mScTransform.IsIdentity() ? nullptr : &pipeline->mScTransform, - wr::TransformStyle::Flat, - nullptr, - pipeline->mMixBlendMode, - nsTArray(), - true, - // This is fine to do unconditionally because we only push images here. - wr::GlyphRasterSpace::Screen()); + Maybe referenceFrameId = builder.PushStackingContext( + wr::ToLayoutRect(pipeline->mScBounds), + nullptr, + nullptr, + &opacity, + pipeline->mScTransform.IsIdentity() ? nullptr : &pipeline->mScTransform, + wr::TransformStyle::Flat, + nullptr, + pipeline->mMixBlendMode, + nsTArray(), + true, + // This is fine to do unconditionally because we only push images here. + wr::GlyphRasterSpace::Screen()); if (pipeline->mCurrentTexture && !keys.IsEmpty()) { LayoutDeviceRect rect(0, 0, pipeline->mCurrentTexture->GetSize().width, pipeline->mCurrentTexture->GetSize().height); @@ -358,7 +359,7 @@ AsyncImagePipelineManager::ApplyAsyncImages(wr::TransactionBuilder& aTxn) } } - builder.PopStackingContext(); + builder.PopStackingContext(referenceFrameId.isSome()); wr::BuiltDisplayList dl; wr::LayoutSize builderContentSize; diff --git a/gfx/layers/wr/StackingContextHelper.cpp b/gfx/layers/wr/StackingContextHelper.cpp index 45615be649c0..35653335bd42 100644 --- a/gfx/layers/wr/StackingContextHelper.cpp +++ b/gfx/layers/wr/StackingContextHelper.cpp @@ -85,7 +85,7 @@ StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParen StackingContextHelper::~StackingContextHelper() { if (mBuilder) { - mBuilder->PopStackingContext(); + mBuilder->PopStackingContext(mReferenceFrameId.isSome()); } } diff --git a/gfx/webrender_bindings/WebRenderAPI.cpp b/gfx/webrender_bindings/WebRenderAPI.cpp index 933acd85c5d7..fa028e74d2d5 100644 --- a/gfx/webrender_bindings/WebRenderAPI.cpp +++ b/gfx/webrender_bindings/WebRenderAPI.cpp @@ -786,10 +786,10 @@ DisplayListBuilder::PushStackingContext(const wr::LayoutRect& aBounds, } void -DisplayListBuilder::PopStackingContext() +DisplayListBuilder::PopStackingContext(bool aIsReferenceFrame) { WRDL_LOG("PopStackingContext\n", mWrState); - wr_dp_pop_stacking_context(mWrState); + wr_dp_pop_stacking_context(mWrState, aIsReferenceFrame); } wr::WrClipChainId diff --git a/gfx/webrender_bindings/WebRenderAPI.h b/gfx/webrender_bindings/WebRenderAPI.h index 55f081a2fbe0..668f6ddf7773 100644 --- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -290,7 +290,7 @@ public: const nsTArray& aFilters, bool aIsBackfaceVisible, const wr::GlyphRasterSpace& aRasterSpace); - void PopStackingContext(); + void PopStackingContext(bool aIsReferenceFrame); wr::WrClipChainId DefineClipChain(const Maybe& aParent, const nsTArray& aClips); diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index ec331aac6d63..222c54d79d5e 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -1661,32 +1661,47 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState, }; let mut prim_info = LayoutPrimitiveInfo::new(bounds); + + *out_is_reference_frame = transform_binding.is_some() || perspective.is_some(); + if *out_is_reference_frame { + let ref_frame_id = state.frame_builder + .dl_builder + .push_reference_frame(&prim_info, transform_binding, perspective); + match ref_frame_id { + ClipId::Clip(id, pipeline_id) => { + assert!(pipeline_id == state.pipeline_id); + *out_reference_frame_id = id; + }, + _ => panic!("Pushing a reference frame must produce a ClipId::Clip"), + } + + prim_info.rect.origin = LayoutPoint::zero(); + prim_info.clip_rect.origin = LayoutPoint::zero(); + state.frame_builder.dl_builder.push_clip_id(ref_frame_id); + } + prim_info.is_backface_visible = is_backface_visible; prim_info.tag = state.current_tag; - let ref_frame_id = state.frame_builder + state.frame_builder .dl_builder .push_stacking_context(&prim_info, clip_node_id, - transform_binding, transform_style, - perspective, mix_blend_mode, filters, glyph_raster_space); - if let Some(ClipId::Clip(id, pipeline_id)) = ref_frame_id { - assert!(pipeline_id == state.pipeline_id); - *out_is_reference_frame = true; - *out_reference_frame_id = id; - } else { - *out_is_reference_frame = false; - } } #[no_mangle] -pub extern "C" fn wr_dp_pop_stacking_context(state: &mut WrState) { +pub extern "C" fn wr_dp_pop_stacking_context(state: &mut WrState, + is_reference_frame: bool) { debug_assert!(unsafe { !is_in_render_thread() }); state.frame_builder.dl_builder.pop_stacking_context(); + if is_reference_frame { + state.frame_builder.dl_builder.pop_clip_id(); + state.frame_builder.dl_builder.pop_reference_frame(); + } } #[no_mangle] diff --git a/gfx/webrender_bindings/webrender_ffi_generated.h b/gfx/webrender_bindings/webrender_ffi_generated.h index 5b0ad02ced58..a58eb0f0811f 100644 --- a/gfx/webrender_bindings/webrender_ffi_generated.h +++ b/gfx/webrender_bindings/webrender_ffi_generated.h @@ -1145,7 +1145,8 @@ void wr_dp_pop_scroll_layer(WrState *aState) WR_FUNC; WR_INLINE -void wr_dp_pop_stacking_context(WrState *aState) +void wr_dp_pop_stacking_context(WrState *aState, + bool aIsReferenceFrame) WR_FUNC; WR_INLINE