Closed Bug 1805209 Opened 3 years ago Closed 3 years ago

Crash during WR scene building when using WebGPU

Categories

(Core :: Graphics: WebGPU, defect, P1)

defect

Tracking

()

RESOLVED FIXED
110 Branch
Tracking Status
firefox110 --- fixed

People

(Reporter: nical, Assigned: sotaro)

References

Details

Attachments

(1 file)

    frame #9: 0x000000011b53d95c XUL`core::panicking::panic::h5713e7735cef5fa8 at panicking.rs:48:5 [opt]
    frame #10: 0x000000011a63a65c XUL`webrender::scene_building::SceneBuilder::build_all::h3791bbca4e6b32ba at scene_building.rs:1084:17 [opt]
    frame #11: 0x000000011a63a644 XUL`webrender::scene_building::SceneBuilder::build_all::h3791bbca4e6b32ba(self=<unavailable>, root_pipeline=<unavailable>) at scene_building.rs:869:50 [opt]
    frame #12: 0x000000011a6374fc XUL`webrender::scene_building::SceneBuilder::build::h52fafe1e57b443de(scene=<unavailable>, fonts=SharedFontResources @ 0x0000000173a142b0, view=0x000000013f051d40, frame_builder_config=0x0000000173a16968, interners=0x000000013f0513e8, spatial_tree=0x000000013f051ca0, stats=0x000000013f051c68) at scene_building.rs:592:9 [opt]
    frame #13: 0x000000011a5e3e90 XUL`webrender::scene_builder_thread::SceneBuilderThread::process_transaction::h9fcd3c1dc5d2f709(self=0x0000000173a16928, txn=<unavailable>) at scene_builder_thread.rs:597:25 [opt]
    frame #14: 0x000000011a7ec0a4 XUL`_$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::h6acc4f4b6e1d2a59 [inlined] webrender::scene_builder_thread::SceneBuilderThread::run::_$u7b$$u7b$closure$u7d$$u7d$::h802df614991915d1(txn=0x00000001275bfb50) at scene_builder_thread.rs:314:36 [opt]
    frame #15: 0x000000011a7ec058 XUL`_$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::h6acc4f4b6e1d2a59 [inlined] core::iter::adapters::map::map_try_fold::_$u7b$$u7b$closure$u7d$$u7d$::hd31b8e8d587a98b4(acc=InPlaceDrop<alloc::boxed::Box<webrender::scene_builder_thread::BuiltTransaction, alloc::alloc::Global>> @ 0x0000600002bb0e70, elt=0x00000001275bfb50) at map.rs:91:28 [opt]
    frame #16: 0x000000011a7ec058 XUL`_$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::h6acc4f4b6e1d2a59 at iterator.rs:2238:21 [opt]
    frame #17: 0x000000011a7ec03c XUL`_$LT$core..iter..adapters..map..Map$LT$I$C$F$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$::try_fold::h6acc4f4b6e1d2a59(self=0x0000000173a15d80, init=InPlaceDrop<alloc::boxed::Box<webrender::scene_builder_thread::BuiltTransaction, alloc::alloc::Global>> @ 0x0000600002bb0e70, g=<unavailable>) at map.rs:117:9 [opt]
    frame #18: 0x000000011a5d5ed0 XUL`alloc::vec::in_place_collect::_$LT$impl$u20$alloc..vec..spec_from_iter..SpecFromIter$LT$T$C$I$GT$$u20$for$u20$alloc..vec..Vec$LT$T$GT$$GT$::from_iter::h349d858cf48103cd at in_place_collect.rs:251:13 [opt]
    frame #19: 0x000000011a5d5eb4 XUL`alloc::vec::in_place_collect::_$LT$impl$u20$alloc..vec..spec_from_iter..SpecFromIter$LT$T$C$I$GT$$u20$for$u20$alloc..vec..Vec$LT$T$GT$$GT$::from_iter::h349d858cf48103cd(iterator=Map<alloc::vec::into_iter::IntoIter<alloc::boxed::Box<webrender::render_api::TransactionMsg, alloc::alloc::Global>, alloc::alloc::Global>, webrender::scene_builder_thread::{impl#2}::run::{closure_env#0}> @ 0x0000000173a15d80) at in_place_collect.rs:178:19 [opt]
    frame #20: 0x000000011a5e20d0 XUL`webrender::scene_builder_thread::SceneBuilderThread::run::h6316ff879f26e28d [inlined] _$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$core..iter..traits..collect..FromIterator$LT$T$GT$$GT$::from_iter::hf796586e92188c75(iter=<unavailable>) at mod.rs:2649:9 [opt]
    frame #21: 0x000000011a5e20a8 XUL`webrender::scene_builder_thread::SceneBuilderThread::run::h6316ff879f26e28d [inlined] core::iter::traits::iterator::Iterator::collect::heaa2617
   1081	        let pipeline = match self.scene.pipelines.get(&iframe_pipeline_id) {
   1082	            Some(pipeline) => pipeline,
   1083	            None => {
-> 1084	                debug_assert!(info.ignore_missing_pipeline);
   1085	                return None
   1086	            },
   1087	        };

