Backed out changeset af9417bd8105 (bug 1581448) for wrench bustages on a CLOSED TREE
authorAndreea Pavel <apavel@mozilla.com>
Wed, 18 Sep 2019 09:54:23 +0300
changeset 493709 432fadcfe39ce8252e9d002adaa4f53bb467d215
parent 493708 fd7de93c7ee56f82002189ee3f7b3c10c0549804
child 493710 f1c646b0f812e911f218e7206b57db27d726caa2
push id114097
push usermalexandru@mozilla.com
push dateWed, 18 Sep 2019 10:10:26 +0000
treeherdermozilla-inbound@4dc3da8794c8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1581448
milestone71.0a1
backs outaf9417bd810595fd0dcf122136f481b64bfec3bc
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
Backed out changeset af9417bd8105 (bug 1581448) for wrench bustages on a CLOSED TREE
gfx/webrender_bindings/src/bindings.rs
gfx/wr/webrender/src/hit_test.rs
gfx/wr/webrender/src/internal_types.rs
gfx/wr/webrender/src/picture.rs
gfx/wr/webrender/src/prim_store/backdrop.rs
gfx/wr/webrender/src/prim_store/gradient.rs
gfx/wr/webrender/src/prim_store/image.rs
gfx/wr/webrender/src/prim_store/mod.rs
gfx/wr/webrender/src/prim_store/picture.rs
gfx/wr/webrender/src/scene_building.rs
gfx/wr/webrender_api/src/display_item.rs
gfx/wr/wrench/src/rawtest.rs
gfx/wr/wrench/src/yaml_frame_reader.rs
gfx/wr/wrench/src/yaml_frame_writer.rs
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -2352,27 +2352,16 @@ pub extern "C" fn wr_dp_push_iframe(stat
         rect,
         clip,
         &parent.to_webrender(state.pipeline_id),
         pipeline_id,
         ignore_missing_pipeline,
     );
 }
 
