Bug 1487588. Update webrender to commit 6415faa7f6acd412d4cc6b745cf802204690611c
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 30 Aug 2018 23:47:47 -0400
changeset 491960 d675059c7ee6099c15818f5d08b46610c1c13869
parent 491959 57e362dbff454de4ae08dbeef0bb72d7cbf37e0b
child 491961 930e12a89a4371a2b62c9fef59d6be4eed21914e
push id1815
push userffxbld-merge
push dateMon, 15 Oct 2018 10:40:45 +0000
treeherdermozilla-release@18d4c09e9378 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1487588
milestone63.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 1487588. Update webrender to commit 6415faa7f6acd412d4cc6b745cf802204690611c
gfx/webrender/src/display_list_flattener.rs
gfx/webrender/src/render_backend.rs
gfx/webrender/src/scene_builder.rs
gfx/webrender_api/src/api.rs
gfx/webrender_bindings/revision.txt
gfx/wrench/src/reftest.rs
--- a/gfx/webrender/src/display_list_flattener.rs
+++ b/gfx/webrender/src/display_list_flattener.rs
@@ -727,20 +727,17 @@ impl<'a> DisplayListFlattener<'a> {
 
             // Do nothing; these are dummy items for the display list parser
             SpecificDisplayItem::SetGradientStops => {}
 
             SpecificDisplayItem::PopStackingContext | SpecificDisplayItem::PopReferenceFrame => {
                 unreachable!("Should have returned in parent method.")
             }
             SpecificDisplayItem::PushShadow(shadow) => {
-                let mut prim_info = prim_info.clone();
-                prim_info.rect = LayoutRect::zero();
-                self
-                    .push_shadow(shadow, clip_and_scroll, &prim_info);
+                self.push_shadow(shadow, clip_and_scroll);
             }
             SpecificDisplayItem::PopAllShadows => {
                 self.pop_all_shadows();
             }
         }
         None
     }
 
@@ -1009,17 +1006,17 @@ impl<'a> DisplayListFlattener<'a> {
                 true,
             );
 
             let prim = BrushPrimitive::new_picture(picture);
 
             let prim_index = self.prim_store.add_primitive(
                 &LayoutRect::zero(),
                 &max_clip,
-                is_backface_visible,
+                true,
                 clip_chain_id,
                 spatial_node_index,
                 None,
                 PrimitiveContainer::Brush(prim),
             );
 
             let parent_prim_index = *self.picture_stack.last().unwrap();
 
@@ -1059,17 +1056,17 @@ impl<'a> DisplayListFlattener<'a> {
                 None,
                 true,
             );
 
             let src_prim = BrushPrimitive::new_picture(picture);
             let src_prim_index = self.prim_store.add_primitive(
                 &LayoutRect::zero(),
                 &max_clip,
-                is_backface_visible,
+                true,
                 clip_chain_id,
                 spatial_node_index,
                 None,
                 PrimitiveContainer::Brush(src_prim),
             );
 
             let parent_pic = self.prim_store.get_pic_mut(parent_prim_index);
             parent_prim_index = src_prim_index;
@@ -1090,17 +1087,17 @@ impl<'a> DisplayListFlattener<'a> {
                 true,
             );
 
             let src_prim = BrushPrimitive::new_picture(picture);
 
             let src_prim_index = self.prim_store.add_primitive(
                 &LayoutRect::zero(),
                 &max_clip,
-                is_backface_visible,
+                true,
                 clip_chain_id,
                 spatial_node_index,
                 None,
                 PrimitiveContainer::Brush(src_prim),
             );
 
             let parent_pic = self.prim_store.get_pic_mut(parent_prim_index);
             parent_prim_index = src_prim_index;
