Test tidy changes. try: -b do -p linux64 -u all[linux64-qr] -t none
authorGlenn Watson <github@intuitionlibrary.com>
Wed, 15 Nov 2017 11:07:30 +1000
changeset 1351311 6e30ae734328485e6f209dcba7b04f3e03f05683
parent 1351065 3f0191530af3351480fd261c2f6e88c2b7c8f036
child 1351505 25ce618bbbae1dfd643f449cf3307d22e12d3b6e
push id235416
push usergwatson@mozilla.com
push dateWed, 15 Nov 2017 01:08:12 +0000
treeherdertry@6e30ae734328 [default view] [failures only]
milestone58.0a1
Test tidy changes. try: -b do -p linux64 -u all[linux64-qr] -t none
gfx/webrender/src/picture.rs
gfx/webrender/src/prim_store.rs
--- a/gfx/webrender/src/picture.rs
+++ b/gfx/webrender/src/picture.rs
@@ -4,17 +4,17 @@
 
 use api::{BorderRadiusKind, ColorF, ClipAndScrollInfo, FilterOp, MixBlendMode};
 use api::{device_length, DeviceIntRect, DeviceIntSize, PipelineId};
 use api::{BoxShadowClipMode, LayerPoint, LayerRect, LayerSize, LayerVector2D, Shadow};
 use api::{ClipId, PremultipliedColorF};
 use box_shadow::BLUR_SAMPLE_SCALE;
 use frame_builder::PrimitiveContext;
 use gpu_cache::GpuDataRequest;