-// A helper fn to construct a PrimitiveFlags
-fn prim_flags(
-    is_backface_visible: bool,
-) -> PrimitiveFlags {
-    if is_backface_visible {
-        PrimitiveFlags::IS_BACKFACE_VISIBLE
-    } else {
-        PrimitiveFlags::empty()
-    }
-}
-
 #[no_mangle]
 pub extern "C" fn wr_dp_push_rect(state: &mut WrState,
                                   rect: LayoutRect,
                                   clip: LayoutRect,
                                   is_backface_visible: bool,
                                   parent: &WrSpaceAndClipChain,
                                   color: ColorF) {
     debug_assert!(unsafe { !is_in_render_thread() });
@@ -2382,17 +2371,17 @@ pub extern "C" fn wr_dp_push_rect(state:
 
     let prim_info = CommonItemProperties {
         // NB: the damp-e10s talos-test will frequently crash on startup if we
         // early-return here for empty rects. I couldn't figure out why, but
         // it's pretty harmless to feed these through, so, uh, we do?
         clip_rect: clip_rect.unwrap_or(LayoutRect::zero()),
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder.dl_builder.push_rect(
         &prim_info,
         color,
     );
 }
@@ -2412,17 +2401,17 @@ pub extern "C" fn wr_dp_push_rect_with_p
 
     let clip_rect = clip.intersection(&rect);
     if clip_rect.is_none() { return; }
 
     let prim_info = CommonItemProperties {
         clip_rect: clip_rect.unwrap(),
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder.dl_builder.push_rect(
         &prim_info,
         color,
     );
 }
@@ -2464,17 +2453,17 @@ pub extern "C" fn wr_dp_push_backdrop_fi
 
     let clip_rect = clip.intersection(&rect);
     if clip_rect.is_none() { return; }
 
     let prim_info = CommonItemProperties {
         clip_rect: clip_rect.unwrap(),
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder.dl_builder.push_backdrop_filter(
         &prim_info,
         &filters,
         &filter_datas,
         &[],
@@ -2492,17 +2481,17 @@ pub extern "C" fn wr_dp_push_clear_rect(
 
     let clip_rect = clip.intersection(&rect);
     if clip_rect.is_none() { return; }
 
     let prim_info = CommonItemProperties {
         clip_rect: clip_rect.unwrap(),
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(true),
+        is_backface_visible: true,
         hit_info: state.current_tag,
     };
 
     state.frame_builder.dl_builder.push_clear_rect(
         &prim_info,
     );
 }
 
@@ -2518,17 +2507,17 @@ pub extern "C" fn wr_dp_push_hit_test(st
 
     let clip_rect = clip.intersection(&rect);
     if clip_rect.is_none() { return; }
 
     let prim_info = CommonItemProperties {
         clip_rect: clip_rect.unwrap(),
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder.dl_builder.push_hit_test(
         &prim_info,
     );
 }
 
@@ -2545,17 +2534,17 @@ pub extern "C" fn wr_dp_push_clear_rect_
 
     let clip_rect = clip.intersection(&rect);
     if clip_rect.is_none() { return; }
 
     let prim_info = CommonItemProperties {
         clip_rect: clip_rect.unwrap(),
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(true),
+        is_backface_visible: true,
         hit_info: state.current_tag,
     };
 
     state.frame_builder.dl_builder.push_clear_rect(
         &prim_info,
     );
 }
 
@@ -2572,17 +2561,17 @@ pub extern "C" fn wr_dp_push_image(state
     debug_assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     let alpha_type = if premultiplied_alpha {
         AlphaType::PremultipliedAlpha
     } else {
         AlphaType::Alpha
     };
@@ -2612,17 +2601,17 @@ pub extern "C" fn wr_dp_push_repeating_i
     debug_assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     let alpha_type = if premultiplied_alpha {
         AlphaType::PremultipliedAlpha
     } else {
         AlphaType::Alpha
     };
@@ -2656,17 +2645,17 @@ pub extern "C" fn wr_dp_push_yuv_planar_
     debug_assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder
          .dl_builder
          .push_yuv_image(&prim_info,
                          bounds,
                          YuvData::PlanarYCbCr(image_key_0, image_key_1, image_key_2),
@@ -2692,17 +2681,17 @@ pub extern "C" fn wr_dp_push_yuv_NV12_im
     debug_assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder
          .dl_builder
          .push_yuv_image(&prim_info,
                          bounds,
                          YuvData::NV12(image_key_0, image_key_1),
@@ -2727,17 +2716,17 @@ pub extern "C" fn wr_dp_push_yuv_interle
     debug_assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder
          .dl_builder
          .push_yuv_image(&prim_info,
                          bounds,
                          YuvData::InterleavedYCbCr(image_key_0),
@@ -2763,17 +2752,17 @@ pub extern "C" fn wr_dp_push_text(state:
     let glyph_slice = unsafe { make_slice(glyphs, glyph_count as usize) };
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         spatial_id: space_and_clip.spatial_id,
         clip_id: space_and_clip.clip_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag
     };
 
     state.frame_builder
          .dl_builder
          .push_text(&prim_info,
                     bounds,
                     &glyph_slice,
@@ -2819,17 +2808,17 @@ pub extern "C" fn wr_dp_push_line(state:
     debug_assert!(unsafe { is_in_main_thread() });
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: *clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder
          .dl_builder
          .push_line(&prim_info,
                     bounds,
                     wavy_line_thickness,
@@ -2864,17 +2853,17 @@ pub extern "C" fn wr_dp_push_border(stat
     });
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder
          .dl_builder
          .push_border(&prim_info,
                       rect,
                       widths,
@@ -2913,17 +2902,17 @@ pub extern "C" fn wr_dp_push_border_imag
         repeat_vertical: params.repeat_vertical,
     });
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder.dl_builder.push_border(
         &prim_info,
         rect,
         params.widths,
         border_details,
@@ -2971,17 +2960,17 @@ pub extern "C" fn wr_dp_push_border_grad
     });
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder.dl_builder.push_border(
         &prim_info,
         rect,
         widths.into(),
         border_details,
@@ -3033,17 +3022,17 @@ pub extern "C" fn wr_dp_push_border_radi
     });
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder.dl_builder.push_border(
         &prim_info,
         rect,
         widths.into(),
         border_details,
@@ -3076,17 +3065,17 @@ pub extern "C" fn wr_dp_push_linear_grad
                                          extend_mode.into());
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder.dl_builder.push_gradient(
         &prim_info,
         rect,
         gradient,
         tile_size.into(),
@@ -3120,17 +3109,17 @@ pub extern "C" fn wr_dp_push_radial_grad
                                                 extend_mode.into());
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder.dl_builder.push_radial_gradient(
         &prim_info,
         rect,
         gradient,
         tile_size,
@@ -3153,17 +3142,17 @@ pub extern "C" fn wr_dp_push_box_shadow(
     debug_assert!(unsafe { is_in_main_thread() });
 
     let space_and_clip = parent.to_webrender(state.pipeline_id);
 
     let prim_info = CommonItemProperties {
         clip_rect: clip,
         clip_id: space_and_clip.clip_id,
         spatial_id: space_and_clip.spatial_id,
-        flags: prim_flags(is_backface_visible),
+        is_backface_visible,
         hit_info: state.current_tag,
     };
 
     state.frame_builder
          .dl_builder
          .push_box_shadow(&prim_info,
                           box_bounds,
                           offset,
--- a/gfx/wr/webrender/src/hit_test.rs
+++ b/gfx/wr/webrender/src/hit_test.rs
@@ -1,13 +1,13 @@
 /* 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::{BorderRadius, ClipMode, HitTestFlags, HitTestItem, HitTestResult, ItemTag, PrimitiveFlags};
+use api::{BorderRadius, ClipMode, HitTestFlags, HitTestItem, HitTestResult, ItemTag};
 use api::PipelineId;
 use api::units::*;
 use crate::clip::{ClipChainId, ClipDataStore, ClipNode, ClipItemKind, ClipStore};
 use crate::clip::{rounded_rectangle_contains_point};
 use crate::clip_scroll_tree::{SpatialNodeIndex, ClipScrollTree};
 use crate::internal_types::{FastHashMap, LayoutPrimitiveInfo};
 use std::{ops, u32};
 use std::sync::Arc;
@@ -99,17 +99,17 @@ impl HitTestingItem {
         info: &LayoutPrimitiveInfo,
         spatial_node_index: SpatialNodeIndex,
         clip_chain_range: ops::Range<HitTestingClipChainIndex>,
     ) -> HitTestingItem {
         HitTestingItem {
             rect: info.rect,
             clip_rect: info.clip_rect,
             tag,
-            is_backface_visible: info.flags.contains(PrimitiveFlags::IS_BACKFACE_VISIBLE),
+            is_backface_visible: info.is_backface_visible,
             spatial_node_index,
             clip_chain_range,
         }
     }
 }
 
 /// Statistics about allocation sizes of current hit tester,
 /// used to pre-allocate size of the next hit tester.
--- a/gfx/wr/webrender/src/internal_types.rs
+++ b/gfx/wr/webrender/src/internal_types.rs
@@ -1,13 +1,13 @@
 /* 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::{ColorF, DebugCommand, DocumentId, ExternalImageData, ExternalImageId, PrimitiveFlags};
+use api::{ColorF, DebugCommand, DocumentId, ExternalImageData, ExternalImageId};
 use api::{ImageFormat, ItemTag, NotificationRequest, Shadow, FilterOp, MAX_BLUR_RADIUS};
 use api::units::*;
 use api;
 use crate::device::TextureFilter;
 use crate::renderer::PipelineInfo;
 use crate::gpu_cache::GpuCacheUpdateList;
 use crate::frame_builder::Frame;
 use fxhash::FxHasher;
@@ -549,22 +549,22 @@ impl ResourceCacheError {
 
 /// Primitive metadata we pass around in a bunch of places
 #[derive(Copy, Clone, Debug)]
 pub struct LayoutPrimitiveInfo {
     /// NOTE: this is *ideally* redundant with the clip_rect
     /// but that's an ongoing project, so for now it exists and is used :(
     pub rect: LayoutRect,
     pub clip_rect: LayoutRect,
-    pub flags: PrimitiveFlags,
+    pub is_backface_visible: bool,
     pub hit_info: Option<ItemTag>,
 }
 
 impl LayoutPrimitiveInfo {
     pub fn with_clip_rect(rect: LayoutRect, clip_rect: LayoutRect) -> Self {
         Self {
             rect,
             clip_rect,
-            flags: PrimitiveFlags::default(),
+            is_backface_visible: true,
             hit_info: None,
         }
     }
 }
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -1,15 +1,15 @@
 /* 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::{MixBlendMode, PipelineId, PremultipliedColorF, FilterPrimitiveKind};
 use api::{PropertyBinding, PropertyBindingId, FilterPrimitive, FontRenderMode};
-use api::{DebugFlags, RasterSpace, ImageKey, ColorF, PrimitiveFlags};
+use api::{DebugFlags, RasterSpace, ImageKey, ColorF};
 use api::units::*;
 use crate::box_shadow::{BLUR_SAMPLE_SCALE};
 use crate::clip::{ClipStore, ClipChainInstance, ClipDataHandle, ClipChainId};
 use crate::clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX,
     ClipScrollTree, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace, CoordinateSystemId
 };
 use crate::debug_colors;
 use euclid::{vec3, Point2D, Scale, Size2D, Vector2D, Rect};
@@ -2342,34 +2342,34 @@ impl PrimitiveList {
     }
 
     /// Add a primitive instance to this list, at the start or end
     fn push(
         &mut self,
         prim_instance: PrimitiveInstance,
         prim_size: LayoutSize,
         spatial_node_index: SpatialNodeIndex,
-        prim_flags: PrimitiveFlags,
+        is_backface_visible: bool,
         insert_position: PrimitiveListPosition,
     ) {
         let mut flags = ClusterFlags::empty();
 
         // Pictures are always put into a new cluster, to make it faster to
         // iterate all pictures in a given primitive list.
         match prim_instance.kind {
             PrimitiveInstanceKind::Picture { .. } => {
                 flags.insert(ClusterFlags::IS_PICTURE);
             }
             PrimitiveInstanceKind::Backdrop { .. } => {
                 flags.insert(ClusterFlags::IS_BACKDROP_FILTER);
             }
             _ => {}
         }
 
-        if prim_flags.contains(PrimitiveFlags::IS_BACKFACE_VISIBLE) {
+        if is_backface_visible {
             flags.insert(ClusterFlags::IS_BACKFACE_VISIBLE);
         }
 
         // Insert the primitive into the first or last cluster as required
         match insert_position {
             PrimitiveListPosition::Begin => {
                 if let Some(cluster) = self.clusters.first_mut() {
                     if cluster.is_compatible(spatial_node_index, flags) {
@@ -2404,40 +2404,40 @@ impl PrimitiveList {
     }
 
     /// Add a primitive instance to the start of the list
     pub fn add_prim_to_start(
         &mut self,
         prim_instance: PrimitiveInstance,
         prim_size: LayoutSize,
         spatial_node_index: SpatialNodeIndex,
-        flags: PrimitiveFlags,
+        is_backface_visible: bool,
     ) {
         self.push(
             prim_instance,
             prim_size,
             spatial_node_index,
-            flags,
+            is_backface_visible,
             PrimitiveListPosition::Begin,
         )
     }
 
     /// Add a primitive instance to the end of the list
     pub fn add_prim(
         &mut self,
         prim_instance: PrimitiveInstance,
         prim_size: LayoutSize,
         spatial_node_index: SpatialNodeIndex,
-        flags: PrimitiveFlags,
+        is_backface_visible: bool,
     ) {
         self.push(
             prim_instance,
             prim_size,
             spatial_node_index,
-            flags,
+            is_backface_visible,
             PrimitiveListPosition::End,
         )
     }
 
     /// Returns true if there are no clusters (and thus primitives)
     pub fn is_empty(&self) -> bool {
         self.clusters.is_empty()
     }
@@ -2643,34 +2643,34 @@ impl PicturePrimitive {
     //           should move some of the parameter list in this
     //           method to be part of the PictureOptions, and
     //           avoid adding new parameters here.
     pub fn new_image(
         requested_composite_mode: Option<PictureCompositeMode>,
         context_3d: Picture3DContext<OrderedPictureChild>,
         frame_output_pipeline_id: Option<PipelineId>,
         apply_local_clip_rect: bool,
-        flags: PrimitiveFlags,
+        is_backface_visible: bool,
         requested_raster_space: RasterSpace,
         prim_list: PrimitiveList,
         spatial_node_index: SpatialNodeIndex,
         tile_cache: Option<Box<TileCacheInstance>>,
         options: PictureOptions,
     ) -> Self {
         PicturePrimitive {
             prim_list,
             state: None,
             secondary_render_task_id: None,
             requested_composite_mode,
             raster_config: None,
             context_3d,
             frame_output_pipeline_id,
             extra_gpu_data_handles: SmallVec::new(),
             apply_local_clip_rect,
-            is_backface_visible: flags.contains(PrimitiveFlags::IS_BACKFACE_VISIBLE),
+            is_backface_visible,
             requested_raster_space,
             spatial_node_index,
             local_rect: LayoutRect::zero(),
             tile_cache,
             options,
             segments_are_valid: false,
         }
     }
--- a/gfx/wr/webrender/src/prim_store/backdrop.rs
+++ b/gfx/wr/webrender/src/prim_store/backdrop.rs
@@ -1,13 +1,12 @@
 /* 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::PrimitiveFlags;
 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,
 };
@@ -30,23 +29,23 @@ impl From<Backdrop> for BackdropData {
         }
     }
 }
 
 pub type BackdropKey = PrimKey<Backdrop>;
 
 impl BackdropKey {
     pub fn new(
-        flags: PrimitiveFlags,
+        is_backface_visible: bool,
         prim_size: LayoutSize,
         backdrop: Backdrop,
     ) -> Self {
         BackdropKey {
             common: PrimKeyCommonData {
-                flags,
+                is_backface_visible,
                 prim_size: prim_size.into(),
             },
             kind: backdrop,
         }
     }
 }
 
 impl InternDebug for BackdropKey {}
@@ -82,17 +81,17 @@ impl Internable for Backdrop {
 }
 
 impl InternablePrimitive for Backdrop {
     fn into_key(
         self,
         info: &LayoutPrimitiveInfo,
     ) -> BackdropKey {
         BackdropKey::new(
-            info.flags,
+            info.is_backface_visible,
             info.rect.size,
             self
         )
     }
 
     fn make_instance_kind(
         _key: BackdropKey,
         data_handle: BackdropDataHandle,
--- a/gfx/wr/webrender/src/prim_store/gradient.rs
+++ b/gfx/wr/webrender/src/prim_store/gradient.rs
@@ -1,15 +1,15 @@
 /* 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::{
     ColorF, ColorU, ExtendMode, GradientStop,
-    PremultipliedColorF, LineOrientation, PrimitiveFlags,
+    PremultipliedColorF, LineOrientation,
 };
 use api::units::{LayoutPoint, LayoutSize, LayoutVector2D};
 use crate::scene_building::IsVisible;
 use euclid::approxeq::ApproxEq;
 use crate::frame_builder::FrameBuildingState;
 use crate::gpu_cache::{GpuCacheHandle, GpuDataRequest};
 use crate::intern::{Internable, InternDebug, Handle as InternHandle};
 use crate::internal_types::LayoutPrimitiveInfo;
@@ -73,23 +73,23 @@ pub struct LinearGradientKey {
     pub tile_spacing: SizeKey,
     pub stops: Vec<GradientStopKey>,
     pub reverse_stops: bool,
     pub nine_patch: Option<Box<NinePatchDescriptor>>,
 }
 
 impl LinearGradientKey {
     pub fn new(
-        flags: PrimitiveFlags,
+        is_backface_visible: bool,
         prim_size: LayoutSize,
         linear_grad: LinearGradient,
     ) -> Self {
         LinearGradientKey {
             common: PrimKeyCommonData {
-                flags,
+                is_backface_visible,
                 prim_size: prim_size.into(),
             },
             extend_mode: linear_grad.extend_mode,
             start_point: linear_grad.start_point,
             end_point: linear_grad.end_point,
             stretch_size: linear_grad.stretch_size,
             tile_spacing: linear_grad.tile_spacing,
             stops: linear_grad.stops,
@@ -303,17 +303,17 @@ impl Internable for LinearGradient {
 }
 
 impl InternablePrimitive for LinearGradient {
     fn into_key(
         self,
         info: &LayoutPrimitiveInfo,
     ) -> LinearGradientKey {
         LinearGradientKey::new(
-            info.flags,
+            info.is_backface_visible,
             info.rect.size,
             self
         )
     }
 
     fn make_instance_kind(
         _key: LinearGradientKey,
         data_handle: LinearGradientDataHandle,
@@ -379,23 +379,23 @@ pub struct RadialGradientKey {
     pub stretch_size: SizeKey,
     pub stops: Vec<GradientStopKey>,
     pub tile_spacing: SizeKey,
     pub nine_patch: Option<Box<NinePatchDescriptor>>,
 }
 
 impl RadialGradientKey {
     pub fn new(
-        flags: PrimitiveFlags,
+        is_backface_visible: bool,
         prim_size: LayoutSize,
         radial_grad: RadialGradient,
     ) -> Self {
         RadialGradientKey {
             common: PrimKeyCommonData {
-                flags,
+                is_backface_visible,
                 prim_size: prim_size.into(),
             },
             extend_mode: radial_grad.extend_mode,
             center: radial_grad.center,
             params: radial_grad.params,
             stretch_size: radial_grad.stretch_size,
             stops: radial_grad.stops,
             tile_spacing: radial_grad.tile_spacing,
@@ -533,17 +533,17 @@ impl Internable for RadialGradient {
 }
 
 impl InternablePrimitive for RadialGradient {
     fn into_key(
         self,
         info: &LayoutPrimitiveInfo,
     ) -> RadialGradientKey {
         RadialGradientKey::new(
-            info.flags,
+            info.is_backface_visible,
             info.rect.size,
             self,
         )
     }
 
     fn make_instance_kind(
         _key: RadialGradientKey,
         data_handle: RadialGradientDataHandle,
--- a/gfx/wr/webrender/src/prim_store/image.rs
+++ b/gfx/wr/webrender/src/prim_store/image.rs
@@ -1,14 +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/. */
 
 use api::{
-    AlphaType, ColorDepth, ColorF, ColorU, PrimitiveFlags,
+    AlphaType, ColorDepth, ColorF, ColorU,
     ImageKey as ApiImageKey, ImageRendering,
     PremultipliedColorF, Shadow, YuvColorSpace, ColorRange, YuvFormat,
 };
 use api::units::*;
 use crate::scene_building::{CreateShadow, IsVisible};
 use crate::frame_builder::FrameBuildingState;
 use crate::gpu_cache::{GpuCache, GpuDataRequest};
 use crate::intern::{Internable, InternDebug, Handle as InternHandle};
@@ -80,23 +80,23 @@ pub struct Image {
     pub image_rendering: ImageRendering,
     pub alpha_type: AlphaType,
 }
 
 pub type ImageKey = PrimKey<Image>;
 
 impl ImageKey {
     pub fn new(
-        flags: PrimitiveFlags,
+        is_backface_visible: bool,
         prim_size: LayoutSize,
         image: Image,
     ) -> Self {
         ImageKey {
             common: PrimKeyCommonData {
-                flags,
+                is_backface_visible,
                 prim_size: prim_size.into(),
             },
             kind: image,
         }
     }
 }
 
 impl InternDebug for ImageKey {}
@@ -322,17 +322,17 @@ impl Internable for Image {
 }
 
 impl InternablePrimitive for Image {
     fn into_key(
         self,
         info: &LayoutPrimitiveInfo,
     ) -> ImageKey {
         ImageKey::new(
-            info.flags,
+            info.is_backface_visible,
             info.rect.size,
             self
         )
     }
 
     fn make_instance_kind(
         _key: ImageKey,
         data_handle: ImageDataHandle,
@@ -388,24 +388,24 @@ pub struct YuvImage {
     pub color_range: ColorRange,
     pub image_rendering: ImageRendering,
 }
 
 pub type YuvImageKey = PrimKey<YuvImage>;
 
 impl YuvImageKey {
     pub fn new(
-        flags: PrimitiveFlags,
+        is_backface_visible: bool,
         prim_size: LayoutSize,
         yuv_image: YuvImage,
     ) -> Self {
 
         YuvImageKey {
             common: PrimKeyCommonData {
-                flags,
+                is_backface_visible,
                 prim_size: prim_size.into(),
             },
             kind: yuv_image,
         }
     }
 }
 
 impl InternDebug for YuvImageKey {}
@@ -504,17 +504,17 @@ impl Internable for YuvImage {
 }
 
 impl InternablePrimitive for YuvImage {
     fn into_key(
         self,
         info: &LayoutPrimitiveInfo,
     ) -> YuvImageKey {
         YuvImageKey::new(
-            info.flags,
+            info.is_backface_visible,
             info.rect.size,
             self,
         )
     }
 
     fn make_instance_kind(
         _key: YuvImageKey,
         data_handle: YuvImageDataHandle,
--- a/gfx/wr/webrender/src/prim_store/mod.rs
+++ b/gfx/wr/webrender/src/prim_store/mod.rs
@@ -1,14 +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/. */
 
 use api::{BorderRadius, ClipMode, ColorF};
-use api::{ImageRendering, RepeatMode, PrimitiveFlags};
+use api::{ImageRendering, RepeatMode};
 use api::{PremultipliedColorF, PropertyBinding, Shadow, GradientStop};
 use api::{BoxShadowClipMode, LineStyle, LineOrientation, BorderStyle};
 use api::{PrimitiveKeyKind};
 use api::units::*;
 use crate::border::{get_max_scale_for_border, build_border_instances};
 use crate::border::BorderSegmentCacheKey;
 use crate::clip::{ClipStore};
 use crate::clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace};
@@ -384,17 +384,17 @@ impl GpuCacheAddress {
 /// The information about an interned primitive that
 /// is stored and available in the scene builder
 /// thread.
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 #[derive(MallocSizeOf)]
 pub struct PrimitiveSceneData {
     pub prim_size: LayoutSize,
-    pub flags: PrimitiveFlags,
+    pub is_backface_visible: bool,
 }
 
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 #[derive(Copy, Debug, Clone, MallocSizeOf, PartialEq)]
 pub struct RectangleKey {
     pub x: f32,
     pub y: f32,
@@ -648,26 +648,26 @@ impl From<WorldPoint> for PointKey {
         }
     }
 }
 
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 #[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash)]
 pub struct PrimKeyCommonData {
-    pub flags: PrimitiveFlags,
+    pub is_backface_visible: bool,
     pub prim_size: SizeKey,
 }
 
 impl PrimKeyCommonData {
     pub fn with_info(
         info: &LayoutPrimitiveInfo,
     ) -> Self {
         PrimKeyCommonData {
-            flags: info.flags,
+            is_backface_visible: info.is_backface_visible,
             prim_size: info.rect.size.into(),
         }
     }
 }
 
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 #[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash)]
@@ -681,23 +681,23 @@ pub struct PrimKey<T: MallocSizeOf> {
 #[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash)]
 pub struct PrimitiveKey {
     pub common: PrimKeyCommonData,
     pub kind: PrimitiveKeyKind,
 }
 
 impl PrimitiveKey {
     pub fn new(
-        flags: PrimitiveFlags,
+        is_backface_visible: bool,
         prim_size: LayoutSize,
         kind: PrimitiveKeyKind,
     ) -> Self {
         PrimitiveKey {
             common: PrimKeyCommonData {
-                flags,
+                is_backface_visible,
                 prim_size: prim_size.into(),
             },
             kind,
         }
     }
 }
 
 impl intern::InternDebug for PrimitiveKey {}
@@ -731,31 +731,31 @@ impl From<PrimitiveKeyKind> for Primitiv
         }
     }
 }
 
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 #[derive(MallocSizeOf)]
 pub struct PrimTemplateCommonData {
-    pub flags: PrimitiveFlags,
+    pub is_backface_visible: bool,
     pub may_need_repetition: bool,
     pub prim_size: LayoutSize,
     pub opacity: PrimitiveOpacity,
     /// The GPU cache handle for a primitive template. Since this structure
     /// is retained across display lists by interning, this GPU cache handle
     /// also remains valid, which reduces the number of updates to the GPU
     /// cache when a new display list is processed.
     pub gpu_cache_handle: GpuCacheHandle,
 }
 
 impl PrimTemplateCommonData {
     pub fn with_key_common(common: PrimKeyCommonData) -> Self {
         PrimTemplateCommonData {
-            flags: common.flags,
+            is_backface_visible: common.is_backface_visible,
             may_need_repetition: true,
             prim_size: common.prim_size.into(),
             gpu_cache_handle: GpuCacheHandle::new(),
             opacity: PrimitiveOpacity::translucent(),
         }
     }
 }
 
@@ -848,17 +848,17 @@ impl intern::Internable for PrimitiveKey
 }
 
 impl InternablePrimitive for PrimitiveKeyKind {
     fn into_key(
         self,
         info: &LayoutPrimitiveInfo,
     ) -> PrimitiveKey {
         PrimitiveKey::new(
-            info.flags,
+            info.is_backface_visible,
             info.rect.size,
             self,
         )
     }
 
     fn make_instance_kind(
         key: PrimitiveKey,
         data_handle: PrimitiveDataHandle,
--- a/gfx/wr/webrender/src/prim_store/picture.rs
+++ b/gfx/wr/webrender/src/prim_store/picture.rs
@@ -1,15 +1,15 @@
 /* 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::{
     ColorU, MixBlendMode, FilterPrimitiveInput, FilterPrimitiveKind, ColorSpace,
-    PropertyBinding, PropertyBindingId, CompositeOperator, PrimitiveFlags,
+    PropertyBinding, PropertyBindingId, CompositeOperator,
 };
 use api::units::{Au, LayoutSize, LayoutVector2D};
 use crate::scene_building::IsVisible;
 use crate::filterdata::SFilterData;
 use crate::intern::ItemUid;
 use crate::intern::{Internable, InternDebug, Handle as InternHandle};
 use crate::internal_types::{LayoutPrimitiveInfo, Filter};
 use crate::picture::PictureCompositeMode;
@@ -234,24 +234,24 @@ impl From<Option<PictureCompositeMode>> 
 pub struct Picture {
     pub composite_mode_key: PictureCompositeKey,
 }
 
 pub type PictureKey = PrimKey<Picture>;
 
 impl PictureKey {
     pub fn new(
-        flags: PrimitiveFlags,
+        is_backface_visible: bool,
         prim_size: LayoutSize,
         pic: Picture,
     ) -> Self {
 
         PictureKey {
             common: PrimKeyCommonData {
-                flags,
+                is_backface_visible,
                 prim_size: prim_size.into(),
             },
             kind: pic,
         }
     }
 }
 
 impl InternDebug for PictureKey {}
@@ -283,17 +283,17 @@ impl Internable for Picture {
 }
 
 impl InternablePrimitive for Picture {
     fn into_key(
         self,
         info: &LayoutPrimitiveInfo,
     ) -> PictureKey {
         PictureKey::new(
-            info.flags,
+            info.is_backface_visible,
             info.rect.size,
             self,
         )
     }
 
     fn make_instance_kind(
         _key: PictureKey,
         _: PictureDataHandle,
--- a/gfx/wr/webrender/src/scene_building.rs
+++ b/gfx/wr/webrender/src/scene_building.rs
@@ -1,13 +1,13 @@
 /* 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, PrimitiveFlags};
+use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter};
 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, MixBlendMode};
 use api::{PropertyBinding, ReferenceFrame, ReferenceFrameKind, ScrollFrameDisplayItem, ScrollSensitivity};
 use api::{Shadow, SpaceAndClipInfo, SpatialId, StackingContext, StickyFrameDisplayItem};
 use api::{ClipMode, PrimitiveKeyKind, TransformStyle, YuvColorSpace, ColorRange, YuvData, TempFilterData};
@@ -663,49 +663,49 @@ impl<'a> SceneBuilder<'a> {
             if clip_chain_instance.push_index < mid_index && clip_chain_instance.pop_index >= mid_index {
                 preceding_prims.add_prim(
                     create_clip_prim_instance(
                         clip_chain_instance.clip_chain_id,
                         PrimitiveInstanceKind::PopClipChain,
                     ),
                     LayoutSize::zero(),
                     clip_chain_instance.spatial_node_index,
-                    PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                    true,
                 );
 
                 remaining_prims.add_prim_to_start(
                     create_clip_prim_instance(
                         clip_chain_instance.clip_chain_id,
                         PrimitiveInstanceKind::PushClipChain,
                     ),
                     LayoutSize::zero(),
                     clip_chain_instance.spatial_node_index,
-                    PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                    true,
                 );
             }
         }
 
         let prim_list = remaining_prims;
 
         // Now, create a picture with tile caching enabled that will hold all
         // of the primitives selected as belonging to the main scroll root.
         let pic_key = PictureKey::new(
-            PrimitiveFlags::IS_BACKFACE_VISIBLE,
+            true,
             LayoutSize::zero(),
             Picture {
                 composite_mode_key: PictureCompositeKey::Identity,
             },
         );
 
         let pic_data_handle = self.interners
             .picture
             .intern(&pic_key, || {
                 PrimitiveSceneData {
                     prim_size: LayoutSize::zero(),
-                    flags: PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                    is_backface_visible: true,
                 }
             }
             );
 
         // Build a clip-chain for the tile cache, that contains any of the shared clips
         // we will apply when drawing the tiles. In all cases provided by Gecko, these
         // are rectangle clips with a scale/offset transform only, and get handled as
         // a simple local clip rect in the vertex shader. However, this should in theory
@@ -727,17 +727,17 @@ impl<'a> SceneBuilder<'a> {
             parent_clip_chain_id,
         ));
 
         let pic_index = self.prim_store.pictures.alloc().init(PicturePrimitive::new_image(
             Some(PictureCompositeMode::TileCache { }),
             Picture3DContext::Out,
             None,
             true,
-            PrimitiveFlags::IS_BACKFACE_VISIBLE,
+            true,
             RasterSpace::Screen,
             prim_list,
             main_scroll_root,
             Some(tile_cache),
             PictureOptions::default(),
         ));
 
         let instance = PrimitiveInstance::new(
@@ -753,17 +753,17 @@ impl<'a> SceneBuilder<'a> {
 
         // This contains the tile caching picture, with preceding and
         // trailing primitives outside the main scroll root.
         main_prim_list.extend(preceding_prims);
         main_prim_list.add_prim(
             instance,
             LayoutSize::zero(),
             main_scroll_root,
-            PrimitiveFlags::IS_BACKFACE_VISIBLE,
+            true,
         );
     }
 
     fn build_items(
         &mut self,
         traversal: &mut BuiltDisplayListIter<'a>,
         pipeline_id: PipelineId,
         apply_pipeline_clip: bool,
@@ -1105,17 +1105,17 @@ impl<'a> SceneBuilder<'a> {
         );
 
         let clip_rect = common.clip_rect.translate(current_offset);
         let rect = bounds.translate(current_offset);
 
         let layout = LayoutPrimitiveInfo {
             rect: snap_to_device.snap_rect(&rect),
             clip_rect: snap_to_device.snap_rect(&clip_rect),
-            flags: common.flags,
+            is_backface_visible: common.is_backface_visible,
             hit_info: common.hit_info,
         };
 
         (layout, rect, clip_and_scroll)
     }
 
     pub fn snap_rect(
         &mut self,
@@ -1589,17 +1589,17 @@ impl<'a> SceneBuilder<'a> {
         let prim_key = prim.into_key(info);
 
         let current_offset = self.current_offset(spatial_node_index);
         let interner = self.interners.as_mut();
         let prim_data_handle = interner
             .intern(&prim_key, || {
                 PrimitiveSceneData {
                     prim_size: info.rect.size,
-                    flags: info.flags,
+                    is_backface_visible: info.is_backface_visible,
                 }
             });
 
         let instance_kind = P::make_instance_kind(
             prim_key,
             prim_data_handle,
             &mut self.prim_store,
             current_offset,
@@ -1654,29 +1654,29 @@ impl<'a> SceneBuilder<'a> {
     }
 
     /// Add an already created primitive to the draw lists.
     pub fn add_primitive_to_draw_list(
         &mut self,
         prim_instance: PrimitiveInstance,
         prim_size: LayoutSize,
         spatial_node_index: SpatialNodeIndex,
-        flags: PrimitiveFlags,
+        is_backface_visible: bool,
     ) {
         // Add primitive to the top-most stacking context on the stack.
         if prim_instance.is_chased() {
             println!("\tadded to stacking context at {}", self.sc_stack.len());
         }
 
         let stacking_context = self.sc_stack.last_mut().unwrap();
         stacking_context.prim_list.add_prim(
             prim_instance,
             prim_size,
             spatial_node_index,
-            flags,
+            is_backface_visible,
         );
     }
 
     /// Convenience interface that creates a primitive entry and adds it
     /// to the draw list.
     fn add_nonshadowable_primitive<P>(
         &mut self,
         clip_and_scroll: ScrollNodeAndClipChain,
@@ -1757,17 +1757,17 @@ impl<'a> SceneBuilder<'a> {
             &info.rect,
             &prim_instance,
         );
         self.add_primitive_to_hit_testing_list(info, clip_and_scroll);
         self.add_primitive_to_draw_list(
             prim_instance,
             info.rect.size,
             clip_and_scroll.spatial_node_index,
-            info.flags,
+            info.is_backface_visible,
         );
     }
 
     pub fn push_stacking_context(
         &mut self,
         pipeline_id: PipelineId,
         composite_ops: CompositeOps,
         transform_style: TransformStyle,
@@ -1816,17 +1816,17 @@ impl<'a> SceneBuilder<'a> {
                     &mut self.interners,
                     Some(PictureCompositeMode::Blit(BlitReason::PRESERVE3D)),
                     flat_items_context_3d,
                 );
                 let extra_instance = extra_instance.map(|(_, instance)| {
                     ExtendedPrimitiveInstance {
                         instance,
                         spatial_node_index: sc.spatial_node_index,
-                        flags: sc.prim_flags,
+                        is_backface_visible: sc.is_backface_visible,
                     }
                 });
                 (true, extra_instance)
             },
             _ => (false, None),
         };
 
         if let Some(instance) = extra_3d_instance {
@@ -1890,28 +1890,22 @@ impl<'a> SceneBuilder<'a> {
         let snap_to_device = self.sc_stack.last().map_or(
             SpaceSnapper::new(
                 ROOT_SPATIAL_NODE_INDEX,
                 device_pixel_scale,
             ),
             |sc| sc.snap_to_device.clone(),
         );
 
-        let prim_flags = if is_backface_visible {
-            PrimitiveFlags::IS_BACKFACE_VISIBLE
-        } else {
-            PrimitiveFlags::empty()
-        };
-
         // Push the SC onto the stack, so we know how to handle things in
         // pop_stacking_context.
         self.sc_stack.push(FlattenedStackingContext {
             prim_list: PrimitiveList::empty(),
             pipeline_id,
-            prim_flags,
+            is_backface_visible,
             requested_raster_space,
             spatial_node_index,
             clip_chain_id,
             frame_output_pipeline_id,
             composite_ops,
             blit_reason,
             transform_style,
             context_3d,
@@ -1940,17 +1934,17 @@ impl<'a> SceneBuilder<'a> {
                         let prim = create_clip_prim_instance(
                             stacking_context.clip_chain_id,
                             PrimitiveInstanceKind::PushClipChain,
                         );
                         parent_sc.prim_list.add_prim(
                             prim,
                             LayoutSize::zero(),
                             stacking_context.spatial_node_index,
-                            PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                            true,
                         );
                     }
 
                     // If the parent context primitives list is empty, it's faster
                     // to assign the storage of the popped context instead of paying
                     // the copying cost for extend.
                     if parent_sc.prim_list.is_empty() {
                         parent_sc.prim_list = stacking_context.prim_list;
@@ -1962,17 +1956,17 @@ impl<'a> SceneBuilder<'a> {
                         let prim = create_clip_prim_instance(
                             stacking_context.clip_chain_id,
                             PrimitiveInstanceKind::PopClipChain,
                         );
                         parent_sc.prim_list.add_prim(
                             prim,
                             LayoutSize::zero(),
                             stacking_context.spatial_node_index,
-                            PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                            true,
                         );
                     }
 
                     return;
                 }
                 parent_sc.prim_list.is_empty()
             },
             None => true,
@@ -2019,29 +2013,29 @@ impl<'a> SceneBuilder<'a> {
             !self.found_explicit_tile_cache &&
             self.config.enable_picture_caching {
 
             let scroll_root = ROOT_SPATIAL_NODE_INDEX;
 
             // Now, create a picture with tile caching enabled that will hold all
             // of the primitives selected as belonging to the main scroll root.
             let pic_key = PictureKey::new(
-                PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                true,
                 LayoutSize::zero(),
                 Picture {
                     composite_mode_key: PictureCompositeKey::Identity,
                 },
             );
 
             let pic_data_handle = self.interners
                 .picture
                 .intern(&pic_key, || {
                     PrimitiveSceneData {
                         prim_size: LayoutSize::zero(),
-                        flags: PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                        is_backface_visible: true,
                     }
                 }
                 );
 
             // TODO(gw): For now, we don't bother trying to share any clips if we create an
             //           implicit picture cache. This cache always caches with a fixed position
             //           root scroll node, so it won't save any invalidations. It might save
             //           some per-item clipping work though. We should handle this by unifying
@@ -2055,17 +2049,17 @@ impl<'a> SceneBuilder<'a> {
                 ClipChainId::NONE,
             );
 
             let pic_index = self.prim_store.pictures.alloc().init(PicturePrimitive::new_image(
                 Some(PictureCompositeMode::TileCache {}),
                 Picture3DContext::Out,
                 None,
                 true,
-                PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                true,
                 RasterSpace::Screen,
                 stacking_context.prim_list,
                 scroll_root,
                 Some(Box::new(tile_cache)),
                 PictureOptions::default(),
             ));
 
             let instance = PrimitiveInstance::new(
@@ -2079,110 +2073,110 @@ impl<'a> SceneBuilder<'a> {
                 ClipChainId::NONE,
             );
 
             let mut prim_list = PrimitiveList::empty();
             prim_list.add_prim(
                 instance,
                 LayoutSize::zero(),
                 scroll_root,
-                PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                true,
             );
             stacking_context.prim_list = prim_list;
         }
 
         // Add picture for this actual stacking context contents to render into.
         let leaf_pic_index = PictureIndex(self.prim_store.pictures
             .alloc()
             .init(PicturePrimitive::new_image(
                 leaf_composite_mode.clone(),
                 leaf_context_3d,
                 leaf_output_pipeline_id,
                 true,
-                stacking_context.prim_flags,
+                stacking_context.is_backface_visible,
                 stacking_context.requested_raster_space,
                 stacking_context.prim_list,
                 stacking_context.spatial_node_index,
                 None,
                 PictureOptions::default(),
             ))
         );
 
         // Create a chain of pictures based on presence of filters,
         // mix-blend-mode and/or 3d rendering context containers.
 
         let mut current_pic_index = leaf_pic_index;
         let mut cur_instance = create_prim_instance(
             leaf_pic_index,
             leaf_composite_mode.into(),
-            stacking_context.prim_flags,
+            stacking_context.is_backface_visible,
             ClipChainId::NONE,
             &mut self.interners,
         );
 
         if cur_instance.is_chased() {
             println!("\tis a leaf primitive for a stacking context");
         }
 
         // If establishing a 3d context, the `cur_instance` represents
         // a picture with all the *trailing* immediate children elements.
         // We append this to the preserve-3D picture set and make a container picture of them.
         if let Picture3DContext::In { root_data: Some(mut prims), ancestor_index } = stacking_context.context_3d {
             prims.push(ExtendedPrimitiveInstance {
                 instance: cur_instance,
                 spatial_node_index: stacking_context.spatial_node_index,
-                flags: stacking_context.prim_flags,
+                is_backface_visible: stacking_context.is_backface_visible,
             });
 
             let mut prim_list = PrimitiveList::empty();
             for ext_prim in prims.drain(..) {
                 prim_list.add_prim(
                     ext_prim.instance,
                     LayoutSize::zero(),
                     ext_prim.spatial_node_index,
-                    ext_prim.flags,
+                    ext_prim.is_backface_visible,
                 );
             }
 
             // This is the acttual picture representing our 3D hierarchy root.
             current_pic_index = PictureIndex(self.prim_store.pictures
                 .alloc()
                 .init(PicturePrimitive::new_image(
                     None,
                     Picture3DContext::In {
                         root_data: Some(Vec::new()),
                         ancestor_index,
                     },
                     stacking_context.frame_output_pipeline_id,
                     true,
-                    stacking_context.prim_flags,
+                    stacking_context.is_backface_visible,
                     stacking_context.requested_raster_space,
                     prim_list,
                     stacking_context.spatial_node_index,
                     None,
                     PictureOptions::default(),
                 ))
             );
 
             cur_instance = create_prim_instance(
                 current_pic_index,
                 PictureCompositeKey::Identity,
-                stacking_context.prim_flags,
+                stacking_context.is_backface_visible,
                 ClipChainId::NONE,
                 &mut self.interners,
             );
         }
 
         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.prim_flags,
+            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;
 
@@ -2201,40 +2195,40 @@ impl<'a> SceneBuilder<'a> {
         let has_mix_blend = if let (Some(mix_blend_mode), false) = (stacking_context.composite_ops.mix_blend_mode, parent_is_empty) {
             let composite_mode = Some(PictureCompositeMode::MixBlend(mix_blend_mode));
 
             let mut prim_list = PrimitiveList::empty();
             prim_list.add_prim(
                 cur_instance.clone(),
                 LayoutSize::zero(),
                 stacking_context.spatial_node_index,
-                stacking_context.prim_flags,
+                stacking_context.is_backface_visible,
             );
 
             let blend_pic_index = PictureIndex(self.prim_store.pictures
                 .alloc()
                 .init(PicturePrimitive::new_image(
                     composite_mode.clone(),
                     Picture3DContext::Out,
                     None,
                     true,
-                    stacking_context.prim_flags,
+                    stacking_context.is_backface_visible,
                     stacking_context.requested_raster_space,
                     prim_list,
                     stacking_context.spatial_node_index,
                     None,
                     PictureOptions::default(),
                 ))
             );
 
             current_pic_index = blend_pic_index;
             cur_instance = create_prim_instance(
                 blend_pic_index,
                 composite_mode.into(),
-                stacking_context.prim_flags,
+                stacking_context.is_backface_visible,
                 ClipChainId::NONE,
                 &mut self.interners,
             );
 
             if cur_instance.is_chased() {
                 println!("\tis a mix-blend picture for a stacking context with {:?}", mix_blend_mode);
             }
             true
@@ -2261,34 +2255,34 @@ impl<'a> SceneBuilder<'a> {
                 // make this picture as isolated.
                 if has_mix_blend {
                     parent_sc.blit_reason |= BlitReason::ISOLATE;
                 }
                 parent_sc.prim_list.add_prim(
                     cur_instance,
                     LayoutSize::zero(),
                     stacking_context.spatial_node_index,
-                    stacking_context.prim_flags,
+                    stacking_context.is_backface_visible,
                 );
                 None
             }
             // This must be the root stacking context
             None => {
                 self.root_pic_index = current_pic_index;
                 None
             }
         };
 
         // finally, if there any outstanding 3D primitive instances,
         // find the 3D hierarchy root and add them there.
         if let Some(instance) = trailing_children_instance {
             self.add_primitive_instance_to_3d_root(ExtendedPrimitiveInstance {
                 instance,
                 spatial_node_index: stacking_context.spatial_node_index,
-                flags: stacking_context.prim_flags,
+                is_backface_visible: stacking_context.is_backface_visible,
             });
         }
 
         assert!(
             self.pending_shadow_items.is_empty(),
             "Found unpopped shadows when popping stacking context!"
         );
     }
@@ -2607,52 +2601,53 @@ impl<'a> SceneBuilder<'a> {
                         // Create a picture that the shadow primitives will be added to. If the
                         // blur radius is 0, the code in Picture::prepare_for_render will
                         // detect this and mark the picture to be drawn directly into the
                         // parent picture, which avoids an intermediate surface and blur.
                         let mut blur_filter = Filter::Blur(std_deviation);
                         blur_filter.sanitize();
                         let composite_mode = PictureCompositeMode::Filter(blur_filter);
                         let composite_mode_key = Some(composite_mode.clone()).into();
+                        let is_backface_visible = true; //TODO: double check this
 
                         // Pass through configuration information about whether WR should
                         // do the bounding rect inflation for text shadows.
                         let options = PictureOptions {
                             inflate_if_required: pending_shadow.should_inflate,
                         };
 
                         // Create the primitive to draw the shadow picture into the scene.
                         let shadow_pic_index = PictureIndex(self.prim_store.pictures
                             .alloc()
                             .init(PicturePrimitive::new_image(
                                 Some(composite_mode),
                                 Picture3DContext::Out,
                                 None,
                                 is_passthrough,
-                                PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                                is_backface_visible,
                                 raster_space,
                                 prim_list,
                                 pending_shadow.clip_and_scroll.spatial_node_index,
                                 None,
                                 options,
                             ))
                         );
 
                         let shadow_pic_key = PictureKey::new(
-                            PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                            true,
                             LayoutSize::zero(),
                             Picture { composite_mode_key },
                         );
 
                         let shadow_prim_data_handle = self.interners
                             .picture
                             .intern(&shadow_pic_key, || {
                                 PrimitiveSceneData {
                                     prim_size: LayoutSize::zero(),
-                                    flags: PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                                    is_backface_visible: true,
                                 }
                             }
                         );
 
                         let shadow_prim_instance = PrimitiveInstance::new(
                             LayoutPoint::zero(),
                             LayoutRect::max_rect(),
                             PrimitiveInstanceKind::Picture {
@@ -2664,17 +2659,17 @@ impl<'a> SceneBuilder<'a> {
                         );
 
                         // Add the shadow primitive. This must be done before pushing this
                         // picture on to the shadow stack, to avoid infinite recursion!
                         self.add_primitive_to_draw_list(
                             shadow_prim_instance,
                             LayoutSize::zero(),
                             pending_shadow.clip_and_scroll.spatial_node_index,
-                            PrimitiveFlags::IS_BACKFACE_VISIBLE,
+                            true,
                         );
                     }
                 }
                 ShadowItem::Image(pending_image) => {
                     self.add_shadow_prim_to_draw_list(
                         pending_image,
                     )
                 },
@@ -2742,17 +2737,17 @@ impl<'a> SceneBuilder<'a> {
             pending_primitive.prim.create_shadow(&pending_shadow.shadow),
         );
 
         // Add the new primitive to the shadow picture.
         prim_list.add_prim(
             shadow_prim_instance,
             info.rect.size,
             pending_primitive.clip_and_scroll.spatial_node_index,
-            info.flags,
+            info.is_backface_visible,
         );
     }
 
     fn add_shadow_prim_to_draw_list<P>(
         &mut self,
         pending_primitive: PendingPrimitive<P>,
     ) where
         P: InternablePrimitive + IsVisible,
@@ -3298,61 +3293,61 @@ impl<'a> SceneBuilder<'a> {
         );
 
         // 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 prim_flags = stacking_context.prim_flags;
+            let is_backface_visible = stacking_context.is_backface_visible;
             let composite_mode = None;
 
             let mut prim_list = PrimitiveList::empty();
             prim_list.add_prim(
                 instance,
                 LayoutSize::zero(),
                 backdrop_spatial_node_index,
-                prim_flags,
+                is_backface_visible,
             );
 
             backdrop_pic_index = PictureIndex(self.prim_store.pictures
                 .alloc()
                 .init(PicturePrimitive::new_image(
                     composite_mode.clone(),
                     Picture3DContext::Out,
                     None,
                     true,
-                    prim_flags,
+                    is_backface_visible,
                     requested_raster_space,
                     prim_list,
                     backdrop_spatial_node_index,
                     None,
                     PictureOptions {
                        inflate_if_required: false,
                     },
                 ))
             );
 
             instance = create_prim_instance(
                 backdrop_pic_index,
                 composite_mode.into(),
-                prim_flags,
+                is_backface_visible,
                 clip_chain_id,
                 &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.flags,
+            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
@@ -3365,17 +3360,17 @@ impl<'a> SceneBuilder<'a> {
             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.flags,
+                info.is_backface_visible,
                 requested_raster_space,
                 backdrop_spatial_node_index,
                 false,
             );
 
             filtered_instance = instance;
             filtered_pic_index = pic_index;
         }
@@ -3387,71 +3382,71 @@ impl<'a> SceneBuilder<'a> {
             .rev()
             .find(|sc| sc.is_backdrop_root)
             .unwrap()
             .prim_list
             .add_prim(
                 filtered_instance,
                 LayoutSize::zero(),
                 backdrop_spatial_node_index,
-                info.flags,
+                info.is_backface_visible,
             );
     }
 
     pub fn cut_backdrop_picture(&mut self) -> Option<PictureIndex> {
         let mut flattened_items = None;
         let mut backdrop_root =  None;
         let mut spatial_node_index = SpatialNodeIndex::INVALID;
-        let mut prim_flags = PrimitiveFlags::default();
+        let mut is_backface_visible = true;
         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.prim_list.add_prim(
                     flattened_instance,
                     LayoutSize::zero(),
                     spatial_node_index,
-                    prim_flags,
+                    is_backface_visible,
                 );
             }
             flattened_items = sc.cut_item_sequence(
                 &mut self.prim_store,
                 &mut self.interners,
                 None,
                 Picture3DContext::Out,
             );
             spatial_node_index = sc.spatial_node_index;
-            prim_flags = sc.prim_flags;
+            is_backface_visible = sc.is_backface_visible;
             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")
             .prim_list
             .add_prim(
                 instance,
                 LayoutSize::zero(),
                 spatial_node_index,
-                prim_flags,
+                is_backface_visible,
             );
 
         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>,
-        flags: PrimitiveFlags,
+        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(),
@@ -3494,42 +3489,42 @@ impl<'a> SceneBuilder<'a> {
                 _ => PictureCompositeMode::Filter(filter.clone()),
             });
 
             let mut prim_list = PrimitiveList::empty();
             prim_list.add_prim(
                 cur_instance.clone(),
                 LayoutSize::zero(),
                 spatial_node_index,
-                flags,
+                is_backface_visible,
             );
 
             let filter_pic_index = PictureIndex(self.prim_store.pictures
                 .alloc()
                 .init(PicturePrimitive::new_image(
                     composite_mode.clone(),
                     Picture3DContext::Out,
                     None,
                     true,
-                    flags,
+                    is_backface_visible,
                     requested_raster_space,
                     prim_list,
                     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(),
-                flags,
+                is_backface_visible,
                 ClipChainId::NONE,
                 &mut self.interners,
             );
 
             if cur_instance.is_chased() {
                 println!("\tis a composite picture for a stacking context with {:?}", filter);
             }
 
@@ -3565,42 +3560,42 @@ impl<'a> SceneBuilder<'a> {
                 filter_datas,
             );
 
             let mut prim_list = PrimitiveList::empty();
             prim_list.add_prim(
                 cur_instance.clone(),
                 LayoutSize::zero(),
                 spatial_node_index,
-                flags,
+                is_backface_visible,
             );
 
             let filter_pic_index = PictureIndex(self.prim_store.pictures
                 .alloc()
                 .init(PicturePrimitive::new_image(
                     Some(composite_mode.clone()),
                     Picture3DContext::Out,
                     None,
                     true,
-                    flags,
+                    is_backface_visible,
                     requested_raster_space,
                     prim_list,
                     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(),
-                flags,
+                is_backface_visible,
                 ClipChainId::NONE,
                 &mut self.interners,
             );
 
             if cur_instance.is_chased() {
                 println!("\tis a composite picture for a stacking context with an SVG filter");
             }
 
@@ -3622,28 +3617,28 @@ pub trait IsVisible {
 }
 
 /// A primitive instance + some extra information about the primitive. This is
 /// stored when constructing 3d rendering contexts, which involve cutting
 /// primitive lists.
 struct ExtendedPrimitiveInstance {
     instance: PrimitiveInstance,
     spatial_node_index: SpatialNodeIndex,
-    flags: PrimitiveFlags,
+    is_backface_visible: bool,
 }
 
 /// Properties of a stacking context that are maintained
 /// during creation of the scene. These structures are
 /// not persisted after the initial scene build.
 struct FlattenedStackingContext {
     /// The list of primitive instances added to this stacking context.
     prim_list: PrimitiveList,
 
-    /// Primitive instance flags for compositing this stacking context
-    prim_flags: PrimitiveFlags,
+    /// Whether this stacking context is visible when backfacing
+    is_backface_visible: bool,
 
     /// Whether or not the caller wants this drawn in
     /// screen space (quality) or local space (performance)
     requested_raster_space: RasterSpace,
 
     /// The positioning node for this stacking context
     spatial_node_index: SpatialNodeIndex,
 
@@ -3714,17 +3709,17 @@ impl FlattenedStackingContext {
         // We can skip mix-blend modes if they are the first primitive in a stacking context,
         // see pop_stacking_context for a full explanation.
         if !self.composite_ops.mix_blend_mode.is_none() &&
             !parent.prim_list.is_empty() {
             return false;
         }
 
         // If backface visibility is explicitly set.
-        if !self.prim_flags.contains(PrimitiveFlags::IS_BACKFACE_VISIBLE) {
+        if !self.is_backface_visible {
             return false;
         }
 
         // If rasterization space is different
         if self.requested_raster_space != parent.requested_raster_space {
             return false;
         }
 
@@ -3756,29 +3751,29 @@ impl FlattenedStackingContext {
 
         let pic_index = PictureIndex(prim_store.pictures
             .alloc()
             .init(PicturePrimitive::new_image(
                 composite_mode.clone(),
                 flat_items_context_3d,
                 None,
                 true,
-                self.prim_flags,
+                self.is_backface_visible,
                 self.requested_raster_space,
                 mem::replace(&mut self.prim_list, PrimitiveList::empty()),
                 self.spatial_node_index,
                 None,
                 PictureOptions::default(),
             ))
         );
 
         let prim_instance = create_prim_instance(
             pic_index,
             composite_mode.into(),
-            self.prim_flags,
+            self.is_backface_visible,
             self.clip_chain_id,
             interners,
         );
 
         Some((pic_index, prim_instance))
     }
 }
 
@@ -3836,32 +3831,32 @@ impl From<PendingPrimitive<TextRun>> for
     fn from(text_run: PendingPrimitive<TextRun>) -> Self {
         ShadowItem::TextRun(text_run)
     }
 }
 
 fn create_prim_instance(
     pic_index: PictureIndex,
     composite_mode_key: PictureCompositeKey,
-    flags: PrimitiveFlags,
+    is_backface_visible: bool,
     clip_chain_id: ClipChainId,
     interners: &mut Interners,
 ) -> PrimitiveInstance {
     let pic_key = PictureKey::new(
-        flags,
+        is_backface_visible,
         LayoutSize::zero(),
         Picture { composite_mode_key },
     );
 
     let data_handle = interners
         .picture
         .intern(&pic_key, || {
             PrimitiveSceneData {
                 prim_size: LayoutSize::zero(),
-                flags,
+                is_backface_visible,
             }
         }
     );
 
     PrimitiveInstance::new(
         LayoutPoint::zero(),
         LayoutRect::max_rect(),
         PrimitiveInstanceKind::Picture {
--- a/gfx/wr/webrender_api/src/display_item.rs
+++ b/gfx/wr/webrender_api/src/display_item.rs
@@ -28,64 +28,45 @@ pub const MAX_BLUR_RADIUS: f32 = 300.;
 /// is missing then the item doesn't take part in hit testing at all. This
 /// is composed of two numbers. In Servo, the first is an identifier while the
 /// second is used to select the cursor that should be used during mouse
 /// movement. In Gecko, the first is a scrollframe identifier, while the second
 /// is used to store various flags that APZ needs to properly process input
 /// events.
 pub type ItemTag = (u64, u16);
 
-bitflags! {
-    #[derive(Deserialize, MallocSizeOf, Serialize, PeekPoke)]
-    pub struct PrimitiveFlags: u8 {
-        /// The CSS backface-visibility property (yes, it can be really granular)
-        const IS_BACKFACE_VISIBLE = 1 << 0;
-        /// If set, this primitive represents part of a scroll bar
-        const IS_SCROLL_BAR = 1 << 1;
-    }
-}
-
-impl Default for PrimitiveFlags {
-    fn default() -> Self {
-        PrimitiveFlags::IS_BACKFACE_VISIBLE
-    }
-}
-
 /// A grouping of fields a lot of display items need, just to avoid
 /// repeating these over and over in this file.
 #[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
 pub struct CommonItemProperties {
     /// Bounds of the display item to clip to. Many items are logically
     /// infinite, and rely on this clip_rect to define their bounds
     /// (solid colors, background-images, gradients, etc).
     pub clip_rect: LayoutRect,
     /// Additional clips
     pub clip_id: ClipId,
     /// The coordinate-space the item is in (yes, it can be really granular)
     pub spatial_id: SpatialId,
     /// Opaque bits for our clients to use for hit-testing. This is the most
     /// dubious "common" field, but because it's an Option, it usually only
     /// wastes a single byte (for None).
     pub hit_info: Option<ItemTag>,
-    /// Various flags describing properties of this primitive.
-    pub flags: PrimitiveFlags,
+    /// The CSS backface-visibility property (yes, it can be really granular)
+    pub is_backface_visible: bool,
 }
 
 impl CommonItemProperties {
     /// Convenience for tests.
-    pub fn new(
-        clip_rect: LayoutRect,
-        space_and_clip: SpaceAndClipInfo,
-    ) -> Self {
+    pub fn new(clip_rect: LayoutRect, space_and_clip: SpaceAndClipInfo) -> Self {
         Self {
             clip_rect,
             spatial_id: space_and_clip.spatial_id,
             clip_id: space_and_clip.clip_id,
             hit_info: None,
-            flags: PrimitiveFlags::default(),
+            is_backface_visible: true,
         }
     }
 }
 
 /// Per-primitive information about the nodes in the clip tree and
 /// the spatial tree that the primitive belongs to.
 ///
 /// Note: this is a separate struct from `PrimitiveInfo` because
--- a/gfx/wr/wrench/src/rawtest.rs
+++ b/gfx/wr/wrench/src/rawtest.rs
@@ -113,32 +113,32 @@ impl<'a> RawtestHarness<'a> {
     }
 
     fn make_common_properties(&self, clip_rect: LayoutRect) -> CommonItemProperties {
         let space_and_clip = SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id);
         CommonItemProperties {
             clip_rect,
             clip_id: space_and_clip.clip_id,
             spatial_id: space_and_clip.spatial_id,
-            flags: PrimitiveFlags::default(),
+            is_backface_visible: true,
             hit_info: None,
         }
     }
 
     fn make_common_properties_with_clip_and_spatial(
         &self,
         clip_rect: LayoutRect,
         clip_id: ClipId,
         spatial_id: SpatialId
     ) -> CommonItemProperties {
         CommonItemProperties {
             clip_rect,
             clip_id,
             spatial_id,
-            flags: PrimitiveFlags::default(),
+            is_backface_visible: true,
             hit_info: None,
         }
     }
 
     fn test_resize_image(&mut self) {
         println!("\tresize image...");
         // This test changes the size of an image to make it go switch back and forth
         // between tiled and non-tiled.
@@ -317,17 +317,17 @@ impl<'a> RawtestHarness<'a> {
             vec![],
             None,
         );
 
         let info = CommonItemProperties {
             clip_rect: rect(0.0, 0.0, 800.0, 800.0),
             clip_id,
             spatial_id: root_space_and_clip.spatial_id,
-            flags: PrimitiveFlags::default(),
+            is_backface_visible: true,
             hit_info: None,
         };
 
         // setup some malicious image size parameters
         builder.push_repeating_image(
             &info,
             size2(15000.0, 15000.0).into(),
             size2(15000.0, 15000.0),
@@ -949,17 +949,17 @@ impl<'a> RawtestHarness<'a> {
                         color: ColorF::new(0.0, 0.0, 0.0, 1.0),
                     },
                     true,
                 );
                 let info = CommonItemProperties {
                     clip_rect: rect(110., 110., 50., 2.),
                     clip_id,
                     spatial_id,
-                    flags: PrimitiveFlags::default(),
+                    is_backface_visible: true,
                     hit_info: None,
                 };
                 builder.push_line(
                     &info,
                     &info.clip_rect,
                     0.0, LineOrientation::Horizontal,
                     &ColorF::new(0.0, 0.0, 0.0, 1.0),
                     LineStyle::Solid,
@@ -1204,17 +1204,17 @@ impl<'a> RawtestHarness<'a> {
             None,
         );
         builder.push_rect(
             &CommonItemProperties {
                 hit_info: Some((0, 4)),
                 clip_rect: rect,
                 clip_id: temp_clip_id,
                 spatial_id: space_and_clip.spatial_id,
-                flags: PrimitiveFlags::default(),
+                is_backface_visible: true,
             },
             ColorF::new(1.0, 1.0, 1.0, 1.0),
         );
 
         // Add a rectangle that is clipped by a ClipChain containing a rounded rect.
         let rect = LayoutRect::new(LayoutPoint::new(200., 100.), LayoutSize::new(100., 100.));
         let clip_id = builder.define_clip(
             &space_and_clip,
@@ -1224,17 +1224,17 @@ impl<'a> RawtestHarness<'a> {
         );
         let clip_chain_id = builder.define_clip_chain(None, vec![clip_id]);
         builder.push_rect(
             &CommonItemProperties {
                 hit_info: Some((0, 5)),
                 clip_rect: rect,
                 clip_id: ClipId::ClipChain(clip_chain_id),
                 spatial_id: space_and_clip.spatial_id,
-                flags: PrimitiveFlags::default(),
+                is_backface_visible: true,
             },
             ColorF::new(1.0, 1.0, 1.0, 1.0),
         );
 
         let mut epoch = Epoch(0);
         let txn = Transaction::new();
         self.submit_dl(&mut epoch, layout_size, builder, &txn.resource_updates);
 
--- a/gfx/wr/wrench/src/yaml_frame_reader.rs
+++ b/gfx/wr/wrench/src/yaml_frame_reader.rs
@@ -459,17 +459,17 @@ impl YamlFrameReader {
         self.spatial_id_stack.push(SpatialId::root_scroll_node(pipeline_id));
 
         let content_size = self.get_root_size_from_yaml(wrench, yaml);
         let mut builder = DisplayListBuilder::new(pipeline_id, content_size);
         let mut info = CommonItemProperties {
             clip_rect: LayoutRect::zero(),
             clip_id: ClipId::invalid(),
             spatial_id: SpatialId::new(0, PipelineId::dummy()),
-            flags: PrimitiveFlags::default(),
+            is_backface_visible: true,
             hit_info: None,
         };
         self.add_stacking_context_from_yaml(&mut builder, wrench, yaml, true, &mut info);
         self.display_lists.push(builder.finalize());
 
         assert_eq!(self.clip_id_stack.len(), 1);
         assert_eq!(self.spatial_id_stack.len(), 1);
     }
@@ -1638,31 +1638,22 @@ impl YamlFrameReader {
                         );
                         self.clip_id_stack.push(id);
                         pushed_clip = true;
                     }
                 }
             }
 
             let space_and_clip = self.top_space_and_clip();
-            let mut flags = PrimitiveFlags::default();
-            if let Some(is_backface_visible) = item["backface-visible"].as_bool() {
-                if is_backface_visible {
-                    flags.insert(PrimitiveFlags::IS_BACKFACE_VISIBLE);
-                } else {
-                    flags.remove(PrimitiveFlags::IS_BACKFACE_VISIBLE);
-                }
-            }
-
             let mut info = CommonItemProperties {
                 clip_rect,
                 clip_id: space_and_clip.clip_id,
                 spatial_id: space_and_clip.spatial_id,
                 hit_info: self.to_hit_testing_tag(&item["hit-testing-tag"]),
-                flags,
+                is_backface_visible: item["backface-visible"].as_bool().unwrap_or(true),
             };
 
             match item_type {
                 "rect" => self.handle_rect(dl, item, &mut info),
                 "hit-test" => self.handle_hit_test(dl, item, &mut info),
                 "clear-rect" => self.handle_clear_rect(dl, item, &mut info),
                 "line" => self.handle_line(dl, item, &mut info),
                 "image" => self.handle_image(dl, wrench, item, &mut info),
@@ -2030,17 +2021,17 @@ impl YamlFrameReader {
 
         let filters = yaml["filters"].as_vec_filter_op().unwrap_or(vec![]);
         let filter_datas = yaml["filter-datas"].as_vec_filter_data().unwrap_or(vec![]);
         let filter_primitives = yaml["filter-primitives"].as_vec_filter_primitive().unwrap_or(vec![]);
 
         dl.push_stacking_context(
             bounds.origin,
             *self.spatial_id_stack.last().unwrap(),
-            info.flags.contains(PrimitiveFlags::IS_BACKFACE_VISIBLE),
+            info.is_backface_visible,
             clip_node_id,
             transform_style,
             mix_blend_mode,
             &filters,
             &filter_datas,
             &filter_primitives,
             raster_space,
             cache_tiles,
--- a/gfx/wr/wrench/src/yaml_frame_writer.rs
+++ b/gfx/wr/wrench/src/yaml_frame_writer.rs
@@ -198,17 +198,17 @@ fn maybe_radius_yaml(radius: &BorderRadi
         size_node(&mut table, "bottom-left", &radius.bottom_left);
         size_node(&mut table, "bottom-right", &radius.bottom_right);
         Some(Yaml::Hash(table))
     }
 }
 
 fn common_node(v: &mut Table, clip_id_mapper: &mut ClipIdMapper, info: &CommonItemProperties) {
     rect_node(v, "clip-rect", &info.clip_rect);
-    bool_node(v, "backface-visible", info.flags.contains(PrimitiveFlags::IS_BACKFACE_VISIBLE));
+    bool_node(v, "backface-visible", info.is_backface_visible);
 
     clip_and_scroll_node(v, clip_id_mapper, info.clip_id, info.spatial_id);
 
     if let Some(tag) = info.hit_info {
         yaml_node(
             v,
             "hit-testing-tag",
              Yaml::Array(vec![Yaml::Integer(tag.0 as i64), Yaml::Integer(tag.1 as i64)])