Skip to content

Commit

Permalink
A few small changes related to custom raster spaces.
Browse files Browse the repository at this point in the history
* Make TransformPalette mut during the culling step. This will
  allow us to add new transforms relative to a given spatial
  node during the frame traversal.
* Switch calculate_screen_bounding_rect use to project_rect. We
  will want to start using / storing world rects in floats most
  of the time, rather than converting to an integer device rect.
* Make TransformPalette pre-allocate the size of the array of
  spatial nodes. This allows us to easily append new transform
  entries at the end of this array, as we need to add new matrices
  that are relevant to a different coordinate space.
  • Loading branch information
gw3583 committed Aug 23, 2018
1 parent e93d1e5 commit 6fcb77d
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 181 deletions.
50 changes: 1 addition & 49 deletions webrender/src/clip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ use clip_scroll_tree::{ClipScrollTree, CoordinateSystemId, SpatialNodeIndex};
use ellipse::Ellipse;
use gpu_cache::{GpuCache, GpuCacheHandle, ToGpuBlocks};
use gpu_types::BoxShadowStretchMode;
use plane_split::{Clipper, Polygon};
use prim_store::{ClipData, ImageMaskData};
use render_task::to_cache_size;
use resource_cache::{ImageRequest, ResourceCache};
use std::{cmp, u32};
use util::{extract_inner_rect_safe, pack_as_float, recycle_vec, MaxRect};
use util::{extract_inner_rect_safe, pack_as_float, project_rect, recycle_vec, MaxRect};

/*
Expand Down Expand Up @@ -1078,53 +1077,6 @@ pub fn rounded_rectangle_contains_point(
true
}

fn project_rect(
transform: &LayoutToWorldTransform,
rect: &LayoutRect,
) -> Option<WorldRect> {
let homogens = [
transform.transform_point2d_homogeneous(&rect.origin),
transform.transform_point2d_homogeneous(&rect.top_right()),
transform.transform_point2d_homogeneous(&rect.bottom_left()),
transform.transform_point2d_homogeneous(&rect.bottom_right()),
];

// Note: we only do the full frustum collision when the polygon approaches the camera plane.
// Otherwise, it will be clamped to the screen bounds anyway.
if homogens.iter().any(|h| h.w <= 0.0) {
let mut clipper = Clipper::new();
clipper.add_frustum(
transform,
None,
);

let polygon = Polygon::from_rect(*rect, 1);
let results = clipper.clip(polygon);
if results.is_empty() {
return None
}

Some(WorldRect::from_points(results
.into_iter()
// filter out parts behind the view plane
.flat_map(|poly| &poly.points)
.map(|p| {
let mut homo = transform.transform_point2d_homogeneous(&p.to_2d());
homo.w = homo.w.max(0.00000001); // avoid infinite values
homo.to_point2d().unwrap()
})
))
} else {
// we just checked for all the points to be in positive hemisphere, so `unwrap` is valid
Some(WorldRect::from_points(&[
homogens[0].to_point2d().unwrap(),
homogens[1].to_point2d().unwrap(),
homogens[2].to_point2d().unwrap(),
homogens[3].to_point2d().unwrap(),
]))
}
}

pub fn project_inner_rect(
transform: &LayoutToWorldTransform,
rect: &LayoutRect,
Expand Down
14 changes: 7 additions & 7 deletions webrender/src/frame_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ pub struct FrameBuildingContext<'a> {
pub pipelines: &'a FastHashMap<PipelineId, Arc<ScenePipeline>>,
pub screen_rect: DeviceIntRect,
pub clip_scroll_tree: &'a ClipScrollTree,
pub transforms: &'a TransformPalette,
pub max_local_clip: LayoutRect,
}

Expand All @@ -84,6 +83,7 @@ pub struct FrameBuildingState<'a> {
pub resource_cache: &'a mut ResourceCache,
pub gpu_cache: &'a mut GpuCache,
pub special_render_passes: &'a mut SpecialRenderPasses,
pub transforms: &'a mut TransformPalette,
}

pub struct PictureContext {
Expand Down Expand Up @@ -113,14 +113,14 @@ impl PictureState {
pub struct PrimitiveContext<'a> {
pub spatial_node: &'a SpatialNode,
pub spatial_node_index: SpatialNodeIndex,
pub transform: Transform<'a>,
pub transform: Transform,
}

impl<'a> PrimitiveContext<'a> {
pub fn new(
spatial_node: &'a SpatialNode,
spatial_node_index: SpatialNodeIndex,
transform: Transform<'a>,
transform: Transform,
) -> Self {
PrimitiveContext {
spatial_node,
Expand Down Expand Up @@ -186,7 +186,7 @@ impl FrameBuilder {
profile_counters: &mut FrameProfileCounters,
device_pixel_scale: DevicePixelScale,
scene_properties: &SceneProperties,
transform_palette: &TransformPalette,
transform_palette: &mut TransformPalette,
) -> Option<RenderTaskId> {
profile_scope!("cull");

Expand All @@ -208,7 +208,6 @@ impl FrameBuilder {
pipelines,
screen_rect: self.screen_rect.to_i32(),
clip_scroll_tree,
transforms: transform_palette,
max_local_clip: LayoutRect::new(
LayoutPoint::new(-MAX_CLIP_COORD, -MAX_CLIP_COORD),
LayoutSize::new(2.0 * MAX_CLIP_COORD, 2.0 * MAX_CLIP_COORD),
Expand All @@ -222,6 +221,7 @@ impl FrameBuilder {
resource_cache,
gpu_cache,
special_render_passes,
transforms: transform_palette,
};

let mut pic_state = PictureState::new();
Expand Down Expand Up @@ -319,7 +319,7 @@ impl FrameBuilder {
resource_cache.begin_frame(frame_id);
gpu_cache.begin_frame();

let transform_palette = clip_scroll_tree.update_tree(
let mut transform_palette = clip_scroll_tree.update_tree(
pan,
scene_properties,
);
Expand All @@ -341,7 +341,7 @@ impl FrameBuilder {
&mut profile_counters,
device_pixel_scale,
scene_properties,
&transform_palette,
&mut transform_palette,
);

resource_cache.block_until_all_resources_added(gpu_cache,
Expand Down
34 changes: 13 additions & 21 deletions webrender/src/gpu_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ impl TransformPaletteId {
}

// The GPU data payload for a transform palette entry.
#[derive(Debug)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[repr(C)]
Expand All @@ -388,10 +388,19 @@ impl TransformData {
}

// Extra data stored about each transform palette entry.
#[derive(Clone)]
pub struct TransformMetadata {
transform_kind: TransformedRectKind,
}

impl TransformMetadata {
fn invalid() -> Self {
TransformMetadata {
transform_kind: TransformedRectKind::AxisAligned,
}
}
}

// Stores a contiguous list of TransformData structs, that
// are ready for upload to the GPU.
// TODO(gw): For now, this only stores the complete local
Expand All @@ -407,27 +416,12 @@ pub struct TransformPalette {
impl TransformPalette {
pub fn new(spatial_node_count: usize) -> Self {
TransformPalette {
transforms: Vec::with_capacity(spatial_node_count),
metadata: Vec::with_capacity(spatial_node_count),
}
}

#[inline]
fn grow(&mut self, index: SpatialNodeIndex) {
// Pad the vectors out if they are not long enough to
// account for this index. This can occur, for instance,
// when we stop recursing down the CST due to encountering
// a node with an invalid transform.
while self.transforms.len() <= index.0 as usize {
self.transforms.push(TransformData::invalid());
self.metadata.push(TransformMetadata {
transform_kind: TransformedRectKind::AxisAligned,
});
transforms: vec![TransformData::invalid(); spatial_node_count],
metadata: vec![TransformMetadata::invalid(); spatial_node_count],
}
}

pub fn invalidate(&mut self, index: SpatialNodeIndex) {
self.grow(index);
self.metadata[index.0 as usize] = TransformMetadata {
transform_kind: TransformedRectKind::AxisAligned,
};
Expand All @@ -439,8 +433,6 @@ impl TransformPalette {
pub fn set(
&mut self, index: SpatialNodeIndex, fast_transform: &LayoutToWorldFastTransform,
) -> bool {
self.grow(index);

match fast_transform.inverse() {
Some(inverted) => {
// Store the transform itself, along with metadata about it.
Expand Down Expand Up @@ -474,7 +466,7 @@ impl TransformPalette {
let metadata = &self.metadata[index.0 as usize];

Transform {
m: &data.transform,
m: data.transform,
transform_kind: metadata.transform_kind,
backface_is_visible: data.transform.is_backface_visible(),
}
Expand Down
47 changes: 29 additions & 18 deletions webrender/src/prim_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ use resource_cache::{ImageProperties, ImageRequest, ResourceCache};
use scene::SceneProperties;
use segment::SegmentBuilder;
use std::{cmp, mem, usize};
use util::{MatrixHelpers, calculate_screen_bounding_rect};
use util::{pack_as_float, recycle_vec, TransformedRectKind};
use util::{MatrixHelpers, pack_as_float, project_rect, recycle_vec};
use util::{TransformedRectKind, world_rect_to_device_pixels};


const MIN_BRUSH_SPLIT_AREA: f32 = 256.0 * 256.0;
Expand Down Expand Up @@ -59,8 +59,8 @@ impl ScrollNodeAndClipChain {
// the information in the clip-scroll tree. However, if we decide
// to rasterize a picture in local space, then this will be the
// transform relative to that picture's coordinate system.
pub struct Transform<'a> {
pub m: &'a LayoutToWorldTransform,
pub struct Transform {
pub m: LayoutToWorldTransform,
pub backface_is_visible: bool,
pub transform_kind: TransformedRectKind,
}
Expand Down Expand Up @@ -1635,13 +1635,8 @@ impl PrimitiveStore {

pic_state.has_non_root_coord_system |= clip_chain.has_non_root_coord_system;

let unclipped_device_rect = match calculate_screen_bounding_rect(
&prim_context.spatial_node.world_content_transform,
&local_rect,
frame_context.device_pixel_scale,
None, //TODO: inflate `frame_context.screen_rect` appropriately
) {
Some(rect) => rect,
let world_rect = match project_rect(&prim_context.transform.m, &local_rect) {
Some(world_rect) => world_rect,
None => {
if cfg!(debug_assertions) && is_chased {
println!("\tculled for being behind the near plane of transform: {:?}",
Expand All @@ -1651,9 +1646,21 @@ impl PrimitiveStore {
}
};

let clipped_device_rect = (clip_chain.world_clip_rect * frame_context.device_pixel_scale)
.round_out()
.to_i32();
let unclipped_device_rect = match world_rect_to_device_pixels(
world_rect,
frame_context.device_pixel_scale,
) {
Some(rect) => rect,
None => return None,
};

let clipped_device_rect = match world_rect_to_device_pixels(
clip_chain.world_clip_rect,
frame_context.device_pixel_scale,
) {
Some(rect) => rect,
None => return None,
};

let clipped_device_rect = match clipped_device_rect.intersection(&frame_context.screen_rect) {
Some(clipped_device_rect) => clipped_device_rect,
Expand Down Expand Up @@ -1757,7 +1764,7 @@ impl PrimitiveStore {
.clip_scroll_tree
.spatial_nodes[spatial_node_index.0];

let transform = frame_context
let transform = frame_state
.transforms
.get_transform(spatial_node_index);

Expand Down Expand Up @@ -2157,9 +2164,13 @@ impl Primitive {
continue;
}

let bounds = (segment_clip_chain.world_clip_rect * frame_context.device_pixel_scale)
.round_out()
.to_i32();
let bounds = match world_rect_to_device_pixels(
segment_clip_chain.world_clip_rect,
frame_context.device_pixel_scale,
) {
Some(rect) => rect,
None => continue,
};

let clip_task = RenderTask::new_mask(
bounds,
Expand Down
Loading

0 comments on commit 6fcb77d

Please sign in to comment.