-use prim_store::{PrimitiveIndex, PrimitiveRun};
+use prim_store::{PrimitiveIndex, PrimitiveRun, PrimitiveRunLocalRect};
 use render_task::{ClearMode, RenderTask, RenderTaskId, RenderTaskTree};
 use tiling::RenderTargetKind;
 
 /*
  A picture represents a dynamically rendered image. It consists of:
 
  * A number of primitives that are drawn onto the picture.
  * A composite operation describing how to composite this
@@ -178,23 +178,24 @@ impl PicturePrimitive {
         self.runs.push(PrimitiveRun {
             base_prim_index: prim_index,
             count: 1,
             clip_and_scroll,
         });
     }
 
     pub fn update_local_rect(&mut self,
-        local_rect: LayerRect,
-        local_content_rect: LayerRect,
-        local_content_rect2: LayerRect,
+        prim_local_rect: LayerRect,
+        prim_run_rect: PrimitiveRunLocalRect,
     ) -> LayerRect {
+        let local_content_rect = prim_run_rect.local_rect_in_actual_parent_space;
+
         match self.kind {
             PictureKind::Image { composite_mode, ref mut real_local_rect, .. } => {
-                *real_local_rect = local_content_rect2;
+                *real_local_rect = prim_run_rect.local_rect_in_original_parent_space;
 
                 match composite_mode {
                     Some(PictureCompositeMode::Filter(FilterOp::Blur(blur_radius))) => {
                         let inflate_size = blur_radius * BLUR_SAMPLE_SCALE;
                         local_content_rect.inflate(inflate_size, inflate_size)
                     }
                     _ => {
                         local_content_rect
@@ -243,17 +244,17 @@ impl PicturePrimitive {
                             }
                         }
                     }
                     BoxShadowClipMode::Inset => {
                         *content_rect = local_content_rect;
                     }
                 }
 
-                local_rect
+                prim_local_rect
             }
         }
     }
 
     pub fn prepare_for_render(
         &mut self,
         prim_index: PrimitiveIndex,
         prim_context: &PrimitiveContext,
--- a/gfx/webrender/src/prim_store.rs
+++ b/gfx/webrender/src/prim_store.rs
@@ -2,17 +2,17 @@
  * 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, BuiltDisplayList, ColorF, ComplexClipRegion, DeviceIntRect};
 use api::{DevicePoint, ExtendMode, GlyphInstance, GlyphKey};
 use api::{GradientStop, ImageKey, ImageRendering, ItemRange, ItemTag, LayerPoint, LayerRect};
 use api::{ClipMode, LayerSize, LayerVector2D, LineOrientation, LineStyle};
 use api::{ClipAndScrollInfo, EdgeAaSegmentMask, PremultipliedColorF, TileOffset};
-use api::{ClipId, PipelineId, YuvColorSpace, YuvFormat};
+use api::{ClipId, LayerTransform, PipelineId, YuvColorSpace, YuvFormat};
 use border::BorderCornerInstance;
 use clip_scroll_tree::ClipScrollTree;
 use clip::{ClipSourcesHandle, ClipStore};
 use frame_builder::PrimitiveContext;
 use glyph_rasterizer::FontInstance;
 use internal_types::FastHashMap;
 use gpu_cache::{GpuBlockData, GpuCache, GpuCacheAddress, GpuCacheHandle, GpuDataRequest,
                 ToGpuBlocks};
@@ -54,16 +54,37 @@ impl PrimitiveOpacity {
         }
     }
 
     pub fn accumulate(&mut self, alpha: f32) {
         self.is_opaque = self.is_opaque && alpha == 1.0;
     }
 }
 
+// Represents the local space rect of a list of
+// primitive runs. For most primitive runs, the
+// primitive runs are attached to the parent they
+// are declared in. However, when a primitive run
+// is part of a 3d rendering context, it may get
+// hoisted to a higher level in the picture tree.
+// When this happens, we need to also calculate the
+// local space rects in the original space. This
+// allows constructing the true world space polygons
+// for the primitive, to enable the plane splitting
+// logic to work correctly.
+// TODO(gw) In the future, we can probably simplify
+//          this - perhaps calculate the world space
+//          polygons directly and store internally
+//          in the picture structure.
+#[derive(Debug)]
+pub struct PrimitiveRunLocalRect {
+    pub local_rect_in_actual_parent_space: LayerRect,
+    pub local_rect_in_original_parent_space: LayerRect,
+}
+
 /// Stores two coordinates in texel space. The coordinates
 /// are stored in texel coordinates because the texture atlas
 /// may grow. Storing them as texel coords and normalizing
 /// the UVs in the vertex shader means nothing needs to be
 /// updated on the CPU when the texture size changes.
 #[derive(Copy, Clone, Debug)]
 pub struct TexelRect {
     pub uv0: DevicePoint,
@@ -1313,17 +1334,17 @@ impl PrimitiveStore {
 
         // If we have dependencies, we need to prepare them first, in order
         // to know the actual rect of this primitive.
         // For example, scrolling may affect the location of an item in
         // local space, which may force us to render this item on a larger
         // picture target, if being composited.
         let mut child_tasks = Vec::new();
         if let Some((pipeline_id, dependencies, rfid)) = dependencies {
-            let (child_local_rect, child_local_rect2) = self.prepare_prim_runs(
+            let result = self.prepare_prim_runs(
                 &dependencies,
                 pipeline_id,
                 gpu_cache,
                 resource_cache,
                 render_tasks,
                 clip_store,
                 clip_scroll_tree,
                 pipelines,
@@ -1337,18 +1358,17 @@ impl PrimitiveStore {
             let metadata = &mut self.cpu_metadata[prim_index.0];
 
             // Restore the dependencies (borrow check dance)
             let pic = &mut self.cpu_pictures[cpu_prim_index.0];
             pic.runs = dependencies;
 
             metadata.local_rect = pic.update_local_rect(
                 metadata.local_rect,
-                child_local_rect,
-                child_local_rect2,
+                result,
             );
         }
 
         let (local_rect, device_rect) = {
             let metadata = &mut self.cpu_metadata[prim_index.0];
             if metadata.local_rect.size.width <= 0.0 ||
                metadata.local_rect.size.height <= 0.0 {
                 warn!("invalid primitive rect {:?}", metadata.local_rect);
@@ -1424,33 +1444,54 @@ impl PrimitiveStore {
         render_tasks: &mut RenderTaskTree,
         clip_store: &mut ClipStore,
         clip_scroll_tree: &ClipScrollTree,
         pipelines: &FastHashMap<PipelineId, ScenePipeline>,
         parent_prim_context: &PrimitiveContext,
         perform_culling: bool,
         parent_tasks: &mut Vec<RenderTaskId>,
         profile_counters: &mut FrameProfileCounters,
-        reference_frame_id: Option<ClipId>,
-    ) -> (LayerRect, LayerRect) {
-        let mut local_rect_in_moved_space = LayerRect::zero();
-        let mut local_rect_in_original_space = LayerRect::zero();
+        original_reference_frame_id: Option<ClipId>,
+    ) -> PrimitiveRunLocalRect {
+        let mut result = PrimitiveRunLocalRect {
+            local_rect_in_actual_parent_space: LayerRect::zero(),
+            local_rect_in_original_parent_space: LayerRect::zero(),
+        };
 
         for run in runs {
             // TODO(gw): Perhaps we can restructure this to not need to create
             //           a new primitive context for every run (if the hash
             //           lookups ever show up in a profile).
             let scroll_node = &clip_scroll_tree.nodes[&run.clip_and_scroll.scroll_node_id];
             let clip_node = &clip_scroll_tree.nodes[&run.clip_and_scroll.clip_node_id()];
 
             if !clip_node.is_visible() {
                 debug!("{:?} of clipped out {:?}", run.base_prim_index, pipeline_id);
                 continue;
             }
 
+            let parent_relative_transform = parent_prim_context
+                .scroll_node
+                .world_content_transform
+                .inverse()
+                .map(|inv_parent| {
+                    inv_parent.pre_mul(&scroll_node.world_content_transform)
+                });
+
+            let original_relative_transform = original_reference_frame_id
+                .and_then(|original_reference_frame_id| {
+                    let parent = clip_scroll_tree
+                        .nodes[&original_reference_frame_id]
+                        .world_content_transform;
+                    parent.inverse()
+                        .map(|inv_parent| {
+                            inv_parent.pre_mul(&scroll_node.world_content_transform)
+                        })
+                });
+
             let display_list = &pipelines
                 .get(&pipeline_id)
                 .expect("No display list?")
                 .display_list;
 
             let child_prim_context = PrimitiveContext::new(
                 parent_prim_context.device_pixel_ratio,
                 display_list,
@@ -1471,78 +1512,32 @@ impl PrimitiveStore {
                     clip_scroll_tree,
                     pipelines,
                     perform_culling,
                     parent_tasks,
                     profile_counters,
                 ) {
                     profile_counters.visible_primitives.inc();
 
-                    if let Some(reference_frame_id) = reference_frame_id {
-                        if let Some(m0) = clip_scroll_tree.nodes[&reference_frame_id].world_content_transform.inverse() {
-                            let m1 = scroll_node.world_content_transform;
-                            let m = m0.pre_mul(&m1);
-
-                            let vertices = [
-                                m.transform_point3d(&prim_local_rect.origin.to_3d()),
-                                m.transform_point3d(&prim_local_rect.bottom_left().to_3d()),
-                                m.transform_point3d(&prim_local_rect.bottom_right().to_3d()),
-                                m.transform_point3d(&prim_local_rect.top_right().to_3d()),
-                            ];
-
-                            let mut x0 = vertices[0].x;
-                            let mut y0 = vertices[0].y;
-                            let mut x1 = vertices[0].x;
-                            let mut y1 = vertices[0].y;
-
-                            for v in &vertices {
-                                x0 = x0.min(v.x);
-                                y0 = y0.min(v.y);
-                                x1 = x1.max(v.x);
-                                y1 = y1.max(v.y);
-                            }
-
-                            let bounds = LayerRect::new(LayerPoint::new(x0, y0), LayerSize::new(x1 - x0, y1 - y0));
-
-                            local_rect_in_original_space = local_rect_in_original_space.union(&bounds);
-                        }
+                    if let Some(ref matrix) = original_relative_transform {
+                        let bounds = get_local_bounding_rect(&prim_local_rect, matrix);
+                        result.local_rect_in_original_parent_space =
+                            result.local_rect_in_original_parent_space.union(&bounds);
                     }
 
-                    if let Some(m0) = parent_prim_context.scroll_node.world_content_transform.inverse() {
-                        let m1 = scroll_node.world_content_transform;
-                        let m = m0.pre_mul(&m1);
-
-                        let vertices = [
-                            m.transform_point3d(&prim_local_rect.origin.to_3d()),
-                            m.transform_point3d(&prim_local_rect.bottom_left().to_3d()),
-                            m.transform_point3d(&prim_local_rect.bottom_right().to_3d()),
-                            m.transform_point3d(&prim_local_rect.top_right().to_3d()),
-                        ];
-
-                        let mut x0 = vertices[0].x;
-                        let mut y0 = vertices[0].y;
-                        let mut x1 = vertices[0].x;
-                        let mut y1 = vertices[0].y;
-
-                        for v in &vertices {
-                            x0 = x0.min(v.x);
-                            y0 = y0.min(v.y);
-                            x1 = x1.max(v.x);
-                            y1 = y1.max(v.y);
-                        }
-
-                        let bounds = LayerRect::new(LayerPoint::new(x0, y0), LayerSize::new(x1 - x0, y1 - y0));
-
-                        local_rect_in_moved_space = local_rect_in_moved_space.union(&bounds);
+                    if let Some(ref matrix) = parent_relative_transform {
+                        let bounds = get_local_bounding_rect(&prim_local_rect, matrix);
+                        result.local_rect_in_actual_parent_space =
+                            result.local_rect_in_actual_parent_space.union(&bounds);
                     }
                 }
             }
         }
 
-        (local_rect_in_moved_space, local_rect_in_original_space)
+        result
     }
 }
 
 //Test for one clip region contains another
 trait InsideTest<T> {
     fn might_contain(&self, clip: &T) -> bool;
 }
 
@@ -1560,8 +1555,34 @@ impl InsideTest<ComplexClipRegion> for C
             clip.radii.top_right.width >= self.radii.top_right.width - delta_right &&
             clip.radii.top_right.height >= self.radii.top_right.height - delta_top &&
             clip.radii.bottom_left.width >= self.radii.bottom_left.width - delta_left &&
             clip.radii.bottom_left.height >= self.radii.bottom_left.height - delta_bottom &&
             clip.radii.bottom_right.width >= self.radii.bottom_right.width - delta_right &&
             clip.radii.bottom_right.height >= self.radii.bottom_right.height - delta_bottom
     }
 }
+
+fn get_local_bounding_rect(
+    local_rect: &LayerRect,
+    matrix: &LayerTransform
+) -> LayerRect {
+    let vertices = [
+        matrix.transform_point3d(&local_rect.origin.to_3d()),
+        matrix.transform_point3d(&local_rect.bottom_left().to_3d()),
+        matrix.transform_point3d(&local_rect.bottom_right().to_3d()),
+        matrix.transform_point3d(&local_rect.top_right().to_3d()),
+    ];
+
+    let mut x0 = vertices[0].x;
+    let mut y0 = vertices[0].y;
+    let mut x1 = vertices[0].x;
+    let mut y1 = vertices[0].y;
+
+    for v in &vertices[1..] {
+        x0 = x0.min(v.x);
+        y0 = y0.min(v.y);
+        x1 = x1.max(v.x);
+        y1 = y1.max(v.y);
+    }
+
+    LayerRect::new(LayerPoint::new(x0, y0), LayerSize::new(x1 - x0, y1 - y0))
+}