Bug 1178765 - Part 2: Implement backdrop-filter in WebRender r=gw
authorConnor Brewster <cbrewster@mozilla.com>
Tue, 13 Aug 2019 22:02:44 +0000
changeset 487807 abdb4f5f3323cc1474d02a3722741c5d2cea5df7
parent 487806 b5d6ed62cda18c51ae303d6b904771850a3d1e03
child 487808 94f900c3b51435d0a098ecd4f0082800bcfd05f7
push id36430
push userdvarga@mozilla.com
push dateWed, 14 Aug 2019 04:09:17 +0000
treeherdermozilla-central@d3deef805f92 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw
bugs1178765
milestone70.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 1178765 - Part 2: Implement backdrop-filter in WebRender r=gw Differential Revision: https://phabricator.services.mozilla.com/D39098
gfx/webrender_bindings/webrender_ffi.h
gfx/wr/webrender/src/batch.rs
gfx/wr/webrender/src/display_list_flattener.rs
gfx/wr/webrender/src/picture.rs
gfx/wr/webrender/src/prim_store/backdrop.rs
gfx/wr/webrender/src/prim_store/interned.rs
gfx/wr/webrender/src/prim_store/mod.rs
gfx/wr/webrender/src/profiler.rs
gfx/wr/webrender/src/render_backend.rs
gfx/wr/webrender/src/render_task.rs
gfx/wr/webrender/src/scene.rs
gfx/wr/webrender/src/scene_builder.rs
gfx/wr/webrender/src/tiling.rs
gfx/wr/webrender_api/src/api.rs
gfx/wr/wrench/reftests/filters/backdrop-filter-basic-ref.yaml
gfx/wr/wrench/reftests/filters/backdrop-filter-basic.yaml
gfx/wr/wrench/reftests/filters/backdrop-filter-perspective.png
gfx/wr/wrench/reftests/filters/backdrop-filter-perspective.yaml
gfx/wr/wrench/reftests/filters/reftest.list
--- a/gfx/webrender_bindings/webrender_ffi.h
+++ b/gfx/webrender_bindings/webrender_ffi.h
@@ -46,17 +46,18 @@ bool gecko_profiler_thread_is_being_prof
   macro(image_border);                     \
   macro(image);                            \
   macro(yuv_image);                        \
   macro(line_decoration);                  \
   macro(linear_grad);                      \
   macro(radial_grad);                      \
   macro(picture);                          \
   macro(text_run);                         \
-  macro(filterdata);
+  macro(filterdata);                       \
+  macro(backdrop);
 
 // Prelude of types necessary before including webrender_ffi_generated.h
 namespace mozilla {
 namespace wr {
 
 // Because this struct is macro-generated on the Rust side, cbindgen can't see
 // it. Work around that by re-declaring it here.
 #define DECLARE_MEMBER(id) uintptr_t id;
--- a/gfx/wr/webrender/src/batch.rs
+++ b/gfx/wr/webrender/src/batch.rs
@@ -1627,19 +1627,29 @@ impl BatchBuilder {
                                     prim_vis_mask,
                                 );
                             }
                             PictureCompositeMode::Blit(_) => {
                                 let cache_task_id = surface_task.expect("bug: surface must be allocated by now");
                                 let uv_rect_address = render_tasks[cache_task_id]
                                     .get_texture_address(gpu_cache)
                                     .as_int();
+                                let textures = match render_tasks[cache_task_id].saved_index {
+                                    Some(saved_index) => BatchTextures {
+                                        colors: [
+                                            TextureSource::RenderTaskCache(saved_index, Swizzle::default()),
+                                            TextureSource::PrevPassAlpha,
+                                            TextureSource::Invalid,
+                                        ]
+                                    },
+                                    None => BatchTextures::render_target_cache(),
+                                };
                                 let batch_params = BrushBatchParameters::shared(
                                     BrushBatchKind::Image(ImageBufferKind::Texture2DArray),
-                                    BatchTextures::render_target_cache(),
+                                    textures,
                                     [
                                         ShaderColorMode::Image as i32 | ((AlphaType::PremultipliedAlpha as i32) << 16),
                                         RasterizationSpace::Screen as i32,
                                         get_shader_opacity(1.0),
                                         0,
                                     ],
                                     uv_rect_address,
                                 );
@@ -2362,16 +2372,77 @@ impl BatchBuilder {
                         gpu_cache,
                         &prim_header,
                         prim_headers,
                         z_id,
                         prim_vis_mask,
                     );
                 }
             }
+            PrimitiveInstanceKind::Backdrop { data_handle } => {
+                let prim_data = &ctx.data_stores.backdrop[data_handle];
+                let backdrop_pic_index = prim_data.kind.pic_index;
+                let backdrop_surface_index = ctx.prim_store.pictures[backdrop_pic_index.0]
+                    .raster_config
+                    .as_ref()
+                    .expect("backdrop surface should be alloc by now")
+                    .surface_index;
+
+                let backdrop_task_id = ctx.surfaces[backdrop_surface_index.0]
+                    .render_tasks
+                    .as_ref()
+                    .expect("backdrop task not available")
+                    .root;
+
+                let backdrop_uv_rect_address = render_tasks[backdrop_task_id]
+                    .get_texture_address(gpu_cache)
+                    .as_int();
+
+                let textures = BatchTextures::render_target_cache();
+                let batch_key = BatchKey::new(
+                    BatchKind::Brush(BrushBatchKind::Image(ImageBufferKind::Texture2DArray)),
+                    BlendMode::PremultipliedAlpha,
+                    textures,
+                );
+
+                let prim_cache_address = gpu_cache.get_address(&ctx.globals.default_image_handle);
+                let backdrop_picture = &ctx.prim_store.pictures[backdrop_pic_index.0];
+                let prim_header = PrimitiveHeader {
+                    local_rect: backdrop_picture.snapped_local_rect,
+                    local_clip_rect: prim_info.combined_local_clip_rect,
+                    transform_id,
+                    snap_offsets,
+                    specific_prim_address: prim_cache_address,
+                };
+
+                let prim_header_index = prim_headers.push(
+                    &prim_header,
+                    z_id,
+                    [
+                        ShaderColorMode::Image as i32 | ((AlphaType::PremultipliedAlpha as i32) << 16),
+                        RasterizationSpace::Screen as i32,
+                        get_shader_opacity(1.0),
+                        0
+                    ],
+                );
+
+                self.add_brush_instance_to_batches(
+                    batch_key,
+                    batch_features,
+                    bounding_rect,
+                    z_id,
+                    INVALID_SEGMENT_INDEX,
+                    EdgeAaSegmentMask::empty(),
+                    OPAQUE_TASK_ADDRESS,
+                    BrushFlags::empty(),
+                    prim_header_index,
+                    backdrop_uv_rect_address,
+                    prim_vis_mask,
+                );
+            }
         }
     }
 
     /// Add a single segment instance to a batch.
     fn add_segment_to_batch(
         &mut self,
         segment: &BrushSegment,
         segment_data: &SegmentInstanceData,
@@ -2690,17 +2761,18 @@ impl PrimitiveInstance {
             PrimitiveInstanceKind::LineDecoration { .. } |
             PrimitiveInstanceKind::NormalBorder { .. } |
             PrimitiveInstanceKind::ImageBorder { .. } |
             PrimitiveInstanceKind::Rectangle { .. } |
             PrimitiveInstanceKind::LinearGradient { .. } |
             PrimitiveInstanceKind::RadialGradient { .. } |
             PrimitiveInstanceKind::PushClipChain |
             PrimitiveInstanceKind::PopClipChain |
-            PrimitiveInstanceKind::Clear { .. } => {
+            PrimitiveInstanceKind::Clear { .. } |
+            PrimitiveInstanceKind::Backdrop { .. } => {
                 return true;
             }
         };
         match resource_cache.get_image_properties(image_key) {
             Some(ImageProperties { external_image: Some(_), .. }) => {
                 false
             }
             _ => true
--- a/gfx/wr/webrender/src/display_list_flattener.rs
+++ b/gfx/wr/webrender/src/display_list_flattener.rs
@@ -1,37 +1,38 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter};
-use api::{ClipId, ColorF, CommonItemProperties, ComplexClipRegion, RasterSpace};
-use api::{DisplayItem, DisplayItemRef, ExtendMode, ExternalScrollId};
+use api::{ClipId, ColorF, CommonItemProperties, ComplexClipRegion, ComponentTransferFuncType, RasterSpace};
+use api::{DisplayItem, DisplayItemRef, ExtendMode, ExternalScrollId, FilterData};
 use api::{FilterOp, FilterPrimitive, FontInstanceKey, GlyphInstance, GlyphOptions, GradientStop};
 use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, ColorDepth};
 use api::{LineOrientation, LineStyle, NinePatchBorderSource, PipelineId};
 use api::{PropertyBinding, ReferenceFrame, ReferenceFrameKind, ScrollFrameDisplayItem, ScrollSensitivity};
 use api::{Shadow, SpaceAndClipInfo, SpatialId, StackingContext, StickyFrameDisplayItem};
 use api::{ClipMode, PrimitiveKeyKind, TransformStyle, YuvColorSpace, ColorRange, YuvData, TempFilterData};
 use api::units::*;
 use crate::clip::{ClipChainId, ClipRegion, ClipItemKey, ClipStore};
 use crate::clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex};
 use crate::frame_builder::{ChasePrimitive, FrameBuilder, FrameBuilderConfig};
 use crate::glyph_rasterizer::FontInstance;
 use crate::hit_test::{HitTestingItem, HitTestingScene};
 use crate::image::simplify_repeated_primitive;
 use crate::intern::Interner;
 use crate::internal_types::{FastHashMap, FastHashSet, LayoutPrimitiveInfo, Filter};
 use crate::picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureOptions};
-use crate::picture::{BlitReason, PrimitiveList, TileCacheInstance};
+use crate::picture::{BlitReason, OrderedPictureChild, PrimitiveList, TileCacheInstance};
 use crate::prim_store::{PrimitiveInstance, PrimitiveSceneData};
 use crate::prim_store::{PrimitiveInstanceKind, NinePatchDescriptor, PrimitiveStore};
 use crate::prim_store::{ScrollNodeAndClipChain, PictureIndex};
 use crate::prim_store::{InternablePrimitive, SegmentInstanceIndex};
 use crate::prim_store::{register_prim_chase_id, get_line_decoration_sizes};
