script: Keep the DOM-side viewport up to date when scrolling happens in

WebRender.

This happens asynchronously, just as it does in non-WebRender mode.

This functionality is a prerequisite for doing proper display-list-based
hit testing in WebRender, since it moves the scroll offsets into Servo
(and, specifically, into the script thread, enabling iframe event
forwarding) instead of keeping them private to WebRender.

Requires servo/webrender_traits#55 and servo/webrender#277.

Partially addresses #11108.
This commit is contained in:
Patrick Walton 2016-05-24 18:40:39 -07:00
parent 55b0bb027c
commit a86f77e36d
32 changed files with 318 additions and 99 deletions

View file

@ -43,8 +43,8 @@ use flow_list::FlowList;
use flow_ref::FlowRef;
use fragment::SpecificFragmentInfo;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, HAS_LAYER, Overflow};
use gfx::display_list::{ClippingRegion, StackingContext, StackingContextId};
use gfx_traits::LayerId;
use gfx::display_list::{ClippingRegion, StackingContext};
use gfx_traits::{LayerId, StackingContextId};
use incremental::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT};
use layout_debug;
use layout_thread::DISPLAY_PORT_SIZE_FACTOR;

View file

@ -21,17 +21,16 @@ use flow::{BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
use flow_ref;
use fragment::SpecificFragmentInfo;
use fragment::{CoordinateSystem, Fragment, HAS_LAYER, ImageFragmentInfo, ScannedTextFragmentInfo};
use gfx::display_list::GradientDisplayItem;
use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDisplayItem};
use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClippingRegion};
use gfx::display_list::{DisplayItem, DisplayItemMetadata, DisplayListSection};
use gfx::display_list::{GradientStop, IframeDisplayItem, ImageDisplayItem, WebGLDisplayItem, LayeredItem, LayerInfo};
use gfx::display_list::{LineDisplayItem, OpaqueNode, SolidColorDisplayItem};
use gfx::display_list::{StackingContext, StackingContextId, StackingContextType};
use gfx::display_list::{DisplayItem, DisplayItemMetadata, DisplayListSection, GradientDisplayItem};
use gfx::display_list::{GradientStop, IframeDisplayItem, ImageDisplayItem, WebGLDisplayItem};
use gfx::display_list::{LayeredItem, LayerInfo, LineDisplayItem, OpaqueNode};
use gfx::display_list::{SolidColorDisplayItem, StackingContext, StackingContextType};
use gfx::display_list::{TextDisplayItem, TextOrientation, WebRenderImageInfo};
use gfx::paint_thread::THREAD_TINT_COLORS;
use gfx::text::glyph::ByteIndex;
use gfx_traits::{color, ScrollPolicy};
use gfx_traits::{color, ScrollPolicy, StackingContextId};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
use ipc_channel::ipc;
use list_item::ListItemFlow;

View file

@ -17,7 +17,8 @@ use flow::{Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
use flow::{INLINE_POSITION_IS_STATIC, IS_ABSOLUTELY_POSITIONED};
use flow_ref::{self, FlowRef};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{StackingContext, StackingContextId};
use gfx::display_list::StackingContext;
use gfx_traits::StackingContextId;
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
use layout_debug;
use model::{IntrinsicISizes, MaybeAuto, MinMaxConstraint};

View file

@ -34,8 +34,8 @@ use floats::{Floats, SpeculatedFloatPlacement};
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
use flow_ref::{self, FlowRef, WeakFlowRef};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow, SpecificFragmentInfo};
use gfx::display_list::{ClippingRegion, StackingContext, StackingContextId};
use gfx_traits::{LayerId, LayerType};
use gfx::display_list::{ClippingRegion, StackingContext};
use gfx_traits::{LayerId, LayerType, StackingContextId};
use incremental::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RestyleDamage};
use inline::InlineFlow;
use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};

View file

@ -14,10 +14,10 @@ use floats::ClearType;
use flow::{self, ImmutableFlowUtils};
use flow_ref::{self, FlowRef};
use gfx;
use gfx::display_list::{BLUR_INFLATION_FACTOR, FragmentType, OpaqueNode, StackingContextId};
use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
use gfx::text::glyph::ByteIndex;
use gfx::text::text_run::{TextRun, TextRunSlice};
use gfx_traits::{LayerId, LayerType};
use gfx_traits::{FragmentType, LayerId, LayerType, StackingContextId};
use incremental::{RECONSTRUCT_FLOW, RestyleDamage};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFragmentContext, InlineFragmentNodeInfo};
use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT};

