mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
compositor: Wait for both Script and the Constellation when shutting down Pipelines (#37505)
Previously, the Constellation would immediately ask the Compositor to shut down a pipeline, even before the ScriptThread finished shutting it down. This meant that the Compositor might remove a Pipeline and then re-add it if the ScriptThread sent a Pipeline-related message (such as a new display list) in the meantime. This change makes it so that the Compositor waits for both the Constellation and the ScriptThread to finish shutting down a Pipeline before removing its data. In addition, the Constellation no longer synchronously waits on the Compositor when shutting down Pipelines. This was important when the Compositor would talk to the ScriptThread directly, but isn't necessary any longer. Testing: This is very hard to test, because it depends on the creation and destruction of many iframes and the particular timing of of all the messaging between Servo bits. That said, this was tested manually by observing the completion of Speedometer 2.1. Fixes: #37458. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
1bd8f38810
commit
c0970ea655
8 changed files with 112 additions and 69 deletions
|
@ -20,7 +20,8 @@ use compositing_traits::display_list::{
|
|||
};
|
||||
use compositing_traits::rendering_context::RenderingContext;
|
||||
use compositing_traits::{
|
||||
CompositionPipeline, CompositorMsg, ImageUpdate, SendableFrameTree, WebViewTrait,
|
||||
CompositionPipeline, CompositorMsg, ImageUpdate, PipelineExitSource, SendableFrameTree,
|
||||
WebViewTrait,
|
||||
};
|
||||
use constellation_traits::{EmbedderToConstellationMessage, PaintMetricEvent};
|
||||
use crossbeam_channel::{Receiver, Sender};
|
||||
|
@ -226,6 +227,10 @@ pub(crate) struct PipelineDetails {
|
|||
|
||||
/// The paint metric status of the first contentful paint.
|
||||
pub first_contentful_paint_metric: PaintMetricState,
|
||||
|
||||
/// Which parts of Servo have reported that this `Pipeline` has exited. Only when all
|
||||
/// have done so will it be discarded.
|
||||
pub exited: PipelineExitSource,
|
||||
}
|
||||
|
||||
impl PipelineDetails {
|
||||
|
@ -255,6 +260,7 @@ impl PipelineDetails {
|
|||
scroll_tree: ScrollTree::default(),
|
||||
first_paint_metric: PaintMetricState::Waiting,
|
||||
first_contentful_paint_metric: PaintMetricState::Waiting,
|
||||
exited: PipelineExitSource::empty(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -604,15 +610,14 @@ impl IOCompositor {
|
|||
}
|
||||
},
|
||||
|
||||
CompositorMsg::PipelineExited(webview_id, pipeline_id, sender) => {
|
||||
CompositorMsg::PipelineExited(webview_id, pipeline_id, pipeline_exit_source) => {
|
||||
debug!(
|
||||
"Compositor got pipeline exited: {:?} {:?}",
|
||||
webview_id, pipeline_id
|
||||
);
|
||||
if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) {
|
||||
webview_renderer.remove_pipeline(pipeline_id);
|
||||
webview_renderer.pipeline_exited(pipeline_id, pipeline_exit_source);
|
||||
}
|
||||
let _ = sender.send(());
|
||||
},
|
||||
|
||||
CompositorMsg::NewWebRenderFrameReady(_document_id, recomposite_needed) => {
|
||||
|
@ -987,15 +992,14 @@ impl IOCompositor {
|
|||
/// compositor no longer does any WebRender frame generation.
|
||||
fn handle_browser_message_while_shutting_down(&mut self, msg: CompositorMsg) {
|
||||
match msg {
|
||||
CompositorMsg::PipelineExited(webview_id, pipeline_id, sender) => {
|
||||
CompositorMsg::PipelineExited(webview_id, pipeline_id, pipeline_exit_source) => {
|
||||
debug!(
|
||||
"Compositor got pipeline exited: {:?} {:?}",
|
||||
webview_id, pipeline_id
|
||||
);
|
||||
if let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) {
|
||||
webview_renderer.remove_pipeline(pipeline_id);
|
||||
webview_renderer.pipeline_exited(pipeline_id, pipeline_exit_source);
|
||||
}
|
||||
let _ = sender.send(());
|
||||
},
|
||||
CompositorMsg::GenerateImageKey(sender) => {
|
||||
let _ = sender.send(self.global.borrow().webrender_api.generate_image_key());
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::hash_map::Keys;
|
||||
use std::collections::hash_map::{Entry, Keys};
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::rc::Rc;
|
||||
|
||||
|
@ -12,7 +12,7 @@ use compositing_traits::display_list::ScrollType;
|
|||
use compositing_traits::viewport_description::{
|
||||
DEFAULT_ZOOM, MAX_ZOOM, MIN_ZOOM, ViewportDescription,
|
||||
};
|
||||
use compositing_traits::{SendableFrameTree, WebViewTrait};
|
||||
use compositing_traits::{PipelineExitSource, SendableFrameTree, WebViewTrait};
|
||||
use constellation_traits::{EmbedderToConstellationMessage, WindowSizeType};
|
||||
use embedder_traits::{
|
||||
AnimationState, CompositorHitTestResult, InputEvent, MouseButton, MouseButtonAction,
|
||||
|
@ -175,12 +175,26 @@ impl WebViewRenderer {
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn remove_pipeline(&mut self, pipeline_id: PipelineId) {
|
||||
pub(crate) fn pipeline_exited(&mut self, pipeline_id: PipelineId, source: PipelineExitSource) {
|
||||
let pipeline = self.pipelines.entry(pipeline_id);
|
||||
let Entry::Occupied(mut pipeline) = pipeline else {
|
||||
return;
|
||||
};
|
||||
|
||||
pipeline.get_mut().exited.insert(source);
|
||||
|
||||
// Do not remove pipeline details until both the Constellation and Script have
|
||||
// finished processing the pipeline shutdown. This prevents any followup messges
|
||||
// from re-adding the pipeline details and creating a zombie.
|
||||
if !pipeline.get().exited.is_all() {
|
||||
return;
|
||||
}
|
||||
|
||||
pipeline.remove_entry();
|
||||
self.global
|
||||
.borrow_mut()
|
||||
.pipeline_to_webview_map
|
||||
.remove(&pipeline_id);
|
||||
self.pipelines.remove(&pipeline_id);
|
||||
}
|
||||
|
||||
pub(crate) fn set_frame_tree(&mut self, frame_tree: &SendableFrameTree) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue