Bug 1504836 - Update webrender to commit fc7ac7b18c62fbb83173d6422eef3a2f70a1f941 (WR PR #3271). r=kats
authorWR Updater Bot <graphics-team@mozilla.staktrace.com>
Mon, 05 Nov 2018 22:25:05 +0000
changeset 444490 b534c7239414f51e27d54740eaa7142ade2e8cb1
parent 444489 fd42da5a8e1a571a356f5a18d7417116dcb63389
child 444491 06dea9e0cd50794679bbefb51776c8e621e64a98
push id34996
push userrgurzau@mozilla.com
push dateTue, 06 Nov 2018 09:53:23 +0000
treeherdermozilla-central@e160f0a60e4f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1504836
milestone65.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 1504836 - Update webrender to commit fc7ac7b18c62fbb83173d6422eef3a2f70a1f941 (WR PR #3271). r=kats Differential Revision: https://phabricator.services.mozilla.com/D10969
gfx/webrender/src/batch.rs
gfx/webrender/src/display_list_flattener.rs
gfx/webrender/src/prim_store.rs
gfx/webrender_bindings/revision.txt
--- a/gfx/webrender/src/batch.rs
+++ b/gfx/webrender/src/batch.rs
@@ -537,16 +537,64 @@ impl AlphaBatchBuilder {
                                          .expect("bug");
         let z_id = z_generator.next();
 
         let clip_task_address = prim_instance
             .clip_task_id
             .map_or(OPAQUE_TASK_ADDRESS, |id| render_tasks.get_task_address(id));
 
         match prim_instance.kind {
+            PrimitiveInstanceKind::Clear => {
+                let prim_data = &ctx
+                    .resources
+                    .prim_data_store[prim_instance.prim_data_handle];
+
+                let prim_cache_address = gpu_cache.get_address(&prim_data.gpu_cache_handle);
+
+                // TODO(gw): We can abstract some of the common code below into
+                //           helper methods, as we port more primitives to make
+                //           use of interning.
+
+                let prim_header = PrimitiveHeader {
+                    local_rect: prim_data.prim_rect,
+                    local_clip_rect: prim_instance.combined_local_clip_rect,
+                    task_address,
+                    specific_prim_address: prim_cache_address,
+                    clip_task_address,
+                    transform_id,
+                };
+
+                let prim_header_index = prim_headers.push(
+                    &prim_header,
+                    z_id,
+                    [get_shader_opacity(1.0), 0, 0],
+                );
+
+                let batch_key = BatchKey {
+                    blend_mode: BlendMode::PremultipliedDestOut,
+                    kind: BatchKind::Brush(BrushBatchKind::Solid),
+                    textures: BatchTextures::no_texture(),
+                };
+
+                let instance = PrimitiveInstanceData::from(BrushInstance {
+                    segment_index: 0,
+                    edge_flags: EdgeAaSegmentMask::all(),
+                    clip_task_address,
+                    brush_flags: BrushFlags::PERSPECTIVE_INTERPOLATION,
+                    prim_header_index,
+                    user_data: 0,
+                });
+
+                self.batch_list.push_single_instance(
+                    batch_key,
+                    bounding_rect,
+                    z_id,
+                    PrimitiveInstanceData::from(instance),
+                );
+            }
             PrimitiveInstanceKind::TextRun { ref run, .. } => {
                 let subpx_dir = run.used_font.get_subpx_dir();
 
                 // The GPU cache data is stored in the template and reused across
                 // frames and display lists.
                 let prim_data = &ctx
                     .resources
                     .prim_data_store[prim_instance.prim_data_handle];
@@ -760,17 +808,18 @@ impl AlphaBatchBuilder {
                     // Convert all children of the 3D hierarchy root into batches.
                     Picture3DContext::In { root_data: Some(ref list), .. } => {
                         for child in list {
                             let prim_instance = &picture.prim_list.prim_instances[child.anchor];
                             let pic_index = match prim_instance.kind {
                                 PrimitiveInstanceKind::Picture { pic_index } => pic_index,
                                 PrimitiveInstanceKind::LineDecoration { .. } |
                                 PrimitiveInstanceKind::TextRun { .. } |
-                                PrimitiveInstanceKind::LegacyPrimitive { .. } => {
+                                PrimitiveInstanceKind::LegacyPrimitive { .. } |
+                                PrimitiveInstanceKind::Clear => {
                                     unreachable!();
                                 }
                             };
                             let pic = &ctx.prim_store.pictures[pic_index.0];
 
                             let clip_task_address = prim_instance
                                 .clip_task_id
                                 .map_or(OPAQUE_TASK_ADDRESS, |id| render_tasks.get_task_address(id));
@@ -1719,24 +1768,16 @@ impl BrushPrimitive {
             BrushKind::Solid { ref opacity_binding, .. } => {
                 Some(BrushBatchParameters::shared(
                     BrushBatchKind::Solid,
                     BatchTextures::no_texture(),
                     [get_shader_opacity(opacity_binding.current), 0, 0],
                     0,
                 ))
             }
-            BrushKind::Clear => {
-                Some(BrushBatchParameters::shared(
-                    BrushBatchKind::Solid,
-                    BatchTextures::no_texture(),
-                    [get_shader_opacity(1.0), 0, 0],
-                    0,
-                ))
-            }
             BrushKind::RadialGradient { ref stops_handle, .. } => {
                 Some(BrushBatchParameters::shared(
                     BrushBatchKind::RadialGradient,
                     BatchTextures::no_texture(),
                     [
                         stops_handle.as_int(gpu_cache),
                         0,
                         0,
@@ -1819,19 +1860,16 @@ impl BrushPrimitive {
 impl PrimitiveInstance {
     fn get_blend_mode(
         &self,
         details: &PrimitiveDetails,
     ) -> BlendMode {
         match *details {
             PrimitiveDetails::Brush(ref brush) => {
                 match brush.kind {
-                    BrushKind::Clear => {
-                        BlendMode::PremultipliedDestOut
-                    }
                     BrushKind::Image { alpha_type, .. } => {
                         match alpha_type {
                             AlphaType::PremultipliedAlpha => BlendMode::PremultipliedAlpha,
                             AlphaType::Alpha => BlendMode::Alpha,
                         }
                     }
                     BrushKind::Solid { .. } |
                     BrushKind::YuvImage { .. } |
--- a/gfx/webrender/src/display_list_flattener.rs
+++ b/gfx/webrender/src/display_list_flattener.rs
@@ -1690,26 +1690,21 @@ impl<'a> DisplayListFlattener<'a> {
         );
     }
 
     pub fn add_clear_rectangle(
         &mut self,
         clip_and_scroll: ScrollNodeAndClipChain,
         info: &LayoutPrimitiveInfo,
     ) {
-        let prim = BrushPrimitive::new(
-            BrushKind::Clear,
-            None,
-        );
-
         self.add_primitive(
             clip_and_scroll,
             info,
             Vec::new(),
-            PrimitiveContainer::Brush(prim),
+            PrimitiveContainer::Clear,
         );
     }
 
     pub fn add_line(
         &mut self,
         clip_and_scroll: ScrollNodeAndClipChain,
         info: &LayoutPrimitiveInfo,
         wavy_line_thickness: f32,
--- a/gfx/webrender/src/prim_store.rs
+++ b/gfx/webrender/src/prim_store.rs
@@ -325,16 +325,18 @@ pub enum PrimitiveKeyKind {
     LineDecoration {
         // If the cache_key is Some(..) it is a line decoration
         // that relies on a render task (e.g. wavy). If the
         // cache key is None, it uses a fast path to draw the
         // line decoration as a solid rect.
         cache_key: Option<LineDecorationCacheKey>,
         color: ColorU,
     },
+    /// Clear an existing rect, used for special effects on some platforms.
+    Clear,
 }
 
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct PrimitiveKey {
     pub is_backface_visible: bool,
     pub prim_rect: LayoutRectAu,
@@ -370,16 +372,19 @@ impl PrimitiveKey {
                 PrimitiveInstanceKind::TextRun {
                     run: TextRunPrimitive {
                         used_font: font.clone(),
                         glyph_keys: Vec::new(),
                         shadow,
                     }
                 }
             }
+            PrimitiveKeyKind::Clear => {
+                PrimitiveInstanceKind::Clear
+            }
             PrimitiveKeyKind::Unused => {
                 // Should never be hit as this method should not be
                 // called for old style primitives.
                 unreachable!();
             }
         }
     }
 }
@@ -393,16 +398,17 @@ pub enum PrimitiveTemplateKind {
         cache_key: Option<LineDecorationCacheKey>,
         color: ColorF,
     },
     TextRun {
         font: FontInstance,
         offset: LayoutVector2DAu,
         glyphs: Vec<GlyphInstance>,
     },
+    Clear,
     Unused,
 }
 
 /// Construct the primitive template data from a primitive key. This
 /// is invoked when a primitive key is created and the interner
 /// doesn't currently contain a primitive with this key.
 impl From<PrimitiveKeyKind> for PrimitiveTemplateKind {
     fn from(item: PrimitiveKeyKind) -> Self {
@@ -410,16 +416,19 @@ impl From<PrimitiveKeyKind> for Primitiv
             PrimitiveKeyKind::Unused => PrimitiveTemplateKind::Unused,
             PrimitiveKeyKind::TextRun { glyphs, font, offset, .. } => {
                 PrimitiveTemplateKind::TextRun {
                     font,
                     offset,
                     glyphs,
                 }
             }
+            PrimitiveKeyKind::Clear => {
+                PrimitiveTemplateKind::Clear
+            }
             PrimitiveKeyKind::LineDecoration { cache_key, color } => {
                 PrimitiveTemplateKind::LineDecoration {
                     cache_key,
                     color: color.into(),
                 }
             }
         }
     }
@@ -456,16 +465,27 @@ impl PrimitiveTemplate {
     /// times per frame, by each primitive reference that refers to this interned
     /// template. The initial request call to the GPU cache ensures that work is only
     /// done if the cache entry is invalid (due to first use or eviction).
     pub fn update(
         &mut self,
         gpu_cache: &mut GpuCache,
     ) {
         match self.kind {
+            PrimitiveTemplateKind::Clear => {
+                if let Some(mut request) = gpu_cache.request(&mut self.gpu_cache_handle) {
+                    // Opaque black with operator dest out
+                    request.push(PremultipliedColorF::BLACK);
+
+                    request.write_segment(
+                        self.prim_rect,
+                        [0.0; 4],
+                    );
+                }
+            }
             PrimitiveTemplateKind::LineDecoration { ref cache_key, ref color } => {
                 if let Some(mut request) = gpu_cache.request(&mut self.gpu_cache_handle) {
                     // Work out the stretch parameters (for image repeat) based on the
                     // line decoration parameters.
 
                     match cache_key {
                         Some(cache_key) => {
                             request.push(color.premultiplied());
@@ -623,17 +643,16 @@ pub enum BorderSource {
     },
 }
 
 pub enum BrushKind {
     Solid {
         color: ColorF,
         opacity_binding: OpacityBinding,
     },
-    Clear,
     Image {
         request: ImageRequest,
         alpha_type: AlphaType,
         stretch_size: LayoutSize,
         tile_spacing: LayoutSize,
         color: ColorF,
         source: ImageSource,
         sub_rect: Option<DeviceIntRect>,
@@ -687,18 +706,16 @@ impl BrushKind {
                     .is_none()
             }
 
             BrushKind::Solid { .. } |
             BrushKind::YuvImage { .. } |
             BrushKind::RadialGradient { .. } |
             BrushKind::Border { .. } |
             BrushKind::LinearGradient { .. } => true,
-
-            BrushKind::Clear => false,
         }
     }
 
     // Construct a brush that is a solid color rectangle.
     pub fn new_solid(color: ColorF) -> BrushKind {
         BrushKind::Solid {
             color,
             opacity_binding: OpacityBinding::new(),
@@ -921,20 +938,16 @@ impl BrushPrimitive {
                     0.0,
                     0.0,
                 ]);
             }
             // Solid rects also support opacity collapsing.
             BrushKind::Solid { ref color, .. } => {
                 request.push(color.premultiplied());
             }
-            BrushKind::Clear => {
-                // Opaque black with operator dest out
-                request.push(PremultipliedColorF::BLACK);
-            }
             BrushKind::LinearGradient { stretch_size, start_point, end_point, extend_mode, .. } => {
                 request.push([
                     start_point.x,
                     start_point.y,
                     end_point.x,
                     end_point.y,
                 ]);
                 request.push([
@@ -1492,16 +1505,17 @@ impl ClipData {
 
 pub enum PrimitiveContainer {
     TextRun {
         font: FontInstance,
         offset: LayoutVector2D,
         glyphs: Vec<GlyphInstance>,
         shadow: bool,
     },
+    Clear,
     Brush(BrushPrimitive),
     LineDecoration {
         color: ColorF,
         style: LineStyle,
         orientation: LineOrientation,
         wavy_line_thickness: f32,
     },
 }
@@ -1519,26 +1533,28 @@ impl PrimitiveContainer {
             PrimitiveContainer::TextRun { ref font, .. } => {
                 font.color.a > 0
             }
             PrimitiveContainer::Brush(ref brush) => {
                 match brush.kind {
                     BrushKind::Solid { ref color, .. } => {
                         color.a > 0.0
                     }
-                    BrushKind::Clear |
                     BrushKind::Image { .. } |
                     BrushKind::YuvImage { .. } |
                     BrushKind::RadialGradient { .. } |
                     BrushKind::Border { .. } |
                     BrushKind::LinearGradient { .. } => {
                         true
                     }
                 }
             }
+            PrimitiveContainer::Clear => {
+                true
+            }
             PrimitiveContainer::LineDecoration { ref color, .. } => {
                 color.a > 0.0
             }
         }
     }
 
     /// Convert a source primitive container into a key, and optionally
     /// an old style PrimitiveDetails structure.
@@ -1552,16 +1568,19 @@ impl PrimitiveContainer {
                     font,
                     offset: offset.to_au(),
                     glyphs,
                     shadow,
                 };
 
                 (key, None)
             }
+            PrimitiveContainer::Clear => {
+                (PrimitiveKeyKind::Clear, None)
+            }
             PrimitiveContainer::LineDecoration { color, style, orientation, wavy_line_thickness } => {
                 // For line decorations, we can construct the render task cache key
                 // here during scene building, since it doesn't depend on device
                 // pixel ratio or transform.
 
                 let size = get_line_decoration_sizes(
                     &info.rect.size,
                     orientation,
@@ -1687,24 +1706,26 @@ impl PrimitiveContainer {
                     BrushKind::Image { request, stretch_size, .. } => {
                         PrimitiveContainer::Brush(BrushPrimitive::new(
                             BrushKind::new_image(request.clone(),
                                                  stretch_size.clone(),
                                                  shadow.color),
                             None,
                         ))
                     }
-                    BrushKind::Clear |
                     BrushKind::YuvImage { .. } |
                     BrushKind::RadialGradient { .. } |
                     BrushKind::LinearGradient { .. } => {
                         panic!("bug: other brush kinds not expected here yet");
                     }
                 }
             }
+            PrimitiveContainer::Clear => {
+                panic!("bug: clear rects are not supported in shadow contexts");
+            }
         }
     }
 }
 
 pub enum PrimitiveDetails {
     Brush(BrushPrimitive),
 }
 
@@ -1742,16 +1763,18 @@ pub enum PrimitiveInstanceKind {
         //           prepare_prims and read during the batching pass.
         //           Once we unify the prepare_prims and batching to
         //           occur at the same time, we can remove most of
         //           the things we store here in the instance, and
         //           use them directly. This will remove cache_handle,
         //           but also the opacity, clip_task_id etc below.
         cache_handle: Option<RenderTaskCacheEntryHandle>,
     },
+    /// Clear out a rect, used for special effects.
+    Clear,
 }
 
 #[derive(Clone, Debug)]
 pub struct PrimitiveInstance {
     /// Identifies the kind of primitive this
     /// instance is, and references to where
     /// the relevant information for the primitive
     /// can be found.
@@ -1928,16 +1951,17 @@ impl PrimitiveStore {
 
         let prim_instance = &pic.prim_list.prim_instances[0];
 
         // For now, we only support opacity collapse on solid rects and images.
         // This covers the most common types of opacity filters that can be
         // handled by this optimization. In the future, we can easily extend
         // this to other primitives, such as text runs and gradients.
         match prim_instance.kind {
+            PrimitiveInstanceKind::Clear |
             PrimitiveInstanceKind::TextRun { .. } |
             PrimitiveInstanceKind::LineDecoration { .. } => {
                 // TODO: Once rectangles and/or images are ported
                 //       to use interned primitives, we will need
                 //       to handle opacity collapse here.
             }
             PrimitiveInstanceKind::Picture { pic_index } => {
                 let pic = &self.pictures[pic_index.0];
@@ -1957,18 +1981,17 @@ impl PrimitiveStore {
                             // If we find a single rect or image, we can use that
                             // as the primitive to collapse the opacity into.
                             BrushKind::Solid { .. } | BrushKind::Image { .. } => {
                                 return Some(prim_index)
                             }
                             BrushKind::Border { .. } |
                             BrushKind::YuvImage { .. } |
                             BrushKind::LinearGradient { .. } |
-                            BrushKind::RadialGradient { .. } |
-                            BrushKind::Clear => {}
+                            BrushKind::RadialGradient { .. } => {}
                         }
                     }
                 }
             }
         }
 
         None
     }
@@ -2000,17 +2023,16 @@ impl PrimitiveStore {
                     PrimitiveDetails::Brush(ref mut brush) => {
                         // By this point, we know we should only have found a primitive
                         // that supports opacity collapse.
                         match brush.kind {
                             BrushKind::Solid { ref mut opacity_binding, .. } |
                             BrushKind::Image { ref mut opacity_binding, .. } => {
                                 opacity_binding.push(binding);
                             }
-                            BrushKind::Clear { .. } |
                             BrushKind::YuvImage { .. } |
                             BrushKind::Border { .. } |
                             BrushKind::LinearGradient { .. } |
                             BrushKind::RadialGradient { .. } => {
                                 unreachable!("bug: invalid prim type for opacity collapse");
                             }
                         }
                     }
@@ -2069,17 +2091,18 @@ impl PrimitiveStore {
                             }
 
                             return false;
                         }
                     }
                 }
                 PrimitiveInstanceKind::TextRun { .. } |
                 PrimitiveInstanceKind::LineDecoration { .. } |
-                PrimitiveInstanceKind::LegacyPrimitive { .. } => {
+                PrimitiveInstanceKind::LegacyPrimitive { .. } |
+                PrimitiveInstanceKind::Clear => {
                     None
                 }
             }
         };
 
         let (is_passthrough, clip_node_collector) = match pic_info {
             Some((pic_context_for_children, mut pic_state_for_children, mut prim_list)) => {
                 // Mark whether this picture has a complex coordinate system.
@@ -2122,16 +2145,17 @@ impl PrimitiveStore {
         };
 
         let (prim_local_rect, prim_local_clip_rect) = match prim_instance.kind {
             PrimitiveInstanceKind::Picture { pic_index } => {
                 let pic = &self.pictures[pic_index.0];
                 (pic.local_rect, LayoutRect::max_rect())
             }
             PrimitiveInstanceKind::TextRun { .. } |
+            PrimitiveInstanceKind::Clear |
             PrimitiveInstanceKind::LineDecoration { .. } => {
                 let prim_data = &frame_state
                     .resources
                     .prim_data_store[prim_instance.prim_data_handle];
                 (prim_data.prim_rect, prim_data.clip_rect)
             }
             PrimitiveInstanceKind::LegacyPrimitive { prim_index } => {
                 let prim = &self.primitives[prim_index.0];
@@ -2293,16 +2317,17 @@ impl PrimitiveStore {
                     ]);
                     request.write_segment(
                         pic.local_rect,
                         [0.0; 4],
                     );
                 }
             }
             PrimitiveInstanceKind::TextRun { .. } |
+            PrimitiveInstanceKind::Clear |
             PrimitiveInstanceKind::LineDecoration { .. } => {
                 prim_instance.prepare_interned_prim_for_render(
                     prim_context,
                     pic_context,
                     pic_state,
                     frame_context,
                     frame_state,
                 );
@@ -2723,16 +2748,17 @@ impl PrimitiveInstance {
         frame_context: &FrameBuildingContext,
         frame_state: &mut FrameBuildingState,
         clip_node_collector: &Option<ClipNodeCollector>,
         primitives: &mut [Primitive],
     ) -> bool {
         let brush = match self.kind {
             PrimitiveInstanceKind::Picture { .. } |
             PrimitiveInstanceKind::TextRun { .. } |
+            PrimitiveInstanceKind::Clear |
             PrimitiveInstanceKind::LineDecoration { .. } => {
                 return false;
             }
             PrimitiveInstanceKind::LegacyPrimitive { prim_index } => {
                 let prim = &mut primitives[prim_index.0];
                 match prim.details {
                     PrimitiveDetails::Brush(ref mut brush) => brush,
                 }
@@ -2906,16 +2932,25 @@ impl PrimitiveInstance {
                     frame_state.resource_cache,
                     frame_state.gpu_cache,
                     frame_state.render_tasks,
                     frame_state.special_render_passes,
                 );
 
                 PrimitiveOpacity::translucent()
             }
+            (
+                PrimitiveInstanceKind::Clear,
+                PrimitiveTemplateKind::Clear
+            ) => {
+                // Nothing specific to prepare for clear rects, since the
+                // GPU cache is updated by the template earlier.
+
+                PrimitiveOpacity::translucent()
+            }
             _ => {
                 unreachable!();
             }
         };
     }
 
     fn prepare_prim_for_render_inner(
         &mut self,
@@ -3343,17 +3378,16 @@ impl PrimitiveInstance {
                         } else {
                             PrimitiveOpacity::translucent()
                         }
                     }
                     BrushKind::Solid { ref color, ref mut opacity_binding, .. } => {
                         opacity_binding.update(frame_context.scene_properties);
                         PrimitiveOpacity::from_alpha(opacity_binding.current * color.a)
                     }
-                    BrushKind::Clear => PrimitiveOpacity::translucent(),
                 }
             }
         };
 
         if is_tiled {
             // we already requested each tile's gpu data.
             return;
         }
--- a/gfx/webrender_bindings/revision.txt
+++ b/gfx/webrender_bindings/revision.txt
@@ -1,1 +1,1 @@
-8a826b81ac28c427a21775f81d4e4f53aabf0dd8
+fc7ac7b18c62fbb83173d6422eef3a2f70a1f941