@@ -1148,17 +1145,17 @@ impl<'a> DisplayListFlattener<'a> {
 
         // Create a brush primitive that draws this picture.
         let sc_prim = BrushPrimitive::new_picture(picture);
 
         // Add the brush to the parent picture.
         let sc_prim_index = self.prim_store.add_primitive(
             &LayoutRect::zero(),
             &max_clip,
-            is_backface_visible,
+            true,
             clip_chain_id,
             spatial_node_index,
             None,
             PrimitiveContainer::Brush(sc_prim),
         );
 
         let parent_pic = self.prim_store.get_pic_mut(parent_prim_index);
         parent_pic.add_primitive(sc_prim_index);
@@ -1358,17 +1355,16 @@ impl<'a> DisplayListFlattener<'a> {
         self.id_to_index_mapper.map_to_parent_clip_chain(new_node_id, &parent_id);
         node_index
     }
 
     pub fn push_shadow(
         &mut self,
         shadow: Shadow,
         clip_and_scroll: ScrollNodeAndClipChain,
-        info: &LayoutPrimitiveInfo,
     ) {
         let pipeline_id = self.sc_stack.last().unwrap().pipeline_id;
         let max_clip = LayoutRect::max_rect();
 
         // Quote from https://drafts.csswg.org/css-backgrounds-3/#shadow-blur
         // "the image that would be generated by applying to the shadow a
         // Gaussian blur with a standard deviation equal to half the blur radius."
         let std_deviation = shadow.blur_radius * 0.5;
@@ -1392,17 +1388,17 @@ impl<'a> DisplayListFlattener<'a> {
             apply_local_clip_rect,
         );
 
         // Create the primitive to draw the shadow picture into the scene.
         let shadow_prim = BrushPrimitive::new_picture(shadow_pic);
         let shadow_prim_index = self.prim_store.add_primitive(
             &LayoutRect::zero(),
             &max_clip,
-            info.is_backface_visible,
+            true,
             clip_and_scroll.clip_chain_id,
             clip_and_scroll.spatial_node_index,
             None,
             PrimitiveContainer::Brush(shadow_prim),
         );
 
         // Add the shadow primitive. This must be done before pushing this
         // picture on to the shadow stack, to avoid infinite recursion!
--- a/gfx/webrender/src/render_backend.rs
+++ b/gfx/webrender/src/render_backend.rs
@@ -12,17 +12,18 @@ use api::{ScrollLocation, ScrollNodeStat
 use api::channel::{MsgReceiver, Payload};
 #[cfg(feature = "capture")]
 use api::CaptureBits;
 #[cfg(feature = "replay")]
 use api::CapturedDocument;
 use clip_scroll_tree::{SpatialNodeIndex, ClipScrollTree};
 #[cfg(feature = "debugger")]
 use debug_server;
-use display_list_flattener::DisplayListFlattener;
+#[cfg(feature = "replay")]
+use display_list_flattener::build_scene;
 use frame_builder::{FrameBuilder, FrameBuilderConfig};
 use gpu_cache::GpuCache;
 use hit_test::{HitTest, HitTester};
 use internal_types::{DebugOutput, FastHashMap, FastHashSet, RenderedDocument, ResultMsg};
 use profiler::{BackendProfileCounters, IpcProfileCounters, ResourceProfileCounters};
 use record::ApiRecordingReceiver;
 use renderer::{AsyncPropertySampler, PipelineInfo};
 use resource_cache::ResourceCache;
@@ -255,70 +256,16 @@ impl Document {
             }
             FrameMsg::AppendDynamicProperties(property_bindings) => {
                 self.dynamic_properties.add_properties(property_bindings);
                 DocumentOps::nop()
             }
         }
     }
 
-    // TODO: We will probably get rid of this soon and always forward to the scene building thread.
-    fn build_scene(&mut self, resource_cache: &mut ResourceCache, scene_id: u64) {
-        let max_texture_size = resource_cache.max_texture_size();
-
-        if self.view.window_size.width > max_texture_size ||
-           self.view.window_size.height > max_texture_size {
-            error!("ERROR: Invalid window dimensions {}x{}. Please call api.set_window_size()",
-                self.view.window_size.width,
-                self.view.window_size.height,
-            );
-
-            return;
-        }
-
-        let old_builder = self.frame_builder.take().unwrap_or_else(FrameBuilder::empty);
-        let root_pipeline_id = match self.pending.scene.root_pipeline_id {
-            Some(root_pipeline_id) => root_pipeline_id,
-            None => return,
-        };
-
-        if !self.pending.scene.pipelines.contains_key(&root_pipeline_id) {
-            return;
-        }
-
-        // The DisplayListFlattener  re-create the up-to-date current scene's pipeline epoch
-        // map and clip scroll tree from the information in the pending scene.
-        self.current.scene.pipeline_epochs.clear();
-        let old_scrolling_states = self.clip_scroll_tree.drain();
-
-        let frame_builder = DisplayListFlattener::create_frame_builder(
-            old_builder,
-            &self.pending.scene,
-            &mut self.clip_scroll_tree,
-            resource_cache.get_font_instances(),
-            &self.view,
-            &self.output_pipelines,
-            &self.frame_builder_config,
-            &mut self.current.scene,
-            scene_id,
-        );
-
-        self.clip_scroll_tree.finalize_and_apply_pending_scroll_offsets(old_scrolling_states);
-
-        if !self.current.removed_pipelines.is_empty() {
-            warn!("Built the scene several times without rendering it.");
-        }
-
-        self.current.removed_pipelines.extend(self.pending.removed_pipelines.drain(..));
-        self.frame_builder = Some(frame_builder);
-
-        // Advance to the next frame.
-        self.frame_id.0 += 1;
-    }
-
     fn forward_transaction_to_scene_builder(
         &mut self,
         transaction_msg: TransactionMsg,
         blobs_to_rasterize: &[ImageKey],
         document_ops: &DocumentOps,
         document_id: DocumentId,
         scene_id: u64,
         resource_cache: &mut ResourceCache,
@@ -919,19 +866,23 @@ impl RenderBackend {
                     DebugCommand::EnableDualSourceBlending(enable) => {
                         // Set in the config used for any future documents
                         // that are created.
                         self.frame_config
                             .dual_source_blending_is_enabled = enable;
 
                         // Set for any existing documents.
                         for (_, doc) in &mut self.documents {
-                            doc.frame_builder_config .dual_source_blending_is_enabled = enable;
+                            doc.frame_builder_config.dual_source_blending_is_enabled = enable;
                         }
 
+                        self.scene_tx.send(SceneBuilderRequest::SetFrameBuilderConfig(
+                            self.frame_config.clone()
+                        )).unwrap();
+
                         // We don't want to forward this message to the renderer.
                         return true;
                     }
                     DebugCommand::FetchDocuments => {
                         let json = self.get_docs_for_debugger();
                         ResultMsg::DebugOutput(DebugOutput::FetchDocuments(json))
                     }
                     DebugCommand::FetchClipScrollTree => {
@@ -1020,17 +971,17 @@ impl RenderBackend {
                     document_id,
                     scene_msg,
                     *frame_counter,
                     &mut profile_counters.ipc,
                 )
             );
         }
 
-        if transaction_msg.use_scene_builder_thread {
+        if !has_built_scene && (op.build || transaction_msg.use_scene_builder_thread) {
             let scene_id = self.make_unique_scene_id();
             let doc = self.documents.get_mut(&document_id).unwrap();
 
             doc.forward_transaction_to_scene_builder(
                 transaction_msg,
                 blob_requests,
                 &op,
                 document_id,
@@ -1042,25 +993,16 @@ impl RenderBackend {
             return;
         }
 
         self.resource_cache.post_scene_building_update(
             transaction_msg.resource_updates,
             &mut profile_counters.resources,
         );
 
-        if op.build {
-            let scene_id = self.make_unique_scene_id();
-            let doc = self.documents.get_mut(&document_id).unwrap();
-            let _timer = profile_counters.total_time.timer();
-            profile_scope!("build scene");
-
-            doc.build_scene(&mut self.resource_cache, scene_id);
-        }
-
         // If we have a sampler, get more frame ops from it and add them
         // to the transaction. This is a hook to allow the WR user code to
         // fiddle with things after a potentially long scene build, but just
         // before rendering. This is useful for rendering with the latest
         // async transforms.
         if op.render || transaction_msg.generate_frame {
             if let Some(ref sampler) = self.sampler {
                 transaction_msg.frame_ops.append(&mut sampler.sample());
@@ -1109,17 +1051,17 @@ impl RenderBackend {
             let (pending_update, rendered_document) = {
                 let _timer = profile_counters.total_time.timer();
                 let render_start_time = precise_time_ns();
 
                 let rendered_document = doc.render(
                     &mut self.resource_cache,
                     &mut self.gpu_cache,
                     &mut profile_counters.resources,
-                    op.build || has_built_scene,
+                    has_built_scene,
                 );
 
                 debug!("generated frame for document {:?} with {} passes",
                     document_id, rendered_document.frame.passes.len());
 
                 let msg = ResultMsg::UpdateGpuCache(self.gpu_cache.extract_updates());
                 self.result_tx.send(msg).unwrap();
 
@@ -1426,17 +1368,17 @@ impl RenderBackend {
                 current: SceneData {
                     scene: scene.clone(),
                     removed_pipelines: Vec::new(),
                 },
                 pending: SceneData {
                     scene,
                     removed_pipelines: Vec::new(),
                 },
-                view,
+                view: view.clone(),
                 clip_scroll_tree: ClipScrollTree::new(),
                 frame_id: FrameId(0),
                 frame_builder_config: self.frame_config.clone(),
                 frame_builder: Some(FrameBuilder::empty()),
                 output_pipelines: FastHashSet::default(),
                 render_on_scroll: None,
                 dynamic_properties: SceneProperties::new(),
                 hit_tester: None,
@@ -1445,17 +1387,25 @@ impl RenderBackend {
             let frame_name = format!("frame-{}-{}", (id.0).0, id.1);
             let render_doc = match CaptureConfig::deserialize::<Frame, _>(root, frame_name) {
                 Some(frame) => {
                     info!("\tloaded a built frame with {} passes", frame.passes.len());
                     RenderedDocument { frame, is_new_scene: true }
                 }
                 None => {
                     last_scene_id += 1;
-                    doc.build_scene(&mut self.resource_cache, last_scene_id);
+                    let built_scene = build_scene(&self.frame_config, SceneRequest {
+                        scene: doc.pending.scene.clone(),
+                        view,
+                        font_instances: self.resource_cache.get_font_instances(),
+                        output_pipelines: doc.output_pipelines.clone(),
+                        removed_pipelines: Vec::new(),
+                        scene_id: last_scene_id,
+                    });
+                    doc.new_async_scene_ready(built_scene);
                     doc.render(
                         &mut self.resource_cache,
                         &mut self.gpu_cache,
                         &mut profile_counters.resources,
                         true,
                     )
                 }
             };
--- a/gfx/webrender/src/scene_builder.rs
+++ b/gfx/webrender/src/scene_builder.rs
@@ -24,16 +24,17 @@ pub enum SceneBuilderRequest {
         blob_requests: Vec<BlobImageParams>,
         blob_rasterizer: Option<Box<AsyncBlobImageRasterizer>>,
         resource_updates: Vec<ResourceUpdate>,
         frame_ops: Vec<FrameMsg>,
         render: bool,
     },
     WakeUp,
     Flush(MsgSender<()>),
+    SetFrameBuilderConfig(FrameBuilderConfig),
     Stop
 }
 
 // Message from scene builder to render backend.
 pub enum SceneBuilderResult {
     Transaction {
         document_id: DocumentId,
         built_scene: Option<BuiltScene>,
@@ -210,13 +211,16 @@ impl SceneBuilder {
                 }
             }
             SceneBuilderRequest::Stop => {
                 self.tx.send(SceneBuilderResult::Stopped).unwrap();
                 // We don't need to send a WakeUp to api_tx because we only
                 // get the Stop when the RenderBackend loop is exiting.
                 return false;
             }
+            SceneBuilderRequest::SetFrameBuilderConfig(cfg) => {
+                self.config = cfg;
+            }
         }
 
         true
     }
 }
--- a/gfx/webrender_api/src/api.rs
+++ b/gfx/webrender_api/src/api.rs
@@ -60,17 +60,17 @@ pub struct Transaction {
 
 impl Transaction {
     pub fn new() -> Self {
         Transaction {
             scene_ops: Vec::new(),
             frame_ops: Vec::new(),
             resource_updates: Vec::new(),
             payloads: Vec::new(),
-            use_scene_builder_thread: false, // TODO: make this true by default.
+            use_scene_builder_thread: true,
             generate_frame: false,
         }
     }
 
     // TODO: better name?
     pub fn skip_scene_builder(&mut self) {
         self.use_scene_builder_thread = false;
     }
@@ -973,16 +973,20 @@ impl RenderApi {
     /// Save a capture of the current frame state for debugging.
     pub fn save_capture(&self, path: PathBuf, bits: CaptureBits) {
         let msg = ApiMsg::DebugCommand(DebugCommand::SaveCapture(path, bits));
         self.send_message(msg);
     }
 
     /// Load a capture of the current frame state for debugging.
     pub fn load_capture(&self, path: PathBuf) -> Vec<CapturedDocument> {
+        // First flush the scene builder otherwise async scenes might clobber
+        // the capture we are about to load.
+        self.flush_scene_builder();
+
         let (tx, rx) = channel::msg_channel().unwrap();
         let msg = ApiMsg::DebugCommand(DebugCommand::LoadCapture(path, tx));
         self.send_message(msg);
 
         let mut documents = Vec::new();
         while let Ok(captured_doc) = rx.recv() {
             documents.push(captured_doc);
         }
--- a/gfx/webrender_bindings/revision.txt
+++ b/gfx/webrender_bindings/revision.txt
@@ -1,1 +1,1 @@
-69dae1fe743bf3656d532672366e7193b041b6f7
+6415faa7f6acd412d4cc6b745cf802204690611c
--- a/gfx/wrench/src/reftest.rs
+++ b/gfx/wrench/src/reftest.rs
@@ -481,16 +481,18 @@ impl<'a> ReftestHarness<'a> {
         font_render_mode: Option<FontRenderMode>,
         allow_mipmaps: bool,
     ) -> (ReftestImage, RendererStats) {
         let mut reader = YamlFrameReader::new(filename);
         reader.set_font_render_mode(font_render_mode);
         reader.allow_mipmaps(allow_mipmaps);
         reader.do_frame(self.wrench);
 
+        self.wrench.api.flush_scene_builder();
+
         // wait for the frame
         self.rx.recv().unwrap();
         let stats = self.wrench.render();
 
         let window_size = self.window.get_inner_size();
         assert!(
             size.width <= window_size.width &&
             size.height <= window_size.height,