View file

@ -17,9 +17,10 @@ use flow::{self, BaseFlow, Flow, FlowClass, ForceNonfloatedFlag, IS_ABSOLUTELY_P
use flow_ref;
use fragment::SpecificFragmentInfo;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{OpaqueNode, StackingContext, StackingContextId};
use gfx::display_list::{OpaqueNode, StackingContext};
use gfx::font::FontMetrics;
use gfx::font_context::FontContext;
use gfx_traits::StackingContextId;
use incremental::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, RESOLVE_GENERATED_CONTENT};
use layout_debug;
use model::IntrinsicISizesContribution;

View file

@ -21,14 +21,13 @@ use euclid::size::Size2D;
use flow::{self, Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
use flow_ref::{self, FlowRef};
use fnv::FnvHasher;
use gfx::display_list::WebRenderImageInfo;
use gfx::display_list::{ClippingRegion, DisplayItemMetadata, DisplayList, LayerInfo};
use gfx::display_list::{OpaqueNode, StackingContext, StackingContextId, StackingContextType};
use gfx::display_list::{OpaqueNode, StackingContext, StackingContextType, WebRenderImageInfo};
use gfx::font;
use gfx::font_cache_thread::FontCacheThread;
use gfx::font_context;
use gfx::paint_thread::LayoutToPaintMsg;
use gfx_traits::{color, Epoch, LayerId, ScrollPolicy};
use gfx_traits::{color, Epoch, LayerId, ScrollPolicy, StackingContextId};
use heapsize::HeapSizeOf;
use incremental::LayoutDamageComputation;
use incremental::{REPAINT, STORE_OVERFLOW, REFLOW_OUT_OF_FLOW, REFLOW, REFLOW_ENTIRE_DOCUMENT};
@ -52,8 +51,8 @@ use script::dom::node::OpaqueStyleAndLayoutData;
use script::layout_interface::{LayoutRPC, OffsetParentResponse, NodeOverflowResponse, MarginStyleResponse};
use script::layout_interface::{Msg, NewLayoutThreadInfo, Reflow, ReflowQueryType, ScriptReflow};
use script::reporter::CSSErrorReporter;
use script_traits::ConstellationControlMsg;
use script_traits::{LayoutControlMsg, LayoutMsg as ConstellationMsg};
use script_traits::StackingContextScrollState;
use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
use sequential;
use serde_json;
use std::borrow::ToOwned;
@ -559,6 +558,11 @@ impl LayoutThread {
self.handle_request_helper(Msg::SetVisibleRects(new_visible_rects),
possibly_locked_rw_data)
},
Request::FromPipeline(LayoutControlMsg::SetStackingContextScrollStates(
new_scroll_states)) => {
self.handle_request_helper(Msg::SetStackingContextScrollStates(new_scroll_states),
possibly_locked_rw_data)
},
Request::FromPipeline(LayoutControlMsg::TickAnimations) => {
self.handle_request_helper(Msg::TickAnimations, possibly_locked_rw_data)
},
@ -644,6 +648,10 @@ impl LayoutThread {
Msg::SetVisibleRects(new_visible_rects) => {
self.set_visible_rects(new_visible_rects, possibly_locked_rw_data);
}
Msg::SetStackingContextScrollStates(new_scroll_states) => {
self.set_stacking_context_scroll_states(new_scroll_states,
possibly_locked_rw_data);
}
Msg::ReapStyleAndLayoutData(dead_data) => {
unsafe {
self.handle_reap_style_and_layout_data(dead_data)
@ -883,19 +891,18 @@ impl LayoutThread {
if flow::base(&**layout_root).restyle_damage.contains(REPAINT) ||
rw_data.display_list.is_none() {
let mut root_stacking_context =
StackingContext::new(StackingContextId::new(0),
StackingContextType::Real,
&Rect::zero(),
&Rect::zero(),
0,
filter::T::new(Vec::new()),
mix_blend_mode::T::normal,
Matrix4D::identity(),
Matrix4D::identity(),
true,
false,
None);
let mut root_stacking_context = StackingContext::new(StackingContextId::new(0),
StackingContextType::Real,
&Rect::zero(),
&Rect::zero(),
0,
filter::T::new(Vec::new()),
mix_blend_mode::T::normal,
Matrix4D::identity(),
Matrix4D::identity(),
true,
false,
None);
let display_list_entries =
sequential::build_display_list_for_subtree(layout_root,
@ -1264,6 +1271,19 @@ impl LayoutThread {
true
}
fn set_stacking_context_scroll_states<'a, 'b>(
&mut self,
new_scroll_states: Vec<StackingContextScrollState>,
_: &mut RwData<'a, 'b>) {
for new_scroll_state in &new_scroll_states {
if self.root_flow.is_some() && new_scroll_state.stacking_context_id.id() == 0 {
let _ = self.script_chan.send(ConstellationControlMsg::SetScrollState(
self.id,
new_scroll_state.scroll_offset));
}
}
}
fn tick_all_animations<'a, 'b>(&mut self, possibly_locked_rw_data: &mut RwData<'a, 'b>) {
let mut rw_data = possibly_locked_rw_data.lock();
self.tick_animations(&mut rw_data);

View file

@ -17,7 +17,8 @@ use flow::{Flow, FlowClass, OpaqueFlow};
use fragment::Overflow;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, GeneratedContentInfo};
use generated_content;
use gfx::display_list::{StackingContext, StackingContextId};
use gfx::display_list::StackingContext;
use gfx_traits::StackingContextId;
use incremental::RESOLVE_GENERATED_CONTENT;
use inline::InlineMetrics;
use std::sync::Arc;

View file

@ -15,7 +15,8 @@ use floats::FloatKind;
use flow::{Flow, FlowClass, OpaqueFlow, mut_base, FragmentationContext};
use flow_ref::{self, FlowRef};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{StackingContext, StackingContextId};
use gfx::display_list::StackingContext;
use gfx_traits::StackingContextId;
use std::cmp::{min, max};
use std::fmt;
use std::sync::Arc;

View file

@ -16,7 +16,8 @@ use flow;
use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
use flow_list::MutFlowListIterator;
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{StackingContext, StackingContextId};
use gfx::display_list::StackingContext;
use gfx_traits::StackingContextId;
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
use layout_debug;
use model::{IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto};

View file

@ -13,7 +13,8 @@ use display_list_builder::DisplayListBuildState;
use euclid::Point2D;
use flow::{Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{StackingContext, StackingContextId};
use gfx::display_list::StackingContext;
use gfx_traits::StackingContextId;
use std::fmt;
use std::sync::Arc;
use style::logical_geometry::LogicalSize;

View file

@ -14,7 +14,8 @@ use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, Dis
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use flow::{self, Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{StackingContext, StackingContextId};
use gfx::display_list::StackingContext;
use gfx_traits::StackingContextId;
use incremental::REFLOW;
use layout_debug;
use model::MaybeAuto;

View file

@ -12,7 +12,8 @@ use display_list_builder::DisplayListBuildState;
use euclid::Point2D;
use flow::{BaseFlow, Flow, FlowClass, ForceNonfloatedFlag, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow, SpecificFragmentInfo};
use gfx::display_list::{StackingContext, StackingContextId};
use gfx::display_list::StackingContext;
use gfx_traits::StackingContextId;
use layout_debug;
use std::cmp::max;
use std::fmt;

View file

@ -15,7 +15,8 @@ use euclid::Point2D;
use flow::{self, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
use flow_list::MutFlowListIterator;
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{StackingContext, StackingContextId};
use gfx::display_list::StackingContext;
use gfx_traits::StackingContextId;
use layout_debug;
use model::MaybeAuto;
use rustc_serialize::{Encodable, Encoder};

View file

@ -13,7 +13,8 @@ use display_list_builder::DisplayListBuildState;
use euclid::Point2D;
use flow::{Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{StackingContext, StackingContextId};
use gfx::display_list::StackingContext;
use gfx_traits::StackingContextId;
use layout_debug;
use rustc_serialize::{Encodable, Encoder};
use std::fmt;

View file

@ -22,7 +22,8 @@ use euclid::Point2D;
use floats::FloatKind;
use flow::{Flow, FlowClass, ImmutableFlowUtils, INLINE_POSITION_IS_STATIC, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{StackingContext, StackingContextId};
use gfx::display_list::StackingContext;
use gfx_traits::StackingContextId;
use model::MaybeAuto;
use std::cmp::{max, min};
use std::fmt;

View file

@ -11,13 +11,13 @@ use app_units::Au;
use azure::azure_hl::Color;
use euclid::{Point2D, Rect, Size2D};
use gfx::display_list::{BorderRadii, BoxShadowClipMode, ClippingRegion};
use gfx::display_list::{DisplayItem, DisplayList};
use gfx::display_list::{DisplayListTraversal, GradientStop, StackingContext, StackingContextType};
use gfx_traits::ScrollPolicy;
use gfx::display_list::{DisplayItem, DisplayList, DisplayListTraversal};
use gfx::display_list::{GradientStop, StackingContext, StackingContextType};
use gfx_traits::{FragmentType, ScrollPolicy, StackingContextId};
use style::computed_values::filter::{self, Filter};
use style::computed_values::{image_rendering, mix_blend_mode};
use style::values::computed::BorderStyle;
use webrender_traits::{self, AuxiliaryListsBuilder, DisplayListId, PipelineId, StackingContextId};
use webrender_traits::{self, AuxiliaryListsBuilder, DisplayListId, PipelineId};
trait WebRenderStackingContextConverter {
fn convert_to_webrender<'a>(&self,
@ -315,8 +315,11 @@ impl WebRenderStackingContextConverter for StackingContext {
ScrollPolicy::FixedPosition => webrender_traits::ScrollPolicy::Fixed,
};
let webrender_stacking_context_id = self.id.convert_to_webrender();
let mut sc =
webrender_traits::StackingContext::new(scroll_layer_id,
webrender_traits::StackingContext::new(webrender_stacking_context_id,
scroll_layer_id,
webrender_scroll_policy,
self.bounds.to_rectf(),
self.overflow.to_rectf(),
@ -514,7 +517,8 @@ impl WebRenderDisplayItemConverter for DisplayItem {
}
pub struct WebRenderFrameBuilder {
pub stacking_contexts: Vec<(StackingContextId, webrender_traits::StackingContext)>,
pub stacking_contexts: Vec<(webrender_traits::StackingContextId,
webrender_traits::StackingContext)>,
pub display_lists: Vec<(DisplayListId, webrender_traits::BuiltDisplayList)>,
pub auxiliary_lists_builder: AuxiliaryListsBuilder,
pub root_pipeline_id: PipelineId,
@ -536,7 +540,7 @@ impl WebRenderFrameBuilder {
api: &mut webrender_traits::RenderApi,
pipeline_id: PipelineId,
stacking_context: webrender_traits::StackingContext)
-> StackingContextId {
-> webrender_traits::StackingContextId {
assert!(pipeline_id == self.root_pipeline_id);
let id = api.next_stacking_context_id();
self.stacking_contexts.push((id, stacking_context));
@ -561,5 +565,32 @@ impl WebRenderFrameBuilder {
self.next_scroll_layer_id += 1;
webrender_traits::ScrollLayerId::new(self.root_pipeline_id, scroll_layer_id)
}
}
trait WebRenderStackingContextIdConverter {
fn convert_to_webrender(&self) -> webrender_traits::ServoStackingContextId;
}
impl WebRenderStackingContextIdConverter for StackingContextId {
fn convert_to_webrender(&self) -> webrender_traits::ServoStackingContextId {
webrender_traits::ServoStackingContextId(self.fragment_type().convert_to_webrender(),
self.id())
}
}
trait WebRenderFragmentTypeConverter {
fn convert_to_webrender(&self) -> webrender_traits::FragmentType;
}
impl WebRenderFragmentTypeConverter for FragmentType {
fn convert_to_webrender(&self) -> webrender_traits::FragmentType {
match *self {
FragmentType::FragmentBody => webrender_traits::FragmentType::FragmentBody,
FragmentType::BeforePseudoContent => {
webrender_traits::FragmentType::BeforePseudoContent
}
FragmentType::AfterPseudoContent => webrender_traits::FragmentType::AfterPseudoContent,
}
}
}