Bug 1574493 - Part 2. Remove snapping in frame building. r=kvark

This will be rewritten in a later patch in the series. The shaders will
be provided the correct information and will no longer need to concern
themselves with snapping.

Differential Revision: https://phabricator.services.mozilla.com/D45057

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrew Osmond 2019-09-12 12:42:39 +00:00
Родитель 7cda552aeb
Коммит 571a0f49e1
15 изменённых файлов: 142 добавлений и 536 удалений

Просмотреть файл

@ -70,9 +70,7 @@ void main(void) {
ph.local_clip_rect,
ph.z,
transform,
pic_task,
ph.local_rect,
ph.snap_offsets
pic_task
);
// TODO(gw): transform bounds may be referenced by

Просмотреть файл

@ -2,7 +2,7 @@
* 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/. */
#include rect,render_task,gpu_cache,snap,transform
#include rect,render_task,gpu_cache,transform
#ifdef WR_VERTEX_SHADER
@ -11,7 +11,6 @@ in ivec4 aClipDataResourceAddress;
in vec2 aClipLocalPos;
in vec4 aClipTileRect;
in vec4 aClipDeviceArea;
in vec4 aClipSnapOffsets;
in vec4 aClipOrigins;
in float aDevicePixelScale;
@ -23,7 +22,6 @@ struct ClipMaskInstance {
vec2 local_pos;
RectWithSize tile_rect;
RectWithSize sub_rect;
vec4 snap_offsets;
vec2 task_origin;
vec2 screen_origin;
float device_pixel_scale;
@ -39,7 +37,6 @@ ClipMaskInstance fetch_clip_item() {
cmi.local_pos = aClipLocalPos;
cmi.tile_rect = RectWithSize(aClipTileRect.xy, aClipTileRect.zw);
cmi.sub_rect = RectWithSize(aClipDeviceArea.xy, aClipDeviceArea.zw);
cmi.snap_offsets = aClipSnapOffsets;
cmi.task_origin = aClipOrigins.xy;
cmi.screen_origin = aClipOrigins.zw;
cmi.device_pixel_scale = aDevicePixelScale;
@ -64,23 +61,10 @@ ClipVertexInfo write_clip_tile_vertex(RectWithSize local_clip_rect,
Transform prim_transform,
Transform clip_transform,
RectWithSize sub_rect,
vec4 snap_offsets,
vec2 task_origin,
vec2 screen_origin,
float device_pixel_scale) {
vec2 device_pos = screen_origin + sub_rect.p0 + aPosition.xy * sub_rect.size;
// If the primitive we are drawing a clip mask for was snapped, then
// remove the effect of that snapping, so that the local position
// interpolation below works correctly relative to the clip item.
vec2 snap_offset = mix(
snap_offsets.xy,
snap_offsets.zw,
aPosition.xy
);
device_pos -= snap_offset;
vec2 world_pos = device_pos / device_pixel_scale;
vec4 pos = prim_transform.m * vec4(world_pos, 0.0, 1.0);

Просмотреть файл

@ -52,7 +52,6 @@ void main(void) {
prim_transform,
clip_transform,
cmi.sub_rect,
cmi.snap_offsets,
cmi.task_origin,
cmi.screen_origin,
cmi.device_pixel_scale

Просмотреть файл

@ -35,7 +35,6 @@ void main(void) {
prim_transform,
clip_transform,
cmi.sub_rect,
cmi.snap_offsets,
cmi.task_origin,
cmi.screen_origin,
cmi.device_pixel_scale

Просмотреть файл

@ -77,7 +77,6 @@ void main(void) {
prim_transform,
clip_transform,
cmi.sub_rect,
cmi.snap_offsets,
cmi.task_origin,
cmi.screen_origin,
cmi.device_pixel_scale

Просмотреть файл

@ -2,7 +2,7 @@
* 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/. */
#include rect,render_task,gpu_cache,snap,transform
#include rect,render_task,gpu_cache,transform
#define EXTEND_MODE_CLAMP 0
#define EXTEND_MODE_REPEAT 1
@ -47,13 +47,12 @@ uniform HIGHP_SAMPLER_FLOAT isampler2D sPrimitiveHeadersI;
// Instanced attributes
in ivec4 aData;
#define VECS_PER_PRIM_HEADER_F 3U
#define VECS_PER_PRIM_HEADER_F 2U
#define VECS_PER_PRIM_HEADER_I 2U
struct PrimitiveHeader {
RectWithSize local_rect;
RectWithSize local_clip_rect;
vec4 snap_offsets;
float z;
int specific_prim_address;
int transform_id;
@ -66,7 +65,6 @@ PrimitiveHeader fetch_prim_header(int index) {
ivec2 uv_f = get_fetch_uv(index, VECS_PER_PRIM_HEADER_F);
vec4 local_rect = TEXEL_FETCH(sPrimitiveHeadersF, uv_f, 0, ivec2(0, 0));
vec4 local_clip_rect = TEXEL_FETCH(sPrimitiveHeadersF, uv_f, 0, ivec2(1, 0));
ph.snap_offsets = TEXEL_FETCH(sPrimitiveHeadersF, uv_f, 0, ivec2(2, 0));
ph.local_rect = RectWithSize(local_rect.xy, local_rect.zw);
ph.local_clip_rect = RectWithSize(local_clip_rect.xy, local_clip_rect.zw);
@ -91,9 +89,7 @@ VertexInfo write_vertex(RectWithSize instance_rect,
RectWithSize local_clip_rect,
float z,
Transform transform,
PictureTask task,
RectWithSize snap_rect,
vec4 snap_offsets) {
PictureTask task) {
// Select the corner of the local rect that we are processing.
vec2 local_pos = instance_rect.p0 + instance_rect.size * aPosition.xy;
@ -101,13 +97,6 @@ VertexInfo write_vertex(RectWithSize instance_rect,
// Clamp to the two local clip rects.
vec2 clamped_local_pos = clamp_rect(local_pos, local_clip_rect);
/// Compute the snapping offset.
vec2 snap_offset = compute_snap_offset(
clamped_local_pos,
snap_rect,
snap_offsets
);
// Transform the current vertex to world space.
vec4 world_pos = transform.m * vec4(clamped_local_pos, 0.0, 1.0);
@ -115,13 +104,13 @@ VertexInfo write_vertex(RectWithSize instance_rect,
vec2 device_pos = world_pos.xy * task.device_pixel_scale;
// Apply offsets for the render task to get correct screen location.
vec2 final_offset = snap_offset - task.content_origin + task.common_data.task_rect.p0;
vec2 final_offset = -task.content_origin + task.common_data.task_rect.p0;
gl_Position = uTransform * vec4(device_pos + final_offset * world_pos.w, z * world_pos.w, world_pos.w);
VertexInfo vi = VertexInfo(
clamped_local_pos,
snap_offset,
vec2(0.0, 0.0),
world_pos
);

Просмотреть файл

@ -1,22 +0,0 @@
/* 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/. */
#ifdef WR_VERTEX_SHADER
/// Given a point within a local rectangle, and the device space corners
/// offsets for the unsnapped primitive, return the snap offsets. This *must*
/// exactly match the logic in the Rust compute_snap_offset_impl function.
vec2 compute_snap_offset(
vec2 reference_pos,
RectWithSize reference_rect,
vec4 snap_positions
) {
/// Compute the position of this vertex inside the snap rectangle.
vec2 normalized_snap_pos = (reference_pos - reference_rect.p0) / reference_rect.size;
/// Compute the actual world offset for this vertex needed to make it snap.
return mix(snap_positions.xy, snap_positions.zw, normalized_snap_pos);
}
#endif //WR_VERTEX_SHADER

Просмотреть файл

@ -10,7 +10,7 @@ use crate::clip_scroll_tree::{ClipScrollTree, ROOT_SPATIAL_NODE_INDEX, SpatialNo
use crate::glyph_rasterizer::GlyphFormat;
use crate::gpu_cache::{GpuBlockData, GpuCache, GpuCacheHandle, GpuCacheAddress};
use crate::gpu_types::{BrushFlags, BrushInstance, PrimitiveHeaders, ZBufferId, ZBufferIdGenerator};
use crate::gpu_types::{ClipMaskInstance, SplitCompositeInstance, SnapOffsets};
use crate::gpu_types::{ClipMaskInstance, SplitCompositeInstance};
use crate::gpu_types::{PrimitiveInstanceData, RasterizationSpace, GlyphInstance};
use crate::gpu_types::{PrimitiveHeader, PrimitiveHeaderIndex, TransformPaletteId, TransformPalette};
use crate::internal_types::{FastHashMap, SavedTargetIndex, Swizzle, TextureSource, Filter};
@ -18,7 +18,6 @@ use crate::picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, T
use crate::prim_store::{DeferredResolve, EdgeAaSegmentMask, PrimitiveInstanceKind, PrimitiveVisibilityIndex, PrimitiveVisibilityMask};
use crate::prim_store::{VisibleGradientTile, PrimitiveInstance, PrimitiveOpacity, SegmentInstanceIndex};
use crate::prim_store::{BrushSegment, ClipMaskKind, ClipTaskIndex, VECS_PER_SEGMENT};
use crate::prim_store::{recompute_snap_offsets};
use crate::prim_store::image::ImageSource;
use crate::render_backend::DataStores;
use crate::render_target::RenderTargetContext;
@ -708,7 +707,7 @@ impl BatchBuilder {
let prim_common_data = &ctx.data_stores.as_common_data(&prim_instance);
let prim_rect = LayoutRect::new(
prim_instance.prim_origin,
prim_common_data.prim_size,
prim_common_data.prim_size
);
let mut batch_features = BatchFeatures::empty();
@ -720,7 +719,6 @@ impl BatchBuilder {
batch_features |= BatchFeatures::ANTIALIASING;
}
let snap_offsets = prim_info.snap_offsets;
let prim_vis_mask = prim_info.visibility_mask;
let clip_task_address = ctx.get_prim_clip_task_address(
prim_info.clip_task_index,
@ -751,7 +749,6 @@ impl BatchBuilder {
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: prim_cache_address,
transform_id,
};
@ -818,7 +815,6 @@ impl BatchBuilder {
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: prim_cache_address,
transform_id,
};
@ -870,7 +866,6 @@ impl BatchBuilder {
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: prim_cache_address,
transform_id,
};
@ -1040,7 +1035,6 @@ impl BatchBuilder {
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: prim_cache_address,
transform_id,
};
@ -1077,9 +1071,8 @@ impl BatchBuilder {
let prim_cache_address = gpu_cache.get_address(&ctx.globals.default_image_handle);
let prim_header = PrimitiveHeader {
local_rect: picture.snapped_local_rect,
local_rect: picture.local_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: prim_cache_address,
transform_id,
};
@ -1104,9 +1097,8 @@ impl BatchBuilder {
);
let prim_header = PrimitiveHeader {
local_rect: pic.snapped_local_rect,
local_rect: pic.local_rect,
local_clip_rect: child_prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: GpuCacheAddress::INVALID,
transform_id: transforms
.get_id(
@ -1225,7 +1217,6 @@ impl BatchBuilder {
let prim_header = PrimitiveHeader {
local_rect: local_tile_rect,
local_clip_rect: local_tile_clip_rect,
snap_offsets: SnapOffsets::empty(),
specific_prim_address: prim_cache_address,
transform_id,
};
@ -1295,7 +1286,6 @@ impl BatchBuilder {
let prim_header = PrimitiveHeader {
local_rect: local_tile_rect,
local_clip_rect: local_tile_clip_rect,
snap_offsets: SnapOffsets::empty(),
specific_prim_address: prim_cache_address,
transform_id,
};
@ -1412,7 +1402,6 @@ impl BatchBuilder {
let shadow_prim_header = PrimitiveHeader {
local_rect: shadow_rect,
snap_offsets: prim_info.shadow_snap_offsets,
specific_prim_address: shadow_prim_address,
..prim_header
};
@ -1705,9 +1694,8 @@ impl BatchBuilder {
};
let prim_header = PrimitiveHeader {
local_rect: picture.snapped_local_rect,
local_rect: picture.local_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: prim_cache_address,
transform_id,
};
@ -1828,7 +1816,6 @@ impl BatchBuilder {
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: prim_cache_address,
transform_id,
};
@ -1903,7 +1890,6 @@ impl BatchBuilder {
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: prim_cache_address,
transform_id,
};
@ -2013,7 +1999,6 @@ impl BatchBuilder {
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: prim_cache_address,
transform_id,
};
@ -2119,7 +2104,6 @@ impl BatchBuilder {
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: prim_cache_address,
transform_id,
};
@ -2168,7 +2152,6 @@ impl BatchBuilder {
let prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: image_instance.tight_local_clip_rect,
snap_offsets,
specific_prim_address: gpu_cache.get_address(&gpu_handle),
transform_id,
};
@ -2212,7 +2195,6 @@ impl BatchBuilder {
let mut prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: GpuCacheAddress::INVALID,
transform_id,
};
@ -2340,7 +2322,6 @@ impl BatchBuilder {
let mut prim_header = PrimitiveHeader {
local_rect: prim_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
snap_offsets,
specific_prim_address: GpuCacheAddress::INVALID,
transform_id,
};
@ -2444,10 +2425,9 @@ impl BatchBuilder {
let prim_cache_address = gpu_cache.get_address(&ctx.globals.default_image_handle);
let backdrop_picture = &ctx.prim_store.pictures[backdrop_pic_index.0];
let prim_header = PrimitiveHeader {
local_rect: backdrop_picture.snapped_local_rect,
local_rect: backdrop_picture.local_rect,
local_clip_rect: prim_info.combined_local_clip_rect,
transform_id,
snap_offsets: SnapOffsets::empty(),
specific_prim_address: prim_cache_address,
};
@ -2668,18 +2648,10 @@ impl BatchBuilder {
let user_data = [stops_handle.as_int(gpu_cache), 0, 0, 0];
for tile in visible_tiles {
// Adjust the snap offsets for the tile.
let snap_offsets = recompute_snap_offsets(
tile.local_rect,
base_prim_header.local_rect,
base_prim_header.snap_offsets,
);
let prim_header = PrimitiveHeader {
specific_prim_address: gpu_cache.get_address(&tile.handle),
local_rect: tile.local_rect,
local_clip_rect: tile.local_clip_rect,
snap_offsets,
..*base_prim_header
};
let prim_header_index = prim_headers.push(&prim_header, z_id, user_data);
@ -2949,7 +2921,6 @@ impl ClipBatcher {
local_pos,
tile_rect: LayoutRect::zero(),
sub_rect,
snap_offsets: SnapOffsets::empty(),
task_origin,
screen_origin,
device_pixel_scale,
@ -3075,7 +3046,6 @@ impl ClipBatcher {
actual_rect: DeviceIntRect,
world_rect: &WorldRect,
device_pixel_scale: DevicePixelScale,
snap_offsets: SnapOffsets,
task_origin: DevicePoint,
screen_origin: DevicePoint,
) {
@ -3108,7 +3078,6 @@ impl ClipBatcher {
DevicePoint::zero(),
actual_rect.size.to_f32(),
),
snap_offsets,
task_origin,
screen_origin,
device_pixel_scale: device_pixel_scale.0,

Просмотреть файл

@ -392,7 +392,7 @@ impl FrameBuilder {
&frame_context,
gpu_cache,
&self.clip_store,
&data_stores.clip,
data_stores,
);
{

Просмотреть файл

@ -169,7 +169,6 @@ pub struct ClipMaskInstance {
pub local_pos: LayoutPoint,
pub tile_rect: LayoutRect,
pub sub_rect: DeviceRect,
pub snap_offsets: SnapOffsets,
pub task_origin: DevicePoint,
pub screen_origin: DevicePoint,
pub device_pixel_scale: f32,
@ -250,7 +249,6 @@ impl PrimitiveHeaders {
self.headers_float.push(PrimitiveHeaderF {
local_rect: prim_header.local_rect,
local_clip_rect: prim_header.local_clip_rect,
snap_offsets: prim_header.snap_offsets,
});
self.headers_int.push(PrimitiveHeaderI {
@ -271,7 +269,6 @@ impl PrimitiveHeaders {
pub struct PrimitiveHeader {
pub local_rect: LayoutRect,
pub local_clip_rect: LayoutRect,
pub snap_offsets: SnapOffsets,
pub specific_prim_address: GpuCacheAddress,
pub transform_id: TransformPaletteId,
}
@ -284,7 +281,6 @@ pub struct PrimitiveHeader {
pub struct PrimitiveHeaderF {
pub local_rect: LayoutRect,
pub local_clip_rect: LayoutRect,
pub snap_offsets: SnapOffsets,
}
// i32 parts of a primitive header
@ -593,33 +589,6 @@ pub enum UvRectKind {
},
}
/// Represents offsets in device pixels that a primitive
/// was snapped to.
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct SnapOffsets {
/// How far the top left corner was snapped
pub top_left: DeviceVector2D,
/// How far the bottom right corner was snapped
pub bottom_right: DeviceVector2D,
}
impl SnapOffsets {
pub fn empty() -> Self {
SnapOffsets {
top_left: DeviceVector2D::zero(),
bottom_right: DeviceVector2D::zero(),
}
}
pub fn is_empty(&self) -> bool {
let zero = DeviceVector2D::zero();
self.top_left == zero && self.bottom_right == zero
}
}
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]

Просмотреть файл

@ -7,7 +7,7 @@ use api::{PropertyBinding, PropertyBindingId, FilterPrimitive, FontRenderMode};
use api::{DebugFlags, RasterSpace, ImageKey, ColorF};
use api::units::*;
use crate::box_shadow::{BLUR_SAMPLE_SCALE};
use crate::clip::{ClipStore, ClipDataStore, ClipChainInstance, ClipDataHandle, ClipChainId};
use crate::clip::{ClipStore, ClipChainInstance, ClipDataHandle, ClipChainId};
use crate::clip_scroll_tree::{ROOT_SPATIAL_NODE_INDEX,
ClipScrollTree, CoordinateSpaceMapping, SpatialNodeIndex, VisibleFace, CoordinateSystemId
};
@ -1781,7 +1781,7 @@ impl<'a> PictureUpdateState<'a> {
frame_context: &FrameBuildingContext,
gpu_cache: &mut GpuCache,
clip_store: &ClipStore,
clip_data_store: &ClipDataStore,
data_stores: &mut DataStores,
) {
profile_marker!("UpdatePictures");
@ -1798,7 +1798,7 @@ impl<'a> PictureUpdateState<'a> {
frame_context,
gpu_cache,
clip_store,
clip_data_store,
data_stores,
);
if !state.are_raster_roots_assigned {
@ -1861,7 +1861,7 @@ impl<'a> PictureUpdateState<'a> {
frame_context: &FrameBuildingContext,
gpu_cache: &mut GpuCache,
clip_store: &ClipStore,
clip_data_store: &ClipDataStore,
data_stores: &mut DataStores,
) {
if let Some(prim_list) = picture_primitives[pic_index.0].pre_update(
self,
@ -1874,7 +1874,7 @@ impl<'a> PictureUpdateState<'a> {
frame_context,
gpu_cache,
clip_store,
clip_data_store,
data_stores,
);
}
@ -1882,6 +1882,7 @@ impl<'a> PictureUpdateState<'a> {
prim_list,
self,
frame_context,
data_stores,
);
}
}
@ -2196,6 +2197,10 @@ pub struct PrimitiveClusterIndex(pub u32);
#[cfg_attr(feature = "capture", derive(Serialize))]
pub struct ClusterIndex(pub u16);
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "capture", derive(Serialize))]
pub struct PrimitiveIndex(pub u32);
impl ClusterIndex {
pub const INVALID: ClusterIndex = ClusterIndex(u16::MAX);
}
@ -2217,6 +2222,10 @@ pub struct PrimitiveList {
pub pictures: PictureList,
/// List of primitives grouped into clusters.
pub clusters: SmallVec<[PrimitiveCluster; 4]>,
/// List of primitive indicies that can only update
/// the cluster during frame building. This maps to
/// primitives in the prim_instances array.
pub deferred_prims: Vec<PrimitiveIndex>,
}
impl PrimitiveList {
@ -2229,6 +2238,7 @@ impl PrimitiveList {
prim_instances: Vec::new(),
pictures: SmallVec::new(),
clusters: SmallVec::new(),
deferred_prims: Vec::new(),
}
}
@ -2243,10 +2253,11 @@ impl PrimitiveList {
let mut pictures = SmallVec::new();
let mut clusters_map = FastHashMap::default();
let mut clusters: SmallVec<[PrimitiveCluster; 4]> = SmallVec::new();
let mut deferred_prims = Vec::new();
// Walk the list of primitive instances and extract any that
// are pictures.
for prim_instance in &mut prim_instances {
for (prim_index, prim_instance) in &mut prim_instances.iter_mut().enumerate() {
// Check if this primitive is a picture. In future we should
// remove this match and embed this info directly in the primitive instance.
let is_pic = match prim_instance.kind {
@ -2302,8 +2313,12 @@ impl PrimitiveList {
(data.is_backface_visible, data.prim_size)
}
PrimitiveInstanceKind::Backdrop { data_handle, .. } => {
// We don't know the actual size of the backdrop until frame
// building, so use an empty rect for now and add it to the
// deferred primitive list.
let data = &interners.backdrop[data_handle];
(data.is_backface_visible, data.prim_size)
deferred_prims.push(PrimitiveIndex(prim_index as u32));
(data.is_backface_visible, LayoutSize::zero())
}
PrimitiveInstanceKind::PushClipChain |
PrimitiveInstanceKind::PopClipChain => {
@ -2358,6 +2373,7 @@ impl PrimitiveList {
prim_instances,
pictures,
clusters,
deferred_prims,
}
}
}
@ -2423,17 +2439,10 @@ pub struct PicturePrimitive {
/// composited into the parent picture.
pub spatial_node_index: SpatialNodeIndex,
/// The local rect of this picture. It is built
/// dynamically when updating visibility. It takes
/// into account snapping in device space for its
/// children.
pub snapped_local_rect: LayoutRect,
/// The local rect of this picture. It is built
/// dynamically during the first picture traversal. It
/// does not take into account snapping in device for
/// its children.
pub unsnapped_local_rect: LayoutRect,
/// is composed of already snapped primitives.
pub local_rect: LayoutRect,
/// If false, this picture needs to (re)build segments
/// if it supports segment rendering. This can occur
@ -2458,8 +2467,7 @@ impl PicturePrimitive {
) {
pt.new_level(format!("{:?}", self_index));
pt.add_item(format!("prim_count: {:?}", self.prim_list.prim_instances.len()));
pt.add_item(format!("snapped_local_rect: {:?}", self.snapped_local_rect));
pt.add_item(format!("unsnapped_local_rect: {:?}", self.unsnapped_local_rect));
pt.add_item(format!("local_rect: {:?}", self.local_rect));
pt.add_item(format!("spatial_node_index: {:?}", self.spatial_node_index));
pt.add_item(format!("raster_config: {:?}", self.raster_config));
pt.add_item(format!("requested_composite_mode: {:?}", self.requested_composite_mode));
@ -2568,8 +2576,7 @@ impl PicturePrimitive {
is_backface_visible,
requested_raster_space,
spatial_node_index,
snapped_local_rect: LayoutRect::zero(),
unsnapped_local_rect: LayoutRect::zero(),
local_rect: LayoutRect::zero(),
tile_cache,
options,
segments_are_valid: false,
@ -2673,7 +2680,7 @@ impl PicturePrimitive {
match self.raster_config {
Some(ref raster_config) => {
let pic_rect = PictureRect::from_untyped(&self.snapped_local_rect.to_untyped());
let pic_rect = PictureRect::from_untyped(&self.local_rect.to_untyped());
let device_pixel_scale = frame_state
.surfaces[raster_config.surface_index.0]
@ -3437,6 +3444,7 @@ impl PicturePrimitive {
prim_list: PrimitiveList,
state: &mut PictureUpdateState,
frame_context: &FrameBuildingContext,
data_stores: &mut DataStores,
) {
// Restore the pictures list used during recursion.
self.prim_list = prim_list;
@ -3444,6 +3452,59 @@ impl PicturePrimitive {
// Pop the state information about this picture.
state.pop_picture();
// Update any primitives/cluster bounding rects that can only be done
// with information available during frame building.
for prim_index in &self.prim_list.deferred_prims {
let prim_instance = &mut self.prim_list.prim_instances[prim_index.0 as usize];
match prim_instance.kind {
PrimitiveInstanceKind::Backdrop { data_handle, .. } => {
// The actual size and clip rect of this primitive are determined by computing the bounding
// box of the projected rect of the backdrop-filter element onto the backdrop.
let prim_data = &mut data_stores.backdrop[data_handle];
let spatial_node_index = prim_data.kind.spatial_node_index;
// We cannot use the relative transform between the backdrop and the element because
// that doesn't take into account any projection transforms that both spatial nodes are children of.
// Instead, we first project from the element to the world space and get a flattened 2D bounding rect
// in the screen space, we then map this rect from the world space to the backdrop space to get the
// proper bounding box where the backdrop-filter needs to be processed.
let prim_to_world_mapper = SpaceMapper::new_with_target(
ROOT_SPATIAL_NODE_INDEX,
spatial_node_index,
LayoutRect::max_rect(),
frame_context.clip_scroll_tree,
);
let backdrop_to_world_mapper = SpaceMapper::new_with_target(
ROOT_SPATIAL_NODE_INDEX,
prim_instance.spatial_node_index,
LayoutRect::max_rect(),
frame_context.clip_scroll_tree,
);
// First map to the screen and get a flattened rect
let prim_rect = prim_to_world_mapper.map(&prim_data.kind.border_rect).unwrap_or_else(LayoutRect::zero);
// Backwards project the flattened rect onto the backdrop
let prim_rect = backdrop_to_world_mapper.unmap(&prim_rect).unwrap_or_else(LayoutRect::zero);
// TODO(aosmond): Is this safe? Updating the primitive size during
// frame building is usually problematic since scene building will cache
// the primitive information in the GPU already.
prim_instance.prim_origin = prim_rect.origin;
prim_data.common.prim_size = prim_rect.size;
prim_instance.local_clip_rect = prim_rect;
// Update the cluster bounding rect now that we have the backdrop rect.
let cluster = &mut self.prim_list.clusters[prim_instance.cluster_index.0 as usize];
cluster.bounding_rect = cluster.bounding_rect.union(&prim_rect);
}
_ => {
panic!("BUG: unexpected deferred primitive kind for cluster updates");
}
}
}
for cluster in &mut self.prim_list.clusters {
// Skip the cluster if backface culled.
if !cluster.is_backface_visible {
@ -3503,11 +3564,6 @@ impl PicturePrimitive {
let surface_index = state.pop_surface();
debug_assert_eq!(surface_index, raster_config.surface_index);
// Snapping may change the local rect slightly, and as such should just be
// considered an estimated size for determining if we need raster roots and
// preparing the tile cache.
self.unsnapped_local_rect = surface_rect;
// Check if any of the surfaces can't be rasterized in local space but want to.
if raster_config.establishes_raster_root {
if surface_rect.size.width > MAX_SURFACE_SIZE ||
@ -3518,6 +3574,8 @@ impl PicturePrimitive {
}
}
self.local_rect = surface_rect;
// Drop shadows draw both a content and shadow rect, so need to expand the local
// rect of any surfaces to be composited in parent surfaces correctly.
match raster_config.composite_mode {
@ -3586,14 +3644,14 @@ impl PicturePrimitive {
// Basic brush primitive header is (see end of prepare_prim_for_render_inner in prim_store.rs)
// [brush specific data]
// [segment_rect, segment data]
let shadow_rect = self.snapped_local_rect.translate(shadow.offset);
let shadow_rect = self.local_rect.translate(shadow.offset);
// ImageBrush colors
request.push(shadow.color.premultiplied());
request.push(PremultipliedColorF::WHITE);
request.push([
self.snapped_local_rect.size.width,
self.snapped_local_rect.size.height,
self.local_rect.size.width,
self.local_rect.size.height,
0.0,
0.0,
]);

Просмотреть файл

@ -22,7 +22,7 @@ use crate::frame_builder::{FrameBuildingContext, FrameBuildingState, PictureCont
use crate::frame_builder::{FrameVisibilityContext, FrameVisibilityState};
use crate::glyph_rasterizer::GlyphKey;
use crate::gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle, GpuDataRequest, ToGpuBlocks};
use crate::gpu_types::{BrushFlags, SnapOffsets};
use crate::gpu_types::{BrushFlags};
use crate::image::{Repetition};
use crate::intern;
use malloc_size_of::MallocSizeOf;
@ -932,7 +932,6 @@ impl BrushSegment {
frame_state: &mut FrameBuildingState,
clip_data_store: &mut ClipDataStore,
unclipped: &DeviceRect,
prim_snap_offsets: SnapOffsets,
device_pixel_scale: DevicePixelScale,
) -> ClipMaskKind {
match clip_chain {
@ -955,9 +954,8 @@ impl BrushSegment {
// Get a minimal device space rect, clipped to the screen that we
// need to allocate for the clip mask, as well as interpolated
// snap offsets.
let (device_rect, snap_offsets) = match get_clipped_device_rect(
let device_rect = match get_clipped_device_rect(
unclipped,
prim_snap_offsets,
&pic_state.map_raster_to_world,
segment_world_rect,
device_pixel_scale,
@ -977,7 +975,6 @@ impl BrushSegment {
frame_state.resource_cache,
frame_state.render_tasks,
clip_data_store,
snap_offsets,
device_pixel_scale,
frame_context.fb_config,
);
@ -1435,18 +1432,6 @@ pub struct PrimitiveVisibility {
/// The current combined local clip for this primitive, from
/// the primitive local clip above and the current clip chain.
pub combined_local_clip_rect: LayoutRect,
/// The snap offsets in device space for this primitive. They are
/// generated based on the visible rect, which is the local rect
/// clipped by the combined local clip for most primitives, or
/// just the local rect for pictures.
pub snap_offsets: SnapOffsets,
/// The snap offsets in device space for the drop shadow for
/// picture primitives, if applicable. Similar to snap offsets,
/// they are generated based on the local rect translated by the
/// drop shadow offset.
pub shadow_snap_offsets: SnapOffsets,
}
#[derive(Clone, Debug)]
@ -1807,7 +1792,7 @@ impl PrimitiveStore {
world_culling_rect: &WorldRect,
frame_context: &FrameVisibilityContext,
frame_state: &mut FrameVisibilityState,
) -> Option<PictureRect> {
) {
let (mut prim_list, surface_index, apply_local_clip_rect, world_culling_rect, is_composite) = {
let pic = &mut self.pictures[pic_index.0];
let mut world_culling_rect = *world_culling_rect;
@ -1827,7 +1812,7 @@ impl PrimitiveStore {
// relative transforms have changed, which means we need to
// re-map the dependencies of any child primitives.
world_culling_rect = tile_cache.pre_update(
PictureRect::from_untyped(&pic.unsnapped_local_rect.to_untyped()),
PictureRect::from_untyped(&pic.local_rect.to_untyped()),
surface_index,
frame_context,
frame_state,
@ -1861,19 +1846,13 @@ impl PrimitiveStore {
frame_context.clip_scroll_tree,
);
let mut map_local_to_raster = SpaceMapper::new(
surface.raster_spatial_node_index,
RasterRect::max_rect(),
);
let mut surface_rect = PictureRect::zero();
for prim_instance in &mut prim_list.prim_instances {
prim_instance.reset();
if prim_instance.is_chased() {
#[cfg(debug_assertions)] // needed for ".id" part
println!("\tpreparing {:?} in {:?}", prim_instance.id, pic_index);
println!("\t{:?}", prim_instance.kind);
}
// Get the cluster and see if is visible
@ -1889,12 +1868,7 @@ impl PrimitiveStore {
frame_context.clip_scroll_tree,
);
map_local_to_raster.set_target_spatial_node(
prim_instance.spatial_node_index,
frame_context.clip_scroll_tree,
);
let (is_passthrough, snap_to_visible, prim_local_rect, prim_shadow_rect) = match prim_instance.kind {
let (is_passthrough, prim_local_rect, prim_shadow_rect) = match prim_instance.kind {
PrimitiveInstanceKind::PushClipChain => {
frame_state.clip_chain_stack.push_clip(
prim_instance.clip_chain_id,
@ -1916,7 +1890,7 @@ impl PrimitiveStore {
frame_state.clip_store,
);
let pic_surface_rect = self.update_visibility(
self.update_visibility(
pic_index,
surface_index,
&world_culling_rect,
@ -1926,8 +1900,6 @@ impl PrimitiveStore {
frame_state.clip_chain_stack.pop_clip();
let pic = &self.pictures[pic_index.0];
// The local rect of pictures is calculated dynamically based on
// the content of children, which may move due to the spatial
// node they are attached to. Other parts of the code (such as
@ -1937,74 +1909,22 @@ impl PrimitiveStore {
// this way. In future, we could perhaps just store the
// size in the picture primitive, to that there isn't
// any duplicated data.
prim_instance.prim_origin = pic.snapped_local_rect.origin;
let pic = &self.pictures[pic_index.0];
prim_instance.prim_origin = pic.local_rect.origin;
let shadow_rect = match pic.raster_config {
Some(ref rc) => match rc.composite_mode {
// If we have a drop shadow filter, we also need to include the shadow in
// our local rect for the purpose of calculating the size of the picture.
PictureCompositeMode::Filter(Filter::DropShadows(ref shadows)) => {
let mut rect = LayoutRect::zero();
for shadow in shadows {
rect = rect.union(&pic.snapped_local_rect.translate(shadow.offset));
}
rect
}
_ => LayoutRect::zero(),
}
None => {
if let Some(ref rect) = pic_surface_rect {
surface_rect = surface_rect.union(rect);
}
LayoutRect::zero()
let shadow_rect = if let Some(RasterConfig { composite_mode: PictureCompositeMode::Filter(Filter::DropShadows(ref shadows)), .. }) = pic.raster_config {
// If we have a drop shadow filter, we also need to include the shadow in
// our local rect for the purpose of calculating the size of the picture.
let mut rect = LayoutRect::zero();
for shadow in shadows {
rect = rect.union(&pic.local_rect.translate(shadow.offset));
}
rect
} else {
LayoutRect::zero()
};
if prim_instance.is_chased() {
if pic.unsnapped_local_rect != pic.snapped_local_rect {
println!("\tsnapped from {:?} to {:?}", pic.unsnapped_local_rect, pic.snapped_local_rect);
}
}
(pic.raster_config.is_none(), false, pic.snapped_local_rect, shadow_rect)
}
PrimitiveInstanceKind::Backdrop { data_handle } => {
// The actual size and clip rect of this primitive are determined by computing the bounding
// box of the projected rect of the backdrop-filter element onto the backdrop.
let prim_data = &mut frame_state.data_stores.backdrop[data_handle];
let spatial_node_index = prim_data.kind.spatial_node_index;
// We cannot use the relative transform between the backdrop and the element because
// that doesn't take into account any projection transforms that both spatial nodes are children of.
// Instead, we first project from the element to the world space and get a flattened 2D bounding rect
// in the screen space, we then map this rect from the world space to the backdrop space to get the
// proper bounding box where the backdrop-filter needs to be processed.
let prim_to_world_mapper = SpaceMapper::new_with_target(
ROOT_SPATIAL_NODE_INDEX,
spatial_node_index,
LayoutRect::max_rect(),
frame_context.clip_scroll_tree,
);
let backdrop_to_world_mapper = SpaceMapper::new_with_target(
ROOT_SPATIAL_NODE_INDEX,
prim_instance.spatial_node_index,
LayoutRect::max_rect(),
frame_context.clip_scroll_tree,
);
// First map to the screen and get a flattened rect
let prim_rect = prim_to_world_mapper.map(&prim_data.kind.border_rect).unwrap_or_else(LayoutRect::zero);
// Backwards project the flattened rect onto the backdrop
let prim_rect = backdrop_to_world_mapper.unmap(&prim_rect).unwrap_or_else(LayoutRect::zero);
prim_instance.prim_origin = prim_rect.origin;
prim_data.common.prim_size = prim_rect.size;
prim_instance.local_clip_rect = prim_rect;
(false, true, prim_rect, LayoutRect::zero())
(pic.raster_config.is_none(), pic.local_rect, shadow_rect)
}
_ => {
let prim_data = &frame_state.data_stores.as_common_data(&prim_instance);
@ -2014,7 +1934,7 @@ impl PrimitiveStore {
prim_data.prim_size,
);
(false, true, prim_rect, LayoutRect::zero())
(false, prim_rect, LayoutRect::zero())
}
};
@ -2027,8 +1947,6 @@ impl PrimitiveStore {
clip_chain: ClipChainInstance::empty(),
clip_task_index: ClipTaskIndex::INVALID,
combined_local_clip_rect: LayoutRect::zero(),
snap_offsets: SnapOffsets::empty(),
shadow_snap_offsets: SnapOffsets::empty(),
visibility_mask: PrimitiveVisibilityMask::empty(),
}
);
@ -2171,56 +2089,6 @@ impl PrimitiveStore {
continue;
}
// All pictures must snap to their primitive rect instead of the
// visible rect like most primitives. This is because the picture's
// visible rect includes the effect of the picture's clip rect,
// which was not considered by the picture's children. The primitive
// rect however is simply the union of the visible rect of the
// children, which they snapped to, which is precisely what we also
// need to snap to in order to be consistent.
let visible_rect = if snap_to_visible {
match combined_local_clip_rect.intersection(&prim_local_rect) {
Some(r) => r,
None => {
if prim_instance.is_chased() {
println!("\tculled for zero visible rectangle");
}
prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
continue;
}
}
} else {
prim_local_rect
};
// This is how primitives get snapped. In general, snapping a picture's
// visible rect here will have no effect, but if it is rasterized in its
// own space, or it has a blur or drop shadow effect applied, it may
// provide a snapping offset.
let (snapped_visible_rect, snap_offsets) = get_snapped_rect(
visible_rect,
&map_local_to_raster,
surface.device_pixel_scale,
).unwrap_or((visible_rect, SnapOffsets::empty()));
let (combined_visible_rect, shadow_snap_offsets) = if !prim_shadow_rect.is_empty() {
let (snapped_shadow_rect, shadow_snap_offsets) = get_snapped_rect(
prim_shadow_rect,
&map_local_to_raster,
surface.device_pixel_scale,
).unwrap_or((prim_shadow_rect, SnapOffsets::empty()));
(snapped_visible_rect.union(&snapped_shadow_rect), shadow_snap_offsets)
} else {
(snapped_visible_rect, SnapOffsets::empty())
};
// Include the snapped primitive/picture local rect, including any shadows,
// in the area affected by the surface.
if let Some(rect) = map_local_to_surface.map(&combined_visible_rect) {
surface_rect = surface_rect.union(&rect);
}
// When the debug display is enabled, paint a colored rectangle around each
// primitive.
if frame_context.debug_flags.contains(::api::DebugFlags::PRIMITIVE_DBG) {
@ -2257,8 +2125,6 @@ impl PrimitiveStore {
clip_chain,
clip_task_index: ClipTaskIndex::INVALID,
combined_local_clip_rect,
snap_offsets,
shadow_snap_offsets,
visibility_mask: PrimitiveVisibilityMask::empty(),
}
);
@ -2289,55 +2155,18 @@ impl PrimitiveStore {
// TODO(gw): In future, if we support specifying a flag which gets the
// stretch size from the segment rect in the shaders, we can
// remove this invalidation here completely.
if let Some(ref raster_config) = pic.raster_config {
// Inflate the local bounding rect if required by the filter effect.
// This inflaction factor is to be applied to the surface itself.
if pic.options.inflate_if_required {
surface_rect = raster_config.composite_mode.inflate_picture_rect(surface_rect, surface.inflation_factor);
}
if let Some(RasterConfig { composite_mode: PictureCompositeMode::TileCache { .. }, .. }) = pic.raster_config {
let mut tile_cache = frame_state.tile_cache.take().unwrap();
// Layout space for the picture is picture space from the
// perspective of its child primitives.
let pic_local_rect = surface_rect * Scale::new(1.0);
if pic.snapped_local_rect != pic_local_rect {
match raster_config.composite_mode {
PictureCompositeMode::Filter(Filter::DropShadows(..)) => {
for handle in &pic.extra_gpu_data_handles {
frame_state.gpu_cache.invalidate(handle);
}
}
_ => {}
}
// Invalidate any segments built for this picture, since the local
// rect has changed.
pic.segments_are_valid = false;
pic.snapped_local_rect = pic_local_rect;
}
if let PictureCompositeMode::TileCache { .. } = raster_config.composite_mode {
let mut tile_cache = frame_state.tile_cache.take().unwrap();
// Build the dirty region(s) for this tile cache.
tile_cache.post_update(
frame_state.resource_cache,
frame_state.gpu_cache,
frame_context,
frame_state.scratch,
);
pic.tile_cache = Some(tile_cache);
}
None
} else {
let parent_surface = &frame_context.surfaces[parent_surface_index.0 as usize];
let map_surface_to_parent_surface = SpaceMapper::new_with_target(
parent_surface.surface_spatial_node_index,
surface.surface_spatial_node_index,
PictureRect::max_rect(),
frame_context.clip_scroll_tree,
// Build the dirty region(s) for this tile cache.
tile_cache.post_update(
frame_state.resource_cache,
frame_state.gpu_cache,
frame_context,
frame_state.scratch,
);
map_surface_to_parent_surface.map(&surface_rect)
pic.tile_cache = Some(tile_cache);
}
}
@ -3311,7 +3140,7 @@ impl PrimitiveStore {
splitter,
frame_context.clip_scroll_tree,
prim_instance.spatial_node_index,
pic.snapped_local_rect,
pic.local_rect,
&prim_info.combined_local_clip_rect,
frame_state.current_dirty_region().combined,
plane_split_anchor,
@ -3621,13 +3450,15 @@ impl<'a> GpuDataRequest<'a> {
impl PrimitiveInstance {
fn build_segments_if_needed(
&mut self,
prim_clip_chain: &ClipChainInstance,
prim_info: &PrimitiveVisibility,
frame_state: &mut FrameBuildingState,
prim_store: &mut PrimitiveStore,
data_stores: &DataStores,
segments_store: &mut SegmentStorage,
segment_instances_store: &mut SegmentInstanceStorage,
) {
let prim_clip_chain = &prim_info.clip_chain;
// Usually, the primitive rect can be found from information
// in the instance and primitive template.
let mut prim_local_rect = LayoutRect::new(
@ -3671,7 +3502,7 @@ impl PrimitiveInstance {
// Override the prim local rect with the dynamically calculated
// local rect for the picture.
prim_local_rect = pic.snapped_local_rect;
prim_local_rect = pic.local_rect;
segment_instance_index
} else {
@ -3858,7 +3689,6 @@ impl PrimitiveInstance {
frame_state,
&mut data_stores.clip,
unclipped,
prim_info.snap_offsets,
device_pixel_scale,
);
clip_mask_instances.push(clip_mask_kind);
@ -3879,10 +3709,7 @@ impl PrimitiveInstance {
let segment_clip_chain = frame_state
.clip_store
.build_clip_chain_instance(
segment.local_rect.translate(LayoutVector2D::new(
self.prim_origin.x,
self.prim_origin.y,
)),
segment.local_rect.translate(self.prim_origin.to_vector()),
&pic_state.map_local_to_pic,
&pic_state.map_pic_to_world,
&frame_context.clip_scroll_tree,
@ -3905,7 +3732,6 @@ impl PrimitiveInstance {
frame_state,
&mut data_stores.clip,
unclipped,
prim_info.snap_offsets,
device_pixel_scale,
);
clip_mask_instances.push(clip_mask_kind);
@ -3944,7 +3770,7 @@ impl PrimitiveInstance {
};
self.build_segments_if_needed(
&prim_info.clip_chain,
&prim_info,
frame_state,
prim_store,
data_stores,
@ -3978,9 +3804,8 @@ impl PrimitiveInstance {
// Get a minimal device space rect, clipped to the screen that we
// need to allocate for the clip mask, as well as interpolated
// snap offsets.
if let Some((device_rect, snap_offsets)) = get_clipped_device_rect(
if let Some(device_rect) = get_clipped_device_rect(
&unclipped,
prim_info.snap_offsets,
&pic_state.map_raster_to_world,
prim_info.clipped_world_rect,
device_pixel_scale,
@ -3994,7 +3819,6 @@ impl PrimitiveInstance {
frame_state.resource_cache,
frame_state.render_tasks,
&mut data_stores.clip,
snap_offsets,
device_pixel_scale,
frame_context.fb_config,
);
@ -4017,80 +3841,6 @@ impl PrimitiveInstance {
}
}
/// Mimics the GLSL mix() function.
fn mix(x: f32, y: f32, a: f32) -> f32 {
x * (1.0 - a) + y * a
}
/// Given a point within a local rectangle, and the device space corners
/// of a snapped primitive, return the snap offsets.
fn compute_snap_offset_impl<PixelSpace>(
reference_pos: Point2D<f32, PixelSpace>,
reference_rect: Rect<f32, PixelSpace>,
prim_top_left: DevicePoint,
prim_bottom_right: DevicePoint,
) -> DeviceVector2D {
let normalized_snap_pos = Point2D::<f32, PixelSpace>::new(
(reference_pos.x - reference_rect.origin.x) / reference_rect.size.width,
(reference_pos.y - reference_rect.origin.y) / reference_rect.size.height,
);
let top_left = DeviceVector2D::new(
(prim_top_left.x + 0.5).floor() - prim_top_left.x,
(prim_top_left.y + 0.5).floor() - prim_top_left.y,
);
let bottom_right = DeviceVector2D::new(
(prim_bottom_right.x + 0.5).floor() - prim_bottom_right.x,
(prim_bottom_right.y + 0.5).floor() - prim_bottom_right.y,
);
DeviceVector2D::new(
mix(top_left.x, bottom_right.x, normalized_snap_pos.x),
mix(top_left.y, bottom_right.y, normalized_snap_pos.y),
)
}
/// Given the snapping offsets for a primitive rectangle, recompute
/// the snapping offsets to be relative to given local rectangle.
/// This *must* exactly match the logic in the GLSL
/// compute_snap_offset function.
pub fn recompute_snap_offsets<PixelSpace>(
local_rect: Rect<f32, PixelSpace>,
prim_rect: Rect<f32, PixelSpace>,
snap_offsets: SnapOffsets,
) -> SnapOffsets
{
if prim_rect.is_empty() || snap_offsets.is_empty() {
return SnapOffsets::empty();
}
let normalized_top_left = Point2D::<f32, PixelSpace>::new(
(local_rect.origin.x - prim_rect.origin.x) / prim_rect.size.width,
(local_rect.origin.y - prim_rect.origin.y) / prim_rect.size.height,
);
let normalized_bottom_right = Point2D::<f32, PixelSpace>::new(
(local_rect.origin.x + local_rect.size.width - prim_rect.origin.x) / prim_rect.size.width,
(local_rect.origin.y + local_rect.size.height - prim_rect.origin.y) / prim_rect.size.height,
);
let top_left = DeviceVector2D::new(
mix(snap_offsets.top_left.x, snap_offsets.bottom_right.x, normalized_top_left.x),
mix(snap_offsets.top_left.y, snap_offsets.bottom_right.y, normalized_top_left.y),
);
let bottom_right = DeviceVector2D::new(
mix(snap_offsets.top_left.x, snap_offsets.bottom_right.x, normalized_bottom_right.x),
mix(snap_offsets.top_left.y, snap_offsets.bottom_right.y, normalized_bottom_right.y),
);
SnapOffsets {
top_left,
bottom_right,
}
}
/// Retrieve the exact unsnapped device space rectangle for a primitive.
fn get_unclipped_device_rect(
prim_rect: PictureRect,
@ -4109,11 +3859,10 @@ fn get_unclipped_device_rect(
/// scale per-raster-root.
fn get_clipped_device_rect(
unclipped: &DeviceRect,
prim_snap_offsets: SnapOffsets,
map_to_world: &SpaceMapper<RasterPixel, WorldPixel>,
prim_bounding_rect: WorldRect,
device_pixel_scale: DevicePixelScale,
) -> Option<(DeviceIntRect, SnapOffsets)> {
) -> Option<DeviceIntRect> {
let unclipped_raster_rect = {
let world_rect = *unclipped * Scale::new(1.0);
let raster_rect = world_rect * device_pixel_scale.inv();
@ -4138,28 +3887,7 @@ fn get_clipped_device_rect(
device_pixel_scale,
);
let fx0 = (clipped.origin.x - unclipped.origin.x) / unclipped.size.width;
let fy0 = (clipped.origin.y - unclipped.origin.y) / unclipped.size.height;
let fx1 = (clipped.origin.x + clipped.size.width - unclipped.origin.x) / unclipped.size.width;
let fy1 = (clipped.origin.y + clipped.size.height - unclipped.origin.y) / unclipped.size.height;
let top_left = DeviceVector2D::new(
mix(prim_snap_offsets.top_left.x, prim_snap_offsets.bottom_right.x, fx0),
mix(prim_snap_offsets.top_left.y, prim_snap_offsets.bottom_right.y, fy0),
);
let bottom_right = DeviceVector2D::new(
mix(prim_snap_offsets.top_left.x, prim_snap_offsets.bottom_right.x, fx1),
mix(prim_snap_offsets.top_left.y, prim_snap_offsets.bottom_right.y, fy1),
);
let snap_offsets = SnapOffsets {
top_left,
bottom_right,
};
Some((clipped.to_i32(), snap_offsets))
Some(clipped.to_i32())
}
pub fn get_raster_rects(
@ -4197,61 +3925,6 @@ pub fn get_raster_rects(
Some((clipped.to_i32(), unclipped))
}
/// Snap the given rect in raster space if the transform is
/// axis-aligned. It return the snapped rect transformed back into the
/// given pixel space, and the snap offsets in device space.
pub fn get_snapped_rect<PixelSpace>(
prim_rect: Rect<f32, PixelSpace>,
map_to_raster: &SpaceMapper<PixelSpace, RasterPixel>,
device_pixel_scale: DevicePixelScale,
) -> Option<(Rect<f32, PixelSpace>, SnapOffsets)> where PixelSpace: fmt::Debug {
let is_axis_aligned = match map_to_raster.kind {
CoordinateSpaceMapping::Local |
CoordinateSpaceMapping::ScaleOffset(..) => true,
CoordinateSpaceMapping::Transform(ref transform) => transform.preserves_2d_axis_alignment(),
};
if is_axis_aligned {
let raster_rect = map_to_raster.map(&prim_rect)?;
let device_rect = {
let world_rect = raster_rect * Scale::new(1.0);
world_rect * device_pixel_scale
};
let top_left = compute_snap_offset_impl(
prim_rect.origin,
prim_rect,
device_rect.origin,
device_rect.bottom_right(),
);
let bottom_right = compute_snap_offset_impl(
prim_rect.bottom_right(),
prim_rect,
device_rect.origin,
device_rect.bottom_right(),
);
let snap_offsets = SnapOffsets {
top_left,
bottom_right,
};
let snapped_device_rect = DeviceRect::new(
device_rect.origin + top_left,
device_rect.size + (bottom_right - top_left).to_size()
);
let snapped_world_rect = snapped_device_rect / device_pixel_scale;
let snapped_raster_rect = snapped_world_rect * Scale::new(1.0);
let snapped_prim_rect = map_to_raster.unmap(&snapped_raster_rect)?;
Some((snapped_prim_rect, snap_offsets))
} else {
None
}
}
/// Get the inline (horizontal) and block (vertical) sizes
/// for a given line decoration.
pub fn get_line_decoration_sizes(

Просмотреть файл

@ -663,7 +663,6 @@ impl RenderTarget for AlphaRenderTarget {
task_info.actual_rect,
&ctx.screen_world_rect,
task_info.device_pixel_scale,
task_info.snap_offsets,
target_rect.origin.to_f32(),
task_info.actual_rect.origin.to_f32(),
);

Просмотреть файл

@ -14,7 +14,7 @@ use crate::filterdata::SFilterData;
use crate::frame_builder::FrameBuilderConfig;
use crate::freelist::{FreeList, FreeListHandle, WeakFreeListHandle};
use crate::gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle};
use crate::gpu_types::{BorderInstance, ImageSource, UvRectKind, SnapOffsets};
use crate::gpu_types::{BorderInstance, ImageSource, UvRectKind};
use crate::internal_types::{CacheTextureId, FastHashMap, LayerIndex, SavedTargetIndex, TextureSource};
use crate::prim_store::{PictureIndex, PrimitiveVisibilityMask};
use crate::prim_store::image::ImageCacheKey;
@ -125,7 +125,6 @@ pub struct CacheMaskTask {
pub actual_rect: DeviceIntRect,
pub root_spatial_node_index: SpatialNodeIndex,
pub clip_node_range: ClipNodeRange,
pub snap_offsets: SnapOffsets,
pub device_pixel_scale: DevicePixelScale,
}
@ -523,7 +522,6 @@ impl RenderTask {
resource_cache: &mut ResourceCache,
render_tasks: &mut RenderTaskGraph,
clip_data_store: &mut ClipDataStore,
snap_offsets: SnapOffsets,
device_pixel_scale: DevicePixelScale,
fb_config: &FrameBuilderConfig,
) -> Self {
@ -617,7 +615,6 @@ impl RenderTask {
actual_rect: outer_rect,
clip_node_range,
root_spatial_node_index,
snap_offsets,
device_pixel_scale,
}),
clear_mode,

Просмотреть файл

@ -620,11 +620,6 @@ pub(crate) mod desc {
count: 4,
kind: VertexAttributeKind::F32,
},
VertexAttribute {
name: "aClipSnapOffsets",
count: 4,
kind: VertexAttributeKind::F32,
},
VertexAttribute {
name: "aClipOrigins",
count: 4,