Bug 1733030 - Remove preserve_frame_state functionality r=gfx-reviewers,nical
authorGlenn Watson <git@intuitionlibrary.com>
Mon, 04 Oct 2021 20:14:04 +0000
changeset 594509 9fe019039481c22a1766f0077e42e3ecc613c006
parent 594508 310926b78a767f1ced08aa632eb50baea9d14889
child 594510 94ec92a5e99f7190d14804ae54fc3dc9a6dedcca
push id150834
push usergwatson@mozilla.com
push dateMon, 04 Oct 2021 20:16:25 +0000
treeherderautoland@9fe019039481 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgfx-reviewers, nical
bugs1733030
milestone94.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1733030 - Remove preserve_frame_state functionality r=gfx-reviewers,nical It's not needed by Gecko, and complicates work in progress to retain the spatial tree across display lists. Differential Revision: https://phabricator.services.mozilla.com/D126863
gfx/webrender_bindings/src/bindings.rs
gfx/wr/example-compositor/compositor/src/main.rs
gfx/wr/examples/common/boilerplate.rs
gfx/wr/examples/document.rs
gfx/wr/examples/iframe.rs
gfx/wr/examples/multiwindow.rs
gfx/wr/webrender/src/render_api.rs
gfx/wr/webrender/src/render_backend.rs
gfx/wr/webrender/src/scene_builder_thread.rs
gfx/wr/webrender/src/spatial_tree.rs
gfx/wr/wrench/src/rawtest.rs
gfx/wr/wrench/src/wrench.rs
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -1850,30 +1850,25 @@ pub extern "C" fn wr_transaction_set_dis
     pipeline_id: WrPipelineId,
     dl_descriptor: BuiltDisplayListDescriptor,
     dl_items_data: &mut WrVecU8,
     dl_cache_data: &mut WrVecU8,
     dl_spatial_tree_data: &mut WrVecU8,
 ) {
     let color = if background.a == 0.0 { None } else { Some(background) };
 
-    // See the documentation of set_display_list in api.rs. I don't think
-    // it makes a difference in gecko at the moment(until APZ is figured out)
-    // but I suppose it is a good default.
-    let preserve_frame_state = true;
-
     let payload = DisplayListPayload {
         items_data: dl_items_data.flush_into_vec(),
         cache_data: dl_cache_data.flush_into_vec(),
         spatial_tree: dl_spatial_tree_data.flush_into_vec(),
     };
 
     let dl = BuiltDisplayList::from_data(payload, dl_descriptor);
 
-    txn.set_display_list(epoch, color, viewport_size, (pipeline_id, dl), preserve_frame_state);
+    txn.set_display_list(epoch, color, viewport_size, (pipeline_id, dl));
 }
 
 #[no_mangle]
 pub extern "C" fn wr_transaction_set_document_view(txn: &mut Transaction, doc_rect: &DeviceIntRect) {
     txn.set_document_view(*doc_rect);
 }
 
 #[no_mangle]
