diff --git a/gfx/wr/webrender/res/brush.glsl b/gfx/wr/webrender/res/brush.glsl index eacbac000e94..83c777b8dbaf 100644 --- a/gfx/wr/webrender/res/brush.glsl +++ b/gfx/wr/webrender/res/brush.glsl @@ -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 diff --git a/gfx/wr/webrender/res/clip_shared.glsl b/gfx/wr/webrender/res/clip_shared.glsl index 030532776505..a6a7d2dd50a1 100644 --- a/gfx/wr/webrender/res/clip_shared.glsl +++ b/gfx/wr/webrender/res/clip_shared.glsl @@ -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); diff --git a/gfx/wr/webrender/res/cs_clip_box_shadow.glsl b/gfx/wr/webrender/res/cs_clip_box_shadow.glsl index 1dac991f21aa..5b4937139ef7 100644 --- a/gfx/wr/webrender/res/cs_clip_box_shadow.glsl +++ b/gfx/wr/webrender/res/cs_clip_box_shadow.glsl @@ -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 diff --git a/gfx/wr/webrender/res/cs_clip_image.glsl b/gfx/wr/webrender/res/cs_clip_image.glsl index 9005fd7d507a..918223343d2d 100644 --- a/gfx/wr/webrender/res/cs_clip_image.glsl +++ b/gfx/wr/webrender/res/cs_clip_image.glsl @@ -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 diff --git a/gfx/wr/webrender/res/cs_clip_rectangle.glsl b/gfx/wr/webrender/res/cs_clip_rectangle.glsl index 85522e542a4c..3fcdd7ef04a3 100644 --- a/gfx/wr/webrender/res/cs_clip_rectangle.glsl +++ b/gfx/wr/webrender/res/cs_clip_rectangle.glsl @@ -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 diff --git a/gfx/wr/webrender/res/prim_shared.glsl b/gfx/wr/webrender/res/prim_shared.glsl index 12f6c12485a5..cb52464b135b 100644 --- a/gfx/wr/webrender/res/prim_shared.glsl +++ b/gfx/wr/webrender/res/prim_shared.glsl @@ -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 ); diff --git a/gfx/wr/webrender/res/snap.glsl b/gfx/wr/webrender/res/snap.glsl deleted file mode 100644 index 1f86e199fbf6..000000000000 --- a/gfx/wr/webrender/res/snap.glsl +++ /dev/null @@ -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 diff --git a/gfx/wr/webrender/src/batch.rs b/gfx/wr/webrender/src/batch.rs index 109e0bb2e2cb..90141c11506f 100644 --- a/gfx/wr/webrender/src/batch.rs +++ b/gfx/wr/webrender/src/batch.rs @@ -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, diff --git a/gfx/wr/webrender/src/frame_builder.rs b/gfx/wr/webrender/src/frame_builder.rs index e7b65fb2c7af..8c7b7bf3dc76 100644 --- a/gfx/wr/webrender/src/frame_builder.rs +++ b/gfx/wr/webrender/src/frame_builder.rs @@ -392,7 +392,7 @@ impl FrameBuilder { &frame_context, gpu_cache, &self.clip_store, - &data_stores.clip, + data_stores, ); { diff --git a/gfx/wr/webrender/src/gpu_types.rs b/gfx/wr/webrender/src/gpu_types.rs index 0f1b9b0f9f5c..ccad6b2f6689 100644 --- a/gfx/wr/webrender/src/gpu_types.rs +++ b/gfx/wr/webrender/src/gpu_types.rs @@ -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))] diff --git a/gfx/wr/webrender/src/picture.rs b/gfx/wr/webrender/src/picture.rs index 40354e79a565..69cdea15e98f 100644 --- a/gfx/wr/webrender/src/picture.rs +++ b/gfx/wr/webrender/src/picture.rs @@ -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, } 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] @@ -3444,6 +3451,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; @@ -3451,6 +3459,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 { @@ -3510,11 +3571,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 || @@ -3525,6 +3581,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 { @@ -3593,14 +3651,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, ]); diff --git a/gfx/wr/webrender/src/prim_store/mod.rs b/gfx/wr/webrender/src/prim_store/mod.rs index db5ddf1611d8..6155783782f1 100644 --- a/gfx/wr/webrender/src/prim_store/mod.rs +++ b/gfx/wr/webrender/src/prim_store/mod.rs @@ -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 crate::internal_types::PlaneSplitAnchor; @@ -933,7 +933,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 { @@ -956,9 +955,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, @@ -978,7 +976,6 @@ impl BrushSegment { frame_state.resource_cache, frame_state.render_tasks, clip_data_store, - snap_offsets, device_pixel_scale, frame_context.fb_config, ); @@ -1436,18 +1433,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)] @@ -1808,7 +1793,7 @@ impl PrimitiveStore { world_culling_rect: &WorldRect, frame_context: &FrameVisibilityContext, frame_state: &mut FrameVisibilityState, - ) -> Option { + ) { 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; @@ -1828,7 +1813,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, @@ -1862,19 +1847,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 @@ -1890,12 +1869,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, @@ -1917,7 +1891,7 @@ impl PrimitiveStore { frame_state.clip_store, ); - let pic_surface_rect = self.update_visibility( + self.update_visibility( pic_index, surface_index, &world_culling_rect, @@ -1927,8 +1901,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 @@ -1938,74 +1910,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); @@ -2015,7 +1935,7 @@ impl PrimitiveStore { prim_data.prim_size, ); - (false, true, prim_rect, LayoutRect::zero()) + (false, prim_rect, LayoutRect::zero()) } }; @@ -2028,8 +1948,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(), } ); @@ -2172,56 +2090,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) { @@ -2258,8 +2126,6 @@ impl PrimitiveStore { clip_chain, clip_task_index: ClipTaskIndex::INVALID, combined_local_clip_rect, - snap_offsets, - shadow_snap_offsets, visibility_mask: PrimitiveVisibilityMask::empty(), } ); @@ -2290,55 +2156,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); } } @@ -3316,7 +3145,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, @@ -3626,13 +3455,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( @@ -3676,7 +3507,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 { @@ -3863,7 +3694,6 @@ impl PrimitiveInstance { frame_state, &mut data_stores.clip, unclipped, - prim_info.snap_offsets, device_pixel_scale, ); clip_mask_instances.push(clip_mask_kind); @@ -3884,10 +3714,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, @@ -3910,7 +3737,6 @@ impl PrimitiveInstance { frame_state, &mut data_stores.clip, unclipped, - prim_info.snap_offsets, device_pixel_scale, ); clip_mask_instances.push(clip_mask_kind); @@ -3949,7 +3775,7 @@ impl PrimitiveInstance { }; self.build_segments_if_needed( - &prim_info.clip_chain, + &prim_info, frame_state, prim_store, data_stores, @@ -3983,9 +3809,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, @@ -3999,7 +3824,6 @@ impl PrimitiveInstance { frame_state.resource_cache, frame_state.render_tasks, &mut data_stores.clip, - snap_offsets, device_pixel_scale, frame_context.fb_config, ); @@ -4022,80 +3846,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( - reference_pos: Point2D, - reference_rect: Rect, - prim_top_left: DevicePoint, - prim_bottom_right: DevicePoint, -) -> DeviceVector2D { - let normalized_snap_pos = Point2D::::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( - local_rect: Rect, - prim_rect: Rect, - snap_offsets: SnapOffsets, -) -> SnapOffsets -{ - if prim_rect.is_empty() || snap_offsets.is_empty() { - return SnapOffsets::empty(); - } - - let normalized_top_left = Point2D::::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::::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, @@ -4114,11 +3864,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, prim_bounding_rect: WorldRect, device_pixel_scale: DevicePixelScale, -) -> Option<(DeviceIntRect, SnapOffsets)> { +) -> Option { let unclipped_raster_rect = { let world_rect = *unclipped * Scale::new(1.0); let raster_rect = world_rect * device_pixel_scale.inv(); @@ -4143,28 +3892,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( @@ -4202,61 +3930,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( - prim_rect: Rect, - map_to_raster: &SpaceMapper, - device_pixel_scale: DevicePixelScale, -) -> Option<(Rect, 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( diff --git a/gfx/wr/webrender/src/render_target.rs b/gfx/wr/webrender/src/render_target.rs index cc83f3a9625c..73d6c9d7dbe8 100644 --- a/gfx/wr/webrender/src/render_target.rs +++ b/gfx/wr/webrender/src/render_target.rs @@ -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(), ); diff --git a/gfx/wr/webrender/src/render_task.rs b/gfx/wr/webrender/src/render_task.rs index 3df2779a26df..a4739a40a999 100644 --- a/gfx/wr/webrender/src/render_task.rs +++ b/gfx/wr/webrender/src/render_task.rs @@ -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, diff --git a/gfx/wr/webrender/src/renderer.rs b/gfx/wr/webrender/src/renderer.rs index d49473376d86..99381c143c9f 100644 --- a/gfx/wr/webrender/src/renderer.rs +++ b/gfx/wr/webrender/src/renderer.rs @@ -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,