The problem happens because AddPipelineIdForCompositable does not have a compositable host, presumably because the compositor runnable that is scheduled by webgpu's present callback is expected to have happened before that point but end up happening after.

Here is some logging of the problem happening:

 - (CT) DL builder :: PushIFramePipelineId(22, 29)
 - (CP) AddPipelineIdForCompositable PipelineId(22, 29)
[Parent 30509, Compositor] WARNING: 'i == sCompositables.end()', file /Users/nical/dev/mozilla/unified/gfx/layers/ipc/CompositableInProcessManager.cpp:56
   !! AddPipelineIdForCompositable missing compositable host!  <-- failing here.
 - (CP) AsyncImagePipelineManager::UpdateAsyncImagePipeline PipelineId(22, 29)
   !! missing pipeline!
 - (CP) send scene txn lowp:true
 - (AC) RecvSwapChainPresent
 - (AC) PresentCallback
 - (CP) send scene txn lowp:false
 - (CP) PresentCallback compositor runnable <-- presumably the texture host is set here
 - (SB) push iframe PipelineId(22, 29)
Hit MOZ_CRASH(assertion failed: info.ignore_missing_pipeline) at gfx/wr/webrender/src/scene_building.rs:1085

CP: compositor (parent) thread
AC: async canvas thread
SB: scene builder thread
CT: content thread

I found that it was easier to reproduce the issue consistently with stress -c 16 running on the background.

The compositable host that is missing in WRBP::AddPipelineIdForCompositable is added a too late (when the timing is wrong) by CompositableInProcessManager::Add which is called in WebGPUParent::RecvDeviceCreateSwapChain.

so the two timelines are:

  • (content thread) Device::InitSwapChain [A]
  • (canvas thread) WebGPUParent::RecvDeviceCreateSwapChain
    • (canvas thread) CompositableInProcessManager::Add [B]

and

  • (content thread) WebRenderInProcessImageData::CreateWebRenderCommands
    • (content thread) WebRenderBridgeChild::AddPipelineIdForCompositable [C]
  • (content thread) WebRenderBridgeChild::SendSetDisplayList
  • (composior thread) WebRenderBridgeParent::AddPipelineIdForCompositable
    • [D] crash! could not find the compositable host that is set in [B]

basically the code expects the order to be "[A] [B] [C] [D]". [A] and [B] happen in the right order on the content thread but since [C] and [D] are on different threads, their order is not guaranteed.

I haven't seen the mechanism for ensuring that the canvas render thread's work completes before certain points of the the compositor thread. Presumably there is one otherwise I'm not sure how any of the canvas render thread stuff could work reliably. That's probably what we need to use here.

It seems that we could address the problem by using WebRenderCanvasData with remote texture like oop WebGL.
ImageClient is created in content process and WebRenderImageHost is created in host side. Then WebRenderImageHost::UseRemoteTexture() set remote texture to WebRenderImageHost.

Assignee: nobody → sotaro.ikeda.g
Status: NEW → ASSIGNED

Thanks Sotaro!

Priority: P3 → P1

At the moment, this is the only defect blocking WebGPU from attaining milestone 1, so I have increased the Priority.

Attachment #9308657 - Attachment description: WIP: Bug 1805209 - Use RemoteTexture for WebGPU → Bug 1805209 - Use RemoteTexture for WebGPU
Pushed by sikeda.birchill@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/c54999e4dd7f Use RemoteTexture for WebGPU r=gfx-reviewers,lsalzman
Status: ASSIGNED → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → 110 Branch
Regressions: 1814533
See Also: → 1843891
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: