Bug 1711648 - Move PictureRect to the endpoint representation. r=gfx-reviewers,jrmuizel

Differential Revision: https://phabricator.services.mozilla.com/D116825
This commit is contained in:
Nicolas Silva 2021-06-11 13:33:08 +00:00
parent 1e02b75f51
commit 724b80d537
13 changed files with 160 additions and 160 deletions

View File

@ -268,17 +268,17 @@ fn tile_to_svg(key: TileOffset,
}
svg += &format!(r#"<rect x="{}" y="{}" width="{}" height="{}" style="{}" ></rect>"#,
tile.rect.origin.x * svg_settings.scale + svg_settings.x,
tile.rect.origin.y * svg_settings.scale + svg_settings.y,
tile.rect.size.width * svg_settings.scale,
tile.rect.size.height * svg_settings.scale,
tile.rect.min.x * svg_settings.scale + svg_settings.x,
tile.rect.min.y * svg_settings.scale + svg_settings.y,
tile.rect.width() * svg_settings.scale,
tile.rect.height() * svg_settings.scale,
tile_style);
svg += &format!("\n\n<g class=\"svg_quadtree\">\n{}</g>\n",
tile_node_to_svg(&tile.root, &slice.transform, svg_settings));
let right = (tile.rect.origin.x + tile.rect.size.width) as i32;
let bottom = (tile.rect.origin.y + tile.rect.size.height) as i32;
let right = tile.rect.max.x as i32;
let bottom = tile.rect.max.y as i32;
*svg_width = if right > *svg_width { right } else { *svg_width };
*svg_height = if bottom > *svg_height { bottom } else { *svg_height };
@ -289,7 +289,7 @@ fn tile_to_svg(key: TileOffset,
let rect_visual_id = Rect {
origin: tile.rect.origin,
origin: tile.rect.min,
size: PictureSize::new(1.0, 1.0)
};
let rect_visual_id_world = slice.transform.outer_transformed_rect(&rect_visual_id).unwrap();
@ -337,10 +337,10 @@ fn tile_to_svg(key: TileOffset,
// nearly invisible, all we want is the toolip really
let style = "style=\"fill-opacity:0.001;";
svg += &format!("<rect x=\"{}\" y=\"{}\" width=\"{}\" height=\"{}\" {}{}\" >{}<\u{2f}rect>",
tile.rect.origin.x * svg_settings.scale + svg_settings.x,
tile.rect.origin.y * svg_settings.scale + svg_settings.y,
tile.rect.size.width * svg_settings.scale,
tile.rect.size.height * svg_settings.scale,
tile.rect.min.x * svg_settings.scale + svg_settings.x,
tile.rect.min.y * svg_settings.scale + svg_settings.y,
tile.rect.width() * svg_settings.scale,
tile.rect.height() * svg_settings.scale,
style,
tile_stroke,
title);

View File

@ -466,7 +466,7 @@ impl OpaqueBatchList {
if self.current_batch_index == usize::MAX ||
!self.batches[self.current_batch_index].key.is_compatible_with(&key) {
let mut selected_batch_index = None;
let item_area = z_bounding_rect.size.area();
let item_area = z_bounding_rect.area();
// If the area of this primitive is larger than the given threshold,
// then it is large enough to warrant breaking a batch for. In this
@ -1376,7 +1376,7 @@ impl BatchBuilder {
);
match map_device_to_surface.unmap(&device_bounding_rect) {
Some(r) => r.to_rect().intersection(bounding_rect),
Some(r) => r.intersection(bounding_rect),
None => Some(*bounding_rect),
}
} else {
@ -1399,10 +1399,10 @@ impl BatchBuilder {
let map_prim_to_surface: SpaceMapper<LayoutPixel, PicturePixel> = SpaceMapper::new_with_target(
surface_spatial_node_index,
prim_spatial_node_index,
bounding_rect.to_box2d(),
*bounding_rect,
ctx.spatial_tree,
);
map_prim_to_surface.map(&local_bounding_rect.to_box2d()).map(|r| r.to_rect())
map_prim_to_surface.map(&local_bounding_rect.to_box2d())
};
let intersected = match pic_bounding_rect {
@ -1567,7 +1567,7 @@ impl BatchBuilder {
let surface = &ctx.surfaces[raster_config.surface_index.0];
let mut is_opaque = prim_info.clip_task_index == ClipTaskIndex::INVALID
&& surface.opaque_rect.contains_rect(&surface.rect)
&& surface.opaque_rect.contains_box(&surface.rect)
&& transform_kind == TransformedRectKind::AxisAligned;
let pic_task_id = picture.primary_render_task_id.unwrap();

View File

@ -1359,7 +1359,7 @@ impl ClipStore {
// reject checks above, so that we don't eliminate masks accidentally (since
// we currently only support a local clip rect in the vertex shader).
if needs_mask {
pic_clip_rect = pic_clip_rect.intersection(&self.active_pic_clip_rect.to_box2d())?;
pic_clip_rect = pic_clip_rect.intersection(&self.active_pic_clip_rect)?;
}
// Return a valid clip chain instance
@ -1367,7 +1367,7 @@ impl ClipStore {
clips_range,
has_non_local_clips,
local_clip_rect: local_clip_rect.to_rect(),
pic_clip_rect: pic_clip_rect.to_rect(),
pic_clip_rect: pic_clip_rect,
pic_spatial_node_index: prim_to_pic_mapper.ref_spatial_node_index,
needs_mask,
})
@ -2166,12 +2166,12 @@ fn add_clip_node_to_current_chain(
let mapper = SpaceMapper::new_with_target(
pic_spatial_node_index,
node.spatial_node_index,
PictureRect::max_rect().to_box2d(),
PictureRect::max_rect(),
spatial_tree,
);
if let Some(pic_clip_rect) = mapper.map(&clip_rect.to_box2d()) {
*current_pic_clip_rect = pic_clip_rect.to_rect()
*current_pic_clip_rect = pic_clip_rect
.intersection(current_pic_clip_rect)
.unwrap_or(PictureRect::zero());
}

View File

@ -6,7 +6,7 @@ use api::{ColorF, YuvColorSpace, YuvFormat, ImageRendering, ExternalImageId, Ima
use api::units::*;
use api::ColorDepth;
use crate::image_source::resolve_image;
use euclid::{Rect, Transform3D};
use euclid::{Box2D, Transform3D};
use crate::gpu_cache::GpuCache;
use crate::gpu_types::{ZBufferId, ZBufferIdGenerator};
use crate::internal_types::TextureSource;
@ -576,21 +576,21 @@ impl CompositeState {
transform_index: CompositorTransformIndex,
) -> DeviceRect {
let transform = &self.transforms[transform_index.0];
transform.local_to_device.map_rect(&local_rect.to_box2d()).round()
transform.local_to_device.map_rect(&local_rect).round()
}
/// Calculate the device-space rect of a local compositor surface rect, normalized
/// to the origin of a given point
pub fn get_surface_rect<T>(
&self,
local_sub_rect: &Rect<f32, T>,
local_bounds: &Rect<f32, T>,
local_sub_rect: &Box2D<f32, T>,
local_bounds: &Box2D<f32, T>,
transform_index: CompositorTransformIndex,
) -> DeviceRect {
let transform = &self.transforms[transform_index.0];
let surface_bounds = transform.local_to_surface.map_rect(&local_bounds.to_box2d());
let surface_rect = transform.local_to_surface.map_rect(&local_sub_rect.to_box2d());
let surface_bounds = transform.local_to_surface.map_rect(&local_bounds);
let surface_rect = transform.local_to_surface.map_rect(&local_sub_rect);
surface_rect
.translate(-surface_bounds.min.to_vector())

View File

@ -455,7 +455,7 @@ impl FrameBuilder {
ROOT_SPATIAL_NODE_INDEX,
);
default_dirty_region.add_dirty_region(
frame_context.global_screen_world_rect.to_rect().cast_unit(),
frame_context.global_screen_world_rect.cast_unit(),
SubSliceIndex::DEFAULT,
frame_context.spatial_tree,
);
@ -730,7 +730,7 @@ impl FrameBuilder {
ctx.spatial_tree,
);
let world_clip_rect = map_local_to_world
.map(&tile_cache.local_clip_rect.to_box2d())
.map(&tile_cache.local_clip_rect)
.expect("bug: unable to map clip rect");
let device_clip_rect = (world_clip_rect * ctx.global_device_pixel_scale).round();

View File

@ -831,8 +831,6 @@ pub struct Tile {
pub world_tile_rect: WorldRect,
/// The current local rect of this tile.
pub local_tile_rect: PictureRect,
/// Same as local_tile_rect, but in min/max form as an optimization
pub local_tile_box: PictureBox2D,
/// The picture space dirty rect for this tile.
pub local_dirty_rect: PictureRect,
/// The device space dirty rect for this tile.
@ -886,7 +884,6 @@ impl Tile {
Tile {
tile_offset,
local_tile_rect: PictureRect::zero(),
local_tile_box: PictureBox2D::zero(),
world_tile_rect: WorldRect::zero(),
world_valid_rect: WorldRect::zero(),
device_valid_rect: DeviceRect::zero(),
@ -946,7 +943,7 @@ impl Tile {
frame_context,
);
dirty_rect.to_rect()
dirty_rect
}
/// Invalidate a tile based on change in content. This
@ -1015,17 +1012,13 @@ impl Tile {
&mut self,
ctx: &TilePreUpdateContext,
) {
self.local_tile_rect = PictureRect::new(
self.local_tile_rect = PictureRect::from_origin_and_size(
PicturePoint::new(
self.tile_offset.x as f32 * ctx.tile_size.width,
self.tile_offset.y as f32 * ctx.tile_size.height,
),
ctx.tile_size,
);
self.local_tile_box = PictureBox2D::new(
self.local_tile_rect.origin,
self.local_tile_rect.bottom_right(),
);
// TODO(gw): This is a hack / fix for Box2D::union in euclid not working with
// zero sized rect accumulation. Once that lands, we'll revert this
// to be zero.
@ -1036,7 +1029,7 @@ impl Tile {
self.invalidation_reason = None;
self.world_tile_rect = ctx.pic_to_world_mapper
.map(&self.local_tile_rect.to_box2d())
.map(&self.local_tile_rect)
.expect("bug: map local tile rect");
// Check if this tile is currently on screen.
@ -1063,7 +1056,7 @@ impl Tile {
&mut self.prev_descriptor,
);
self.current_descriptor.clear();
self.root.clear(self.local_tile_rect.to_box2d());
self.root.clear(self.local_tile_rect);
// Since this tile is determined to be visible, it will get updated
// dependencies, so update the frame id we are storing dependencies for.
@ -1124,8 +1117,8 @@ impl Tile {
// TODO(gw): This is a hot part of the code - we could probably optimize further by:
// - Using min/max instead of clamps below (if we guarantee the rects are well formed)
let tile_p0 = self.local_tile_box.min;
let tile_p1 = self.local_tile_box.max;
let tile_p0 = self.local_tile_rect.min;
let tile_p1 = self.local_tile_rect.max;
let prim_clip_box = PictureBox2D::new(
PicturePoint::new(
@ -1184,7 +1177,7 @@ impl Tile {
}
// Calculate the overall valid rect for this tile.
self.current_descriptor.local_valid_rect = self.local_valid_rect.to_rect();
self.current_descriptor.local_valid_rect = self.local_valid_rect;
// TODO(gw): In theory, the local tile rect should always have an
// intersection with the overall picture rect. In practice,
@ -1204,7 +1197,7 @@ impl Tile {
// The device_valid_rect is referenced during `update_content_validity` so it
// must be updated here first.
self.world_valid_rect = ctx.pic_to_world_mapper
.map(&self.current_descriptor.local_valid_rect.to_box2d())
.map(&self.current_descriptor.local_valid_rect)
.expect("bug: map local valid rect");
// The device rect is guaranteed to be aligned on a device pixel - the round
@ -1244,7 +1237,7 @@ impl Tile {
.unwrap_or_else(PictureRect::zero);
let has_opaque_bg_color = self.background_color.map_or(false, |c| c.a >= 1.0);
let has_opaque_backdrop = ctx.backdrop.map_or(false, |b| b.opaque_rect.contains_rect(&clipped_rect));
let has_opaque_backdrop = ctx.backdrop.map_or(false, |b| b.opaque_rect.contains_box(&clipped_rect));
let is_opaque = has_opaque_bg_color || has_opaque_backdrop;
// Set the correct z_id for this tile
@ -1693,7 +1686,7 @@ impl DirtyRegion {
);
let world_rect = map_pic_to_world
.map(&rect_in_pic_space.to_box2d())
.map(&rect_in_pic_space)
.expect("bug");
// Include this in the overall dirty rect
@ -1726,7 +1719,7 @@ impl DirtyRegion {
let rect_in_pic_space = filter.rect_in_pic_space.inflate(inflate_amount, inflate_amount);
let world_rect = map_pic_to_world
.map(&rect_in_pic_space.to_box2d())
.map(&rect_in_pic_space)
.expect("bug");
combined = combined.union(&world_rect);
@ -2455,13 +2448,13 @@ impl TileCacheInstance {
) -> (TileOffset, TileOffset) {
// Get the tile coordinates in the picture space.
let mut p0 = TileOffset::new(
(rect.origin.x / self.tile_size.width).floor() as i32,
(rect.origin.y / self.tile_size.height).floor() as i32,
(rect.min.x / self.tile_size.width).floor() as i32,
(rect.min.y / self.tile_size.height).floor() as i32,
);
let mut p1 = TileOffset::new(
((rect.origin.x + rect.size.width) / self.tile_size.width).ceil() as i32,
((rect.origin.y + rect.size.height) / self.tile_size.height).ceil() as i32,
(rect.max.x / self.tile_size.width).ceil() as i32,
(rect.max.y / self.tile_size.height).ceil() as i32,
);
// Clamp the tile coordinates here to avoid looping over irrelevant tiles later on.
@ -2509,7 +2502,7 @@ impl TileCacheInstance {
let map_local_to_surface = SpaceMapper::new(
self.spatial_node_index,
pic_rect.to_box2d(),
pic_rect,
);
let mut current_clip_chain_id = self.shared_clip_chain;
@ -2529,7 +2522,7 @@ impl TileCacheInstance {
);
let clip_chain_instance = frame_state.clip_store.build_clip_chain_instance(
pic_rect.cast_unit(),
pic_rect.to_rect().cast_unit(),
&map_local_to_surface,
&pic_to_world_mapper,
frame_context.spatial_tree,
@ -2580,7 +2573,7 @@ impl TileCacheInstance {
}
None => {
if self.slice_flags.contains(SliceFlags::IS_SCROLLBAR) {
if pic_rect.size.width <= pic_rect.size.height {
if pic_rect.width() <= pic_rect.height() {
TILE_SIZE_SCROLLBAR_VERTICAL
} else {
TILE_SIZE_SCROLLBAR_HORIZONTAL
@ -2687,7 +2680,7 @@ impl TileCacheInstance {
.inflate(0.0, 1.0 * self.tile_size.height);
let needed_rect_in_pic_space = desired_rect_in_pic_space
.intersection(&pic_rect.to_box2d())
.intersection(&pic_rect)
.unwrap_or_else(Box2D::zero);
let p0 = needed_rect_in_pic_space.min;
@ -3053,7 +3046,7 @@ impl TileCacheInstance {
let map_local_to_surface = SpaceMapper::new_with_target(
self.spatial_node_index,
prim_spatial_node_index,
self.local_rect.to_box2d(),
self.local_rect,
frame_context.spatial_tree,
);
@ -3106,8 +3099,8 @@ impl TileCacheInstance {
);
let surface_size = composite_state.get_surface_rect(
&local_prim_rect,
&local_prim_rect,
&local_prim_rect.to_box2d(),
&local_prim_rect.to_box2d(),
compositor_transform_index,
).size();
@ -3236,8 +3229,8 @@ impl TileCacheInstance {
is_opaque,
descriptor: ExternalSurfaceDescriptor {
local_surface_size: local_prim_rect.size,
local_rect: prim_rect.to_rect(),
local_clip_rect: prim_info.prim_clip_box.to_rect(),
local_rect: prim_rect,
local_clip_rect: prim_info.prim_clip_box,
dependency,
image_rendering,
clip_rect,
@ -3287,7 +3280,7 @@ impl TileCacheInstance {
// of nested blur elements). To account for this, step through the current
// surface stack, mapping the primitive rect into each surface space, including
// the inflation factor from each intermediate surface.
let mut current_pic_clip_rect = prim_clip_chain.pic_clip_rect.to_box2d();
let mut current_pic_clip_rect = prim_clip_chain.pic_clip_rect;
let mut current_spatial_node_index = frame_context
.surfaces[prim_surface_index.0]
.surface_spatial_node_index;
@ -3298,7 +3291,7 @@ impl TileCacheInstance {
let map_local_to_surface = SpaceMapper::new_with_target(
surface.surface_spatial_node_index,
current_spatial_node_index,
surface.rect.to_box2d(),
surface.rect,
frame_context.spatial_tree,
);
@ -3317,7 +3310,7 @@ impl TileCacheInstance {
current_spatial_node_index = surface.surface_spatial_node_index;
}
current_pic_clip_rect.to_rect()
current_pic_clip_rect
};
// Get the tile coordinates in the picture space.
@ -3332,7 +3325,7 @@ impl TileCacheInstance {
// Build the list of resources that this primitive has dependencies on.
let mut prim_info = PrimitiveDependencyInfo::new(
prim_instance.uid(),
pic_clip_rect.to_box2d(),
pic_clip_rect,
);
let mut sub_slice_index = self.sub_slices.len() - 1;
@ -3667,12 +3660,12 @@ impl TileCacheInstance {
sub_slice.compositor_surfaces.is_empty() &&
!prim_clip_chain.needs_mask {
if backdrop_candidate.opaque_rect.contains_rect(&self.backdrop.opaque_rect) {
if backdrop_candidate.opaque_rect.contains_box(&self.backdrop.opaque_rect) {
self.backdrop.opaque_rect = backdrop_candidate.opaque_rect;
}
if let Some(kind) = backdrop_candidate.kind {
if backdrop_candidate.opaque_rect.contains_rect(&self.local_rect) {
if backdrop_candidate.opaque_rect.contains_box(&self.local_rect) {
// If we have a color backdrop, mark the visibility flags
// of the primitive so it is skipped during batching (and
// also clears any previous primitives).
@ -3769,7 +3762,7 @@ impl TileCacheInstance {
// If the opaque backdrop rect covers the entire tile cache surface,
// we can allow subpixel AA anywhere, skipping the per-text-run tests
// later on during primitive preparation.
if self.backdrop.opaque_rect.contains_rect(&self.local_rect) {
if self.backdrop.opaque_rect.contains_box(&self.local_rect) {
return SubpixelMode::Allow;
}
@ -3915,7 +3908,7 @@ impl TileCacheInstance {
if let Some(local_surface_rect) = local_surface_rect {
let world_surface_rect = map_pic_to_world
.map(&local_surface_rect.to_box2d())
.map(&local_surface_rect)
.expect("bug: unable to map external surface to world space");
frame_state.composite_state.register_occluder(
@ -3940,7 +3933,7 @@ impl TileCacheInstance {
if let Some(backdrop_rect) = backdrop_rect {
let world_backdrop_rect = map_pic_to_world
.map(&backdrop_rect.to_box2d())
.map(&backdrop_rect)
.expect("bug: unable to map backdrop to world space");
// Since we register the entire backdrop rect, use the opaque z-id for the
@ -4154,7 +4147,7 @@ impl SurfaceInfo {
let pic_bounds = map_surface_to_world
.unmap(&map_surface_to_world.bounds)
.unwrap_or_else(|| PictureRect::max_rect().to_box2d());
.unwrap_or_else(PictureRect::max_rect);
let map_local_to_surface = SpaceMapper::new(
surface_spatial_node_index,
@ -4785,7 +4778,7 @@ impl PicturePrimitive {
let pic_bounds = map_pic_to_world
.unmap(&map_pic_to_world.bounds)
.unwrap_or_else(|| PictureRect::max_rect().to_box2d());
.unwrap_or_else(PictureRect::max_rect);
let map_local_to_pic = SpaceMapper::new(
surface_spatial_node_index,
@ -4824,7 +4817,7 @@ impl PicturePrimitive {
// Get the overall world space rect of the picture cache. Used to clip
// the tile rects below for occlusion testing to the relevant area.
let world_clip_rect = map_pic_to_world
.map(&tile_cache.local_clip_rect.to_box2d())
.map(&tile_cache.local_clip_rect)
.expect("bug: unable to map clip rect")
.round();
let device_clip_rect = (world_clip_rect * frame_context.global_device_pixel_scale).round();
@ -4967,7 +4960,7 @@ impl PicturePrimitive {
.unwrap_or_else(PictureRect::zero);
// Update the world/device dirty rect
let world_dirty_rect = map_pic_to_world.map(&tile.local_dirty_rect.to_box2d()).expect("bug");
let world_dirty_rect = map_pic_to_world.map(&tile.local_dirty_rect).expect("bug");
let device_rect = (tile.world_tile_rect * frame_context.global_device_pixel_scale).round();
tile.device_dirty_rect = (world_dirty_rect * frame_context.global_device_pixel_scale)
@ -5058,7 +5051,7 @@ impl PicturePrimitive {
// TODO(gw): `content_origin` should actually be in RasterPixels to be consistent
// with both local / screen raster modes, but this involves a lot of
// changes to render task and picture code.
let content_origin_f = tile.local_tile_rect.origin.cast_unit() * device_pixel_scale;
let content_origin_f = tile.local_tile_rect.min.cast_unit() * device_pixel_scale;
let content_origin = content_origin_f.round();
// TODO: these asserts used to have a threshold of 0.01 but failed intermittently the
// gfx/layers/apz/test/mochitest/test_group_double_tap_zoom-2.html test on android.
@ -5203,7 +5196,7 @@ impl PicturePrimitive {
// TODO(gw): Much of the SurfaceInfo related code assumes it is in device pixels, rather than
// raster pixels. Fixing that in one go is too invasive for now, but we need to
// start incrementally fixing up the unit types used around here.
let surface_raster_rect = map_pic_to_raster.map(&surface_local_rect.to_box2d()).expect("bug: unable to map to raster");
let surface_raster_rect = map_pic_to_raster.map(&surface_local_rect).expect("bug: unable to map to raster");
let surface_device_rect = surface_raster_rect.cast_unit() * device_pixel_scale;
frame_state.init_surface_tiled(
@ -5213,7 +5206,7 @@ impl PicturePrimitive {
);
}
Some(ref mut raster_config) => {
let pic_rect = self.precise_local_rect.cast_unit();
let pic_rect = self.precise_local_rect.to_box2d().cast_unit();
let mut device_pixel_scale = frame_state
.surfaces[raster_config.surface_index.0]
@ -5560,7 +5553,7 @@ impl PicturePrimitive {
frame_context.spatial_tree,
);
let pic_in_raster_space = map_pic_to_parent
.map(&pic_rect.to_box2d())
.map(&pic_rect)
.expect("bug: unable to map mix-blend content into parent")
.to_rect();
@ -6395,7 +6388,7 @@ impl PicturePrimitive {
// backface checks.
cluster.flags.insert(ClusterFlags::IS_VISIBLE);
if let Some(cluster_rect) = surface.map_local_to_surface.map(&cluster.bounding_rect.to_box2d()) {
surface.rect = surface.rect.union(&cluster_rect.to_rect());
surface.rect = surface.rect.union(&cluster_rect);
}
}
@ -6409,7 +6402,7 @@ impl PicturePrimitive {
surface.rect = raster_config.composite_mode.inflate_picture_rect(surface.rect, surface.scale_factors);
}
let mut surface_rect = surface.rect * Scale::new(1.0);
let mut surface_rect = surface.rect.to_rect() * Scale::new(1.0);
// Pop this surface from the stack
let surface_index = state.pop_surface();
@ -6442,7 +6435,7 @@ impl PicturePrimitive {
.map_local_to_surface
.map(&surface_rect.to_box2d())
{
parent_surface.rect = parent_surface.rect.union(&parent_surface_rect.to_rect());
parent_surface.rect = parent_surface.rect.union(&parent_surface_rect);
}
}
}
@ -6961,7 +6954,7 @@ impl TileNode {
debug_colors::YELLOW
};
if let Some(local_rect) = local_valid_rect.to_box2d().intersection(&self.rect) {
if let Some(local_rect) = local_valid_rect.intersection(&self.rect) {
let world_rect = pic_to_world_mapper
.map(&local_rect)
.unwrap();
@ -7392,7 +7385,7 @@ pub fn get_raster_rects(
prim_bounding_rect: WorldRect,
device_pixel_scale: DevicePixelScale,
) -> Option<(DeviceRect, DeviceRect)> {
let unclipped_raster_rect = map_to_raster.map(&pic_rect.to_box2d())?;
let unclipped_raster_rect = map_to_raster.map(&pic_rect)?;
let unclipped = raster_rect_to_device_pixels(
unclipped_raster_rect.to_rect(),

View File

@ -133,7 +133,7 @@ pub fn prepare_primitives(
let surface = &mut frame_state.surfaces[pic_context.surface_index.0];
if let Some(cluster_opaque_rect) = surface.map_local_to_surface.map_inner_bounds(&cluster.opaque_rect.to_box2d()) {
surface.opaque_rect = crate::util::conservative_union_rect(&surface.opaque_rect, &cluster_opaque_rect.to_rect());
surface.opaque_rect = crate::util::conservative_union_rect(&surface.opaque_rect, &cluster_opaque_rect);
}
}
}
@ -382,7 +382,7 @@ fn prepare_interned_prim_for_render(
SubpixelMode::Conditional { allowed_rect } => {
// Conditional mode allows subpixel AA to be enabled for this
// text run, so long as it's inside the allowed rect.
allowed_rect.contains_rect(&prim_instance.vis.clip_chain.pic_clip_rect)
allowed_rect.contains_box(&prim_instance.vis.clip_chain.pic_clip_rect)
}
}
} else {
@ -863,7 +863,7 @@ fn prepare_interned_prim_for_render(
prim_instance,
store,
);
cluster.opaque_rect = crate::util::conservative_union_rect(&cluster.opaque_rect, &prim_local_rect);
cluster.opaque_rect = crate::util::conservative_union_rect(&cluster.opaque_rect.to_box2d(), &prim_local_rect.to_box2d()).to_rect();
}
}
@ -1284,7 +1284,7 @@ pub fn update_brush_segment_clip_task(
return ClipMaskKind::None;
}
let segment_world_rect = match pic_state.map_pic_to_world.map(&clip_chain.pic_clip_rect.to_box2d()) {
let segment_world_rect = match pic_state.map_pic_to_world.map(&clip_chain.pic_clip_rect) {
Some(rect) => rect,
None => return ClipMaskKind::Clipped,
};
@ -1544,7 +1544,7 @@ fn get_unclipped_device_rect(
map_to_raster: &SpaceMapper<PicturePixel, RasterPixel>,
device_pixel_scale: DevicePixelScale,
) -> Option<DeviceRect> {
let raster_rect = map_to_raster.map(&prim_rect.to_box2d())?;
let raster_rect = map_to_raster.map(&prim_rect)?;
let world_rect = raster_rect * Scale::new(1.0);
Some(world_rect * device_pixel_scale)
}

View File

@ -191,10 +191,10 @@ impl From<LayoutRect> for RectangleKey {
impl From<PictureRect> for RectangleKey {
fn from(rect: PictureRect) -> RectangleKey {
RectangleKey {
x: rect.origin.x,
y: rect.origin.y,
w: rect.size.width,
h: rect.size.height,
x: rect.min.x,
y: rect.min.y,
w: rect.width(),
h: rect.height(),
}
}
}

View File

@ -4,7 +4,7 @@
use api::BorderRadius;
use api::units::*;
use euclid::{Point2D, Rect, Box2D, Size2D, Vector2D, point2, size2};
use euclid::{Point2D, Rect, Box2D, Size2D, Vector2D, point2};
use euclid::{default, Transform2D, Transform3D, Scale};
use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
use plane_split::{Clipper, Polygon};
@ -1528,19 +1528,19 @@ macro_rules! c_str {
}
// Find a rectangle that is contained by the sum of r1 and r2.
pub fn conservative_union_rect<U>(r1: &Rect<f32, U>, r2: &Rect<f32, U>) -> Rect<f32, U> {
pub fn conservative_union_rect<U>(r1: &Box2D<f32, U>, r2: &Box2D<f32, U>) -> Box2D<f32, U> {
// +---+---+ +--+-+--+
// | | | | | | |
// | | | | | | |
// +---+---+ +--+-+--+
if r1.origin.y == r2.origin.y && r1.size.height == r2.size.height {
if r2.min_x() <= r1.max_x() && r2.max_x() >= r1.min_x() {
let origin_x = f32::min(r1.origin.x, r2.origin.x);
let width = f32::max(r1.max_x(), r2.max_x()) - origin_x;
if r1.min.y == r2.min.y && r1.max.y == r2.max.y {
if r2.min.x <= r1.max.x && r2.max.x >= r1.min.x {
let min_x = f32::min(r1.min.x, r2.min.x);
let max_x = f32::max(r1.max.x, r2.max.x);
return Rect {
origin: point2(origin_x, r1.origin.y),
size: size2(width, r1.size.height),
return Box2D {
min: point2(min_x, r1.min.y),
max: point2(max_x, r1.max.y),
}
}
}
@ -1552,14 +1552,14 @@ pub fn conservative_union_rect<U>(r1: &Rect<f32, U>, r2: &Rect<f32, U>) -> Rect<
// | | +----+
// | | | |
// +----+ +----+
if r1.origin.x == r2.origin.x && r1.size.width == r2.size.width {
if r2.min_y() <= r1.max_y() && r2.max_y() >= r1.min_y() {
let origin_y = f32::min(r1.origin.y, r2.origin.y);
let height = f32::max(r1.max_y(), r2.max_y()) - origin_y;
if r1.min.x == r2.min.x && r1.max.x == r2.max.x {
if r2.min.y <= r1.max.y && r2.max.y >= r1.min.y {
let min_y = f32::min(r1.min.y, r2.min.y);
let max_y = f32::max(r1.max.y, r2.max.y);
return Rect {
origin: point2(r1.origin.x, origin_y),
size: size2(r1.size.width, height),
return Box2D {
min: point2(r1.min.x, min_y),
max: point2(r1.max.x, max_y),
}
}
}
@ -1569,98 +1569,99 @@ pub fn conservative_union_rect<U>(r1: &Rect<f32, U>, r2: &Rect<f32, U>) -> Rect<
#[test]
fn test_conservative_union_rect() {
use euclid::size2;
// Adjacent, x axis
let r = conservative_union_rect(
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(4.0, 2.0), size: size2(5.0, 4.0) },
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(4.0, 2.0), size: size2(5.0, 4.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(8.0, 4.0) });
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(8.0, 4.0) }.to_box2d());
let r = conservative_union_rect(
&LayoutRect { origin: point2(4.0, 2.0), size: size2(5.0, 4.0) },
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(4.0, 2.0), size: size2(5.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(8.0, 4.0) });
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(8.0, 4.0) }.to_box2d());
// Averlapping adjacent, x axis
let r = conservative_union_rect(
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(3.0, 2.0), size: size2(5.0, 4.0) },
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(3.0, 2.0), size: size2(5.0, 4.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(7.0, 4.0) });
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(7.0, 4.0) }.to_box2d());
let r = conservative_union_rect(
&LayoutRect { origin: point2(5.0, 2.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(1.0, 2.0), size: size2(5.0, 4.0) },
&LayoutRect { origin: point2(5.0, 2.0), size: size2(3.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(1.0, 2.0), size: size2(5.0, 4.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(7.0, 4.0) });
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(7.0, 4.0) }.to_box2d());
// Adjacent but not touching, x axis
let r = conservative_union_rect(
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(6.0, 2.0), size: size2(5.0, 4.0) },
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(6.0, 2.0), size: size2(5.0, 4.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(6.0, 2.0), size: size2(5.0, 4.0) });
assert_eq!(r, LayoutRect { origin: point2(6.0, 2.0), size: size2(5.0, 4.0) }.to_box2d());
let r = conservative_union_rect(
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(-6.0, 2.0), size: size2(1.0, 4.0) },
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(-6.0, 2.0), size: size2(1.0, 4.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) });
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) }.to_box2d());
// Adjacent, y axis
let r = conservative_union_rect(
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(1.0, 6.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(1.0, 6.0), size: size2(3.0, 4.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 8.0) });
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 8.0) }.to_box2d());
let r = conservative_union_rect(
&LayoutRect { origin: point2(1.0, 5.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(1.0, 1.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(1.0, 5.0), size: size2(3.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(1.0, 1.0), size: size2(3.0, 4.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(1.0, 1.0), size: size2(3.0, 8.0) });
assert_eq!(r, LayoutRect { origin: point2(1.0, 1.0), size: size2(3.0, 8.0) }.to_box2d());
// Averlapping adjacent, y axis
let r = conservative_union_rect(
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(1.0, 3.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(1.0, 3.0), size: size2(3.0, 4.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 5.0) });
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 5.0) }.to_box2d());
let r = conservative_union_rect(
&LayoutRect { origin: point2(1.0, 4.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(1.0, 4.0), size: size2(3.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 6.0) });
assert_eq!(r, LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 6.0) }.to_box2d());
// Adjacent but not touching, y axis
let r = conservative_union_rect(
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(1.0, 10.0), size: size2(3.0, 5.0) },
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(1.0, 10.0), size: size2(3.0, 5.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(1.0, 10.0), size: size2(3.0, 5.0) });
assert_eq!(r, LayoutRect { origin: point2(1.0, 10.0), size: size2(3.0, 5.0) }.to_box2d());
let r = conservative_union_rect(
&LayoutRect { origin: point2(1.0, 5.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(1.0, 0.0), size: size2(3.0, 3.0) },
&LayoutRect { origin: point2(1.0, 5.0), size: size2(3.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(1.0, 0.0), size: size2(3.0, 3.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(1.0, 5.0), size: size2(3.0, 4.0) });
assert_eq!(r, LayoutRect { origin: point2(1.0, 5.0), size: size2(3.0, 4.0) }.to_box2d());
// Contained
let r = conservative_union_rect(
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(0.0, 1.0), size: size2(10.0, 11.0) },
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) }.to_box2d(),
&LayoutRect { origin: point2(0.0, 1.0), size: size2(10.0, 11.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(0.0, 1.0), size: size2(10.0, 11.0) });
assert_eq!(r, LayoutRect { origin: point2(0.0, 1.0), size: size2(10.0, 11.0) }.to_box2d());
let r = conservative_union_rect(
&LayoutRect { origin: point2(0.0, 1.0), size: size2(10.0, 11.0) },
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) },
&LayoutRect { origin: point2(0.0, 1.0), size: size2(10.0, 11.0) }.to_box2d(),
&LayoutRect { origin: point2(1.0, 2.0), size: size2(3.0, 4.0) }.to_box2d(),
);
assert_eq!(r, LayoutRect { origin: point2(0.0, 1.0), size: size2(10.0, 11.0) });
assert_eq!(r, LayoutRect { origin: point2(0.0, 1.0), size: size2(10.0, 11.0) }.to_box2d());
}
/// This is inspired by the `weak-table` crate.

View File

@ -447,7 +447,7 @@ pub fn update_primitive_visibility(
match prim_instance.vis.combined_local_clip_rect.intersection(&local_rect) {
Some(visible_rect) => {
if let Some(rect) = map_local_to_surface.map(&visible_rect.to_box2d()) {
surface_rect = surface_rect.union(&rect.to_rect());
surface_rect = surface_rect.union(&rect);
}
}
None => {
@ -571,7 +571,7 @@ pub fn update_primitive_visibility(
// Layout space for the picture is picture space from the
// perspective of its child primitives.
pic.precise_local_rect = surface_rect * Scale::new(1.0);
pic.precise_local_rect = surface_rect.to_rect() * Scale::new(1.0);
// If the precise rect changed since last frame, we need to invalidate
// any segments and gpu cache handles for drop-shadows.
@ -614,10 +614,10 @@ pub fn update_primitive_visibility(
let map_surface_to_parent_surface = SpaceMapper::new_with_target(
parent_surface.surface_spatial_node_index,
surface.surface_spatial_node_index,
PictureRect::max_rect().to_box2d(),
PictureRect::max_rect(),
frame_context.spatial_tree,
);
map_surface_to_parent_surface.map(&surface_rect.to_box2d()).map(|r| r.to_rect())
map_surface_to_parent_surface.map(&surface_rect)
}
}
@ -636,7 +636,7 @@ fn update_prim_post_visibility(
// minimize the size of the render target that is required.
if let Some(ref mut raster_config) = pic.raster_config {
raster_config.clipped_bounding_rect = map_surface_to_world
.map(&prim_instance.vis.clip_chain.pic_clip_rect.to_box2d())
.map(&prim_instance.vis.clip_chain.pic_clip_rect)
.and_then(|rect| {
rect.intersection(&world_culling_rect)
})
@ -672,7 +672,7 @@ pub fn compute_conservative_visible_rect(
let map_local_to_pic: SpaceMapper<LayoutPixel, PicturePixel> = SpaceMapper::new_with_target(
clip_chain.pic_spatial_node_index,
prim_spatial_node_index,
PictureRect::max_rect().to_box2d(),
PictureRect::max_rect(),
spatial_tree,
);
@ -687,7 +687,7 @@ pub fn compute_conservative_visible_rect(
// is in picture space (the clip-chain already takes into account the bounds of the
// primitive local_rect and local_clip_rect). If there is no intersection here, the
// primitive is not visible at all.
let pic_culling_rect = match pic_culling_rect.intersection(&clip_chain.pic_clip_rect.to_box2d()) {
let pic_culling_rect = match pic_culling_rect.intersection(&clip_chain.pic_clip_rect) {
Some(rect) => rect,
None => return LayoutRect::zero(),
};
@ -706,7 +706,7 @@ fn calculate_prim_clipped_world_rect(
map_surface_to_world: &SpaceMapper<PicturePixel, WorldPixel>,
) -> Option<WorldRect> {
map_surface_to_world
.map(&pic_clip_rect.to_box2d())
.map(&pic_clip_rect)
.and_then(|world_rect| {
world_rect.intersection(world_culling_rect)
})

View File

@ -52,10 +52,10 @@ pub type FramebufferIntRect = Box2D<i32, FramebufferPixel>;
#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct PicturePixel;
pub type PictureIntRect = Rect<i32, PicturePixel>;
pub type PictureIntRect = Box2D<i32, PicturePixel>;
pub type PictureIntPoint = Point2D<i32, PicturePixel>;
pub type PictureIntSize = Size2D<i32, PicturePixel>;
pub type PictureRect = Rect<f32, PicturePixel>;
pub type PictureRect = Box2D<f32, PicturePixel>;
pub type PicturePoint = Point2D<f32, PicturePixel>;
pub type PictureSize = Size2D<f32, PicturePixel>;
pub type PicturePoint3D = Point3D<f32, PicturePixel>;
@ -326,7 +326,7 @@ impl<U> RectExt for Box2D<f32, U> {
#[inline]
pub fn layout_rect_as_picture_rect(layout_rect: &LayoutRect) -> PictureRect {
layout_rect.cast_unit()
layout_rect.to_box2d().cast_unit()
}
#[inline]

View File

@ -344,6 +344,12 @@ impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Rect<T, U> {
}
}
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::Box2D<T, U> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.min.size_of(ops) + self.max.size_of(ops)
}
}
impl<T: MallocSizeOf, U> MallocSizeOf for euclid::SideOffsets2D<T, U> {
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
self.top.size_of(ops) +

View File

@ -24,7 +24,7 @@ struct RenderResult {
// Convenience method to build a picture rect
fn pr(x: f32, y: f32, w: f32, h: f32) -> PictureRect {
PictureRect::new(
PictureRect::from_origin_and_size(
PicturePoint::new(x, y),
PictureSize::new(w, h),
)