@@ -2147,26 +2142,24 @@ pub extern "C" fn wr_api_send_transactio
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn wr_transaction_clear_display_list(
     txn: &mut Transaction,
     epoch: WrEpoch,
     pipeline_id: WrPipelineId,
 ) {
-    let preserve_frame_state = true;
     let mut frame_builder = WebRenderFrameBuilder::new(pipeline_id);
     frame_builder.dl_builder.begin();
 
     txn.set_display_list(
         epoch,
         None,
         LayoutSize::new(0.0, 0.0),
         frame_builder.dl_builder.end(),
-        preserve_frame_state,
     );
 }
 
 #[no_mangle]
 pub extern "C" fn wr_api_send_external_event(dh: &mut DocumentHandle, evt: usize) {
     assert!(unsafe { !is_in_render_thread() });
 
     dh.api.send_external_event(ExternalEvent::from_raw(evt));
--- a/gfx/wr/example-compositor/compositor/src/main.rs
+++ b/gfx/wr/example-compositor/compositor/src/main.rs
@@ -479,17 +479,16 @@ fn main() {
             inv_mode,
         );
 
         txn.set_display_list(
             current_epoch,
             None,
             layout_size,
             root_builder.end(),
-            true,
         );
     }
 
     txn.generate_frame(0);
     api.send_transaction(document_id, txn);
 
     // Tick the compositor (in this sample, we don't block on UI events)
     while compositor::tick(window) {
@@ -518,17 +517,16 @@ fn main() {
                         inv_mode,
                     );
 
                     txn.set_display_list(
                         current_epoch,
                         None,
                         layout_size,
                         root_builder.end(),
-                        true,
                     );
                 }
                 Invalidations::Scrolling => {
                     let d = 0.5 - 0.5 * (2.0 * f32::consts::PI * 5.0 * time).cos();
                     txn.scroll_node_with_id(
                         LayoutPoint::new(0.0, (d * 100.0).round()),
                         scroll_id,
                         ScrollClamping::NoClamping,
--- a/gfx/wr/examples/common/boilerplate.rs
+++ b/gfx/wr/examples/common/boilerplate.rs
@@ -207,17 +207,16 @@ pub fn main_wrapper<E: Example>(
         pipeline_id,
         document_id,
     );
     txn.set_display_list(
         epoch,
         Some(ColorF::new(0.3, 0.0, 0.0, 1.0)),
         layout_size,
         builder.end(),
-        true,
     );
     txn.set_root_pipeline(pipeline_id);
     txn.generate_frame(0);
     api.send_transaction(document_id, txn);
 
     println!("Entering event loop");
     events_loop.run_forever(|global_event| {
         let mut txn = Transaction::new();
@@ -298,17 +297,16 @@ pub fn main_wrapper<E: Example>(
                 pipeline_id,
                 document_id,
             );
             txn.set_display_list(
                 epoch,
                 Some(ColorF::new(0.3, 0.0, 0.0, 1.0)),
                 layout_size,
                 builder.end(),
-                true,
             );
             txn.generate_frame(0);
         }
         api.send_transaction(document_id, txn);
 
         renderer.update();
         renderer.render(device_size, 0).unwrap();
         let _ = renderer.flush_pipeline_info();
--- a/gfx/wr/examples/document.rs
+++ b/gfx/wr/examples/document.rs
@@ -118,17 +118,16 @@ impl Example for App {
             builder.pop_stacking_context();
 
             let mut txn = Transaction::new();
             txn.set_display_list(
                 Epoch(0),
                 None,
                 doc.content_rect.size(),
                 builder.end(),
-                true,
             );
             txn.generate_frame(0);
             api.send_transaction(doc.id, txn);
         }
     }
 }
 
 fn main() {
--- a/gfx/wr/examples/iframe.rs
+++ b/gfx/wr/examples/iframe.rs
@@ -55,17 +55,16 @@ impl Example for App {
         sub_builder.pop_stacking_context();
 
         let mut txn = Transaction::new();
         txn.set_display_list(
             Epoch(0),
             None,
             sub_bounds.size(),
             sub_builder.end(),
-            true,
         );
         api.send_transaction(document_id, txn);
 
         space_and_clip.spatial_id = builder.push_reference_frame(
             sub_bounds.min,
             space_and_clip.spatial_id,
             TransformStyle::Flat,
             PropertyBinding::Binding(PropertyBindingKey::new(42), LayoutTransform::identity()),
--- a/gfx/wr/examples/multiwindow.rs
+++ b/gfx/wr/examples/multiwindow.rs
@@ -277,17 +277,16 @@ impl Window {
 
         builder.pop_stacking_context();
 
         txn.set_display_list(
             self.epoch,
             None,
             layout_size,
             builder.end(),
-            true,
         );
         txn.set_root_pipeline(self.pipeline_id);
         txn.generate_frame(0);
         api.send_transaction(self.document_id, txn);
 
         renderer.update();
         renderer.render(device_size, 0).unwrap();
         context.swap_buffers().ok();
--- a/gfx/wr/webrender/src/render_api.rs
+++ b/gfx/wr/webrender/src/render_api.rs
@@ -264,36 +264,31 @@ impl Transaction {
     ///
     /// Arguments:
     ///
     /// * `epoch`: The unique Frame ID, monotonically increasing.
     /// * `background`: The background color of this pipeline.
     /// * `viewport_size`: The size of the viewport for this frame.
     /// * `pipeline_id`: The ID of the pipeline that is supplying this display list.
     /// * `display_list`: The root Display list used in this frame.
-    /// * `preserve_frame_state`: If a previous frame exists which matches this pipeline
-    ///                           id, this setting determines if frame state (such as scrolling
-    ///                           position) should be preserved for this new display list.
     pub fn set_display_list(
         &mut self,
         epoch: Epoch,
         background: Option<ColorF>,
         viewport_size: LayoutSize,
         (pipeline_id, mut display_list): (PipelineId, BuiltDisplayList),
-        preserve_frame_state: bool,
     ) {
         display_list.set_send_time_ns(precise_time_ns());
         self.scene_ops.push(
             SceneMsg::SetDisplayList {
                 display_list,
                 epoch,
                 pipeline_id,
                 background,
                 viewport_size,
-                preserve_frame_state,
             }
         );
     }
 
     /// Add a set of persistent resource updates to apply as part of this transaction.
     pub fn update_resources(&mut self, mut resources: Vec<ResourceUpdate>) {
         self.resource_updates.append(&mut resources);
     }
@@ -771,18 +766,16 @@ pub enum SceneMsg {
         ///
         epoch: Epoch,
         ///
         pipeline_id: PipelineId,
         ///
         background: Option<ColorF>,
         ///
         viewport_size: LayoutSize,
-        ///
-        preserve_frame_state: bool,
     },
     ///
     SetDocumentView {
         ///
         device_rect: DeviceIntRect,
     },
     /// Set the current quality / performance configuration for this document.
     SetQualitySettings {
--- a/gfx/wr/webrender/src/render_backend.rs
+++ b/gfx/wr/webrender/src/render_backend.rs
@@ -574,20 +574,18 @@ impl Document {
         self.hit_tester_is_valid = false;
 
         self.update_tile_caches_for_new_scene(
             mem::replace(&mut built_scene.tile_cache_config.tile_caches, FastHashMap::default()),
             tile_caches,
             resource_cache,
         );
 
-        let old_scrolling_states = self.scene.spatial_tree.drain();
         self.scene = built_scene;
         self.scratch.recycle(recycler);
-        self.scene.spatial_tree.finalize_and_apply_pending_scroll_offsets(old_scrolling_states);
     }
 }
 
 struct DocumentOps {
     scroll: bool,
 }
 
 impl DocumentOps {
@@ -826,22 +824,16 @@ impl RenderBackend {
                     tx.send(SceneSwapResult::Complete(resume_tx)).unwrap();
                     // Block until the post-swap hook has completed on
                     // the scene builder thread. We need to do this before
                     // we can sample from the sampler hook which might happen
                     // 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);
-                }
-
                 self.resource_cache.add_rasterized_blob_images(
                     txn.rasterized_blobs.take(),
                     &mut doc.profile,
                 );
 
             } else {
                 // The document was removed while we were building it, skip it.
                 // TODO: we might want to just ensure that removed documents are
--- a/gfx/wr/webrender/src/scene_builder_thread.rs
+++ b/gfx/wr/webrender/src/scene_builder_thread.rs
@@ -60,17 +60,16 @@ pub struct BuiltTransaction {
     pub rasterized_blobs: Vec<(BlobImageRequest, BlobImageResult)>,
     pub blob_rasterizer: Option<Box<dyn AsyncBlobImageRasterizer>>,
     pub frame_ops: Vec<FrameMsg>,
     pub removed_pipelines: Vec<(PipelineId, DocumentId)>,
     pub notifications: Vec<NotificationRequest>,
     pub interner_updates: Option<InternerUpdates>,
     pub render_frame: bool,
     pub invalidate_rendered_frame: bool,
-    pub discard_frame_state_for_pipelines: Vec<PipelineId>,
     pub profile: TransactionProfile,
     pub frame_stats: FullFrameStats,
 }
 
 #[cfg(feature = "replay")]
 pub struct LoadScene {
     pub document_id: DocumentId,
     pub scene: Scene,
@@ -446,17 +445,16 @@ impl SceneBuilderThread {
                 invalidate_rendered_frame: false,
                 built_scene,
                 view: item.view,
                 resource_updates: Vec::new(),
                 rasterized_blobs: Vec::new(),
                 blob_rasterizer: None,
                 frame_ops: Vec::new(),
                 removed_pipelines: Vec::new(),
-                discard_frame_state_for_pipelines: Vec::new(),
                 notifications: Vec::new(),
                 interner_updates,
                 profile: TransactionProfile::new(),
                 frame_stats: FullFrameStats::default(),
             })];
 
             self.forward_built_transactions(txns);
         }
@@ -499,17 +497,16 @@ impl SceneBuilderThread {
         }
 
         let doc = self.documents.get_mut(&txn.document_id).unwrap();
         let scene = &mut doc.scene;
 
         let mut profile = txn.profile.take();
 
         let scene_build_start = precise_time_ns();
-        let mut discard_frame_state_for_pipelines = Vec::new();
         let mut removed_pipelines = Vec::new();
         let mut rebuild_scene = false;
         let mut frame_stats = FullFrameStats::default();
 
         for message in txn.scene_ops.drain(..) {
             match message {
                 SceneMsg::UpdateEpoch(pipeline_id, epoch) => {
                     scene.update_epoch(pipeline_id, epoch);
@@ -521,17 +518,16 @@ impl SceneBuilderThread {
                     doc.view.device_rect = device_rect;
                 }
                 SceneMsg::SetDisplayList {
                     epoch,
                     pipeline_id,
                     background,
                     viewport_size,
                     display_list,
-                    preserve_frame_state,
                 } => {
                     let (builder_start_time_ns, builder_end_time_ns, send_time_ns) =
                       display_list.times();
                     let content_send_time = profiler::ns_to_ms(precise_time_ns() - send_time_ns);
                     let dl_build_time = profiler::ns_to_ms(builder_end_time_ns - builder_start_time_ns);
                     profile.set(profiler::CONTENT_SEND_TIME, content_send_time);
                     profile.set(profiler::DISPLAY_LIST_BUILD_TIME, dl_build_time);
                     profile.set(profiler::DISPLAY_LIST_MEM, profiler::bytes_to_mb(display_list.size_in_bytes()));
@@ -552,20 +548,16 @@ impl SceneBuilderThread {
 
                     scene.set_display_list(
                         pipeline_id,
                         epoch,
                         display_list,
                         background,
                         viewport_size,
                     );
-
-                    if !preserve_frame_state {
-                        discard_frame_state_for_pipelines.push(pipeline_id);
-                    }
                 }
                 SceneMsg::SetRootPipeline(pipeline_id) => {
                     if scene.root_pipeline_id != Some(pipeline_id) {
                         rebuild_scene = true;
                         scene.set_root_pipeline_id(pipeline_id);
                     }
                 }
                 SceneMsg::RemovePipeline(pipeline_id) => {
@@ -633,17 +625,16 @@ impl SceneBuilderThread {
             invalidate_rendered_frame: txn.invalidate_rendered_frame,
             built_scene,
             view: doc.view,
             rasterized_blobs: txn.rasterized_blobs,
             resource_updates: txn.resource_updates,
             blob_rasterizer: txn.blob_rasterizer,
             frame_ops: txn.frame_ops,
             removed_pipelines,
-            discard_frame_state_for_pipelines,
             notifications: txn.notifications,
             interner_updates,
             profile,
             frame_stats,
         })
     }
 
     /// Send the results of process_transaction back to the render backend.
--- a/gfx/wr/webrender/src/spatial_tree.rs
+++ b/gfx/wr/webrender/src/spatial_tree.rs
@@ -2,27 +2,25 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use api::{ExternalScrollId, PropertyBinding, ReferenceFrameKind, TransformStyle, PropertyBindingId};
 use api::{PipelineId, ScrollClamping, ScrollSensitivity, SpatialTreeItemKey};
 use api::units::*;
 use euclid::Transform3D;
 use crate::gpu_types::TransformPalette;
-use crate::internal_types::{FastHashMap, FastHashSet};
+use crate::internal_types::FastHashSet;
 use crate::print_tree::{PrintableTree, PrintTree, PrintTreePrinter};
 use crate::scene::SceneProperties;
-use crate::spatial_node::{ScrollFrameInfo, SpatialNode, SpatialNodeType, StickyFrameInfo};
+use crate::spatial_node::{SpatialNode, SpatialNodeType, StickyFrameInfo};
 use crate::spatial_node::{SpatialNodeUid, ScrollFrameKind, SceneSpatialNode, SpatialNodeInfo};
 use std::{ops, u32};
 use crate::util::{FastTransform, LayoutToWorldFastTransform, MatrixHelpers, ScaleOffset, scale_factors};
 use smallvec::SmallVec;
 
-pub type ScrollStates = FastHashMap<ExternalScrollId, ScrollFrameInfo>;
-
 /// An id that identifies coordinate systems in the SpatialTree. Each
 /// coordinate system has an id and those ids will be shared when the coordinates
 /// system are the same or are in the same axis-aligned space. This allows
 /// for optimizing mask generation.
 #[derive(Debug, Copy, Clone, PartialEq)]
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 pub struct CoordinateSystemId(pub u32);
@@ -400,22 +398,16 @@ pub struct SpatialTree {
     /// and clips.
     spatial_nodes: Vec<SpatialNode>,
 
     /// A list of transforms that establish new coordinate systems.
     /// Spatial nodes only establish a new coordinate system when
     /// they have a transform that is not a simple 2d translation.
     coord_systems: Vec<CoordinateSystem>,
 
-    pending_scroll_offsets: FastHashMap<ExternalScrollId, (LayoutPoint, ScrollClamping)>,
-
-    /// A set of pipelines which should be discarded the next time this
-    /// tree is drained.
-    pipelines_to_discard: FastHashSet<PipelineId>,
-
     root_reference_frame_index: SpatialNodeIndex,
 
     /// Stack of current state for each parent node while traversing and updating tree
     update_state_stack: Vec<TransformUpdateState>,
 }
 
 #[derive(Clone)]
 pub struct TransformUpdateState {
@@ -539,18 +531,16 @@ impl SpatialTree {
             .map(|node| {
                 SpatialNode::from(node)
             })
             .collect();
 
         SpatialTree {
             spatial_nodes,
             coord_systems: Vec::new(),
-            pending_scroll_offsets: FastHashMap::default(),
-            pipelines_to_discard: FastHashSet::default(),
             root_reference_frame_index: scene.root_reference_frame_index,
             update_state_stack: Vec::new(),
         }
     }
 
     pub fn get_spatial_node(&self, index: SpatialNodeIndex) -> &SpatialNode {
         &self.spatial_nodes[index.0 as usize]
     }
@@ -720,49 +710,28 @@ impl SpatialTree {
         self.get_world_transform_impl(index, TransformScroll::Unscrolled)
     }
 
     /// The root reference frame, which is the true root of the SpatialTree.
     pub fn root_reference_frame_index(&self) -> SpatialNodeIndex {
         self.root_reference_frame_index
     }
 
-    pub fn drain(&mut self) -> ScrollStates {
-        let mut scroll_states = FastHashMap::default();
-        for old_node in &mut self.spatial_nodes.drain(..) {
-            if self.pipelines_to_discard.contains(&old_node.pipeline_id) {
-                continue;
-            }
-
-            match old_node.node_type {
-                SpatialNodeType::ScrollFrame(info) => {
-                    scroll_states.insert(info.external_id, info);
-                }
-                _ => {}
-            }
-        }
-
-        self.coord_systems.clear();
-        self.pipelines_to_discard.clear();
-        scroll_states
-    }
-
     pub fn scroll_node(
         &mut self,
         origin: LayoutPoint,
         id: ExternalScrollId,
         clamp: ScrollClamping
     ) -> bool {
         for node in &mut self.spatial_nodes {
             if node.matches_external_id(id) {
                 return node.set_scroll_origin(&origin, clamp);
             }
         }
 
-        self.pending_scroll_offsets.insert(id, (origin, clamp));
         false
     }
 
     pub fn update_tree(
         &mut self,
         scene_properties: &SceneProperties,
     ) {
         if self.spatial_nodes.is_empty() {
@@ -831,37 +800,16 @@ impl SpatialTree {
         }
     }
 
     pub fn build_transform_palette(&self) -> TransformPalette {
         profile_scope!("build_transform_palette");
         TransformPalette::new(self.spatial_nodes.len())
     }
 
-    pub fn finalize_and_apply_pending_scroll_offsets(&mut self, old_states: ScrollStates) {
-        for node in &mut self.spatial_nodes {
-            let external_id = match node.node_type {
-                SpatialNodeType::ScrollFrame(ScrollFrameInfo { external_id, ..}) => external_id,
-                _ => continue,
-            };
-
-            if let Some(scrolling_state) = old_states.get(&external_id) {
-                node.apply_old_scrolling_state(scrolling_state);
-            }
-
-            if let Some((offset, clamping)) = self.pending_scroll_offsets.remove(&external_id) {
-                node.set_scroll_origin(&offset, clamping);
-            }
-        }
-    }
-
-    pub fn discard_frame_state_for_pipeline(&mut self, pipeline_id: PipelineId) {
-        self.pipelines_to_discard.insert(pipeline_id);
-    }
-
     fn print_node<T: PrintTreePrinter>(
         &self,
         index: SpatialNodeIndex,
         pt: &mut T,
     ) {
         let node = self.get_spatial_node(index);
         match node.node_type {
             SpatialNodeType::StickyFrame(ref sticky_frame_info) => {
--- a/gfx/wr/wrench/src/rawtest.rs
+++ b/gfx/wr/wrench/src/rawtest.rs
@@ -98,17 +98,16 @@ impl<'a> RawtestHarness<'a> {
         let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));
         txn.use_scene_builder_thread();
 
         txn.set_display_list(
             *epoch,
             root_background_color,
             layout_size,
             builder.end(),
-            false,
         );
         epoch.0 += 1;
 
         txn.generate_frame(0);
         self.wrench.api.send_transaction(self.wrench.document_id, txn);
     }
 
     fn make_common_properties(&self, clip_rect: LayoutRect) -> CommonItemProperties {
@@ -1247,17 +1246,16 @@ impl<'a> RawtestHarness<'a> {
 
         let mut txn = Transaction::new();
 
         txn.set_display_list(
             Epoch(0),
             Some(ColorF::new(1.0, 1.0, 1.0, 1.0)),
             layout_size,
             builder.end(),
-            false,
         );
         txn.generate_frame(0);
 
         self.wrench.api.send_transaction(self.wrench.document_id, txn);
 
         let pixels0 = self.render_and_get_pixels(window_rect);
 
         // 2. capture it
@@ -1269,17 +1267,16 @@ impl<'a> RawtestHarness<'a> {
         builder.begin();
 
         let mut txn = Transaction::new();
         txn.set_display_list(
             Epoch(1),
             Some(ColorF::new(1.0, 0.0, 0.0, 1.0)),
             layout_size,
             builder.end(),
-            false,
         );
         self.wrench.api.send_transaction(self.wrench.document_id, txn);
 
         // 4. load the first one
 
         let mut documents = self.wrench.api.load_capture(path.into(), None);
         let captured = documents.swap_remove(0);
 
@@ -1316,17 +1313,16 @@ impl<'a> RawtestHarness<'a> {
 
         let mut txn = Transaction::new();
         txn.set_root_pipeline(self.wrench.root_pipeline_id);
         txn.set_display_list(
             Epoch(1),
             Some(ColorF::new(1.0, 0.0, 0.0, 1.0)),
             layout_size,
             builder.end(),
-            false,
         );
         txn.generate_frame(0);
         self.wrench.api.send_transaction(doc_id, txn);
 
         // Ensure we get a notification from rendering the above, even though
         // there are zero visible pixels
         assert!(self.rx.recv().unwrap() == NotifierEvent::WakeUp { composite_needed: true });
     }
--- a/gfx/wr/wrench/src/wrench.rs
+++ b/gfx/wr/wrench/src/wrench.rs
@@ -568,17 +568,16 @@ impl Wrench {
 
         let mut txn = Transaction::new();
         for display_list in display_lists {
             txn.set_display_list(
                 Epoch(frame_number),
                 root_background_color,
                 self.window_size_f32(),
                 display_list,
-                false,
             );
         }
 
         for (id, offset) in scroll_offsets {
             txn.scroll_node_with_id(*offset, *id, ScrollClamping::NoClamping);
         }
 
         txn.generate_frame(0);