diff --git a/gfx/wr/webrender/src/render_backend.rs b/gfx/wr/webrender/src/render_backend.rs index ee846feb013c..4ce01148bd9e 100644 --- a/gfx/wr/webrender/src/render_backend.rs +++ b/gfx/wr/webrender/src/render_backend.rs @@ -10,7 +10,7 @@ use api::{ApiMsg, ClearCache, DebugCommand, DebugFlags}; use api::{DocumentId, DocumentLayer, ExternalScrollId, FrameMsg, HitTestFlags, HitTestResult}; -use api::{IdNamespace, MemoryReport, PipelineId, RenderNotifier, SceneMsg, ScrollClamping}; +use api::{IdNamespace, MemoryReport, PipelineId, RenderNotifier, ScrollClamping}; use api::{ScrollLocation, TransactionMsg, ResourceUpdate, BlobImageKey}; use api::{NotificationRequest, Checkpoint, QualitySettings}; use api::{ClipIntern, FilterDataIntern, PrimitiveKeyKind}; @@ -1015,6 +1015,12 @@ impl RenderBackend { // in the update_document call below. resume_rx.recv().ok(); } + + for pipeline_id in &txn.discard_frame_state_for_pipelines { + doc.scene + .spatial_tree + .discard_frame_state_for_pipeline(*pipeline_id); + } } else { // The document was removed while we were building it, skip it. // TODO: we might want to just ensure that removed documents are @@ -1346,19 +1352,6 @@ impl RenderBackend { &mut profile_counters.resources, ); - // TODO(nical) I believe this is wrong. We should discard this state when swapping the - // scene after it is built. - for msg in &transaction_msg.scene_ops { - if let SceneMsg::SetDisplayList { preserve_frame_state: false, pipeline_id, .. } = *msg { - self.documents - .get_mut(&document_id) - .unwrap() - .scene - .spatial_tree - .discard_frame_state_for_pipeline(pipeline_id); - } - } - let mut txn = Box::new(Transaction { document_id, blob_rasterizer: None, diff --git a/gfx/wr/webrender/src/scene_builder_thread.rs b/gfx/wr/webrender/src/scene_builder_thread.rs index 1cb375ed0ac8..e1a45f37da69 100644 --- a/gfx/wr/webrender/src/scene_builder_thread.rs +++ b/gfx/wr/webrender/src/scene_builder_thread.rs @@ -102,6 +102,7 @@ pub struct BuiltTransaction { pub scene_build_end_time: u64, pub render_frame: bool, pub invalidate_rendered_frame: bool, + pub discard_frame_state_for_pipelines: Vec, pub timings: Option, } @@ -486,6 +487,7 @@ impl SceneBuilderThread { blob_rasterizer: None, frame_ops: Vec::new(), removed_pipelines: Vec::new(), + discard_frame_state_for_pipelines: Vec::new(), notifications: Vec::new(), scene_build_start_time, scene_build_end_time: precise_time_ns(), @@ -603,6 +605,7 @@ impl SceneBuilderThread { let mut timings = None; + let mut discard_frame_state_for_pipelines = Vec::new(); let mut removed_pipelines = Vec::new(); let rebuild_scene = !txn.scene_ops.is_empty(); for message in txn.scene_ops.drain(..) { @@ -628,7 +631,7 @@ impl SceneBuilderThread { content_size, list_descriptor, list_data, - .. + preserve_frame_state, } => { let built_display_list = BuiltDisplayList::from_data(list_data, list_descriptor); @@ -659,6 +662,10 @@ impl SceneBuilderThread { blob_rasterization_end_time_ns: 0, display_list_len, }); + + if !preserve_frame_state { + discard_frame_state_for_pipelines.push(pipeline_id); + } } SceneMsg::SetRootPipeline(pipeline_id) => { scene.set_root_pipeline_id(pipeline_id); @@ -737,6 +744,7 @@ impl SceneBuilderThread { blob_rasterizer: replace(&mut txn.blob_rasterizer, None), frame_ops: replace(&mut txn.frame_ops, Vec::new()), removed_pipelines, + discard_frame_state_for_pipelines, notifications: replace(&mut txn.notifications, Vec::new()), interner_updates, scene_build_start_time,