Bug 1532174 - Refactor get_relative_transform to not return an option r=gw
authorDzmitry Malyshau <dmalyshau@mozilla.com>
Tue, 12 Mar 2019 02:27:29 +0000
changeset 521474 c154ee9861ab
parent 521473 46ad1441e7f2
child 521475 0d55cac5f346
push id10866
push usernerli@mozilla.com
push dateTue, 12 Mar 2019 18:59:09 +0000
treeherdermozilla-beta@445c24a51727 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw
bugs1532174
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1532174 - Refactor get_relative_transform to not return an option r=gw Just a refactor without any semantical changes. Makes it for cleaner client code. Also prepares for caching of the world transforms. Differential Revision: https://phabricator.services.mozilla.com/D23015
gfx/wr/webrender/src/clip.rs
gfx/wr/webrender/src/clip_scroll_tree.rs
gfx/wr/webrender/src/gpu_types.rs
gfx/wr/webrender/src/picture.rs
gfx/wr/webrender/src/prim_store/mod.rs
--- a/gfx/wr/webrender/src/clip.rs
+++ b/gfx/wr/webrender/src/clip.rs
@@ -5,17 +5,17 @@
 use api::{BorderRadius, ClipMode, ComplexClipRegion, DeviceIntRect, DevicePixelScale, ImageMask};
 use api::{ImageRendering, LayoutRect, LayoutSize, LayoutPoint, LayoutVector2D};
 use api::{BoxShadowClipMode, LayoutToWorldScale, PicturePixel, WorldPixel};
 use api::{PictureRect, LayoutPixel, WorldPoint, WorldSize, WorldRect, LayoutToWorldTransform};
 use api::{ClipIntern, ImageKey};
 use app_units::Au;
 use border::{ensure_no_corner_overlap, BorderRadiusAu};
 use box_shadow::{BLUR_SAMPLE_SCALE, BoxShadowClipSource, BoxShadowCacheKey};
-use clip_scroll_tree::{ClipScrollTree, ROOT_SPATIAL_NODE_INDEX, SpatialNodeIndex};
+use clip_scroll_tree::{ClipScrollTree, SpatialNodeIndex};
 use ellipse::Ellipse;
 use gpu_cache::{GpuCache, GpuCacheHandle, ToGpuBlocks};
 use gpu_types::{BoxShadowStretchMode};
 use image::{self, Repetition};
 use intern;
 use prim_store::{ClipData, ImageMaskData, SpaceMapper, VisibleMaskImageTile};
 use prim_store::{PointKey, SizeKey, RectangleKey};
 use render_task::to_cache_size;
