diff --git a/webrender/res/ps_split_composite.glsl b/webrender/res/ps_split_composite.glsl index cd77836e2f..9071ff1793 100644 --- a/webrender/res/ps_split_composite.glsl +++ b/webrender/res/ps_split_composite.glsl @@ -38,11 +38,15 @@ void main(void) { CompositeInstance ci = fetch_composite_instance(); SplitGeometry geometry = fetch_split_geometry(ci.user_data0); AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index); + AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index); + + vec2 dest_origin = dest_task.render_target_origin - + dest_task.screen_space_origin; vec3 world_pos = bilerp(geometry.points[0], geometry.points[1], geometry.points[3], geometry.points[2], aPosition.y, aPosition.x); - vec4 final_pos = vec4(world_pos.xy * uDevicePixelRatio, ci.z, 1.0); + vec4 final_pos = vec4((world_pos.xy + dest_origin) * uDevicePixelRatio, ci.z, 1.0); gl_Position = uTransform * final_pos; diff --git a/webrender/src/frame_builder.rs b/webrender/src/frame_builder.rs index 48e9a85161..ffae0f75fb 100644 --- a/webrender/src/frame_builder.rs +++ b/webrender/src/frame_builder.rs @@ -8,7 +8,7 @@ use api::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceUintRect, DeviceUi use api::{ExtendMode, FIND_ALL, FilterOp, FontInstance, FontRenderMode}; use api::{GlyphInstance, GlyphOptions, GradientStop, HitTestFlags, HitTestItem, HitTestResult}; use api::{ImageKey, ImageRendering, ItemRange, ItemTag, LayerPoint, LayerPrimitiveInfo, LayerRect}; -use api::{LayerSize, LayerToScrollTransform, LayerVector2D, LayoutVector2D, LineOrientation}; +use api::{LayerPixel, LayerSize, LayerToScrollTransform, LayerVector2D, LayoutVector2D, LineOrientation}; use api::{LineStyle, LocalClip, POINT_RELATIVE_TO_PIPELINE_VIEWPORT, PipelineId, RepeatMode}; use api::{ScrollSensitivity, Shadow, TileOffset, TransformStyle}; use api::{WorldPixel, WorldPoint, YuvColorSpace, YuvData, device_length}; @@ -1731,6 +1731,7 @@ impl FrameBuilder { stacking_context.isolated_items_bounds = stacking_context .isolated_items_bounds .union(&prim_geom.local_rect); + stacking_context.has_any_primitive = true; profile_counters.visible_primitives.inc(); } @@ -1739,12 +1740,22 @@ impl FrameBuilder { true //visible } - fn handle_pop_stacking_context(&mut self, screen_rect: &DeviceIntRect) { + fn handle_pop_stacking_context( + &mut self, + screen_rect: &DeviceIntRect, + clip_scroll_tree: &ClipScrollTree) { let stacking_context_index = self.stacking_context_stack.pop().unwrap(); let (bounding_rect, is_visible, is_preserve_3d, reference_id, reference_bounds) = { let stacking_context = &mut self.stacking_context_store[stacking_context_index.0]; + if !stacking_context.has_any_primitive { + stacking_context.isolated_items_bounds = stacking_context.children_sc_bounds; + } else if stacking_context.isolation != ContextIsolation::Items { + stacking_context.isolated_items_bounds = stacking_context + .isolated_items_bounds + .union(&stacking_context.children_sc_bounds); + } stacking_context.screen_bounds = stacking_context .screen_bounds .intersection(screen_rect) @@ -1763,9 +1774,21 @@ impl FrameBuilder { if let Some(ref mut parent_index) = self.stacking_context_stack.last_mut() { let parent = &mut self.stacking_context_store[parent_index.0]; parent.screen_bounds = parent.screen_bounds.union(&bounding_rect); + let child_bounds = reference_bounds.translate(&-parent.reference_frame_offset); + let frame_node = clip_scroll_tree + .nodes + .get(&reference_id) + .unwrap(); + let local_transform = match frame_node.node_type { + NodeType::ReferenceFrame(ref info) => info.transform, + _ => LayerToScrollTransform::identity(), + }; + let transformed_bounds = local_transform + .with_destination::() + .transform_rect(&child_bounds); + parent.children_sc_bounds = parent.children_sc_bounds.union(&transformed_bounds); // add children local bounds only for non-item-isolated contexts if !is_preserve_3d && parent.reference_frame_id == reference_id { - let child_bounds = reference_bounds.translate(&-parent.reference_frame_offset); parent.isolated_items_bounds = parent.isolated_items_bounds.union(&child_bounds); } // Per-primitive stacking context visibility checks do not take into account @@ -1917,7 +1940,7 @@ impl FrameBuilder { ); } PrimitiveRunCmd::PopStackingContext => { - self.handle_pop_stacking_context(screen_rect); + self.handle_pop_stacking_context(screen_rect, clip_scroll_tree); } } } diff --git a/webrender/src/tiling.rs b/webrender/src/tiling.rs index 2a1813493c..e2a6364f93 100644 --- a/webrender/src/tiling.rs +++ b/webrender/src/tiling.rs @@ -1606,6 +1606,12 @@ pub struct StackingContext { /// This is a temporary hack while we don't support subpixel AA /// on transparent stacking contexts. pub allow_subpixel_aa: bool, + + /// Indicate that if any pritimive contained in this stacking context. + pub has_any_primitive: bool, + + /// Union of all stacking context bounds of all children. + pub children_sc_bounds: LayerRect, } impl StackingContext { @@ -1638,6 +1644,8 @@ impl StackingContext { is_visible: false, is_backface_visible, allow_subpixel_aa, + has_any_primitive: false, + children_sc_bounds: LayerRect::zero(), } } diff --git a/wrench/reftests/split/intermediate-1-ref.yaml b/wrench/reftests/split/intermediate-1-ref.yaml new file mode 100644 index 0000000000..2d67df4ead --- /dev/null +++ b/wrench/reftests/split/intermediate-1-ref.yaml @@ -0,0 +1,12 @@ +--- +root: + items: + - type: rect + bounds: 8 36 100 100 + color: green + - type: rect + bounds: 108 36 100 100 + color: blue + - type: rect + bounds: 208 36 100 100 + color: yellow diff --git a/wrench/reftests/split/intermediate-1.yaml b/wrench/reftests/split/intermediate-1.yaml new file mode 100644 index 0000000000..0c02fe8e3c --- /dev/null +++ b/wrench/reftests/split/intermediate-1.yaml @@ -0,0 +1,38 @@ +--- +root: + items: + - type: rect + bounds: 8 36 300 100 + color: red + - type: stacking-context + transform-style: preserve-3d + transform: translate(8, 36, 0) + items: + - type: stacking-context + transform-style: preserve-3d + items: + - type: rect + bounds: 0 0 100 100 + color: green + - type: stacking-context # flat, intermediate surface + items: + - type: stacking-context + transform: translate(100, 0, 0) + transform-style: preserve-3d + items: + - type: stacking-context + transform-style: preserve-3d + items: + - type: rect + bounds: 0 0 100 100 + color: blue + - type: stacking-context + transform: translate(100, 0, 0) + transform-style: preserve-3d + items: + - type: stacking-context + transform-style: preserve-3d + items: + - type: rect + bounds: 0 0 100 100 + color: yellow diff --git a/wrench/reftests/split/intermediate-2.yaml b/wrench/reftests/split/intermediate-2.yaml new file mode 100644 index 0000000000..7d926ade4a --- /dev/null +++ b/wrench/reftests/split/intermediate-2.yaml @@ -0,0 +1,34 @@ +--- +root: + items: + - type: rect + bounds: 8 36 300 100 + color: red + - type: stacking-context + transform-style: preserve-3d + transform: translate(8, 36, 0) + items: + - type: stacking-context + transform-style: preserve-3d + items: + - type: rect + bounds: 0 0 100 100 + color: green + - type: stacking-context + items: + - type: stacking-context + transform: translate(100, 0, 0) + items: + - type: rect + bounds: 0 0 100 100 + color: blue + - type: stacking-context + transform: translate(100, 0, 0) + transform-style: preserve-3d + items: + - type: stacking-context + transform-style: preserve-3d + items: + - type: rect + bounds: 0 0 100 100 + color: yellow diff --git a/wrench/reftests/split/reftest.list b/wrench/reftests/split/reftest.list index 94a7cd5980..22e3889733 100644 --- a/wrench/reftests/split/reftest.list +++ b/wrench/reftests/split/reftest.list @@ -3,4 +3,6 @@ == nested.yaml nested-ref.yaml == nested-preserve3d-crash.yaml nested-preserve3d-crash.yaml == perspective-clipping.yaml perspective-clipping-ref.yaml +== intermediate-1.yaml intermediate-1-ref.yaml +== intermediate-2.yaml intermediate-1-ref.yaml #== cross.yaml cross-ref.yaml #TODO: investigate sub-pixel differences