+use crate::prim_store::backdrop::Backdrop;
 use crate::prim_store::borders::{ImageBorder, NormalBorderPrim};
 use crate::prim_store::gradient::{GradientStopKey, LinearGradient, RadialGradient, RadialGradientParams};
 use crate::prim_store::image::{Image, YuvImage};
 use crate::prim_store::line_dec::{LineDecoration, LineDecorationCacheKey};
 use crate::prim_store::picture::{Picture, PictureCompositeKey, PictureKey};
 use crate::prim_store::text_run::TextRun;
 use crate::render_backend::{DocumentView};
 use crate::resource_cache::{FontInstanceMap, ImageRequest};
@@ -326,16 +327,17 @@ impl<'a> DisplayListFlattener<'a> {
             root_pipeline.pipeline_id,
             CompositeOps::default(),
             TransformStyle::Flat,
             /* is_backface_visible = */ true,
             /* create_tile_cache = */ false,
             ROOT_SPATIAL_NODE_INDEX,
             ClipChainId::NONE,
             RasterSpace::Screen,
+            /* is_backdrop_root = */ true,
         );
 
         flattener.flatten_items(
             &mut root_pipeline.display_list.iter(),
             root_pipeline.pipeline_id,
             true,
         );
 
@@ -803,19 +805,19 @@ impl<'a> DisplayListFlattener<'a> {
         // Avoid doing unnecessary work for empty stacking contexts.
         if traversal.current_stacking_context_empty() {
             traversal.skip_current_stacking_context();
             return;
         }
 
         let composition_operations = {
             CompositeOps::new(
-                stacking_context.filter_ops_for_compositing(filters),
-                stacking_context.filter_datas_for_compositing(filter_datas),
-                stacking_context.filter_primitives_for_compositing(filter_primitives),
+                filter_ops_for_compositing(filters),
+                filter_datas_for_compositing(filter_datas),
+                filter_primitives_for_compositing(filter_primitives),
                 stacking_context.mix_blend_mode_for_compositing(),
             )
         };
 
         let clip_chain_id = match stacking_context.clip_id {
             Some(clip_id) => self.id_to_index_mapper.get_clip_chain_id(clip_id),
             None => ClipChainId::NONE,
         };
@@ -824,16 +826,17 @@ impl<'a> DisplayListFlattener<'a> {
             pipeline_id,
             composition_operations,
             stacking_context.transform_style,
             is_backface_visible,
             stacking_context.cache_tiles,
             spatial_node_index,
             clip_chain_id,
             stacking_context.raster_space,
+            stacking_context.is_backdrop_root,
         );
 
         if cfg!(debug_assertions) && apply_pipeline_clip && clip_chain_id != ClipChainId::NONE {
             // This is the rootmost stacking context in this pipeline that has
             // a clip set. Check that the clip chain includes the pipeline clip
             // as well, because this where we recurse with `apply_pipeline_clip`
             // set to false and stop explicitly adding the pipeline clip to
             // individual items.
@@ -1307,17 +1310,32 @@ impl<'a> DisplayListFlattener<'a> {
             DisplayItem::StickyFrame(ref info) => {
                 let parent_space = self.get_space(&info.parent_spatial_id);
                 self.flatten_sticky_frame(
                     info,
                     parent_space,
                 );
             }
             DisplayItem::BackdropFilter(ref info) => {
-                unimplemented!();
+                let (layout, clip_and_scroll) = self.process_common_properties(
+                    &info.common,
+                    apply_pipeline_clip,
+                );
+
+                let filters = filter_ops_for_compositing(item.filters());
+                let filter_datas = filter_datas_for_compositing(item.filter_datas());
+                let filter_primitives = filter_primitives_for_compositing(item.filter_primitives());
+
+                self.add_backdrop_filter(
+                    clip_and_scroll,
+                    &layout,
+                    filters,
+                    filter_datas,
+                    filter_primitives,
+                );
             }
 
             // Do nothing; these are dummy items for the display list parser
             DisplayItem::SetGradientStops |
             DisplayItem::SetFilterOps |
             DisplayItem::SetFilterData |
             DisplayItem::SetFilterPrimitives => {}
 
@@ -1569,16 +1587,17 @@ impl<'a> DisplayListFlattener<'a> {
         pipeline_id: PipelineId,
         composite_ops: CompositeOps,
         transform_style: TransformStyle,
         is_backface_visible: bool,
         create_tile_cache: bool,
         spatial_node_index: SpatialNodeIndex,
         clip_chain_id: ClipChainId,
         requested_raster_space: RasterSpace,
+        is_backdrop_root: bool,
     ) {
         // Check if this stacking context is the root of a pipeline, and the caller
         // has requested it as an output frame.
         let is_pipeline_root =
             self.sc_stack.last().map_or(true, |sc| sc.pipeline_id != pipeline_id);
         let frame_output_pipeline_id = if is_pipeline_root && self.output_pipelines.contains(&pipeline_id) {
             Some(pipeline_id)
         } else {
@@ -1592,26 +1611,35 @@ impl<'a> DisplayListFlattener<'a> {
             // we don't expect any nested tile-cache-enabled stacking contexts
             debug_assert!(!self.sc_stack.iter().any(|sc| sc.create_tile_cache));
         }
 
         // Get the transform-style of the parent stacking context,
         // which determines if we *might* need to draw this on
         // an intermediate surface for plane splitting purposes.
         let (parent_is_3d, extra_3d_instance) = match self.sc_stack.last_mut() {
-            Some(sc) => {
+            Some(ref mut sc) if sc.is_3d() => {
+                let flat_items_context_3d = match sc.context_3d {
+                    Picture3DContext::In { ancestor_index, .. } => Picture3DContext::In {
+                        root_data: None,
+                        ancestor_index,
+                    },
+                    Picture3DContext::Out => panic!("Unexpected out of 3D context"),
+                };
                 // Cut the sequence of flat children before starting a child stacking context,
                 // so that the relative order between them and our current SC is preserved.
-                let extra_instance = sc.cut_flat_item_sequence(
+                let extra_instance = sc.cut_item_sequence(
                     &mut self.prim_store,
                     &mut self.interners,
+                    Some(PictureCompositeMode::Blit(BlitReason::PRESERVE3D)),
+                    flat_items_context_3d,
                 );
-                (sc.is_3d(), extra_instance)
+                (true, extra_instance.map(|(_, instance)| instance))
             },
-            None => (false, None),
+            _ => (false, None),
         };
 
         if let Some(instance) = extra_3d_instance {
             self.add_primitive_instance_to_3d_root(instance);
         }
 
         // If this is preserve-3d *or* the parent is, then this stacking
         // context is participating in the 3d rendering context. In that
@@ -1675,16 +1703,17 @@ impl<'a> DisplayListFlattener<'a> {
             spatial_node_index,
             clip_chain_id,
             frame_output_pipeline_id,
             composite_ops,
             blit_reason,
             transform_style,
             context_3d,
             create_tile_cache,
+            is_backdrop_root,
         });
     }
 
     pub fn pop_stacking_context(&mut self) {
         let mut stacking_context = self.sc_stack.pop().unwrap();
 
         // If we encounter a stacking context that is effectively a no-op, then instead
         // of creating a picture, just append the primitive list to the parent stacking
@@ -1905,155 +1934,30 @@ impl<'a> DisplayListFlattener<'a> {
                 PictureCompositeKey::Identity,
                 stacking_context.is_backface_visible,
                 ClipChainId::NONE,
                 stacking_context.spatial_node_index,
                 &mut self.interners,
             );
         }
 
-        // For each filter, create a new image with that composite mode.
-        let mut current_filter_data_index = 0;
-        for filter in &mut stacking_context.composite_ops.filters {
-            filter.sanitize();
-
-            let composite_mode = Some(match *filter {
-                Filter::ComponentTransfer => {
-                    let filter_data =
-                        &stacking_context.composite_ops.filter_datas[current_filter_data_index];
-                    let filter_data = filter_data.sanitize();
-                    current_filter_data_index = current_filter_data_index + 1;
-                    if filter_data.is_identity() {
-                        continue
-                    } else {
-                        let filter_data_key = SFilterDataKey {
-                            data:
-                                SFilterData {
-                                    r_func: SFilterDataComponent::from_functype_values(
-                                        filter_data.func_r_type, &filter_data.r_values),
-                                    g_func: SFilterDataComponent::from_functype_values(
-                                        filter_data.func_g_type, &filter_data.g_values),
-                                    b_func: SFilterDataComponent::from_functype_values(
-                                        filter_data.func_b_type, &filter_data.b_values),
-                                    a_func: SFilterDataComponent::from_functype_values(
-                                        filter_data.func_a_type, &filter_data.a_values),
-                                },
-                        };
-
-                        let handle = self.interners
-                            .filter_data
-                            .intern(&filter_data_key, || ());
-                        PictureCompositeMode::ComponentTransferFilter(handle)
-                    }
-                }
-                _ => PictureCompositeMode::Filter(filter.clone()),
-            });
-
-            let filter_pic_index = PictureIndex(self.prim_store.pictures
-                .alloc()
-                .init(PicturePrimitive::new_image(
-                    composite_mode.clone(),
-                    Picture3DContext::Out,
-                    None,
-                    true,
-                    stacking_context.is_backface_visible,
-                    stacking_context.requested_raster_space,
-                    PrimitiveList::new(
-                        vec![cur_instance.clone()],
-                        &self.interners,
-                    ),
-                    stacking_context.spatial_node_index,
-                    None,
-                    PictureOptions::default(),
-                ))
-            );
-
-            current_pic_index = filter_pic_index;
-            cur_instance = create_prim_instance(
-                current_pic_index,
-                composite_mode.into(),
-                stacking_context.is_backface_visible,
-                ClipChainId::NONE,
-                stacking_context.spatial_node_index,
-                &mut self.interners,
-            );
-
-            if cur_instance.is_chased() {
-                println!("\tis a composite picture for a stacking context with {:?}", filter);
-            }
-
-            // Run the optimize pass on this picture, to see if we can
-            // collapse opacity and avoid drawing to an off-screen surface.
-            self.prim_store.optimize_picture_if_possible(current_pic_index);
-        }
-
-        if !stacking_context.composite_ops.filter_primitives.is_empty() {
-            let filter_datas = stacking_context.composite_ops.filter_datas.iter()
-                .map(|filter_data| filter_data.sanitize())
-                .map(|filter_data| {
-                    SFilterData {
-                        r_func: SFilterDataComponent::from_functype_values(
-                            filter_data.func_r_type, &filter_data.r_values),
-                        g_func: SFilterDataComponent::from_functype_values(
-                            filter_data.func_g_type, &filter_data.g_values),
-                        b_func: SFilterDataComponent::from_functype_values(
-                            filter_data.func_b_type, &filter_data.b_values),
-                        a_func: SFilterDataComponent::from_functype_values(
-                            filter_data.func_a_type, &filter_data.a_values),
-                    }
-                })
-                .collect();
-
-            // Sanitize filter inputs
-            for primitive in &mut stacking_context.composite_ops.filter_primitives {
-                primitive.sanitize();
-            }
-
-            let composite_mode = PictureCompositeMode::SvgFilter(
-                stacking_context.composite_ops.filter_primitives,
-                filter_datas,
-            );
-
-            let filter_pic_index = PictureIndex(self.prim_store.pictures
-                .alloc()
-                .init(PicturePrimitive::new_image(
-                    Some(composite_mode.clone()),
-                    Picture3DContext::Out,
-                    None,
-                    true,
-                    stacking_context.is_backface_visible,
-                    stacking_context.requested_raster_space,
-                    PrimitiveList::new(
-                        vec![cur_instance.clone()],
-                        &self.interners,
-                    ),
-                    stacking_context.spatial_node_index,
-                    None,
-                    PictureOptions::default(),
-                ))
-            );
-
-            current_pic_index = filter_pic_index;
-            cur_instance = create_prim_instance(
-                current_pic_index,
-                Some(composite_mode).into(),
-                stacking_context.is_backface_visible,
-                ClipChainId::NONE,
-                stacking_context.spatial_node_index,
-                &mut self.interners,
-            );
-
-            if cur_instance.is_chased() {
-                println!("\tis a composite picture for a stacking context with an SVG filter");
-            }
-
-            // Run the optimize pass on this picture, to see if we can
-            // collapse opacity and avoid drawing to an off-screen surface.
-            self.prim_store.optimize_picture_if_possible(current_pic_index);
-        }
+        let (filtered_pic_index, filtered_instance) = self.wrap_prim_with_filters(
+            cur_instance,
+            current_pic_index,
+            stacking_context.composite_ops.filters,
+            stacking_context.composite_ops.filter_primitives,
+            stacking_context.composite_ops.filter_datas,
+            stacking_context.is_backface_visible,
+            stacking_context.requested_raster_space,
+            stacking_context.spatial_node_index,
+            true,
+        );
+
+        current_pic_index = filtered_pic_index;
+        cur_instance = filtered_instance;
 
         // Same for mix-blend-mode, except we can skip if this primitive is the first in the parent
         // stacking context.
         // From https://drafts.fxtf.org/compositing-1/#generalformula, the formula for blending is:
         // Cs = (1 - ab) x Cs + ab x Blend(Cb, Cs)
         // where
         // Cs = Source color
         // ab = Backdrop alpha
@@ -3056,16 +2960,323 @@ impl<'a> DisplayListFlattener<'a> {
                     prims.push(instance);
                     break;
                 }
                 Picture3DContext::In { .. } => {}
                 Picture3DContext::Out => panic!("Unable to find 3D root"),
             }
         }
     }
+
+    pub fn add_backdrop_filter(
+        &mut self,
+        clip_and_scroll: ScrollNodeAndClipChain,
+        info: &LayoutPrimitiveInfo,
+        filters: Vec<Filter>,
+        filter_datas: Vec<FilterData>,
+        filter_primitives: Vec<FilterPrimitive>,
+    ) {
+        let mut backdrop_pic_index = match self.cut_backdrop_picture() {
+            // Backdrop contains no content, so no need to add backdrop-filter
+            None => return,
+            Some(backdrop_pic_index) => backdrop_pic_index,
+        };
+
+        let backdrop_spatial_node_index = self.prim_store.pictures[backdrop_pic_index.0].spatial_node_index;
+        let requested_raster_space = self.sc_stack.last().expect("no active stacking context").requested_raster_space;
+
+        let mut instance = self.create_primitive(
+            info,
+            // TODO(cbrewster): This is a bit of a hack to help figure out the correct sizing of the backdrop
+            // region. By makings sure to include this, the clip chain instance computes the correct clip rect,
+            // but we don't actually apply the filtered backdrop clip yet (this is done to the last instance in
+            // the filter chain below).
+            clip_and_scroll.clip_chain_id,
+            backdrop_spatial_node_index,
+            Backdrop {
+                pic_index: backdrop_pic_index,
+                spatial_node_index: clip_and_scroll.spatial_node_index,
+                border_rect: info.rect.into(),
+            },
+        );
+
+        // We will append the filtered backdrop to the backdrop root, but we need to
+        // make sure all clips between the current stacking context and backdrop root
+        // are taken into account. So we wrap the backdrop filter instance with a picture with
+        // a clip for each stacking context.
+        for stacking_context in self.sc_stack.iter().rev().take_while(|sc| !sc.is_backdrop_root) {
+            let clip_chain_id = stacking_context.clip_chain_id;
+            let is_backface_visible = stacking_context.is_backface_visible;
+            let composite_mode = None;
+
+            backdrop_pic_index = PictureIndex(self.prim_store.pictures
+                .alloc()
+                .init(PicturePrimitive::new_image(
+                    composite_mode.clone(),
+                    Picture3DContext::Out,
+                    None,
+                    true,
+                    is_backface_visible,
+                    requested_raster_space,
+                    PrimitiveList::new(
+                        vec![instance],
+                        &mut self.interners,
+                    ),
+                    backdrop_spatial_node_index,
+                    None,
+                    PictureOptions {
+                       inflate_if_required: false,
+                    },
+                ))
+            );
+
+            instance = create_prim_instance(
+                backdrop_pic_index,
+                composite_mode.into(),
+                is_backface_visible,
+                clip_chain_id,
+                backdrop_spatial_node_index,
+                &mut self.interners,
+            );
+        }
+
+        let (mut filtered_pic_index, mut filtered_instance) = self.wrap_prim_with_filters(
+            instance,
+            backdrop_pic_index,
+            filters,
+            filter_primitives,
+            filter_datas,
+            info.is_backface_visible,
+            requested_raster_space,
+            backdrop_spatial_node_index,
+            false,
+        );
+
+        // Apply filters from all stacking contexts up to, but not including the backdrop root.
+        // Gecko pushes separate stacking contexts for filters and opacity,
+        // so we must iterate through multiple stacking contexts to find all effects
+        // that need to be applied to the filtered backdrop.
+        let backdrop_root_pos = self.sc_stack.iter().rposition(|sc| sc.is_backdrop_root).expect("no backdrop root?");
+        for i in ((backdrop_root_pos + 1)..self.sc_stack.len()).rev() {
+            let stacking_context = &self.sc_stack[i];
+            let filters = stacking_context.composite_ops.filters.clone();
+            let filter_primitives = stacking_context.composite_ops.filter_primitives.clone();
+            let filter_datas = stacking_context.composite_ops.filter_datas.clone();
+
+            let (pic_index, instance) = self.wrap_prim_with_filters(
+                filtered_instance,
+                filtered_pic_index,
+                filters,
+                filter_primitives,
+                filter_datas,
+                info.is_backface_visible,
+                requested_raster_space,
+                backdrop_spatial_node_index,
+                false,
+            );
+
+            filtered_instance = instance;
+            filtered_pic_index = pic_index;
+        }
+
+        filtered_instance.clip_chain_id = clip_and_scroll.clip_chain_id;
+
+        self.sc_stack.iter_mut().rev().find(|sc| sc.is_backdrop_root).unwrap().primitives.push(filtered_instance);
+    }
+
+    pub fn cut_backdrop_picture(&mut self) -> Option<PictureIndex> {
+        let mut flattened_items = None;
+        let mut backdrop_root =  None;
+        for sc in self.sc_stack.iter_mut().rev() {
+            // Add child contents to parent stacking context
+            if let Some((_, flattened_instance)) = flattened_items.take() {
+                sc.primitives.push(flattened_instance);
+            }
+            flattened_items = sc.cut_item_sequence(
+                &mut self.prim_store,
+                &mut self.interners,
+                None,
+                Picture3DContext::Out,
+            );
+            if sc.is_backdrop_root {
+                backdrop_root = Some(sc);
+                break;
+            }
+        }
+
+        let (pic_index, instance) = flattened_items?;
+        self.prim_store.pictures[pic_index.0].requested_composite_mode = Some(PictureCompositeMode::Blit(BlitReason::BACKDROP));
+        backdrop_root.expect("no backdrop root found").primitives.push(instance);
+
+        Some(pic_index)
+    }
+
+    fn wrap_prim_with_filters(
+        &mut self,
+        mut cur_instance: PrimitiveInstance,
+        mut current_pic_index: PictureIndex,
+        mut filter_ops: Vec<Filter>,
+        mut filter_primitives: Vec<FilterPrimitive>,
+        filter_datas: Vec<FilterData>,
+        is_backface_visible: bool,
+        requested_raster_space: RasterSpace,
+        spatial_node_index: SpatialNodeIndex,
+        inflate_if_required: bool,
+    ) -> (PictureIndex, PrimitiveInstance) {
+        // TODO(cbrewster): Currently CSS and SVG filters live side by side in WebRender, but unexpected results will
+        // happen if they are used simulataneously. Gecko only provides either filter ops or filter primitives.
+        // At some point, these two should be combined and CSS filters should be expressed in terms of SVG filters.
+        assert!(filter_ops.is_empty() || filter_primitives.is_empty(),
+            "Filter ops and filter primitives are not allowed on the same stacking context.");
+
+        // For each filter, create a new image with that composite mode.
+        let mut current_filter_data_index = 0;
+        for filter in &mut filter_ops {
+            filter.sanitize();
+
+            let composite_mode = Some(match *filter {
+                Filter::ComponentTransfer => {
+                    let filter_data =
+                        &filter_datas[current_filter_data_index];
+                    let filter_data = filter_data.sanitize();
+                    current_filter_data_index = current_filter_data_index + 1;
+                    if filter_data.is_identity() {
+                        continue
+                    } else {
+                        let filter_data_key = SFilterDataKey {
+                            data:
+                                SFilterData {
+                                    r_func: SFilterDataComponent::from_functype_values(
+                                        filter_data.func_r_type, &filter_data.r_values),
+                                    g_func: SFilterDataComponent::from_functype_values(
+                                        filter_data.func_g_type, &filter_data.g_values),
+                                    b_func: SFilterDataComponent::from_functype_values(
+                                        filter_data.func_b_type, &filter_data.b_values),
+                                    a_func: SFilterDataComponent::from_functype_values(
+                                        filter_data.func_a_type, &filter_data.a_values),
+                                },
+                        };
+
+                        let handle = self.interners
+                            .filter_data
+                            .intern(&filter_data_key, || ());
+                        PictureCompositeMode::ComponentTransferFilter(handle)
+                    }
+                }
+                _ => PictureCompositeMode::Filter(filter.clone()),
+            });
+
+            let filter_pic_index = PictureIndex(self.prim_store.pictures
+                .alloc()
+                .init(PicturePrimitive::new_image(
+                    composite_mode.clone(),
+                    Picture3DContext::Out,
+                    None,
+                    true,
+                    is_backface_visible,
+                    requested_raster_space,
+                    PrimitiveList::new(
+                        vec![cur_instance.clone()],
+                        &mut self.interners,
+                    ),
+                    spatial_node_index,
+                    None,
+                    PictureOptions {
+                       inflate_if_required,
+                    },
+                ))
+            );
+
+            current_pic_index = filter_pic_index;
+            cur_instance = create_prim_instance(
+                current_pic_index,
+                composite_mode.into(),
+                is_backface_visible,
+                ClipChainId::NONE,
+                spatial_node_index,
+                &mut self.interners,
+            );
+
+            if cur_instance.is_chased() {
+                println!("\tis a composite picture for a stacking context with {:?}", filter);
+            }
+
+            // Run the optimize pass on this picture, to see if we can
+            // collapse opacity and avoid drawing to an off-screen surface.
+            self.prim_store.optimize_picture_if_possible(current_pic_index);
+        }
+
+        if !filter_primitives.is_empty() {
+            let filter_datas = filter_datas.iter()
+                .map(|filter_data| filter_data.sanitize())
+                .map(|filter_data| {
+                    SFilterData {
+                        r_func: SFilterDataComponent::from_functype_values(
+                            filter_data.func_r_type, &filter_data.r_values),
+                        g_func: SFilterDataComponent::from_functype_values(
+                            filter_data.func_g_type, &filter_data.g_values),
+                        b_func: SFilterDataComponent::from_functype_values(
+                            filter_data.func_b_type, &filter_data.b_values),
+                        a_func: SFilterDataComponent::from_functype_values(
+                            filter_data.func_a_type, &filter_data.a_values),
+                    }
+                })
+                .collect();
+
+            // Sanitize filter inputs
+            for primitive in &mut filter_primitives {
+                primitive.sanitize();
+            }
+
+            let composite_mode = PictureCompositeMode::SvgFilter(
+                filter_primitives,
+                filter_datas,
+            );
+
+            let filter_pic_index = PictureIndex(self.prim_store.pictures
+                .alloc()
+                .init(PicturePrimitive::new_image(
+                    Some(composite_mode.clone()),
+                    Picture3DContext::Out,
+                    None,
+                    true,
+                    is_backface_visible,
+                    requested_raster_space,
+                    PrimitiveList::new(
+                        vec![cur_instance.clone()],
+                        &mut self.interners,
+                    ),
+                    spatial_node_index,
+                    None,
+                    PictureOptions {
+                        inflate_if_required,
+                    },
+                ))
+            );
+
+            current_pic_index = filter_pic_index;
+            cur_instance = create_prim_instance(
+                current_pic_index,
+                Some(composite_mode).into(),
+                is_backface_visible,
+                ClipChainId::NONE,
+                spatial_node_index,
+                &mut self.interners,
+            );
+
+            if cur_instance.is_chased() {
+                println!("\tis a composite picture for a stacking context with an SVG filter");
+            }
+
+            // Run the optimize pass on this picture, to see if we can
+            // collapse opacity and avoid drawing to an off-screen surface.
+            self.prim_store.optimize_picture_if_possible(current_pic_index);
+        }
+        (current_pic_index, cur_instance)
+    }
 }
 
 
 pub trait CreateShadow {
     fn create_shadow(&self, shadow: &Shadow) -> Self;
 }
 
 pub trait IsVisible {
@@ -3110,16 +3321,19 @@ struct FlattenedStackingContext {
     /// CSS transform-style property.
     transform_style: TransformStyle,
 
     /// Defines the relationship to a preserve-3D hiearachy.
     context_3d: Picture3DContext<PrimitiveInstance>,
 
     /// If true, create a tile cache for this stacking context.
     create_tile_cache: bool,
+
+    /// True if this stacking context is a backdrop root.
+    is_backdrop_root: bool,
 }
 
 impl FlattenedStackingContext {
     /// Return true if the stacking context has a valid preserve-3d property
     pub fn is_3d(&self) -> bool {
         self.transform_style == TransformStyle::Preserve3D && self.composite_ops.is_empty()
     }
 
@@ -3169,38 +3383,32 @@ impl FlattenedStackingContext {
         if self.create_tile_cache {
             return false;
         }
 
         // It is redundant!
         true
     }
 
-    /// For a Preserve3D context, cut the sequence of the immediate flat children
-    /// recorded so far and generate a picture from them.
-    pub fn cut_flat_item_sequence(
+    /// Cut the sequence of the immediate children recorded so far and generate a picture from them.
+    pub fn cut_item_sequence(
         &mut self,
         prim_store: &mut PrimitiveStore,
         interners: &mut Interners,
-    ) -> Option<PrimitiveInstance> {
-        if !self.is_3d() || self.primitives.is_empty() {
+        composite_mode: Option<PictureCompositeMode>,
+        flat_items_context_3d: Picture3DContext<OrderedPictureChild>,
+    ) -> Option<(PictureIndex, PrimitiveInstance)> {
+        if self.primitives.is_empty() {
             return None
         }
-        let flat_items_context_3d = match self.context_3d {
-            Picture3DContext::In { ancestor_index, .. } => Picture3DContext::In {
-                root_data: None,
-                ancestor_index,
-            },
-            Picture3DContext::Out => panic!("Unexpected out of 3D context"),
-        };
 
         let pic_index = PictureIndex(prim_store.pictures
             .alloc()
             .init(PicturePrimitive::new_image(
-                Some(PictureCompositeMode::Blit(BlitReason::PRESERVE3D)),
+                composite_mode.clone(),
                 flat_items_context_3d,
                 None,
                 true,
                 self.is_backface_visible,
                 self.requested_raster_space,
                 PrimitiveList::new(
                     mem::replace(&mut self.primitives, Vec::new()),
                     interners,
@@ -3208,24 +3416,24 @@ impl FlattenedStackingContext {
                 self.spatial_node_index,
                 None,
                 PictureOptions::default(),
             ))
         );
 
         let prim_instance = create_prim_instance(
             pic_index,
-            PictureCompositeKey::Identity,
+            composite_mode.into(),
             self.is_backface_visible,
             self.clip_chain_id,
             self.spatial_node_index,
             interners,
         );
 
-        Some(prim_instance)
+        Some((pic_index, prim_instance))
     }
 }
 
 /// A primitive that is added while a shadow context is
 /// active is stored as a pending primitive and only
 /// added to pictures during pop_all_shadows.
 pub struct PendingPrimitive<T> {
     clip_and_scroll: ScrollNodeAndClipChain,
@@ -3325,8 +3533,52 @@ fn create_clip_prim_instance(
     PrimitiveInstance::new(
         LayoutPoint::zero(),
         LayoutRect::max_rect(),
         kind,
         clip_chain_id,
         spatial_node_index,
     )
 }
+
+
+fn filter_ops_for_compositing(
+    input_filters: ItemRange<FilterOp>,
+) -> Vec<Filter> {
+    // TODO(gw): Now that we resolve these later on,
+    //           we could probably make it a bit
+    //           more efficient than cloning these here.
+    input_filters.iter().map(|filter| filter.into()).collect()
+}
+
+fn filter_datas_for_compositing(
+    input_filter_datas: &[TempFilterData],
+) -> Vec<FilterData> {
+    // TODO(gw): Now that we resolve these later on,
+    //           we could probably make it a bit
+    //           more efficient than cloning these here.
+    let mut filter_datas = vec![];
+    for temp_filter_data in input_filter_datas {
+        let func_types : Vec<ComponentTransferFuncType> = temp_filter_data.func_types.iter().collect();
+        debug_assert!(func_types.len() == 4);
+        filter_datas.push( FilterData {
+            func_r_type: func_types[0],
+            r_values: temp_filter_data.r_values.iter().collect(),
+            func_g_type: func_types[1],
+            g_values: temp_filter_data.g_values.iter().collect(),
+            func_b_type: func_types[2],
+            b_values: temp_filter_data.b_values.iter().collect(),
+            func_a_type: func_types[3],
+            a_values: temp_filter_data.a_values.iter().collect(),
+        });
+    }
+    filter_datas
+}
+
+fn filter_primitives_for_compositing(
+    input_filter_primitives: ItemRange<FilterPrimitive>,
+) -> Vec<FilterPrimitive> {
+    // Resolve these in the flattener?
+    // TODO(gw): Now that we resolve these later on,
+    //           we could probably make it a bit
+    //           more efficient than cloning these here.
+    input_filter_primitives.iter().map(|primitive| primitive.into()).collect()
+}
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -1560,17 +1560,18 @@ impl TileCacheInstance {
                         }
                     }
                 }
             }
             PrimitiveInstanceKind::LineDecoration { .. } |
             PrimitiveInstanceKind::Clear { .. } |
             PrimitiveInstanceKind::NormalBorder { .. } |
             PrimitiveInstanceKind::LinearGradient { .. } |
-            PrimitiveInstanceKind::RadialGradient { .. } => {
+            PrimitiveInstanceKind::RadialGradient { .. } |
+            PrimitiveInstanceKind::Backdrop { .. } => {
                 // These don't contribute dependencies
             }
         };
 
         // Normalize the tile coordinates before adding to tile dependencies.
         // For each affected tile, mark any of the primitive dependencies.
         for y in p0.y .. p1.y {
             for x in p0.x .. p1.x {
@@ -1886,16 +1887,18 @@ bitflags! {
     #[cfg_attr(feature = "capture", derive(Serialize))]
     pub struct BlitReason: u32 {
         /// Mix-blend-mode on a child that requires isolation.
         const ISOLATE = 1;
         /// Clip node that _might_ require a surface.
         const CLIP = 2;
         /// Preserve-3D requires a surface for plane-splitting.
         const PRESERVE3D = 4;
+        /// A backdrop that is reused which requires a surface.
+        const BACKDROP = 8;
     }
 }
 
 /// Specifies how this Picture should be composited
 /// onto the target it belongs to.
 #[allow(dead_code)]
 #[derive(Debug, Clone)]
 #[cfg_attr(feature = "capture", derive(Serialize))]
@@ -2157,16 +2160,20 @@ impl PrimitiveList {
                 PrimitiveInstanceKind::TextRun { data_handle, .. } => {
                     let data = &interners.text_run[data_handle];
                     (data.is_backface_visible, data.prim_size)
                 }
                 PrimitiveInstanceKind::YuvImage { data_handle, .. } => {
                     let data = &interners.yuv_image[data_handle];
                     (data.is_backface_visible, data.prim_size)
                 }
+                PrimitiveInstanceKind::Backdrop { data_handle, .. } => {
+                    let data = &interners.backdrop[data_handle];
+                    (data.is_backface_visible, data.prim_size)
+                }
                 PrimitiveInstanceKind::PushClipChain |
                 PrimitiveInstanceKind::PopClipChain => {
                     (true, LayoutSize::zero())
                 }
             };
 
             // Get the key for the cluster that this primitive should
             // belong to.
@@ -2298,17 +2305,17 @@ pub struct PicturePrimitive {
     /// transform animation and/or scrolling.
     pub segments_are_valid: bool,
 
     /// If Some(..) the tile cache that is associated with this picture.
     #[cfg_attr(feature = "capture", serde(skip))] //TODO
     pub tile_cache: Option<Box<TileCacheInstance>>,
 
     /// The config options for this picture.
-    options: PictureOptions,
+    pub options: PictureOptions,
 }
 
 impl PicturePrimitive {
     pub fn print<T: PrintTreePrinter>(
         &self,
         pictures: &[Self],
         self_index: PictureIndex,
         pt: &mut T,
@@ -2551,49 +2558,55 @@ impl PicturePrimitive {
                 let dep_info = match raster_config.composite_mode {
                     PictureCompositeMode::Filter(Filter::Blur(blur_radius)) => {
                         let blur_std_deviation = blur_radius * device_pixel_scale.0;
                         let scale_factors = scale_factors(&transform);
                         let blur_std_deviation = DeviceSize::new(
                             blur_std_deviation * scale_factors.0,
                             blur_std_deviation * scale_factors.1
                         );
-                        let inflation_factor = frame_state.surfaces[raster_config.surface_index.0].inflation_factor;
-                        let inflation_factor = (inflation_factor * device_pixel_scale.0).ceil();
-
-                        // The clipped field is the part of the picture that is visible
-                        // on screen. The unclipped field is the screen-space rect of
-                        // the complete picture, if no screen / clip-chain was applied
-                        // (this includes the extra space for blur region). To ensure
-                        // that we draw a large enough part of the picture to get correct
-                        // blur results, inflate that clipped area by the blur range, and
-                        // then intersect with the total screen rect, to minimize the
-                        // allocation size.
-                        // We cast clipped to f32 instead of casting unclipped to i32
-                        // because unclipped can overflow an i32.
-                        let device_rect = clipped.to_f32()
-                            .inflate(inflation_factor, inflation_factor)
-                            .intersection(&unclipped)
-                            .unwrap();
-
-                        let mut device_rect = match device_rect.try_cast::<i32>() {
-                            Some(rect) => rect,
-                            None => {
-                                return None
-                            }
+                        let device_rect = if self.options.inflate_if_required {
+                            let inflation_factor = frame_state.surfaces[raster_config.surface_index.0].inflation_factor;
+                            let inflation_factor = (inflation_factor * device_pixel_scale.0).ceil();
+
+                            // The clipped field is the part of the picture that is visible
+                            // on screen. The unclipped field is the screen-space rect of
+                            // the complete picture, if no screen / clip-chain was applied
+                            // (this includes the extra space for blur region). To ensure
+                            // that we draw a large enough part of the picture to get correct
+                            // blur results, inflate that clipped area by the blur range, and
+                            // then intersect with the total screen rect, to minimize the
+                            // allocation size.
+                            // We cast clipped to f32 instead of casting unclipped to i32
+                            // because unclipped can overflow an i32.
+                            let device_rect = clipped.to_f32()
+                                .inflate(inflation_factor, inflation_factor)
+                                .intersection(&unclipped)
+                                .unwrap();
+
+                            let mut device_rect = match device_rect.try_cast::<i32>() {
+                                Some(rect) => rect,
+                                None => {
+                                    return None
+                                }
+                            };
+
+                            // Adjust the size to avoid introducing sampling errors during the down-scaling passes.
+                            // what would be even better is to rasterize the picture at the down-scaled size
+                            // directly.
+                            device_rect.size = RenderTask::adjusted_blur_source_size(
+                                device_rect.size,
+                                blur_std_deviation,
+                            );
+
+                            device_rect
+                        } else {
+                            clipped
                         };
 
-                        // Adjust the size to avoid introducing sampling errors during the down-scaling passes.
-                        // what would be even better is to rasterize the picture at the down-scaled size
-                        // directly.
-                        device_rect.size = RenderTask::adjusted_blur_source_size(
-                            device_rect.size,
-                            blur_std_deviation,
-                        );
-
                         let uv_rect_kind = calculate_uv_rect_kind(
                             &pic_rect,
                             &transform,
                             &device_rect,
                             device_pixel_scale,
                             true,
                         );
 
@@ -3320,17 +3333,19 @@ impl PicturePrimitive {
 
         // If this picture establishes a surface, then map the surface bounding
         // rect into the parent surface coordinate space, and propagate that up
         // to the parent.
         if let Some(ref mut raster_config) = self.raster_config {
             let surface = state.current_surface_mut();
             // Inflate the local bounding rect if required by the filter effect.
             // This inflaction factor is to be applied to the surface itself.
-            surface.rect = raster_config.composite_mode.inflate_picture_rect(surface.rect, surface.inflation_factor);
+            if self.options.inflate_if_required {
+                surface.rect = raster_config.composite_mode.inflate_picture_rect(surface.rect, surface.inflation_factor);
+            }
 
             let mut surface_rect = surface.rect * Scale::new(1.0);
 
             // Pop this surface from the stack
             let surface_index = state.pop_surface();
             debug_assert_eq!(surface_index, raster_config.surface_index);
 
             // Snapping may change the local rect slightly, and as such should just be
new file mode 100644
--- /dev/null
+++ b/gfx/wr/webrender/src/prim_store/backdrop.rs
@@ -0,0 +1,105 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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::units::*;
+use crate::clip_scroll_tree::SpatialNodeIndex;
+use crate::intern::{Internable, InternDebug, Handle as InternHandle};
+use crate::internal_types::LayoutPrimitiveInfo;
+use crate::prim_store::{
+    InternablePrimitive, PictureIndex, PrimitiveInstanceKind, PrimKey, PrimKeyCommonData, PrimTemplate,
+    PrimTemplateCommonData, PrimitiveStore, PrimitiveSceneData, RectangleKey,
+};
+
+#[cfg_attr(feature = "capture", derive(Serialize))]
+#[cfg_attr(feature = "replay", derive(Deserialize))]
+#[derive(Debug, Clone, Eq, PartialEq, MallocSizeOf, Hash)]
+pub struct Backdrop {
+    pub pic_index: PictureIndex,
+    pub spatial_node_index: SpatialNodeIndex,
+    pub border_rect: RectangleKey,
+}
+
+impl From<Backdrop> for BackdropData {
+    fn from(backdrop: Backdrop) -> Self {
+        BackdropData {
+            pic_index: backdrop.pic_index,
+            spatial_node_index: backdrop.spatial_node_index,
+            border_rect: backdrop.border_rect.into(),
+        }
+    }
+}
+
+pub type BackdropKey = PrimKey<Backdrop>;
+
+impl BackdropKey {
+    pub fn new(
+        is_backface_visible: bool,
+        prim_size: LayoutSize,
+        backdrop: Backdrop,
+    ) -> Self {
+        BackdropKey {
+            common: PrimKeyCommonData {
+                is_backface_visible,
+                prim_size: prim_size.into(),
+            },
+            kind: backdrop,
+        }
+    }
+}
+
+impl InternDebug for BackdropKey {}
+
+#[cfg_attr(feature = "capture", derive(Serialize))]
+#[cfg_attr(feature = "replay", derive(Deserialize))]
+#[derive(Debug, MallocSizeOf)]
+pub struct BackdropData {
+    pub pic_index: PictureIndex,
+    pub spatial_node_index: SpatialNodeIndex,
+    pub border_rect: LayoutRect,
+}
+
+pub type BackdropTemplate = PrimTemplate<BackdropData>;
+
+impl From<BackdropKey> for BackdropTemplate {
+    fn from(backdrop: BackdropKey) -> Self {
+        let common = PrimTemplateCommonData::with_key_common(backdrop.common);
+
+        BackdropTemplate {
+            common,
+            kind: backdrop.kind.into(),
+        }
+    }
+}
+
+pub type BackdropDataHandle = InternHandle<Backdrop>;
+
+impl Internable for Backdrop {
+    type Key = BackdropKey;
+    type StoreData = BackdropTemplate;
+    type InternData = PrimitiveSceneData;
+}
+
+impl InternablePrimitive for Backdrop {
+    fn into_key(
+        self,
+        info: &LayoutPrimitiveInfo,
+    ) -> BackdropKey {
+        BackdropKey::new(
+            info.is_backface_visible,
+            info.rect.size,
+            self
+        )
+    }
+
+    fn make_instance_kind(
+        _key: BackdropKey,
+        data_handle: BackdropDataHandle,
+        _prim_store: &mut PrimitiveStore,
+        _reference_frame_relative_offset: LayoutVector2D,
+    ) -> PrimitiveInstanceKind {
+        PrimitiveInstanceKind::Backdrop {
+            data_handle,
+        }
+    }
+}
--- a/gfx/wr/webrender/src/prim_store/interned.rs
+++ b/gfx/wr/webrender/src/prim_store/interned.rs
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 // list of all interned primitives to match enumerate_interners!
 
+pub use crate::prim_store::backdrop::Backdrop;
 pub use crate::prim_store::borders::{ImageBorder, NormalBorderPrim};
 pub use crate::prim_store::image::{Image, YuvImage};
 pub use crate::prim_store::line_dec::{LineDecoration};
 pub use crate::prim_store::gradient::{LinearGradient, RadialGradient};
 pub use crate::prim_store::picture::Picture;
 pub use crate::prim_store::text_run::TextRun;
+
--- a/gfx/wr/webrender/src/prim_store/mod.rs
+++ b/gfx/wr/webrender/src/prim_store/mod.rs
@@ -23,16 +23,17 @@ use crate::frame_builder::{FrameVisibili
 use crate::glyph_rasterizer::GlyphKey;
 use crate::gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle, GpuDataRequest, ToGpuBlocks};
 use crate::gpu_types::{BrushFlags, SnapOffsets};
 use crate::image::{Repetition};
 use crate::intern;
 use malloc_size_of::MallocSizeOf;
 use crate::picture::{PictureCompositeMode, PicturePrimitive};
 use crate::picture::{ClusterIndex, PrimitiveList, RecordedDirtyRegion, SurfaceIndex, RetainedTiles, RasterConfig};
+use crate::prim_store::backdrop::BackdropDataHandle;
 use crate::prim_store::borders::{ImageBorderDataHandle, NormalBorderDataHandle};
 use crate::prim_store::gradient::{GRADIENT_FP_STOPS, GradientCacheKey, GradientStopKey};
 use crate::prim_store::gradient::{LinearGradientPrimitive, LinearGradientDataHandle, RadialGradientDataHandle};
 use crate::prim_store::image::{ImageDataHandle, ImageInstance, VisibleImageTile, YuvImageDataHandle};
 use crate::prim_store::line_dec::LineDecorationDataHandle;
 use crate::prim_store::picture::PictureDataHandle;
 use crate::prim_store::text_run::{TextRunDataHandle, TextRunPrimitive};
 #[cfg(debug_assertions)]
@@ -49,16 +50,17 @@ use std::{cmp, fmt, hash, ops, u32, usiz
 use std::sync::atomic::{AtomicUsize, Ordering};
 use crate::storage;
 use crate::texture_cache::TEXTURE_REGION_DIMENSIONS;
 use crate::util::{MatrixHelpers, MaxRect, Recycler};
 use crate::util::{clamp_to_scale_factor, pack_as_float, project_rect, raster_rect_to_device_pixels};
 use crate::internal_types::{LayoutPrimitiveInfo, Filter};
 use smallvec::SmallVec;
 
+pub mod backdrop;
 pub mod borders;
 pub mod gradient;
 pub mod image;
 pub mod line_dec;
 pub mod picture;
 pub mod text_run;
 pub mod interned;
 
@@ -266,17 +268,17 @@ pub struct DeferredResolve {
 
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub struct ClipTaskIndex(pub u16);
 
 impl ClipTaskIndex {
     pub const INVALID: ClipTaskIndex = ClipTaskIndex(0);
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, MallocSizeOf, Ord, PartialOrd)]
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 pub struct PictureIndex(pub usize);
 
 impl GpuCacheHandle {
     pub fn as_int(&self, gpu_cache: &GpuCache) -> i32 {
         gpu_cache.get_address(self).as_int()
     }
@@ -1320,16 +1322,20 @@ pub enum PrimitiveInstanceKind {
         data_handle: RadialGradientDataHandle,
         visible_tiles_range: GradientTileRange,
     },
     /// Clear out a rect, used for special effects.
     Clear {
         /// Handle to the common interned data for this primitive.
         data_handle: PrimitiveDataHandle,
     },
+    /// Render a portion of a specified backdrop.
+    Backdrop {
+        data_handle: BackdropDataHandle,
+    },
     /// These are non-visual instances. They are used during the
     /// visibility pass to allow pushing/popping a clip chain
     /// without the presence of a stacking context / picture.
     /// TODO(gw): In some ways this seems like a hack, in some
     ///           ways it seems reasonable. We should discuss
     ///           other potential methods for non-visual items
     ///           without the need for a grouping picture.
     PushClipChain,
@@ -1536,16 +1542,19 @@ impl PrimitiveInstance {
                 data_handle.uid()
             }
             PrimitiveInstanceKind::TextRun { data_handle, .. } => {
                 data_handle.uid()
             }
             PrimitiveInstanceKind::YuvImage { data_handle, .. } => {
                 data_handle.uid()
             }
+            PrimitiveInstanceKind::Backdrop { data_handle, .. } => {
+                data_handle.uid()
+            }
             PrimitiveInstanceKind::PushClipChain |
             PrimitiveInstanceKind::PopClipChain => {
                 unreachable!();
             }
         }
     }
 }
 
@@ -1949,16 +1958,53 @@ impl PrimitiveStore {
                     if prim_instance.is_chased() {
                         if pic.unsnapped_local_rect != pic.snapped_local_rect {
                             println!("\tsnapped from {:?} to {:?}", pic.unsnapped_local_rect, pic.snapped_local_rect);
                         }
                     }
 
                     (pic.raster_config.is_none(), false, pic.snapped_local_rect, shadow_rect)
                 }
+                PrimitiveInstanceKind::Backdrop { data_handle } => {
+                    // The actual size and clip rect of this primitive are determined by computing the bounding
+                    // box of the projected rect of the backdrop-filter element onto the backdrop.
+                    let prim_data = &mut frame_state.data_stores.backdrop[data_handle];
+                    let spatial_node_index = prim_data.kind.spatial_node_index;
+
+                    // We cannot use the relative transform between the backdrop and the element because
+                    // that doesn't take into account any projection transforms that both spatial nodes are children of.
+                    // Instead, we first project from the element to the world space and get a flattened 2D bounding rect
+                    // in the screen space, we then map this rect from the world space to the backdrop space to get the
+                    // proper bounding box where the backdrop-filter needs to be processed.
+
+                    let prim_to_world_mapper = SpaceMapper::new_with_target(
+                        ROOT_SPATIAL_NODE_INDEX,
+                        spatial_node_index,
+                        LayoutRect::max_rect(),
+                        frame_context.clip_scroll_tree,
+                    );
+
+                    let backdrop_to_world_mapper = SpaceMapper::new_with_target(
+                        ROOT_SPATIAL_NODE_INDEX,
+                        prim_instance.spatial_node_index,
+                        LayoutRect::max_rect(),
+                        frame_context.clip_scroll_tree,
+                    );
+
+                    // First map to the screen and get a flattened rect
+                    let prim_rect = prim_to_world_mapper.map(&prim_data.kind.border_rect).unwrap_or_else(LayoutRect::zero);
+                    // Backwards project the flattened rect onto the backdrop
+                    let prim_rect = backdrop_to_world_mapper.unmap(&prim_rect).unwrap_or_else(LayoutRect::zero);
+
+                    prim_instance.prim_origin = prim_rect.origin;
+                    prim_data.common.prim_size = prim_rect.size;
+                    prim_instance.local_clip_rect = prim_rect;
+
+                    (false, true, prim_rect, LayoutRect::zero())
+                }
                 _ => {
                     let prim_data = &frame_state.data_stores.as_common_data(&prim_instance);
 
                     let prim_rect = LayoutRect::new(
                         prim_instance.prim_origin,
                         prim_data.prim_size,
                     );
 
@@ -2183,16 +2229,17 @@ impl PrimitiveStore {
                         PrimitiveInstanceKind::NormalBorder { .. } |
                         PrimitiveInstanceKind::ImageBorder { .. } => debug_colors::ORANGE,
                         PrimitiveInstanceKind::Rectangle { .. } => ColorF { r: 0.8, g: 0.8, b: 0.8, a: 0.5 },
                         PrimitiveInstanceKind::YuvImage { .. } => debug_colors::BLUE,
                         PrimitiveInstanceKind::Image { .. } => debug_colors::BLUE,
                         PrimitiveInstanceKind::LinearGradient { .. } => debug_colors::PINK,
                         PrimitiveInstanceKind::RadialGradient { .. } => debug_colors::PINK,
                         PrimitiveInstanceKind::Clear { .. } => debug_colors::CYAN,
+                        PrimitiveInstanceKind::Backdrop { .. } => debug_colors::MEDIUMAQUAMARINE,
                     };
                     if debug_color.a != 0.0 {
                         let debug_rect = clipped_world_rect * frame_context.global_device_pixel_scale;
                         frame_state.scratch.push_debug_rect(debug_rect, debug_color);
                     }
                 }
 
                 let vis_index = PrimitiveVisibilityIndex(frame_state.scratch.prim_info.len() as u32);
@@ -2236,17 +2283,19 @@ impl PrimitiveStore {
         // and stretch size. Drop shadow filters also depend on the local rect
         // size for the extra GPU cache data handle.
         // TODO(gw): In future, if we support specifying a flag which gets the
         //           stretch size from the segment rect in the shaders, we can
         //           remove this invalidation here completely.
         if let Some(ref raster_config) = pic.raster_config {
             // Inflate the local bounding rect if required by the filter effect.
             // This inflaction factor is to be applied to the surface itself.
-            surface_rect = raster_config.composite_mode.inflate_picture_rect(surface_rect, surface.inflation_factor);
+            if pic.options.inflate_if_required {
+                surface_rect = raster_config.composite_mode.inflate_picture_rect(surface_rect, surface.inflation_factor);
+            }
 
             // Layout space for the picture is picture space from the
             // perspective of its child primitives.
             let pic_local_rect = surface_rect * Scale::new(1.0);
             if pic.snapped_local_rect != pic_local_rect {
                 match raster_config.composite_mode {
                     PictureCompositeMode::Filter(Filter::DropShadows(..)) => {
                         for handle in &pic.extra_gpu_data_handles {
@@ -2469,17 +2518,18 @@ impl PrimitiveStore {
             PrimitiveInstanceKind::TextRun { .. } |
             PrimitiveInstanceKind::NormalBorder { .. } |
             PrimitiveInstanceKind::ImageBorder { .. } |
             PrimitiveInstanceKind::YuvImage { .. } |
             PrimitiveInstanceKind::LinearGradient { .. } |
             PrimitiveInstanceKind::RadialGradient { .. } |
             PrimitiveInstanceKind::PushClipChain |
             PrimitiveInstanceKind::PopClipChain |
-            PrimitiveInstanceKind::LineDecoration { .. } => {
+            PrimitiveInstanceKind::LineDecoration { .. } |
+            PrimitiveInstanceKind::Backdrop { .. } => {
                 // These prims don't support opacity collapse
             }
             PrimitiveInstanceKind::Picture { pic_index, .. } => {
                 let pic = &self.pictures[pic_index.0];
 
                 // If we encounter a picture that is a pass-through
                 // (i.e. no composite mode), then we can recurse into
                 // that to try and find a primitive to collapse to.
@@ -2607,17 +2657,18 @@ impl PrimitiveStore {
                 PrimitiveInstanceKind::NormalBorder { .. } |
                 PrimitiveInstanceKind::ImageBorder { .. } |
                 PrimitiveInstanceKind::YuvImage { .. } |
                 PrimitiveInstanceKind::Image { .. } |
                 PrimitiveInstanceKind::LinearGradient { .. } |
                 PrimitiveInstanceKind::RadialGradient { .. } |
                 PrimitiveInstanceKind::PushClipChain |
                 PrimitiveInstanceKind::PopClipChain |
-                PrimitiveInstanceKind::Clear { .. } => {
+                PrimitiveInstanceKind::Clear { .. } |
+                PrimitiveInstanceKind::Backdrop { .. } => {
                     None
                 }
             }
         };
 
         let is_passthrough = match pic_info {
             Some((pic_context_for_children, mut pic_state_for_children, mut prim_list)) => {
                 let is_passthrough = pic_context_for_children.is_passthrough;
@@ -3284,16 +3335,31 @@ impl PrimitiveStore {
                                 ]);
                             }
                         );
                     }
                 } else {
                     prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
                 }
             }
+            PrimitiveInstanceKind::Backdrop { data_handle } => {
+                let backdrop_pic_index = data_stores.backdrop[*data_handle].kind.pic_index;
+
+                // Setup a dependency on the backdrop picture to ensure it is rendered prior to rendering this primitive.
+                let backdrop_surface_index = self.pictures[backdrop_pic_index.0].raster_config.as_ref().unwrap().surface_index;
+                if let Some(backdrop_tasks) = frame_state.surfaces[backdrop_surface_index.0].render_tasks {
+                    let picture_task_id = frame_state.surfaces[pic_context.surface_index.0].render_tasks.as_ref().unwrap().port;
+                    frame_state.render_tasks.add_dependency(picture_task_id, backdrop_tasks.root);
+                } else {
+                    if prim_instance.is_chased() {
+                        println!("\tBackdrop primitive culled because backdrop task was not assigned render tasks");
+                    }
+                    prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
+                }
+            }
             PrimitiveInstanceKind::PushClipChain |
             PrimitiveInstanceKind::PopClipChain => {}
         };
     }
 }
 
 fn write_segment<F>(
     segment_instance_index: SegmentInstanceIndex,
@@ -3614,17 +3680,18 @@ impl PrimitiveInstance {
             PrimitiveInstanceKind::TextRun { .. } |
             PrimitiveInstanceKind::NormalBorder { .. } |
             PrimitiveInstanceKind::ImageBorder { .. } |
             PrimitiveInstanceKind::Clear { .. } |
             PrimitiveInstanceKind::LinearGradient { .. } |
             PrimitiveInstanceKind::RadialGradient { .. } |
             PrimitiveInstanceKind::PushClipChain |
             PrimitiveInstanceKind::PopClipChain |
-            PrimitiveInstanceKind::LineDecoration { .. } => {
+            PrimitiveInstanceKind::LineDecoration { .. } |
+            PrimitiveInstanceKind::Backdrop { .. } => {
                 // These primitives don't support / need segments.
                 return;
             }
         };
 
         if *segment_instance_index == SegmentInstanceIndex::INVALID {
             let mut segments: SmallVec<[BrushSegment; 8]> = SmallVec::new();
 
@@ -3680,17 +3747,18 @@ impl PrimitiveInstance {
         unclipped: &DeviceRect,
         device_pixel_scale: DevicePixelScale,
     ) -> bool {
         let segments = match self.kind {
             PrimitiveInstanceKind::TextRun { .. } |
             PrimitiveInstanceKind::Clear { .. } |
             PrimitiveInstanceKind::PushClipChain |
             PrimitiveInstanceKind::PopClipChain |
-            PrimitiveInstanceKind::LineDecoration { .. } => {
+            PrimitiveInstanceKind::LineDecoration { .. } |
+            PrimitiveInstanceKind::Backdrop { .. } => {
                 return false;
             }
             PrimitiveInstanceKind::Image { image_instance_index, .. } => {
                 let segment_instance_index = prim_store
                     .images[image_instance_index]
                     .segment_instance_index;
 
                 if segment_instance_index == SegmentInstanceIndex::UNUSED {
--- a/gfx/wr/webrender/src/profiler.rs
+++ b/gfx/wr/webrender/src/profiler.rs
@@ -575,16 +575,17 @@ impl BackendProfileCounters {
                 linear_grad: ResourceProfileCounter::new("Interned linear gradients"),
                 normal_border: ResourceProfileCounter::new("Interned normal borders"),
                 picture: ResourceProfileCounter::new("Interned pictures"),
                 radial_grad: ResourceProfileCounter::new("Interned radial gradients"),
                 text_run: ResourceProfileCounter::new("Interned text runs"),
                 yuv_image: ResourceProfileCounter::new("Interned YUV images"),
                 clip: ResourceProfileCounter::new("Interned clips"),
                 filter_data: ResourceProfileCounter::new("Interned filter data"),
+                backdrop: ResourceProfileCounter::new("Interned backdrops"),
             },
         }
     }
 
     pub fn reset(&mut self) {
         self.total_time.reset();
         self.ipc.total_time.reset();
         self.ipc.build_time.reset();
--- a/gfx/wr/webrender/src/render_backend.rs
+++ b/gfx/wr/webrender/src/render_backend.rs
@@ -303,16 +303,20 @@ impl DataStores {
             PrimitiveInstanceKind::TextRun { data_handle, .. }  => {
                 let prim_data = &self.text_run[data_handle];
                 &prim_data.common
             }
             PrimitiveInstanceKind::YuvImage { data_handle, .. } => {
                 let prim_data = &self.yuv_image[data_handle];
                 &prim_data.common
             }
+            PrimitiveInstanceKind::Backdrop { data_handle, .. } => {
+                let prim_data = &self.backdrop[data_handle];
+                &prim_data.common
+            }
             PrimitiveInstanceKind::PushClipChain |
             PrimitiveInstanceKind::PopClipChain => {
                 unreachable!();
             }
         }
     }
 }
 
--- a/gfx/wr/webrender/src/render_task.rs
+++ b/gfx/wr/webrender/src/render_task.rs
@@ -326,17 +326,30 @@ impl RenderTaskGraph {
                 let child_task_index = self.tasks[task_index].children[nth_child].index as usize;
                 let child_pass_index = task_passes[child_task_index];
 
                 if child_pass_index == pass_index - 1 {
                     // This should be the most common case.
                     continue;
                 }
 
-                if child_pass_index % 2 != pass_index % 2 {
+                // TODO: Picture tasks don't support having their dependency tasks redirected.
+                // Pictures store their respective render task(s) on their SurfaceInfo.
+                // We cannot blit the picture task here because we would need to update the
+                // surface's render tasks, but we don't have access to that info here.
+                // Also a surface may be expecting a picture task and not a blit task, so
+                // even if we could update the surface's render task(s), it might cause other issues.
+                // For now we mark the task to be saved rather than trying to redirect to a blit task.
+                let task_is_picture = if let RenderTaskKind::Picture(..) = self.tasks[task_index].kind {
+                    true
+                } else {
+                    false
+                };
+
+                if child_pass_index % 2 != pass_index % 2 || task_is_picture {
                     // The tasks and its dependency aren't on the same targets,
                     // but the dependency needs to be kept alive.
                     self.tasks[child_task_index].mark_for_saving();
                     continue;
                 }
 
                 if let Some(blit_id) = task_redirects[child_task_index] {
                     // We already resolved a similar conflict with a blit task,
@@ -2164,17 +2177,18 @@ pub fn dump_render_tasks_as_svg(
             let task_index = task_id.index as usize;
             let task = &render_tasks.tasks[task_index];
 
             let rect = layout.push_rectangle(node_height);
 
             let tx = rect.x + rect.w / 2.0;
             let ty = rect.y + 10.0;
 
-            let label = text(tx, ty, task.kind.as_str());
+            let saved = if task.saved_index.is_some() { " (Saved)" } else { "" };
+            let label = text(tx, ty, format!("{}{}", task.kind.as_str(), saved));
             let size = text(tx, ty + 12.0, format!("{}", task.location.size()));
 
             nodes[task_index] = Some(Node { rect, label, size });
 
             layout.advance(vertical_spacing);
         }
 
         pass_rects.push(layout.total_rectangle());
--- a/gfx/wr/webrender/src/scene.rs
+++ b/gfx/wr/webrender/src/scene.rs
@@ -1,17 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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::{BuiltDisplayList, ColorF, DynamicProperties, Epoch};
-use api::{FilterOp, TempFilterData, FilterData, FilterPrimitive, ComponentTransferFuncType};
-use api::{PipelineId, PropertyBinding, PropertyBindingId, ItemRange, MixBlendMode, StackingContext};
+use api::{PipelineId, PropertyBinding, PropertyBindingId, MixBlendMode, StackingContext};
 use api::units::{LayoutSize, LayoutTransform};
-use crate::internal_types::{FastHashMap, Filter};
+use crate::internal_types::FastHashMap;
 use std::sync::Arc;
 
 /// Stores a map of the animated property bindings for the current display list. These
 /// can be used to animate the transform and/or opacity of a display list without
 /// re-submitting the display list itself.
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 pub struct SceneProperties {
@@ -193,80 +192,18 @@ impl Scene {
         }
 
         false
     }
 }
 
 pub trait StackingContextHelpers {
     fn mix_blend_mode_for_compositing(&self) -> Option<MixBlendMode>;
-    fn filter_ops_for_compositing(
-        &self,
-        input_filters: ItemRange<FilterOp>,
-    ) -> Vec<Filter>;
-    fn filter_datas_for_compositing(
-        &self,
-        input_filter_datas: &[TempFilterData],
-    ) -> Vec<FilterData>;
-    fn filter_primitives_for_compositing(
-        &self,
-        input_filter_primitives: ItemRange<FilterPrimitive>,
-    ) -> Vec<FilterPrimitive>;
 }
 
 impl StackingContextHelpers for StackingContext {
     fn mix_blend_mode_for_compositing(&self) -> Option<MixBlendMode> {
         match self.mix_blend_mode {
             MixBlendMode::Normal => None,
             _ => Some(self.mix_blend_mode),
         }
     }
-
-    fn filter_ops_for_compositing(
-        &self,
-        input_filters: ItemRange<FilterOp>,
-    ) -> Vec<Filter> {
-        // TODO(gw): Now that we resolve these later on,
-        //           we could probably make it a bit
-        //           more efficient than cloning these here.
-        let mut filters = vec![];
-        for filter in input_filters {
-            filters.push(filter.into());
-        }
-        filters
-    }
-
-    fn filter_datas_for_compositing(
-        &self,
-        input_filter_datas: &[TempFilterData],
-    ) -> Vec<FilterData> {
-        // TODO(gw): Now that we resolve these later on,
-        //           we could probably make it a bit
-        //           more efficient than cloning these here.
-        let mut filter_datas = vec![];
-        for temp_filter_data in input_filter_datas {
-            let func_types : Vec<ComponentTransferFuncType> = temp_filter_data.func_types.iter().collect();
-            debug_assert!(func_types.len() == 4);
-            filter_datas.push( FilterData {
-                func_r_type: func_types[0],
-                r_values: temp_filter_data.r_values.iter().collect(),
-                func_g_type: func_types[1],
-                g_values: temp_filter_data.g_values.iter().collect(),
-                func_b_type: func_types[2],
-                b_values: temp_filter_data.b_values.iter().collect(),
-                func_a_type: func_types[3],
-                a_values: temp_filter_data.a_values.iter().collect(),
-            });
-        }
-        filter_datas
-    }
-
-    fn filter_primitives_for_compositing(
-        &self,
-        input_filter_primitives: ItemRange<FilterPrimitive>,
-    ) -> Vec<FilterPrimitive> {
-        // Resolve these in the flattener?
-        // TODO(gw): Now that we resolve these later on,
-        //           we could probably make it a bit
-        //           more efficient than cloning these here.
-        input_filter_primitives.iter().map(|primitive| primitive.into()).collect()
-    }
 }
--- a/gfx/wr/webrender/src/scene_builder.rs
+++ b/gfx/wr/webrender/src/scene_builder.rs
@@ -13,16 +13,17 @@ use crate::capture::CaptureConfig;
 use crate::frame_builder::{FrameBuilderConfig, FrameBuilder};
 use crate::clip_scroll_tree::ClipScrollTree;
 use crate::display_list_flattener::DisplayListFlattener;
 use crate::hit_test::HitTestingSceneStats;
 use crate::intern::{Internable, Interner, UpdateList};
 use crate::internal_types::{FastHashMap, FastHashSet};
 use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
 use crate::prim_store::PrimitiveStoreStats;
+use crate::prim_store::backdrop::Backdrop;
 use crate::prim_store::borders::{ImageBorder, NormalBorderPrim};
 use crate::prim_store::gradient::{LinearGradient, RadialGradient};
 use crate::prim_store::image::{Image, YuvImage};
 use crate::prim_store::line_dec::LineDecoration;
 use crate::prim_store::picture::Picture;
 use crate::prim_store::text_run::TextRun;
 use crate::resource_cache::{AsyncBlobImageInfo, FontInstanceMap};
 use crate::render_backend::DocumentView;
--- a/gfx/wr/webrender/src/tiling.rs
+++ b/gfx/wr/webrender/src/tiling.rs
@@ -1315,17 +1315,19 @@ impl CompositeOps {
             filters,
             filter_datas,
             filter_primitives,
             mix_blend_mode,
         }
     }
 
     pub fn is_empty(&self) -> bool {
-        self.filters.is_empty() && self.filter_datas.is_empty() && self.mix_blend_mode.is_none()
+        self.filters.is_empty() &&
+            self.filter_primitives.is_empty() &&
+            self.mix_blend_mode.is_none()
     }
 }
 
 /// A rendering-oriented representation of the frame built by the render backend
 /// and presented to the renderer.
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 pub struct Frame {
--- a/gfx/wr/webrender_api/src/api.rs
+++ b/gfx/wr/webrender_api/src/api.rs
@@ -881,16 +881,17 @@ macro_rules! enumerate_interners {
             image: Image,
             yuv_image: YuvImage,
             line_decoration: LineDecoration,
             linear_grad: LinearGradient,
             radial_grad: RadialGradient,
             picture: Picture,
             text_run: TextRun,
             filter_data: FilterDataIntern,
+            backdrop: Backdrop,
         }
     }
 }
 
 macro_rules! declare_interning_memory_report {
     ( $( $name:ident: $ty:ident, )+ ) => {
         #[repr(C)]
         #[derive(AddAssign, Clone, Debug, Default, Deserialize, Serialize)]
new file mode 100644
--- /dev/null
+++ b/gfx/wr/wrench/reftests/filters/backdrop-filter-basic-ref.yaml
@@ -0,0 +1,11 @@
+
+# Tests that a basic invert backdrop-filter works
+---
+root:
+  items:
+    - type: stacking-context
+      bounds: 0 0 0 0
+      items:
+      - type: rect
+        color: [0, 255, 255, 1]
+        bounds: 0 0 256 256
new file mode 100644
--- /dev/null
+++ b/gfx/wr/wrench/reftests/filters/backdrop-filter-basic.yaml
@@ -0,0 +1,21 @@
+# Tests that a basic invert backdrop-filter works
+---
+root:
+  items:
+    - type: stacking-context
+      bounds: 0 0 0 0
+      items:
+      - type: rect
+        color: [255, 0, 0, 1]
+        bounds: 0 0 256 256
+      - type: clip
+        id: 2
+        bounds: 0 0 256 256
+        clip-rect: 0 0 256 256
+      - type: stacking-context
+        bounds: 0 0 0 0
+        items:
+        - type: backdrop-filter
+          bounds: 0 0 256 256
+          clip-node: 2
+          filters: invert(1)
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..382171c2ae92000af8ba16378ea243b4ac6cc863
GIT binary patch
literal 60370
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
LU6lr<XJP*X`ZYS(
new file mode 100644
--- /dev/null
+++ b/gfx/wr/wrench/reftests/filters/backdrop-filter-perspective.yaml
@@ -0,0 +1,28 @@
+# Tests that backdrop filter works with a perspective transform
+---
+root:
+  items:
+    - type: stacking-context
+      bounds: 0 0 0 0
+      perspective: 500
+      items:
+      - type: rect
+        color: [255, 255, 255, 1]
+        bounds: 0 0 1024 1024
+      - image: "firefox.png"
+        bounds: 0 0 256 256
+      - type: stacking-context
+        bounds: 50 50 0 0
+        transform: ["rotate-y(50)", "rotate-z(45)"]
+        items:
+        - type: clip
+          id: 2
+          bounds: 0 0 100 100
+          clip-rect: 0 0 100 100
+        - type: stacking-context
+          bounds: 0 0 0 0
+          items:
+          - type: backdrop-filter
+            bounds: 0 0 100 100
+            clip-and-scroll: 2
+            filters: invert(1)
--- a/gfx/wr/wrench/reftests/filters/reftest.list
+++ b/gfx/wr/wrench/reftests/filters/reftest.list
@@ -51,8 +51,10 @@ skip_on(android) == svg-filter-blend.yam
 skip_on(android,device) == svg-filter-color-matrix.yaml filter-color-matrix-ref.yaml  # fails on Pixel2
 platform(linux,mac) == draw_calls(8) color_targets(8) alpha_targets(0) svg-filter-blur.yaml filter-blur.png # Extra draw call is due to render task graph workaround
 platform(linux,mac) == svg-filter-drop-shadow.yaml svg-filter-drop-shadow.png
 == fuzzy(1,10000) svg-srgb-to-linear.yaml srgb-to-linear-ref.yaml
 platform(linux,mac) == fuzzy(4,28250) svg-filter-drop-shadow-rotate.yaml svg-filter-drop-shadow-rotate-ref.yaml
 platform(linux,mac) == svg-filter-blur-transforms.yaml svg-filter-blur-transforms.png
 platform(linux,mac) == svg-filter-drop-shadow-on-viewport-edge.yaml svg-filter-drop-shadow-on-viewport-edge.png
 platform(linux,mac) == svg-filter-drop-shadow-perspective.yaml svg-filter-drop-shadow-perspective.png
+== backdrop-filter-basic.yaml backdrop-filter-basic-ref.yaml
+platform(linux,mac) == backdrop-filter-perspective.yaml backdrop-filter-perspective.png