@@ -1305,25 +1305,21 @@ fn add_clip_node_to_current_chain(
     let conversion = if spatial_node_index == node.spatial_node_index {
         ClipSpaceConversion::Local
     } else if ref_spatial_node.coordinate_system_id == clip_spatial_node.coordinate_system_id {
         let scale_offset = ref_spatial_node.coordinate_system_relative_scale_offset
             .inverse()
             .accumulate(&clip_spatial_node.coordinate_system_relative_scale_offset);
         ClipSpaceConversion::ScaleOffset(scale_offset)
     } else {
-        match clip_scroll_tree.get_relative_transform(
-            node.spatial_node_index,
-            ROOT_SPATIAL_NODE_INDEX,
-        ) {
-            None => return true,
-            Some(relative) => ClipSpaceConversion::Transform(
-                relative.flattened.with_destination::<WorldPixel>(),
-            ),
-        }
+        ClipSpaceConversion::Transform(
+            clip_scroll_tree
+                .get_world_transform(node.spatial_node_index)
+                .flattened
+        )
     };
 
     // If we can convert spaces, try to reduce the size of the region
     // requested, and cache the conversion information for the next step.
     if let Some(clip_rect) = clip_node.item.get_local_clip_rect(node.local_pos) {
         match conversion {
             ClipSpaceConversion::Local => {
                 *local_clip_rect = match local_clip_rect.intersection(&clip_rect) {
--- a/gfx/wr/webrender/src/clip_scroll_tree.rs
+++ b/gfx/wr/webrender/src/clip_scroll_tree.rs
@@ -1,15 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-use api::{ExternalScrollId, LayoutPoint, LayoutRect, LayoutVector2D, ReferenceFrameKind};
+use api::{ExternalScrollId, PropertyBinding, ReferenceFrameKind, TransformStyle};
 use api::{PipelineId, ScrollClamping, ScrollNodeState, ScrollLocation, ScrollSensitivity};
-use api::{LayoutSize, LayoutTransform, PropertyBinding, TransformStyle, WorldPoint};
+use api::units::*;
+use euclid::TypedTransform3D;
 use gpu_types::TransformPalette;
 use internal_types::{FastHashMap, FastHashSet};
 use print_tree::{PrintableTree, PrintTree, PrintTreePrinter};
 use scene::SceneProperties;
 use spatial_node::{ScrollFrameInfo, SpatialNode, SpatialNodeType, StickyFrameInfo, ScrollFrameKind};
 use std::{ops, u32};
 use util::{project_rect, LayoutToWorldFastTransform, MatrixHelpers, ScaleOffset};
 
@@ -135,19 +136,19 @@ pub struct TransformUpdateState {
     pub invertible: bool,
 
     /// True if this node is a part of Preserve3D hierarchy.
     pub preserves_3d: bool,
 }
 
 /// A processed relative transform between two nodes in the clip-scroll tree.
 #[derive(Debug, Default)]
-pub struct RelativeTransform {
+pub struct RelativeTransform<U> {
     /// The flattened transform, produces Z = 0 at all times.
-    pub flattened: LayoutTransform,
+    pub flattened: TypedTransform3D<f32, LayoutPixel, U>,
     /// Visible face of the original transform.
     pub visible_face: VisibleFace,
     /// True if the original transform had perspective.
     pub is_perspective: bool,
 }
 
 impl ClipScrollTree {
     pub fn new() -> Self {
@@ -161,17 +162,17 @@ impl ClipScrollTree {
     }
 
     /// Calculate the relative transform from `child_index` to `parent_index`.
     /// This method will panic if the nodes are not connected!
     pub fn get_relative_transform(
         &self,
         child_index: SpatialNodeIndex,
         parent_index: SpatialNodeIndex,
-    ) -> Option<RelativeTransform> {
+    ) -> RelativeTransform<LayoutPixel> {
         assert!(child_index.0 >= parent_index.0);
         let child = &self.spatial_nodes[child_index.0 as usize];
         let parent = &self.spatial_nodes[parent_index.0 as usize];
 
         let mut coordinate_system_id = child.coordinate_system_id;
         let mut transform = child.coordinate_system_relative_scale_offset.to_transform();
         let mut visible_face = VisibleFace::Front;
         let mut is_perspective = false;
@@ -203,21 +204,34 @@ impl ClipScrollTree {
         }
 
         transform = transform.post_mul(
             &parent.coordinate_system_relative_scale_offset
                 .inverse()
                 .to_transform()
         );
 
-        Some(RelativeTransform {
+        RelativeTransform {
             flattened: transform,
             visible_face,
             is_perspective,
-        })
+        }
+    }
+
+    /// Calculate the relative transform from `child_index` to the scene root.
+    pub fn get_world_transform(
+        &self,
+        index: SpatialNodeIndex,
+    ) -> RelativeTransform<WorldPixel> {
+        let relative = self.get_relative_transform(index, ROOT_SPATIAL_NODE_INDEX);
+        RelativeTransform {
+            flattened: relative.flattened.with_destination::<WorldPixel>(),
+            visible_face: relative.visible_face,
+            is_perspective: relative.is_perspective,
+        }
     }
 
     /// Map a rectangle in some child space to a parent.
     /// Doesn't handle preserve-3d islands.
     pub fn map_rect_to_parent_space(
         &self,
         mut rect: LayoutRect,
         child_index: SpatialNodeIndex,
@@ -624,17 +638,17 @@ fn test_pt(
     parent: SpatialNodeIndex,
     expected_x: f32,
     expected_y: f32,
 ) {
     use euclid::approxeq::ApproxEq;
     const EPSILON: f32 = 0.0001;
 
     let p = LayoutPoint::new(px, py);
-    let m = cst.get_relative_transform(child, parent).unwrap().flattened;
+    let m = cst.get_relative_transform(child, parent).flattened;
     let pt = m.transform_point2d(&p).unwrap();
     assert!(pt.x.approx_eq_eps(&expected_x, &EPSILON) &&
             pt.y.approx_eq_eps(&expected_y, &EPSILON),
             "p: {:?} -> {:?}\nm={:?}",
             p, pt, m,
             );
 }
 
--- a/gfx/wr/webrender/src/gpu_types.rs
+++ b/gfx/wr/webrender/src/gpu_types.rs
@@ -496,17 +496,16 @@ impl TransformPalette {
 
             *self.map
                 .entry(key)
                 .or_insert_with(|| {
                     let transform = clip_scroll_tree.get_relative_transform(
                         child_index,
                         parent_index,
                     )
-                    .unwrap_or_default()
                     .flattened
                     .with_destination::<PicturePixel>();
 
                     register_transform(
                         metadata,
                         transforms,
                         child_index,
                         parent_index,
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -783,21 +783,17 @@ impl TileCache {
             return;
         }
 
         let DeviceIntSize { width: tile_width, height: tile_height, _unit: _ } =
             Self::tile_dimensions(frame_context.config.testing);
 
         // Work out the scroll offset to apply to the world reference point.
         let scroll_offset_point = frame_context.clip_scroll_tree
-            .get_relative_transform(
-                self.spatial_node_index,
-                ROOT_SPATIAL_NODE_INDEX,
-            )
-            .expect("bug: unable to get scroll transform")
+            .get_world_transform(self.spatial_node_index)
             .flattened
             .inverse_project_2d_origin()
             .unwrap_or_else(LayoutPoint::zero);
 
         let scroll_offset = WorldVector2D::new(scroll_offset_point.x, scroll_offset_point.y);
         let scroll_delta = match self.scroll_offset {
             Some(prev) => prev - scroll_offset,
             None => WorldVector2D::zero(),
@@ -1428,26 +1424,24 @@ impl TileCache {
                 // Note: this is the only place where we don't know beforehand if the tile-affecting
                 // spatial node is below or above the current picture.
                 let inverse_origin = if self.spatial_node_index >= spatial_node_index {
                     frame_context.clip_scroll_tree
                         .get_relative_transform(
                             self.spatial_node_index,
                             spatial_node_index,
                         )
-                        .expect("BUG: unable to get relative transform")
                         .flattened
                         .transform_point2d(&LayoutPoint::zero())
                 } else {
                     frame_context.clip_scroll_tree
                         .get_relative_transform(
                             spatial_node_index,
                             self.spatial_node_index,
                         )
-                        .expect("BUG: unable to get relative transform")
                         .flattened
                         .inverse_project_2d_origin()
                 };
                 // Store the result of transforming a fixed point by this
                 // transform.
                 // TODO(gw): This could in theory give incorrect results for a
                 //           primitive behind the near plane.
                 let key = inverse_origin
@@ -2690,17 +2684,16 @@ impl PicturePrimitive {
                     0.0
                 }
             };
 
             // Check if there is perspective, and thus whether a new
             // rasterization root should be established.
             let establishes_raster_root = frame_context.clip_scroll_tree
                 .get_relative_transform(surface_spatial_node_index, parent_raster_node_index)
-                .expect("BUG: unable to get relative transform")
                 .is_perspective;
 
             let surface = SurfaceInfo::new(
                 surface_spatial_node_index,
                 if establishes_raster_root {
                     surface_spatial_node_index
                 } else {
                     parent_raster_node_index
--- a/gfx/wr/webrender/src/prim_store/mod.rs
+++ b/gfx/wr/webrender/src/prim_store/mod.rs
@@ -136,37 +136,37 @@ pub enum CoordinateSpaceMapping<F, T> {
     Transform(TypedTransform3D<f32, F, T>),
 }
 
 impl<F, T> CoordinateSpaceMapping<F, T> {
     pub fn new(
         ref_spatial_node_index: SpatialNodeIndex,
         target_node_index: SpatialNodeIndex,
         clip_scroll_tree: &ClipScrollTree,
-    ) -> Option<(Self, VisibleFace)> {
+    ) -> (Self, VisibleFace) {
         let spatial_nodes = &clip_scroll_tree.spatial_nodes;
         let ref_spatial_node = &spatial_nodes[ref_spatial_node_index.0 as usize];
         let target_spatial_node = &spatial_nodes[target_node_index.0 as usize];
 
         if ref_spatial_node_index == target_node_index {
-            Some((CoordinateSpaceMapping::Local, VisibleFace::Front))
+            (CoordinateSpaceMapping::Local, VisibleFace::Front)
         } else if ref_spatial_node.coordinate_system_id == target_spatial_node.coordinate_system_id {
             let scale_offset = ref_spatial_node.coordinate_system_relative_scale_offset
                 .inverse()
                 .accumulate(&target_spatial_node.coordinate_system_relative_scale_offset);
-            Some((CoordinateSpaceMapping::ScaleOffset(scale_offset), VisibleFace::Front))
+            (CoordinateSpaceMapping::ScaleOffset(scale_offset), VisibleFace::Front)
         } else {
-            clip_scroll_tree
-                .get_relative_transform(target_node_index, ref_spatial_node_index)
-                .map(|relative| (
-                    CoordinateSpaceMapping::Transform(
-                        relative.flattened.with_source::<F>().with_destination::<T>()
-                    ),
-                    relative.visible_face,
-                ))
+            let relative = clip_scroll_tree
+                .get_relative_transform(target_node_index, ref_spatial_node_index);
+            (
+                CoordinateSpaceMapping::Transform(
+                    relative.flattened.with_source::<F>().with_destination::<T>()
+                ),
+                relative.visible_face,
+            )
         }
     }
 }
 
 #[derive(Debug, Clone)]
 pub struct SpaceMapper<F, T> {
     kind: CoordinateSpaceMapping<F, T>,
     pub ref_spatial_node_index: SpatialNodeIndex,
@@ -207,17 +207,17 @@ impl<F, T> SpaceMapper<F, T> where F: fm
     ) {
         if target_node_index != self.current_target_spatial_node_index {
             self.current_target_spatial_node_index = target_node_index;
 
             let (kind, visible_face) = CoordinateSpaceMapping::new(
                 self.ref_spatial_node_index,
                 target_node_index,
                 clip_scroll_tree,
-            ).expect("bug: should have been culled by invalid node");
+            );
 
             self.kind = kind;
             self.visible_face = visible_face;
         }
     }
 
     pub fn get_transform(&self) -> TypedTransform3D<f32, F, T> {
         match self.kind {