зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1532174 - Repace WR RelativeTransform with CoordinateSpaceMapping, improve flattening semantics. r=gw
This change makes get_relative_transform() to no longer rely on any flattening done before in the pipeline. This makes it correct is some of the cases we failed previously (see ini files removed). It now does flattening on every flat coordinate system it passes through, and it's used for SpaceMapper. The old RelativeTransform is now replaced with CoordinateSpaceMapping, which reduces the zoo of our types :) Differential Revision: https://phabricator.services.mozilla.com/D30600 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
6b3623045e
Коммит
7f9b0ee390
|
@ -2867,12 +2867,11 @@ impl ClipBatcher {
|
|||
clip_instance.local_pos,
|
||||
clip_rect_size,
|
||||
);
|
||||
let transform = clip_scroll_tree.get_relative_transform(
|
||||
let transform = clip_scroll_tree.get_world_transform(
|
||||
clip_instance.spatial_node_index,
|
||||
ROOT_SPATIAL_NODE_INDEX,
|
||||
);
|
||||
let world_clip_rect = match project_rect(
|
||||
&transform.flattened.with_destination::<WorldPixel>(),
|
||||
&transform.into_transform(),
|
||||
&local_clip_rect,
|
||||
world_rect,
|
||||
) {
|
||||
|
|
|
@ -239,11 +239,12 @@ pub struct ClipNodeRange {
|
|||
pub count: u32,
|
||||
}
|
||||
|
||||
// A helper struct for converting between coordinate systems
|
||||
// of clip sources and primitives.
|
||||
/// A helper struct for converting between coordinate systems
|
||||
/// of clip sources and primitives.
|
||||
// todo(gw): optimize:
|
||||
// separate arrays for matrices
|
||||
// cache and only build as needed.
|
||||
//TODO: merge with `CoordinateSpaceMapping`?
|
||||
#[derive(Debug, MallocSizeOf)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
enum ClipSpaceConversion {
|
||||
|
@ -1342,6 +1343,9 @@ fn add_clip_node_to_current_chain(
|
|||
|
||||
// Determine the most efficient way to convert between coordinate
|
||||
// systems of the primitive and clip node.
|
||||
//Note: this code is different from `get_relative_transform` in a way that we only try
|
||||
// getting the relative transform if it's Local or ScaleOffset,
|
||||
// falling back to the world transform otherwise.
|
||||
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 {
|
||||
|
@ -1353,7 +1357,7 @@ fn add_clip_node_to_current_chain(
|
|||
ClipSpaceConversion::Transform(
|
||||
clip_scroll_tree
|
||||
.get_world_transform(node.spatial_node_index)
|
||||
.flattened
|
||||
.into_transform()
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
use api::{ExternalScrollId, PropertyBinding, ReferenceFrameKind, TransformStyle};
|
||||
use api::{PipelineId, ScrollClamping, ScrollNodeState, ScrollLocation, ScrollSensitivity};
|
||||
use api::units::*;
|
||||
use euclid::TypedTransform3D;
|
||||
use euclid::{TypedPoint2D, TypedScale, TypedTransform3D};
|
||||
use crate::gpu_types::TransformPalette;
|
||||
use crate::internal_types::{FastHashMap, FastHashSet};
|
||||
use crate::print_tree::{PrintableTree, PrintTree, PrintTreePrinter};
|
||||
use crate::scene::SceneProperties;
|
||||
use crate::spatial_node::{ScrollFrameInfo, SpatialNode, SpatialNodeType, StickyFrameInfo, ScrollFrameKind};
|
||||
use std::{ops, u32};
|
||||
use crate::util::{LayoutToWorldFastTransform, MatrixHelpers, ScaleOffset};
|
||||
use crate::util::{LayoutToWorldFastTransform, MatrixHelpers, ScaleOffset, scale_factors};
|
||||
|
||||
pub type ScrollStates = FastHashMap<ExternalScrollId, ScrollFrameInfo>;
|
||||
|
||||
|
@ -30,7 +30,7 @@ pub struct CoordinateSystemId(pub u32);
|
|||
#[derive(Debug)]
|
||||
pub struct CoordinateSystem {
|
||||
pub transform: LayoutTransform,
|
||||
pub transform_style: TransformStyle,
|
||||
pub should_flatten: bool,
|
||||
pub parent: Option<CoordinateSystemId>,
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ impl CoordinateSystem {
|
|||
fn root() -> Self {
|
||||
CoordinateSystem {
|
||||
transform: LayoutTransform::identity(),
|
||||
transform_style: TransformStyle::Flat,
|
||||
should_flatten: false,
|
||||
parent: None,
|
||||
}
|
||||
}
|
||||
|
@ -92,17 +92,6 @@ impl ops::Not for VisibleFace {
|
|||
}
|
||||
}
|
||||
|
||||
impl VisibleFace {
|
||||
/// A convenient constructor from methods like `is_backface_visible()`
|
||||
pub fn from_bool(is_backface: bool) -> Self {
|
||||
if is_backface {
|
||||
VisibleFace::Back
|
||||
} else {
|
||||
VisibleFace::Front
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClipScrollTree {
|
||||
/// Nodes which determine the positions (offsets and transforms) for primitives
|
||||
/// and clips.
|
||||
|
@ -148,13 +137,109 @@ pub struct TransformUpdateState {
|
|||
pub preserves_3d: bool,
|
||||
}
|
||||
|
||||
/// A processed relative transform between two nodes in the clip-scroll tree.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct RelativeTransform<U> {
|
||||
/// The flattened transform, produces Z = 0 at all times.
|
||||
pub flattened: TypedTransform3D<f32, LayoutPixel, U>,
|
||||
/// True if the original transform had perspective.
|
||||
pub has_perspective: bool,
|
||||
|
||||
/// Transformation between two nodes in the clip-scroll tree that can sometimes be
|
||||
/// encoded more efficiently than with a full matrix.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CoordinateSpaceMapping<Src, Dst> {
|
||||
Local,
|
||||
ScaleOffset(ScaleOffset),
|
||||
Transform(TypedTransform3D<f32, Src, Dst>),
|
||||
}
|
||||
|
||||
impl<Src, Dst> CoordinateSpaceMapping<Src, Dst> {
|
||||
pub fn into_transform(self) -> TypedTransform3D<f32, Src, Dst> {
|
||||
match self {
|
||||
CoordinateSpaceMapping::Local => TypedTransform3D::identity(),
|
||||
CoordinateSpaceMapping::ScaleOffset(scale_offset) => scale_offset.to_transform(),
|
||||
CoordinateSpaceMapping::Transform(transform) => transform,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visible_face(&self) -> VisibleFace {
|
||||
match *self {
|
||||
CoordinateSpaceMapping::Transform(ref transform) if transform.is_backface_visible() => VisibleFace::Back,
|
||||
CoordinateSpaceMapping::Local |
|
||||
CoordinateSpaceMapping::Transform(_) |
|
||||
CoordinateSpaceMapping::ScaleOffset(_) => VisibleFace::Front,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_perspective(&self) -> bool {
|
||||
match *self {
|
||||
CoordinateSpaceMapping::Local |
|
||||
CoordinateSpaceMapping::ScaleOffset(_) => false,
|
||||
CoordinateSpaceMapping::Transform(ref transform) => transform.has_perspective_component(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn project_2d_origin(&self) -> Option<TypedPoint2D<f32, Dst>> {
|
||||
match *self {
|
||||
CoordinateSpaceMapping::Local => Some(TypedPoint2D::zero()),
|
||||
CoordinateSpaceMapping::ScaleOffset(ref scale_offset) => Some(
|
||||
scale_offset.offset.to_point() * TypedScale::new(1.0)
|
||||
),
|
||||
CoordinateSpaceMapping::Transform(ref transform) => {
|
||||
transform.transform_point2d(&TypedPoint2D::zero())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inverse_project_2d_origin(&self) -> Option<TypedPoint2D<f32, Src>> {
|
||||
match *self {
|
||||
CoordinateSpaceMapping::Local => Some(TypedPoint2D::zero()),
|
||||
CoordinateSpaceMapping::ScaleOffset(ref scale_offset) => Some(
|
||||
scale_offset.inverse().offset.to_point() * TypedScale::new(1.0)
|
||||
),
|
||||
CoordinateSpaceMapping::Transform(ref transform) => {
|
||||
transform.inverse_project_2d_origin()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scale_factors(&self) -> (f32, f32) {
|
||||
match *self {
|
||||
CoordinateSpaceMapping::Local => (1.0, 1.0),
|
||||
CoordinateSpaceMapping::ScaleOffset(ref scale_offset) => (scale_offset.scale.x, scale_offset.scale.y),
|
||||
CoordinateSpaceMapping::Transform(ref transform) => scale_factors(transform),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inverse(&self) -> Option<CoordinateSpaceMapping<Dst, Src>> {
|
||||
match *self {
|
||||
CoordinateSpaceMapping::Local => Some(CoordinateSpaceMapping::Local),
|
||||
CoordinateSpaceMapping::ScaleOffset(ref scale_offset) => {
|
||||
Some(CoordinateSpaceMapping::ScaleOffset(scale_offset.inverse()))
|
||||
}
|
||||
CoordinateSpaceMapping::Transform(ref transform) => {
|
||||
transform.inverse().map(CoordinateSpaceMapping::Transform)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_destination<NewDst>(self) -> CoordinateSpaceMapping<Src, NewDst> {
|
||||
match self {
|
||||
CoordinateSpaceMapping::Local => CoordinateSpaceMapping::Local,
|
||||
CoordinateSpaceMapping::ScaleOffset(scale_offset) => CoordinateSpaceMapping::ScaleOffset(scale_offset),
|
||||
CoordinateSpaceMapping::Transform(transform) => CoordinateSpaceMapping::Transform(
|
||||
transform.with_destination::<NewDst>()
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn post_mul_transform<NewDst>(
|
||||
&self, other: &CoordinateSpaceMapping<Dst, NewDst>
|
||||
) -> TypedTransform3D<f32, Src, NewDst>
|
||||
where Self: Clone
|
||||
{
|
||||
let matrix = self.clone().into_transform();
|
||||
match *other {
|
||||
CoordinateSpaceMapping::Local => matrix.with_destination::<NewDst>(),
|
||||
CoordinateSpaceMapping::ScaleOffset(ref scale_offset) => matrix.post_mul(&scale_offset.to_transform()),
|
||||
CoordinateSpaceMapping::Transform(ref transform) => matrix.post_mul(transform),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ClipScrollTree {
|
||||
|
@ -203,25 +288,24 @@ impl ClipScrollTree {
|
|||
&self,
|
||||
child_index: SpatialNodeIndex,
|
||||
parent_index: SpatialNodeIndex,
|
||||
) -> RelativeTransform<LayoutPixel> {
|
||||
) -> CoordinateSpaceMapping<LayoutPixel, LayoutPixel> {
|
||||
assert!(child_index.0 >= parent_index.0);
|
||||
if child_index == parent_index {
|
||||
return CoordinateSpaceMapping::Local;
|
||||
}
|
||||
|
||||
let child = &self.spatial_nodes[child_index.0 as usize];
|
||||
let parent = &self.spatial_nodes[parent_index.0 as usize];
|
||||
let mut has_perspective = false;
|
||||
|
||||
if child.coordinate_system_id == parent.coordinate_system_id {
|
||||
return RelativeTransform {
|
||||
flattened: parent.coordinate_system_relative_scale_offset
|
||||
let scale_offset = parent.coordinate_system_relative_scale_offset
|
||||
.inverse()
|
||||
.accumulate(&child.coordinate_system_relative_scale_offset)
|
||||
.to_transform(),
|
||||
has_perspective,
|
||||
}
|
||||
.accumulate(&child.coordinate_system_relative_scale_offset);
|
||||
return CoordinateSpaceMapping::ScaleOffset(scale_offset);
|
||||
}
|
||||
|
||||
let mut coordinate_system_id = child.coordinate_system_id;
|
||||
let mut transform = child.coordinate_system_relative_scale_offset.to_transform();
|
||||
let mut transform_style = child.transform_style();
|
||||
|
||||
// we need to update the associated parameters of a transform in two cases:
|
||||
// 1) when the flattening happens, so that we don't lose that original 3D aspects
|
||||
|
@ -230,48 +314,33 @@ impl ClipScrollTree {
|
|||
while coordinate_system_id != parent.coordinate_system_id {
|
||||
let coord_system = &self.coord_systems[coordinate_system_id.0 as usize];
|
||||
|
||||
if coord_system.transform_style == TransformStyle::Flat {
|
||||
has_perspective |= transform.has_perspective_component();
|
||||
if transform_style != TransformStyle::Flat {
|
||||
//Note: this function makes the transform to ignore the Z coordinate of inputs
|
||||
// *even* for computing the X and Y coordinates of the output.
|
||||
//transform = transform.project_to_2d();
|
||||
if coord_system.should_flatten {
|
||||
transform.m13 = 0.0;
|
||||
transform.m23 = 0.0;
|
||||
transform.m33 = 1.0;
|
||||
transform.m43 = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
coordinate_system_id = coord_system.parent.expect("invalid parent!");
|
||||
transform = transform.post_mul(&coord_system.transform);
|
||||
transform_style = coord_system.transform_style;
|
||||
}
|
||||
|
||||
has_perspective |= transform.has_perspective_component();
|
||||
|
||||
transform = transform.post_mul(
|
||||
&parent.coordinate_system_relative_scale_offset
|
||||
.inverse()
|
||||
.to_transform(),
|
||||
);
|
||||
|
||||
RelativeTransform {
|
||||
flattened: transform,
|
||||
has_perspective,
|
||||
}
|
||||
CoordinateSpaceMapping::Transform(transform)
|
||||
}
|
||||
|
||||
/// 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>(),
|
||||
has_perspective: relative.has_perspective,
|
||||
}
|
||||
) -> CoordinateSpaceMapping<LayoutPixel, WorldPixel> {
|
||||
self.get_relative_transform(index, ROOT_SPATIAL_NODE_INDEX)
|
||||
.with_destination::<WorldPixel>()
|
||||
}
|
||||
|
||||
/// Returns true if the spatial node is the same as the parent, or is
|
||||
|
@ -394,16 +463,11 @@ impl ClipScrollTree {
|
|||
&mut self,
|
||||
pan: WorldPoint,
|
||||
scene_properties: &SceneProperties,
|
||||
mut transform_palette: Option<&mut TransformPalette>,
|
||||
) {
|
||||
if self.spatial_nodes.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(ref mut palette) = transform_palette {
|
||||
palette.allocate(self.spatial_nodes.len());
|
||||
}
|
||||
|
||||
self.coord_systems.clear();
|
||||
self.coord_systems.push(CoordinateSystem::root());
|
||||
|
||||
|
@ -429,9 +493,6 @@ impl ClipScrollTree {
|
|||
};
|
||||
|
||||
node.update(&mut state, &mut self.coord_systems, scene_properties, &*previous);
|
||||
if let Some(ref mut palette) = transform_palette {
|
||||
node.push_gpu_data(palette, node_index);
|
||||
}
|
||||
|
||||
if !node.children.is_empty() {
|
||||
node.prepare_state_for_children(&mut state);
|
||||
|
@ -444,6 +505,17 @@ impl ClipScrollTree {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn build_transform_palette(&self) -> TransformPalette {
|
||||
let mut palette = TransformPalette::new(self.spatial_nodes.len());
|
||||
//TODO: this could be faster by a bit of dynamic programming
|
||||
for i in 0 .. self.spatial_nodes.len() {
|
||||
let index = SpatialNodeIndex(i as u32);
|
||||
let world_transform = self.get_world_transform(index).into_transform();
|
||||
palette.set_world_transform(index, world_transform);
|
||||
}
|
||||
palette
|
||||
}
|
||||
|
||||
pub fn finalize_and_apply_pending_scroll_offsets(&mut self, old_states: ScrollStates) {
|
||||
for node in &mut self.spatial_nodes {
|
||||
let external_id = match node.node_type {
|
||||
|
@ -544,26 +616,26 @@ impl ClipScrollTree {
|
|||
match node.node_type {
|
||||
SpatialNodeType::StickyFrame(ref sticky_frame_info) => {
|
||||
pt.new_level(format!("StickyFrame"));
|
||||
pt.add_item(format!("index: {:?}", index));
|
||||
pt.add_item(format!("sticky info: {:?}", sticky_frame_info));
|
||||
}
|
||||
SpatialNodeType::ScrollFrame(scrolling_info) => {
|
||||
pt.new_level(format!("ScrollFrame"));
|
||||
pt.add_item(format!("index: {:?}", index));
|
||||
pt.add_item(format!("viewport: {:?}", scrolling_info.viewport_rect));
|
||||
pt.add_item(format!("scrollable_size: {:?}", scrolling_info.scrollable_size));
|
||||
pt.add_item(format!("scroll offset: {:?}", scrolling_info.offset));
|
||||
pt.add_item(format!("external_scroll_offset: {:?}", scrolling_info.external_scroll_offset));
|
||||
}
|
||||
SpatialNodeType::ReferenceFrame(ref _info) => {
|
||||
SpatialNodeType::ReferenceFrame(ref info) => {
|
||||
pt.new_level(format!("ReferenceFrame"));
|
||||
pt.add_item(format!("index: {:?}", index));
|
||||
pt.add_item(format!("kind: {:?}", info.kind));
|
||||
pt.add_item(format!("transform_style: {:?}", info.transform_style));
|
||||
}
|
||||
}
|
||||
|
||||
pt.add_item(format!("index: {:?}", index));
|
||||
pt.add_item(format!("world_viewport_transform: {:?}", node.world_viewport_transform));
|
||||
pt.add_item(format!("world_content_transform: {:?}", node.world_content_transform));
|
||||
pt.add_item(format!("coordinate_system_id: {:?}", node.coordinate_system_id));
|
||||
pt.add_item(format!("coordinate_system_scale_offset: {:?}", node.coordinate_system_relative_scale_offset));
|
||||
|
||||
for child_index in &node.children {
|
||||
self.print_node(*child_index, pt);
|
||||
|
@ -579,12 +651,8 @@ impl ClipScrollTree {
|
|||
Some(index) => index,
|
||||
None => return VisibleFace::Front
|
||||
};
|
||||
VisibleFace::from_bool(
|
||||
self
|
||||
.get_relative_transform(node_index, parent_index)
|
||||
.flattened
|
||||
.is_backface_visible()
|
||||
)
|
||||
self.get_relative_transform(node_index, parent_index)
|
||||
.visible_face()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -635,7 +703,7 @@ fn test_pt(
|
|||
const EPSILON: f32 = 0.0001;
|
||||
|
||||
let p = LayoutPoint::new(px, py);
|
||||
let m = cst.get_relative_transform(child, parent).flattened;
|
||||
let m = cst.get_relative_transform(child, parent).into_transform();
|
||||
let pt = m.transform_point2d(&p).unwrap();
|
||||
assert!(pt.x.approx_eq_eps(&expected_x, &EPSILON) &&
|
||||
pt.y.approx_eq_eps(&expected_y, &EPSILON),
|
||||
|
@ -678,7 +746,7 @@ fn test_cst_simple_translation() {
|
|||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new(), None);
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new());
|
||||
|
||||
test_pt(100.0, 100.0, &cst, child1, root, 200.0, 100.0);
|
||||
test_pt(100.0, 100.0, &cst, child2, root, 200.0, 150.0);
|
||||
|
@ -720,7 +788,7 @@ fn test_cst_simple_scale() {
|
|||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new(), None);
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new());
|
||||
|
||||
test_pt(100.0, 100.0, &cst, child1, root, 400.0, 100.0);
|
||||
test_pt(100.0, 100.0, &cst, child2, root, 400.0, 200.0);
|
||||
|
@ -770,7 +838,7 @@ fn test_cst_scale_translation() {
|
|||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new(), None);
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new());
|
||||
|
||||
test_pt(100.0, 100.0, &cst, child1, root, 200.0, 150.0);
|
||||
test_pt(100.0, 100.0, &cst, child2, root, 300.0, 450.0);
|
||||
|
@ -804,7 +872,7 @@ fn test_cst_translation_rotate() {
|
|||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new(), None);
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new());
|
||||
|
||||
test_pt(100.0, 0.0, &cst, child1, root, 0.0, -100.0);
|
||||
}
|
||||
|
|
|
@ -512,6 +512,7 @@ impl<'a> DisplayListFlattener<'a> {
|
|||
&prim_list.prim_instances,
|
||||
*self.pipeline_clip_chain_stack.last().unwrap(),
|
||||
&self.prim_store.pictures,
|
||||
&self.clip_scroll_tree,
|
||||
);
|
||||
|
||||
let pic_index = self.prim_store.pictures.alloc().init(PicturePrimitive::new_image(
|
||||
|
|
|
@ -532,12 +532,11 @@ impl FrameBuilder {
|
|||
|
||||
self.globals.update(gpu_cache);
|
||||
|
||||
let mut transform_palette = TransformPalette::new();
|
||||
clip_scroll_tree.update_tree(
|
||||
pan,
|
||||
scene_properties,
|
||||
Some(&mut transform_palette),
|
||||
);
|
||||
let mut transform_palette = clip_scroll_tree.build_transform_palette();
|
||||
self.clip_store.clear_old_instances();
|
||||
|
||||
let mut render_tasks = RenderTaskTree::new(
|
||||
|
|
|
@ -476,11 +476,11 @@ pub struct TransformPalette {
|
|||
}
|
||||
|
||||
impl TransformPalette {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(count: usize) -> Self {
|
||||
let _ = VECS_PER_TRANSFORM;
|
||||
TransformPalette {
|
||||
transforms: Vec::new(),
|
||||
metadata: Vec::new(),
|
||||
transforms: vec![TransformData::invalid(); count],
|
||||
metadata: vec![TransformMetadata::invalid(); count],
|
||||
map: FastHashMap::default(),
|
||||
}
|
||||
}
|
||||
|
@ -489,11 +489,6 @@ impl TransformPalette {
|
|||
self.transforms
|
||||
}
|
||||
|
||||
pub fn allocate(&mut self, count: usize) {
|
||||
self.transforms = vec![TransformData::invalid(); count];
|
||||
self.metadata = vec![TransformMetadata::invalid(); count];
|
||||
}
|
||||
|
||||
pub fn set_world_transform(
|
||||
&mut self,
|
||||
index: SpatialNodeIndex,
|
||||
|
@ -535,7 +530,7 @@ impl TransformPalette {
|
|||
child_index,
|
||||
parent_index,
|
||||
)
|
||||
.flattened
|
||||
.into_transform()
|
||||
.with_destination::<PicturePixel>();
|
||||
|
||||
register_transform(
|
||||
|
|
|
@ -9,10 +9,10 @@ use api::units::*;
|
|||
use crate::box_shadow::{BLUR_SAMPLE_SCALE};
|
||||
use crate::clip::{ClipChainId, ClipChainNode, ClipItem, ClipStore, ClipDataStore, ClipChainStack};
|
||||
use crate::clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX,
|
||||
ClipScrollTree, CoordinateSystemId, SpatialNodeIndex, VisibleFace
|
||||
ClipScrollTree, CoordinateSystemId, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace
|
||||
};
|
||||
use crate::debug_colors;
|
||||
use euclid::{size2, vec3, TypedPoint2D, TypedScale, TypedSize2D};
|
||||
use euclid::{size2, vec3, TypedPoint2D, TypedScale, TypedSize2D, Vector2D};
|
||||
use euclid::approxeq::ApproxEq;
|
||||
use crate::frame_builder::{FrameVisibilityContext, FrameVisibilityState};
|
||||
use crate::intern::ItemUid;
|
||||
|
@ -21,7 +21,7 @@ use crate::frame_builder::{FrameBuildingContext, FrameBuildingState, PictureStat
|
|||
use crate::gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle};
|
||||
use crate::gpu_types::UvRectKind;
|
||||
use plane_split::{Clipper, Polygon, Splitter};
|
||||
use crate::prim_store::{CoordinateSpaceMapping, SpaceMapper};
|
||||
use crate::prim_store::SpaceMapper;
|
||||
use crate::prim_store::{PictureIndex, PrimitiveInstance, PrimitiveInstanceKind};
|
||||
use crate::prim_store::{get_raster_rects, PrimitiveScratchBuffer, VectorKey, PointKey};
|
||||
use crate::prim_store::{OpacityBindingStorage, ImageInstanceStorage, OpacityBindingIndex, RectangleKey};
|
||||
|
@ -703,6 +703,7 @@ impl TileCache {
|
|||
prim_instances: &[PrimitiveInstance],
|
||||
root_clip_chain_id: ClipChainId,
|
||||
pictures: &[PicturePrimitive],
|
||||
clip_scroll_tree: &ClipScrollTree,
|
||||
) -> Self {
|
||||
// Build the list of reference primitives
|
||||
// for this picture cache.
|
||||
|
@ -717,6 +718,7 @@ impl TileCache {
|
|||
map_local_to_world: SpaceMapper::new(
|
||||
ROOT_SPATIAL_NODE_INDEX,
|
||||
WorldRect::zero(),
|
||||
clip_scroll_tree,
|
||||
),
|
||||
tiles_to_draw: Vec::new(),
|
||||
opacity_bindings: FastHashMap::default(),
|
||||
|
@ -793,7 +795,6 @@ impl TileCache {
|
|||
// Work out the scroll offset to apply to the world reference point.
|
||||
let scroll_offset_point = frame_context.clip_scroll_tree
|
||||
.get_world_transform(self.spatial_node_index)
|
||||
.flattened
|
||||
.inverse_project_2d_origin()
|
||||
.unwrap_or_else(LayoutPoint::zero);
|
||||
|
||||
|
@ -833,6 +834,7 @@ impl TileCache {
|
|||
self.map_local_to_world = SpaceMapper::new(
|
||||
ROOT_SPATIAL_NODE_INDEX,
|
||||
frame_context.screen_world_rect,
|
||||
frame_context.clip_scroll_tree,
|
||||
);
|
||||
|
||||
let world_mapper = SpaceMapper::new_with_target(
|
||||
|
@ -1439,15 +1441,13 @@ impl TileCache {
|
|||
self.spatial_node_index,
|
||||
spatial_node_index,
|
||||
)
|
||||
.flattened
|
||||
.transform_point2d(&LayoutPoint::zero())
|
||||
.project_2d_origin()
|
||||
} else {
|
||||
frame_context.clip_scroll_tree
|
||||
.get_relative_transform(
|
||||
spatial_node_index,
|
||||
self.spatial_node_index,
|
||||
)
|
||||
.flattened
|
||||
.inverse_project_2d_origin()
|
||||
};
|
||||
// Store the result of transforming a fixed point by this
|
||||
|
@ -1843,6 +1843,7 @@ impl SurfaceInfo {
|
|||
let map_local_to_surface = SpaceMapper::new(
|
||||
surface_spatial_node_index,
|
||||
pic_bounds,
|
||||
clip_scroll_tree,
|
||||
);
|
||||
|
||||
SurfaceInfo {
|
||||
|
@ -2400,6 +2401,7 @@ impl PicturePrimitive {
|
|||
let map_local_to_pic = SpaceMapper::new(
|
||||
surface_spatial_node_index,
|
||||
pic_bounds,
|
||||
frame_context.clip_scroll_tree,
|
||||
);
|
||||
|
||||
let (map_raster_to_world, map_pic_to_raster) = create_raster_mappers(
|
||||
|
@ -2797,9 +2799,8 @@ impl PicturePrimitive {
|
|||
plane_split_anchor: usize,
|
||||
) -> bool {
|
||||
let transform = clip_scroll_tree
|
||||
.get_world_transform(prim_spatial_node_index)
|
||||
.flattened;
|
||||
let matrix = transform.cast();
|
||||
.get_world_transform(prim_spatial_node_index);
|
||||
let matrix = transform.clone().into_transform().cast();
|
||||
|
||||
// Apply the local clip rect here, before splitting. This is
|
||||
// because the local clip rect can't be applied in the vertex
|
||||
|
@ -2815,20 +2816,26 @@ impl PicturePrimitive {
|
|||
};
|
||||
let world_rect = world_rect.cast();
|
||||
|
||||
if transform.is_simple_translation() {
|
||||
let inv_transform = clip_scroll_tree
|
||||
.get_world_transform(prim_spatial_node_index)
|
||||
.flattened
|
||||
.inverse()
|
||||
.expect("Simple translation, really?");
|
||||
match transform {
|
||||
CoordinateSpaceMapping::Local => {
|
||||
let polygon = Polygon::from_rect(
|
||||
local_rect * TypedScale::new(1.0),
|
||||
plane_split_anchor,
|
||||
);
|
||||
splitter.add(polygon);
|
||||
}
|
||||
CoordinateSpaceMapping::ScaleOffset(scale_offset) if scale_offset.scale == Vector2D::new(1.0, 1.0) => {
|
||||
let inv_matrix = scale_offset.inverse().to_transform().cast();
|
||||
let polygon = Polygon::from_transformed_rect_with_inverse(
|
||||
local_rect,
|
||||
&matrix,
|
||||
&inv_transform.cast(),
|
||||
&inv_matrix,
|
||||
plane_split_anchor,
|
||||
).unwrap();
|
||||
splitter.add(polygon);
|
||||
} else {
|
||||
}
|
||||
CoordinateSpaceMapping::ScaleOffset(_) |
|
||||
CoordinateSpaceMapping::Transform(_) => {
|
||||
let mut clipper = Clipper::new();
|
||||
let results = clipper.clip_transformed(
|
||||
Polygon::from_rect(
|
||||
|
@ -2844,6 +2851,7 @@ impl PicturePrimitive {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
@ -2866,10 +2874,9 @@ impl PicturePrimitive {
|
|||
let spatial_node_index = self.prim_list.prim_instances[poly.anchor].spatial_node_index;
|
||||
let transform = match clip_scroll_tree
|
||||
.get_world_transform(spatial_node_index)
|
||||
.flattened
|
||||
.inverse()
|
||||
{
|
||||
Some(transform) => transform,
|
||||
Some(transform) => transform.into_transform(),
|
||||
// logging this would be a bit too verbose
|
||||
None => continue,
|
||||
};
|
||||
|
@ -3015,7 +3022,7 @@ impl PicturePrimitive {
|
|||
// 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)
|
||||
.has_perspective;
|
||||
.is_perspective();
|
||||
|
||||
// Disallow subpixel AA if an intermediate surface is needed.
|
||||
// TODO(lsalzman): allow overriding parent if intermediate surface is opaque
|
||||
|
@ -3079,13 +3086,12 @@ impl PicturePrimitive {
|
|||
// For in-preserve-3d primitives and pictures, the backface visibility is
|
||||
// evaluated relative to the containing block.
|
||||
if let Picture3DContext::In { ancestor_index, .. } = self.context_3d {
|
||||
match CoordinateSpaceMapping::<LayoutPoint, LayoutPoint>::new(
|
||||
ancestor_index,
|
||||
cluster.spatial_node_index,
|
||||
&frame_context.clip_scroll_tree,
|
||||
) {
|
||||
(_, VisibleFace::Back) => continue,
|
||||
(_, VisibleFace::Front) => (),
|
||||
match frame_context.clip_scroll_tree
|
||||
.get_relative_transform(cluster.spatial_node_index, ancestor_index)
|
||||
.visible_face()
|
||||
{
|
||||
VisibleFace::Back => continue,
|
||||
VisibleFace::Front => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3383,6 +3389,7 @@ fn build_ref_prims(
|
|||
let mut map_local_to_world = SpaceMapper::new(
|
||||
ROOT_SPATIAL_NODE_INDEX,
|
||||
WorldRect::zero(),
|
||||
clip_scroll_tree,
|
||||
);
|
||||
|
||||
for ref_prim in ref_prims {
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::border::{get_max_scale_for_border, build_border_instances};
|
|||
use crate::border::BorderSegmentCacheKey;
|
||||
use crate::box_shadow::{BLUR_SAMPLE_SCALE};
|
||||
use crate::clip::{ClipStore};
|
||||
use crate::clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, SpatialNodeIndex, VisibleFace};
|
||||
use crate::clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX, ClipScrollTree, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace};
|
||||
use crate::clip::{ClipDataStore, ClipNodeFlags, ClipChainId, ClipChainInstance, ClipItem};
|
||||
use crate::debug_colors;
|
||||
use crate::debug_render::DebugItem;
|
||||
|
@ -50,9 +50,8 @@ use std::{cmp, fmt, hash, ops, u32, usize, mem};
|
|||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use crate::storage;
|
||||
use crate::texture_cache::TEXTURE_REGION_DIMENSIONS;
|
||||
use crate::util::{ScaleOffset, MatrixHelpers, MaxRect, Recycler};
|
||||
use crate::util::{pack_as_float, project_rect, raster_rect_to_device_pixels};
|
||||
use crate::util::{scale_factors, clamp_to_scale_factor};
|
||||
use crate::util::{MatrixHelpers, MaxRect, Recycler};
|
||||
use crate::util::{clamp_to_scale_factor, pack_as_float, project_rect, raster_rect_to_device_pixels};
|
||||
use crate::internal_types::LayoutPrimitiveInfo;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
|
@ -131,47 +130,11 @@ impl PrimitiveOpacity {
|
|||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CoordinateSpaceMapping<F, T> {
|
||||
Local,
|
||||
ScaleOffset(ScaleOffset),
|
||||
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,
|
||||
) -> (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 {
|
||||
(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);
|
||||
(CoordinateSpaceMapping::ScaleOffset(scale_offset), VisibleFace::Front)
|
||||
} else {
|
||||
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>()
|
||||
),
|
||||
VisibleFace::from_bool(relative.flattened.is_backface_visible())
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SpaceMapper<F, T> {
|
||||
kind: CoordinateSpaceMapping<F, T>,
|
||||
pub ref_spatial_node_index: SpatialNodeIndex,
|
||||
ref_world_inv_transform: CoordinateSpaceMapping<WorldPixel, T>,
|
||||
pub current_target_spatial_node_index: SpatialNodeIndex,
|
||||
pub bounds: TypedRect<f32, T>,
|
||||
visible_face: VisibleFace,
|
||||
|
@ -181,10 +144,16 @@ impl<F, T> SpaceMapper<F, T> where F: fmt::Debug {
|
|||
pub fn new(
|
||||
ref_spatial_node_index: SpatialNodeIndex,
|
||||
bounds: TypedRect<f32, T>,
|
||||
clip_scroll_tree: &ClipScrollTree,
|
||||
) -> Self {
|
||||
SpaceMapper {
|
||||
kind: CoordinateSpaceMapping::Local,
|
||||
ref_spatial_node_index,
|
||||
ref_world_inv_transform: clip_scroll_tree
|
||||
.get_world_transform(ref_spatial_node_index)
|
||||
.inverse()
|
||||
.unwrap()
|
||||
.with_destination::<T>(),
|
||||
current_target_spatial_node_index: ref_spatial_node_index,
|
||||
bounds,
|
||||
visible_face: VisibleFace::Front,
|
||||
|
@ -197,7 +166,7 @@ impl<F, T> SpaceMapper<F, T> where F: fmt::Debug {
|
|||
bounds: TypedRect<f32, T>,
|
||||
clip_scroll_tree: &ClipScrollTree,
|
||||
) -> Self {
|
||||
let mut mapper = SpaceMapper::new(ref_spatial_node_index, bounds);
|
||||
let mut mapper = SpaceMapper::new(ref_spatial_node_index, bounds, clip_scroll_tree);
|
||||
mapper.set_target_spatial_node(target_node_index, clip_scroll_tree);
|
||||
mapper
|
||||
}
|
||||
|
@ -207,18 +176,30 @@ impl<F, T> SpaceMapper<F, T> where F: fmt::Debug {
|
|||
target_node_index: SpatialNodeIndex,
|
||||
clip_scroll_tree: &ClipScrollTree,
|
||||
) {
|
||||
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,
|
||||
);
|
||||
|
||||
self.kind = kind;
|
||||
self.visible_face = visible_face;
|
||||
if target_node_index == self.current_target_spatial_node_index {
|
||||
return
|
||||
}
|
||||
|
||||
let ref_spatial_node = &clip_scroll_tree.spatial_nodes[self.ref_spatial_node_index.0 as usize];
|
||||
let target_spatial_node = &clip_scroll_tree.spatial_nodes[target_node_index.0 as usize];
|
||||
|
||||
self.kind = if self.ref_spatial_node_index == target_node_index {
|
||||
CoordinateSpaceMapping::Local
|
||||
} 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);
|
||||
CoordinateSpaceMapping::ScaleOffset(scale_offset)
|
||||
} else {
|
||||
let transform = clip_scroll_tree
|
||||
.get_world_transform(target_node_index)
|
||||
.post_mul_transform(&self.ref_world_inv_transform)
|
||||
.with_source::<F>();
|
||||
CoordinateSpaceMapping::Transform(transform)
|
||||
};
|
||||
|
||||
self.visible_face = self.kind.visible_face();
|
||||
self.current_target_spatial_node_index = target_node_index;
|
||||
}
|
||||
|
||||
pub fn get_transform(&self) -> TypedTransform3D<f32, F, T> {
|
||||
|
@ -1783,6 +1764,7 @@ impl PrimitiveStore {
|
|||
let mut map_local_to_raster = SpaceMapper::new(
|
||||
surface.raster_spatial_node_index,
|
||||
RasterRect::max_rect(),
|
||||
frame_context.clip_scroll_tree,
|
||||
);
|
||||
|
||||
let mut surface_rect = PictureRect::zero();
|
||||
|
@ -2197,17 +2179,15 @@ impl PrimitiveStore {
|
|||
// The transform only makes sense for screen space rasterization
|
||||
let relative_transform = frame_context
|
||||
.clip_scroll_tree
|
||||
.get_relative_transform(
|
||||
prim_instance.spatial_node_index,
|
||||
ROOT_SPATIAL_NODE_INDEX,
|
||||
);
|
||||
.get_world_transform(prim_instance.spatial_node_index)
|
||||
.into_transform();
|
||||
let prim_offset = prim_instance.prim_origin.to_vector() - run.reference_frame_relative_offset;
|
||||
|
||||
run.request_resources(
|
||||
prim_offset,
|
||||
&prim_data.font,
|
||||
&prim_data.glyphs,
|
||||
&relative_transform.flattened.with_destination::<WorldPixel>(),
|
||||
&relative_transform,
|
||||
surface,
|
||||
raster_space,
|
||||
frame_state.resource_cache,
|
||||
|
@ -2773,16 +2753,13 @@ impl PrimitiveStore {
|
|||
// based on the true world transform of the primitive. When
|
||||
// raster roots with local scale are supported in future,
|
||||
// that will need to be accounted for here.
|
||||
let relative_transform = frame_context
|
||||
let scale = frame_context
|
||||
.clip_scroll_tree
|
||||
.get_relative_transform(
|
||||
prim_instance.spatial_node_index,
|
||||
ROOT_SPATIAL_NODE_INDEX,
|
||||
);
|
||||
.get_world_transform(prim_instance.spatial_node_index)
|
||||
.scale_factors();
|
||||
|
||||
// Scale factors are normalized to a power of 2 to reduce the number of
|
||||
// resolution changes
|
||||
let scale = scale_factors(&relative_transform.flattened);
|
||||
// resolution changes.
|
||||
// For frames with a changing scale transform round scale factors up to
|
||||
// nearest power-of-2 boundary so that we don't keep having to redraw
|
||||
// the content as it scales up and down. Rounding up to nearest
|
||||
|
|
|
@ -554,7 +554,6 @@ impl Document {
|
|||
self.clip_scroll_tree.update_tree(
|
||||
pan,
|
||||
&self.dynamic_properties,
|
||||
None,
|
||||
);
|
||||
|
||||
self.hit_tester = Some(frame_builder.create_hit_tester(
|
||||
|
|
|
@ -8,7 +8,6 @@ use api::{TransformStyle, ScrollSensitivity, StickyOffsetBounds};
|
|||
use api::units::*;
|
||||
use crate::clip_scroll_tree::{CoordinateSystem, CoordinateSystemId, SpatialNodeIndex, TransformUpdateState};
|
||||
use euclid::SideOffsets2D;
|
||||
use crate::gpu_types::TransformPalette;
|
||||
use crate::scene::SceneProperties;
|
||||
use crate::util::{LayoutFastTransform, LayoutToWorldFastTransform, ScaleOffset, TransformedRectKind};
|
||||
|
||||
|
@ -40,7 +39,7 @@ pub struct SpatialNode {
|
|||
/// World transform for content transformed by this node.
|
||||
pub world_content_transform: LayoutToWorldFastTransform,
|
||||
|
||||
/// The current transform kind of world_content_transform.
|
||||
/// The current transform kind of this node.
|
||||
pub transform_kind: TransformedRectKind,
|
||||
|
||||
/// Pipeline that this layer belongs to
|
||||
|
@ -236,21 +235,6 @@ impl SpatialNode {
|
|||
self.world_viewport_transform = LayoutToWorldFastTransform::identity();
|
||||
}
|
||||
|
||||
pub fn push_gpu_data(
|
||||
&mut self,
|
||||
transform_palette: &mut TransformPalette,
|
||||
node_index: SpatialNodeIndex,
|
||||
) {
|
||||
if self.invertible {
|
||||
transform_palette.set_world_transform(
|
||||
node_index,
|
||||
self.world_content_transform
|
||||
.to_transform()
|
||||
.into_owned()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
state: &mut TransformUpdateState,
|
||||
|
@ -266,7 +250,7 @@ impl SpatialNode {
|
|||
}
|
||||
|
||||
self.update_transform(state, coord_systems, scene_properties, previous_spatial_nodes);
|
||||
self.transform_kind = self.world_content_transform.kind();
|
||||
self.transform_kind = self.world_viewport_transform.kind();
|
||||
|
||||
// If this node is a reference frame, we check if it has a non-invertible matrix.
|
||||
// For non-reference-frames we assume that they will produce only additional
|
||||
|
@ -363,7 +347,10 @@ impl SpatialNode {
|
|||
// Push that new coordinate system and record the new id.
|
||||
let coord_system = CoordinateSystem {
|
||||
transform,
|
||||
transform_style: info.transform_style,
|
||||
should_flatten: match (info.transform_style, info.kind) {
|
||||
(TransformStyle::Flat, ReferenceFrameKind::Transform) => true,
|
||||
(_, _) => false,
|
||||
},
|
||||
parent: Some(state.current_coordinate_system_id),
|
||||
};
|
||||
state.current_coordinate_system_id = CoordinateSystemId(coord_systems.len() as u32);
|
||||
|
@ -393,8 +380,6 @@ impl SpatialNode {
|
|||
state.parent_reference_frame_transform
|
||||
};
|
||||
|
||||
// The transformation for any content inside of us is the viewport transformation, plus
|
||||
// whatever scrolling offset we supply as well.
|
||||
let scroll_offset = self.scroll_offset();
|
||||
self.world_content_transform = if scroll_offset != LayoutVector2D::zero() {
|
||||
self.world_viewport_transform.pre_translate(&scroll_offset)
|
||||
|
@ -402,7 +387,10 @@ impl SpatialNode {
|
|||
self.world_viewport_transform
|
||||
};
|
||||
|
||||
let added_offset = state.parent_accumulated_scroll_offset + sticky_offset + scroll_offset;
|
||||
|
||||
// The transformation for any content inside of us is the viewport transformation, plus
|
||||
// whatever scrolling offset we supply as well.
|
||||
let added_offset = accumulated_offset + self.scroll_offset();
|
||||
self.coordinate_system_relative_scale_offset =
|
||||
state.coordinate_system_relative_scale_offset.offset(added_offset.to_untyped());
|
||||
|
||||
|
@ -642,14 +630,6 @@ impl SpatialNode {
|
|||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_style(&self) -> TransformStyle {
|
||||
match self.node_type {
|
||||
SpatialNodeType::ReferenceFrame(ref info) => info.transform_style,
|
||||
SpatialNodeType::StickyFrame(_) |
|
||||
SpatialNodeType::ScrollFrame(_) => TransformStyle::Flat,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Defines whether we have an implicit scroll frame for a pipeline root,
|
||||
|
@ -852,7 +832,7 @@ fn test_cst_perspective_relative_scroll() {
|
|||
pipeline_id,
|
||||
);
|
||||
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new(), None);
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new());
|
||||
|
||||
let scroll_offset = compute_offset_from(
|
||||
cst.spatial_nodes[ref_frame.0 as usize].parent,
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
root:
|
||||
items:
|
||||
- type: rect
|
||||
bounds: [100, 100, 200, 100]
|
||||
color: green
|
|
@ -0,0 +1,21 @@
|
|||
# This test ensures that we flatten the "flat" style trasformations.
|
||||
# If the flattening doesn't happen here, the rect gets rotated back
|
||||
# to the original position.
|
||||
---
|
||||
root:
|
||||
items:
|
||||
-
|
||||
bounds: [100, 100, 0, 0]
|
||||
type: stacking-context
|
||||
transform: rotate-x(45)
|
||||
transform-origin: 0 0
|
||||
items:
|
||||
-
|
||||
type: "stacking-context"
|
||||
transform: rotate-x(-45)
|
||||
transform-origin: 0 0
|
||||
items:
|
||||
-
|
||||
bounds: [0, 0, 200, 200]
|
||||
type: rect
|
||||
color: green
|
|
@ -37,5 +37,6 @@ platform(linux,mac) fuzzy(1,74) == border-scale-4.yaml border-scale-4.png
|
|||
# Just make sure we aren't crashing here
|
||||
!= large-raster-root.yaml blank.yaml
|
||||
== flatten-preserve-3d-root.yaml flatten-preserve-3d-root-ref.yaml
|
||||
== flatten-twice.yaml flatten-twice-ref.yaml
|
||||
== strange-w.yaml strange-w-ref.yaml
|
||||
== big-axis-aligned-scale.yaml big-axis-aligned-scale-ref.yaml
|
||||
|
|
|
@ -2,4 +2,3 @@
|
|||
expected:
|
||||
if (os == "android") and not e10s: FAIL
|
||||
if (os == "android") and e10s: FAIL
|
||||
if webrender or (os == "android" and not e10s): FAIL
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[transform-flattening-001.html]
|
||||
expected:
|
||||
if webrender: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[transform3d-preserve3d-008.html]
|
||||
expected:
|
||||
if webrender: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[transform3d-preserve3d-009.html]
|
||||
expected:
|
||||
if webrender: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[transform3d-preserve3d-013.html]
|
||||
expected:
|
||||
if webrender: FAIL
|
Загрузка…
Ссылка в новой задаче