diff options
Diffstat (limited to 'components')
-rw-r--r-- | components/compositing/compositor.rs | 21 | ||||
-rw-r--r-- | components/constellation/constellation.rs | 40 | ||||
-rw-r--r-- | components/constellation/pipeline.rs | 26 | ||||
-rw-r--r-- | components/constellation/session_history.rs | 5 | ||||
-rw-r--r-- | components/layout/display_list/builder.rs | 19 | ||||
-rw-r--r-- | components/layout/query.rs | 12 | ||||
-rw-r--r-- | components/layout_2020/query.rs | 11 | ||||
-rw-r--r-- | components/layout_thread/lib.rs | 42 | ||||
-rw-r--r-- | components/layout_thread_2020/lib.rs | 37 | ||||
-rw-r--r-- | components/layout_traits/lib.rs | 7 | ||||
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 18 | ||||
-rw-r--r-- | components/script/dom/window.rs | 13 | ||||
-rw-r--r-- | components/script/script_thread.rs | 10 | ||||
-rw-r--r-- | components/script_layout_interface/Cargo.toml | 1 | ||||
-rw-r--r-- | components/script_layout_interface/message.rs | 6 | ||||
-rw-r--r-- | components/script_layout_interface/rpc.rs | 4 | ||||
-rw-r--r-- | components/script_traits/lib.rs | 4 | ||||
-rw-r--r-- | components/servo/lib.rs | 37 |
18 files changed, 163 insertions, 150 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index 94f578d48f1..3df7e1a8a0c 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -209,9 +209,6 @@ pub struct IOCompositor<Window: WindowMethods + ?Sized> { /// True to translate mouse input into touch events. convert_mouse_to_touch: bool, - - /// Ratio of device pixels per px at the default scale. - device_pixels_per_px: Option<f32>, } #[derive(Clone, Copy)] @@ -284,7 +281,6 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { is_running_problem_test: bool, exit_after_load: bool, convert_mouse_to_touch: bool, - device_pixels_per_px: Option<f32>, ) -> Self { let composite_target = match output_file { Some(_) => CompositeTarget::PngFile, @@ -327,7 +323,6 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { is_running_problem_test, exit_after_load, convert_mouse_to_touch, - device_pixels_per_px, } } @@ -338,7 +333,6 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { is_running_problem_test: bool, exit_after_load: bool, convert_mouse_to_touch: bool, - device_pixels_per_px: Option<f32>, ) -> Self { let mut compositor = IOCompositor::new( window, @@ -347,15 +341,11 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { is_running_problem_test, exit_after_load, convert_mouse_to_touch, - device_pixels_per_px, ); // Set the size of the root layer. compositor.update_zoom_transform(); - // Tell the constellation about the initial window size. - compositor.send_window_size(WindowSizeType::Initial); - compositor } @@ -645,8 +635,6 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { self.create_pipeline_details_for_frame_tree(&frame_tree); - self.send_window_size(WindowSizeType::Initial); - self.frame_tree_id.next(); } @@ -1081,13 +1069,10 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> { } fn hidpi_factor(&self) -> Scale<f32, DeviceIndependentPixel, DevicePixel> { - match self.device_pixels_per_px { - Some(device_pixels_per_px) => Scale::new(device_pixels_per_px), - None => match self.output_file { - Some(_) => Scale::new(1.0), - None => self.embedder_coordinates.hidpi_factor, - }, + if self.output_file.is_some() { + return Scale::new(1.0); } + self.embedder_coordinates.hidpi_factor } fn device_pixels_per_page_px(&self) -> Scale<f32, CSSPixel, DevicePixel> { diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 685f620f6b5..807495ff3f1 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -112,7 +112,7 @@ use compositing::SendableFrameTree; use crossbeam_channel::{after, never, unbounded, Receiver, Sender}; use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg}; use embedder_traits::{Cursor, EmbedderMsg, EmbedderProxy, EventLoopWaker}; -use euclid::{default::Size2D as UntypedSize2D, Scale, Size2D}; +use euclid::{default::Size2D as UntypedSize2D, Size2D}; use gfx::font_cache_thread::FontCacheThread; use gfx_traits::Epoch; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; @@ -157,7 +157,6 @@ use script_traits::{MessagePortMsg, PortMessageTask, StructuredSerializedData}; use script_traits::{SWManagerMsg, ScopeThings, UpdatePipelineIdReason, WebDriverCommandMsg}; use serde::{Deserialize, Serialize}; use servo_config::{opts, pref}; -use servo_geometry::DeviceIndependentPixel; use servo_rand::{random, Rng, ServoRng, SliceRandom}; use servo_remutex::ReentrantMutex; use servo_url::{Host, ImmutableOrigin, ServoUrl}; @@ -463,10 +462,6 @@ pub struct Constellation<Message, LTF, STF> { /// Mechanism to force the compositor to process events. event_loop_waker: Option<Box<dyn EventLoopWaker>>, - - /// The ratio of device pixels per px at the default scale. If unspecified, will use the - /// platform default setting. - device_pixels_per_px: Option<f32>, } /// State needed to construct a constellation. @@ -523,10 +518,6 @@ pub struct InitialConstellationState { /// Mechanism to force the compositor to process events. pub event_loop_waker: Option<Box<dyn EventLoopWaker>>, - - /// The ratio of device pixels per px at the default scale. If unspecified, will use the - /// platform default setting. - pub device_pixels_per_px: Option<f32>, } /// Data needed for webdriver @@ -702,8 +693,7 @@ where /// Create a new constellation thread. pub fn start( state: InitialConstellationState, - initial_window_size: Size2D<u32, DeviceIndependentPixel>, - device_pixels_per_px: Option<f32>, + initial_window_size: WindowSizeData, random_pipeline_closure_probability: Option<f32>, random_pipeline_closure_seed: Option<usize>, is_running_problem_test: bool, @@ -811,10 +801,7 @@ where next_pipeline_namespace_id: PipelineNamespaceId(2), time_profiler_chan: state.time_profiler_chan, mem_profiler_chan: state.mem_profiler_chan, - window_size: WindowSizeData { - initial_viewport: initial_window_size.to_f32() * Scale::new(1.0), - device_pixel_ratio: Scale::new(device_pixels_per_px.unwrap_or(1.0)), - }, + window_size: initial_window_size, phantom: PhantomData, webdriver: WebDriverData::new(), timer_scheduler: TimerScheduler::new(), @@ -844,7 +831,6 @@ where glplayer_threads: state.glplayer_threads, player_context: state.player_context, event_loop_waker: state.event_loop_waker, - device_pixels_per_px, }; constellation.run(); @@ -1074,10 +1060,12 @@ where resource_threads, time_profiler_chan: self.time_profiler_chan.clone(), mem_profiler_chan: self.mem_profiler_chan.clone(), - window_size: initial_window_size, + window_size: WindowSizeData { + initial_viewport: initial_window_size, + device_pixel_ratio: self.window_size.device_pixel_ratio, + }, event_loop, load_data, - device_pixel_ratio: self.window_size.device_pixel_ratio, prev_visibility: is_visible, webrender_api_sender: self.webrender_api_sender.clone(), webrender_document: self.webrender_document, @@ -1089,7 +1077,6 @@ where webxr_registry: self.webxr_registry.clone(), player_context: self.player_context.clone(), event_loop_waker: self.event_loop_waker.as_ref().map(|w| (*w).clone_box()), - device_pixels_per_px: self.device_pixels_per_px, }); let pipeline = match result { @@ -2229,6 +2216,7 @@ where new_pipeline_id: new_pipeline_id, replace: None, new_browsing_context_info: None, + window_size, }); } @@ -2373,6 +2361,7 @@ where is_private: is_private, is_visible: is_visible, }), + window_size, }); } @@ -2544,6 +2533,10 @@ where // https://github.com/rust-lang/rust/issues/59159 let browsing_context_size = browsing_context.size; let browsing_context_is_visible = browsing_context.is_visible; + debug_assert_eq!( + browsing_context_size, + load_info.window_size.initial_viewport + ); // Create the new pipeline, attached to the parent and push to pending changes self.new_pipeline( @@ -2565,6 +2558,7 @@ where replace: replace, // Browsing context for iframe already exists. new_browsing_context_info: None, + window_size: load_info.window_size.initial_viewport, }); } @@ -2623,6 +2617,7 @@ where is_private: is_private, is_visible: is_parent_visible, }), + window_size: load_info.window_size.initial_viewport, }); } @@ -2711,6 +2706,7 @@ where is_private: is_opener_private, is_visible: is_opener_visible, }), + window_size: self.window_size.initial_viewport, }); } @@ -2914,6 +2910,7 @@ where replace, // `load_url` is always invoked on an existing browsing context. new_browsing_context_info: None, + window_size, }); Some(new_pipeline_id) }, @@ -3233,6 +3230,7 @@ where replace: Some(NeedsToReload::Yes(pipeline_id, load_data)), // Browsing context must exist at this point. new_browsing_context_info: None, + window_size, }); return; }, @@ -3990,7 +3988,7 @@ where change.top_level_browsing_context_id, change.new_pipeline_id, new_context_info.parent_pipeline_id, - self.window_size.initial_viewport, //XXXjdm is this valid? + change.window_size, new_context_info.is_private, new_context_info.is_visible, ); diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index 2579343f3fe..3ac5ded15ed 100644 --- a/components/constellation/pipeline.rs +++ b/components/constellation/pipeline.rs @@ -12,7 +12,6 @@ use compositing::CompositorProxy; use crossbeam_channel::{unbounded, Sender}; use devtools_traits::{DevtoolsControlMsg, ScriptToDevtoolsControlMsg}; use embedder_traits::EventLoopWaker; -use euclid::{Scale, Size2D}; use gfx::font_cache_thread::FontCacheThread; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; @@ -47,8 +46,6 @@ use std::process; use std::rc::Rc; use std::sync::atomic::AtomicBool; use std::sync::Arc; -use style_traits::CSSPixel; -use style_traits::DevicePixel; use webvr_traits::WebVRMsg; /// A `Pipeline` is the constellation's view of a `Document`. Each pipeline has an @@ -165,10 +162,7 @@ pub struct InitialPipelineState { pub mem_profiler_chan: profile_mem::ProfilerChan, /// Information about the initial window size. - pub window_size: Size2D<f32, CSSPixel>, - - /// Information about the device pixel ratio. - pub device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>, + pub window_size: WindowSizeData, /// The ID of the pipeline namespace for this script thread. pub pipeline_namespace_id: PipelineNamespaceId, @@ -205,10 +199,6 @@ pub struct InitialPipelineState { /// Mechanism to force the compositor to process events. pub event_loop_waker: Option<Box<dyn EventLoopWaker>>, - - /// The ratio of device pixels per px at the default scale. If unspecified, will use the - /// platform default setting. - pub device_pixels_per_px: Option<f32>, } pub struct NewPipeline { @@ -228,11 +218,6 @@ impl Pipeline { // probably requires a general low-memory strategy. let (pipeline_chan, pipeline_port) = ipc::channel().expect("Pipeline main chan"); - let window_size = WindowSizeData { - initial_viewport: state.window_size, - device_pixel_ratio: state.device_pixel_ratio, - }; - let (script_chan, sampler_chan) = match state.event_loop { Some(script_chan) => { let new_layout_info = NewLayoutInfo { @@ -242,7 +227,7 @@ impl Pipeline { top_level_browsing_context_id: state.top_level_browsing_context_id, opener: state.opener, load_data: state.load_data.clone(), - window_size: window_size, + window_size: state.window_size, pipeline_port: pipeline_port, }; @@ -301,7 +286,7 @@ impl Pipeline { resource_threads: state.resource_threads, time_profiler_chan: state.time_profiler_chan, mem_profiler_chan: state.mem_profiler_chan, - window_size: window_size, + window_size: state.window_size, layout_to_constellation_chan: state.layout_to_constellation_chan, script_chan: script_chan.clone(), load_data: state.load_data.clone(), @@ -316,7 +301,6 @@ impl Pipeline { webvr_chan: state.webvr_chan, webxr_registry: state.webxr_registry, player_context: state.player_context, - device_pixels_per_px: state.device_pixels_per_px, }; // Spawn the child process. @@ -523,7 +507,6 @@ pub struct UnprivilegedPipelineContent { webvr_chan: Option<IpcSender<WebVRMsg>>, webxr_registry: webxr_api::Registry, player_context: WindowGLContext, - device_pixels_per_px: Option<f32>, } impl UnprivilegedPipelineContent { @@ -614,8 +597,7 @@ impl UnprivilegedPipelineContent { paint_time_metrics, layout_thread_busy_flag.clone(), self.opts.load_webfonts_synchronously, - self.opts.initial_window_size, - self.device_pixels_per_px, + self.window_size, self.opts.dump_display_list, self.opts.dump_display_list_json, self.opts.dump_style_tree, diff --git a/components/constellation/session_history.rs b/components/constellation/session_history.rs index 0fdcd129baa..3e15591215e 100644 --- a/components/constellation/session_history.rs +++ b/components/constellation/session_history.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::browsingcontext::NewBrowsingContextInfo; +use euclid::Size2D; use msg::constellation_msg::{ BrowsingContextId, HistoryStateId, PipelineId, TopLevelBrowsingContextId, }; @@ -10,6 +11,7 @@ use script_traits::LoadData; use servo_url::ServoUrl; use std::cmp::PartialEq; use std::{fmt, mem}; +use style_traits::CSSPixel; /// Represents the joint session history /// https://html.spec.whatwg.org/multipage/#joint-session-history @@ -122,6 +124,9 @@ pub struct SessionHistoryChange { /// Holds data for not-yet constructed browsing contexts that are not /// easily available when they need to be constructed. pub new_browsing_context_info: Option<NewBrowsingContextInfo>, + + /// The size of the viewport for the browsing context. + pub window_size: Size2D<f32, CSSPixel>, } /// Represents a pipeline or discarded pipeline in a history entry. diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs index f951bd3f8f2..c44324d43a1 100644 --- a/components/layout/display_list/builder.rs +++ b/components/layout/display_list/builder.rs @@ -1800,18 +1800,9 @@ impl Fragment { Some(browsing_context_id) => browsing_context_id, None => return warn!("No browsing context id for iframe."), }; - let pipeline_id = match fragment_info.pipeline_id { - Some(pipeline_id) => pipeline_id, - None => return warn!("No pipeline id for iframe {}.", browsing_context_id), - }; let base = create_base_display_item(state); let bounds = stacking_relative_content_box.to_layout(); - let item = DisplayItem::Iframe(Box::new(IframeDisplayItem { - base, - bounds, - iframe: pipeline_id, - })); // XXXjdm: This sleight-of-hand to convert LayoutRect -> Size2D<CSSPixel> // looks bogus. @@ -1820,6 +1811,16 @@ impl Fragment { size: euclid::Size2D::new(bounds.size.width, bounds.size.height), }); + let pipeline_id = match fragment_info.pipeline_id { + Some(pipeline_id) => pipeline_id, + None => return warn!("No pipeline id for iframe {}.", browsing_context_id), + }; + + let item = DisplayItem::Iframe(Box::new(IframeDisplayItem { + base, + bounds, + iframe: pipeline_id, + })); state.add_display_item(item); } }, diff --git a/components/layout/query.rs b/components/layout/query.rs index 8dfd1bab795..4850b75009c 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -16,6 +16,7 @@ use crate::sequential; use crate::wrapper::LayoutNodeLayoutData; use app_units::Au; use euclid::default::{Point2D, Rect, Size2D, Vector2D}; +use euclid::Size2D as TypedSize2D; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::PipelineId; use script_layout_interface::rpc::TextIndexResponse; @@ -40,7 +41,7 @@ use style::dom::TElement; use style::logical_geometry::{BlockFlowDirection, InlineBaseDirection, WritingMode}; use style::properties::{style_structs, LonghandId, PropertyDeclarationId, PropertyId}; use style::selector_parser::PseudoElement; -use style_traits::ToCss; +use style_traits::{CSSPixel, ToCss}; use webrender_api::ExternalScrollId; /// Mutable data belonging to the LayoutThread. @@ -90,6 +91,9 @@ pub struct LayoutThreadData { /// A queued response for the inner text of a given element. pub element_inner_text_response: String, + + /// A queued response for the viewport dimensions for a given browsing context. + pub inner_window_dimensions_response: Option<TypedSize2D<f32, CSSPixel>>, } pub struct LayoutRPCImpl(pub Arc<Mutex<LayoutThreadData>>); @@ -193,6 +197,12 @@ impl LayoutRPC for LayoutRPCImpl { let rw_data = rw_data.lock().unwrap(); rw_data.element_inner_text_response.clone() } + + fn inner_window_dimensions(&self) -> Option<TypedSize2D<f32, CSSPixel>> { + let &LayoutRPCImpl(ref rw_data) = self; + let rw_data = rw_data.lock().unwrap(); + rw_data.inner_window_dimensions_response.clone() + } } struct UnioningFragmentBorderBoxIterator { diff --git a/components/layout_2020/query.rs b/components/layout_2020/query.rs index 23816521c70..1317759b33b 100644 --- a/components/layout_2020/query.rs +++ b/components/layout_2020/query.rs @@ -7,6 +7,7 @@ use crate::context::LayoutContext; use app_units::Au; use euclid::default::{Point2D, Rect}; +use euclid::Size2D; use euclid::Vector2D; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::PipelineId; @@ -22,6 +23,7 @@ use std::sync::{Arc, Mutex}; use style::dom::OpaqueNode; use style::properties::PropertyId; use style::selector_parser::PseudoElement; +use style_traits::CSSPixel; use webrender_api::units::LayoutPixel; use webrender_api::ExternalScrollId; @@ -70,6 +72,9 @@ pub struct LayoutThreadData { /// A queued response for the inner text of a given element. pub element_inner_text_response: String, + + /// A queued response for the viewport dimensions for a given browsing context. + pub inner_window_dimensions_response: Option<Size2D<f32, CSSPixel>>, } pub struct LayoutRPCImpl(pub Arc<Mutex<LayoutThreadData>>); @@ -150,6 +155,12 @@ impl LayoutRPC for LayoutRPCImpl { let rw_data = rw_data.lock().unwrap(); rw_data.element_inner_text_response.clone() } + + fn inner_window_dimensions(&self) -> Option<Size2D<f32, CSSPixel>> { + let &LayoutRPCImpl(ref rw_data) = self; + let rw_data = rw_data.lock().unwrap(); + rw_data.inner_window_dimensions_response.clone() + } } pub fn process_content_box_request(_requested_node: OpaqueNode) -> Option<Rect<Au>> { diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 84ace1c1efe..48b7591c242 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -86,13 +86,13 @@ use script_layout_interface::wrapper_traits::LayoutNode; use script_traits::Painter; use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg}; use script_traits::{DrawAPaintImageResult, IFrameSizeMsg, PaintWorkletError, WindowSizeType}; -use script_traits::{ScrollState, UntrustedNodeAddress}; +use script_traits::{ScrollState, UntrustedNodeAddress, WindowSizeData}; use selectors::Element; use servo_arc::Arc as ServoArc; use servo_atoms::Atom; use servo_config::opts; use servo_config::pref; -use servo_geometry::{DeviceIndependentPixel, MaxRect}; +use servo_geometry::MaxRect; use servo_url::ServoUrl; use std::borrow::ToOwned; use std::cell::{Cell, RefCell}; @@ -254,13 +254,6 @@ pub struct LayoutThread { /// Load web fonts synchronously to avoid non-deterministic network-driven reflows. load_webfonts_synchronously: bool, - /// The initial request size of the window - initial_window_size: Size2D<u32, DeviceIndependentPixel>, - - /// The ratio of device pixels per px at the default scale. - /// If unspecified, will use the platform default setting. - device_pixels_per_px: Option<f32>, - /// Dumps the display list form after a layout. dump_display_list: bool, @@ -311,8 +304,7 @@ impl LayoutThreadFactory for LayoutThread { paint_time_metrics: PaintTimeMetrics, busy: Arc<AtomicBool>, load_webfonts_synchronously: bool, - initial_window_size: Size2D<u32, DeviceIndependentPixel>, - device_pixels_per_px: Option<f32>, + window_size: WindowSizeData, dump_display_list: bool, dump_display_list_json: bool, dump_style_tree: bool, @@ -360,8 +352,7 @@ impl LayoutThreadFactory for LayoutThread { paint_time_metrics, busy, load_webfonts_synchronously, - initial_window_size, - device_pixels_per_px, + window_size, dump_display_list, dump_display_list_json, dump_style_tree, @@ -531,8 +522,7 @@ impl LayoutThread { paint_time_metrics: PaintTimeMetrics, busy: Arc<AtomicBool>, load_webfonts_synchronously: bool, - initial_window_size: Size2D<u32, DeviceIndependentPixel>, - device_pixels_per_px: Option<f32>, + window_size: WindowSizeData, dump_display_list: bool, dump_display_list_json: bool, dump_style_tree: bool, @@ -542,12 +532,10 @@ impl LayoutThread { trace_layout: bool, dump_flow_tree: bool, ) -> LayoutThread { - // The device pixel ratio is incorrect (it does not have the hidpi value), - // but it will be set correctly when the initial reflow takes place. let device = Device::new( MediaType::screen(), - initial_window_size.to_f32() * Scale::new(1.0), - Scale::new(device_pixels_per_px.unwrap_or(1.0)), + window_size.initial_viewport, + window_size.device_pixel_ratio, ); // Create the channel on which new animations can be sent. @@ -609,6 +597,7 @@ impl LayoutThread { text_index_response: TextIndexResponse(None), nodes_from_point_response: vec![], element_inner_text_response: String::new(), + inner_window_dimensions_response: None, })), webrender_image_cache: Arc::new(RwLock::new(FnvHashMap::default())), timer: if pref!(layout.animations.test.enabled) { @@ -621,8 +610,6 @@ impl LayoutThread { last_iframe_sizes: Default::default(), busy, load_webfonts_synchronously, - initial_window_size, - device_pixels_per_px, dump_display_list, dump_display_list_json, dump_style_tree, @@ -953,8 +940,7 @@ impl LayoutThread { info.paint_time_metrics, info.layout_is_busy, self.load_webfonts_synchronously, - self.initial_window_size, - self.device_pixels_per_px, + info.window_size, self.dump_display_list, self.dump_display_list_json, self.dump_style_tree, @@ -1333,6 +1319,9 @@ impl LayoutThread { &QueryMsg::ElementInnerTextQuery(_) => { rw_data.element_inner_text_response = String::new(); }, + &QueryMsg::InnerWindowDimensionsQuery(_) => { + rw_data.inner_window_dimensions_response = None; + }, }, ReflowGoal::Full | ReflowGoal::TickAnimations => {}, } @@ -1685,6 +1674,13 @@ impl LayoutThread { rw_data.element_inner_text_response = process_element_inner_text_query(node, &rw_data.indexable_text); }, + &QueryMsg::InnerWindowDimensionsQuery(browsing_context_id) => { + rw_data.inner_window_dimensions_response = self + .last_iframe_sizes + .borrow() + .get(&browsing_context_id) + .cloned(); + }, }, ReflowGoal::Full | ReflowGoal::TickAnimations => {}, } diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index 13cf35975ee..106dace088b 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -67,13 +67,12 @@ use script_layout_interface::rpc::{LayoutRPC, OffsetParentResponse, StyleRespons use script_traits::Painter; use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg}; use script_traits::{DrawAPaintImageResult, PaintWorkletError}; -use script_traits::{ScrollState, UntrustedNodeAddress}; +use script_traits::{ScrollState, UntrustedNodeAddress, WindowSizeData}; use selectors::Element; use servo_arc::Arc as ServoArc; use servo_atoms::Atom; use servo_config::opts; use servo_config::pref; -use servo_geometry::DeviceIndependentPixel; use servo_url::ServoUrl; use std::cell::{Cell, RefCell}; use std::collections::HashMap; @@ -212,13 +211,6 @@ pub struct LayoutThread { /// Load web fonts synchronously to avoid non-deterministic network-driven reflows. load_webfonts_synchronously: bool, - /// The initial request size of the window - initial_window_size: Size2D<u32, DeviceIndependentPixel>, - - /// The ratio of device pixels per px at the default scale. - /// If unspecified, will use the platform default setting. - device_pixels_per_px: Option<f32>, - /// Emits notifications when there is a relayout. relayout_event: bool, } @@ -246,8 +238,7 @@ impl LayoutThreadFactory for LayoutThread { paint_time_metrics: PaintTimeMetrics, busy: Arc<AtomicBool>, load_webfonts_synchronously: bool, - initial_window_size: Size2D<u32, DeviceIndependentPixel>, - device_pixels_per_px: Option<f32>, + window_size: WindowSizeData, _dump_display_list: bool, _dump_display_list_json: bool, _dump_style_tree: bool, @@ -294,8 +285,7 @@ impl LayoutThreadFactory for LayoutThread { paint_time_metrics, busy, load_webfonts_synchronously, - initial_window_size, - device_pixels_per_px, + window_size, relayout_event, ); @@ -457,16 +447,15 @@ impl LayoutThread { paint_time_metrics: PaintTimeMetrics, busy: Arc<AtomicBool>, load_webfonts_synchronously: bool, - initial_window_size: Size2D<u32, DeviceIndependentPixel>, - device_pixels_per_px: Option<f32>, + window_size: WindowSizeData, relayout_event: bool, ) -> LayoutThread { // The device pixel ratio is incorrect (it does not have the hidpi value), // but it will be set correctly when the initial reflow takes place. let device = Device::new( MediaType::screen(), - initial_window_size.to_f32() * Scale::new(1.0), - Scale::new(device_pixels_per_px.unwrap_or(1.0)), + window_size.initial_viewport, + window_size.device_pixel_ratio, ); // Create the channel on which new animations can be sent. @@ -523,6 +512,7 @@ impl LayoutThread { text_index_response: TextIndexResponse(None), nodes_from_point_response: vec![], element_inner_text_response: String::new(), + inner_window_dimensions_response: None, })), timer: if pref!(layout.animations.test.enabled) { Timer::test_mode() @@ -532,8 +522,6 @@ impl LayoutThread { paint_time_metrics: paint_time_metrics, busy, load_webfonts_synchronously, - initial_window_size, - device_pixels_per_px, relayout_event, } } @@ -819,8 +807,7 @@ impl LayoutThread { info.paint_time_metrics, info.layout_is_busy, self.load_webfonts_synchronously, - self.initial_window_size, - self.device_pixels_per_px, + info.window_size, false, // dump_display_list false, // dump_display_list_json false, // dump_style_tree @@ -937,6 +924,9 @@ impl LayoutThread { &QueryMsg::ElementInnerTextQuery(_) => { rw_data.element_inner_text_response = String::new(); }, + &QueryMsg::InnerWindowDimensionsQuery(_) => { + rw_data.inner_window_dimensions_response = None; + }, }, ReflowGoal::Full | ReflowGoal::TickAnimations => {}, } @@ -1189,6 +1179,11 @@ impl LayoutThread { let node = unsafe { ServoLayoutNode::new(&node) }; rw_data.element_inner_text_response = process_element_inner_text_query(node); }, + &QueryMsg::InnerWindowDimensionsQuery(_browsing_context_id) => { + // TODO(jdm): port the iframe sizing code from layout2013's display + // builder in order to support query iframe sizing. + rw_data.inner_window_dimensions_response = None; + }, }, ReflowGoal::Full | ReflowGoal::TickAnimations => {}, } diff --git a/components/layout_traits/lib.rs b/components/layout_traits/lib.rs index cfb824f6c98..b499bef85c6 100644 --- a/components/layout_traits/lib.rs +++ b/components/layout_traits/lib.rs @@ -10,7 +10,6 @@ // that these modules won't have to depend on layout. use crossbeam_channel::{Receiver, Sender}; -use euclid::Size2D; use gfx::font_cache_thread::FontCacheThread; use ipc_channel::ipc::{IpcReceiver, IpcSender}; use metrics::PaintTimeMetrics; @@ -19,8 +18,7 @@ use msg::constellation_msg::{BackgroundHangMonitorRegister, PipelineId}; use net_traits::image_cache::ImageCache; use profile_traits::{mem, time}; use script_traits::LayoutMsg as ConstellationMsg; -use script_traits::{ConstellationControlMsg, LayoutControlMsg}; -use servo_geometry::DeviceIndependentPixel; +use script_traits::{ConstellationControlMsg, LayoutControlMsg, WindowSizeData}; use servo_url::ServoUrl; use std::sync::atomic::AtomicBool; use std::sync::Arc; @@ -48,8 +46,7 @@ pub trait LayoutThreadFactory { paint_time_metrics: PaintTimeMetrics, busy: Arc<AtomicBool>, load_webfonts_synchronously: bool, - initial_window_size: Size2D<u32, DeviceIndependentPixel>, - device_pixels_per_px: Option<f32>, + window_size: WindowSizeData, dump_display_list: bool, dump_display_list_json: bool, dump_style_tree: bool, diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index f5a820458c2..e58e65ea5bb 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -28,7 +28,6 @@ use crate::dom::windowproxy::WindowProxy; use crate::script_thread::ScriptThread; use crate::task_source::TaskSource; use dom_struct::dom_struct; -use euclid::Size2D; use html5ever::{LocalName, Prefix}; use ipc_channel::ipc; use msg::constellation_msg::{BrowsingContextId, PipelineId, TopLevelBrowsingContextId}; @@ -173,6 +172,13 @@ impl HTMLIFrameElement { replace: replace, }; + let window_size = WindowSizeData { + initial_viewport: window + .inner_window_dimensions_query(browsing_context_id) + .unwrap_or_default(), + device_pixel_ratio: window.device_pixel_ratio(), + }; + match nav_type { NavigationType::InitialAboutBlank => { let (pipeline_sender, pipeline_receiver) = ipc::channel().unwrap(); @@ -184,6 +190,7 @@ impl HTMLIFrameElement { load_data: load_data.clone(), old_pipeline_id: old_pipeline_id, sandbox: sandboxed, + window_size, }; global_scope .script_to_constellation_chan() @@ -198,13 +205,7 @@ impl HTMLIFrameElement { opener: None, load_data: load_data, pipeline_port: pipeline_receiver, - window_size: WindowSizeData { - initial_viewport: { - let rect = self.upcast::<Node>().bounding_content_box_or_zero(); - Size2D::new(rect.size.width.to_f32_px(), rect.size.height.to_f32_px()) - }, - device_pixel_ratio: window.device_pixel_ratio(), - }, + window_size, }; self.pipeline_id.set(Some(new_pipeline_id)); @@ -216,6 +217,7 @@ impl HTMLIFrameElement { load_data: load_data, old_pipeline_id: old_pipeline_id, sandbox: sandboxed, + window_size, }; global_scope .script_to_constellation_chan() diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 70099ee5866..95326b46352 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -89,7 +89,7 @@ use js::jsval::{JSVal, NullValue}; use js::rust::wrappers::JS_DefineProperty; use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue}; use media::WindowGLContext; -use msg::constellation_msg::PipelineId; +use msg::constellation_msg::{BrowsingContextId, PipelineId}; use net_traits::image_cache::{ImageCache, ImageResponder, ImageResponse}; use net_traits::image_cache::{PendingImageId, PendingImageResponse}; use net_traits::storage_thread::StorageType; @@ -1829,6 +1829,16 @@ impl Window { DOMString::from(resolved) } + pub fn inner_window_dimensions_query( + &self, + browsing_context: BrowsingContextId, + ) -> Option<Size2D<f32, CSSPixel>> { + if !self.layout_reflow(QueryMsg::InnerWindowDimensionsQuery(browsing_context)) { + return None; + } + self.layout_rpc.inner_window_dimensions() + } + #[allow(unsafe_code)] pub fn offset_parent_query(&self, node: &Node) -> (Option<DomRoot<Element>>, UntypedRect<Au>) { if !self.layout_reflow(QueryMsg::OffsetParentQuery(node.to_opaque())) { @@ -2359,6 +2369,7 @@ fn debug_reflow_events(id: PipelineId, reflow_goal: &ReflowGoal, reason: &Reflow &QueryMsg::StyleQuery(_n) => "\tStyleQuery", &QueryMsg::TextIndexQuery(..) => "\tTextIndexQuery", &QueryMsg::ElementInnerTextQuery(_) => "\tElementInnerTextQuery", + &QueryMsg::InnerWindowDimensionsQuery(_) => "\tInnerWindowDimensionsQuery", }, }); diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 6a7a69651e7..191df335ec5 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -2392,6 +2392,7 @@ impl ScriptThread { load_data.url.clone(), ), layout_is_busy: layout_is_busy.clone(), + window_size, }); // Pick a layout thread, any layout thread @@ -3696,6 +3697,15 @@ impl ScriptThread { }; let window = document.window(); + if window.window_size() == new_size { + return; + } + debug!( + "resizing pipeline {:?} from {:?} to {:?}", + pipeline_id, + window.window_size(), + new_size + ); window.set_window_size(new_size); window.force_reflow(ReflowGoal::Full, ReflowReason::WindowResize); diff --git a/components/script_layout_interface/Cargo.toml b/components/script_layout_interface/Cargo.toml index 8ad33fc7d43..2e436761dc8 100644 --- a/components/script_layout_interface/Cargo.toml +++ b/components/script_layout_interface/Cargo.toml @@ -33,4 +33,5 @@ servo_arc = {path = "../servo_arc"} servo_atoms = {path = "../atoms"} servo_url = {path = "../url"} style = {path = "../style", features = ["servo"]} +style_traits = {path = "../style_traits", features = ["servo"]} webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} diff --git a/components/script_layout_interface/message.rs b/components/script_layout_interface/message.rs index 01a589d53cb..fb2bac65d07 100644 --- a/components/script_layout_interface/message.rs +++ b/components/script_layout_interface/message.rs @@ -10,7 +10,7 @@ use euclid::default::{Point2D, Rect}; use gfx_traits::Epoch; use ipc_channel::ipc::{IpcReceiver, IpcSender}; use metrics::PaintTimeMetrics; -use msg::constellation_msg::{BackgroundHangMonitorRegister, PipelineId}; +use msg::constellation_msg::{BackgroundHangMonitorRegister, BrowsingContextId, PipelineId}; use net_traits::image_cache::ImageCache; use profile_traits::mem::ReportsChan; use script_traits::Painter; @@ -128,6 +128,7 @@ pub enum QueryMsg { ResolvedStyleQuery(TrustedNodeAddress, Option<PseudoElement>, PropertyId), StyleQuery(TrustedNodeAddress), ElementInnerTextQuery(TrustedNodeAddress), + InnerWindowDimensionsQuery(BrowsingContextId), } /// Any query to perform with this reflow. @@ -147,6 +148,7 @@ impl ReflowGoal { ReflowGoal::LayoutQuery(ref querymsg, _) => match *querymsg { QueryMsg::NodesFromPointQuery(..) | QueryMsg::TextIndexQuery(..) | + QueryMsg::InnerWindowDimensionsQuery(_) | QueryMsg::ElementInnerTextQuery(_) => true, QueryMsg::ContentBoxQuery(_) | QueryMsg::ContentBoxesQuery(_) | @@ -176,6 +178,7 @@ impl ReflowGoal { QueryMsg::NodeScrollIdQuery(_) | QueryMsg::ResolvedStyleQuery(..) | QueryMsg::OffsetParentQuery(_) | + QueryMsg::InnerWindowDimensionsQuery(_) | QueryMsg::StyleQuery(_) => false, }, } @@ -227,4 +230,5 @@ pub struct LayoutThreadInit { pub image_cache: Arc<dyn ImageCache>, pub paint_time_metrics: PaintTimeMetrics, pub layout_is_busy: Arc<AtomicBool>, + pub window_size: WindowSizeData, } diff --git a/components/script_layout_interface/rpc.rs b/components/script_layout_interface/rpc.rs index 95d25082ed8..19da8fa6afc 100644 --- a/components/script_layout_interface/rpc.rs +++ b/components/script_layout_interface/rpc.rs @@ -4,9 +4,11 @@ use app_units::Au; use euclid::default::Rect; +use euclid::Size2D; use script_traits::UntrustedNodeAddress; use servo_arc::Arc; use style::properties::ComputedValues; +use style_traits::CSSPixel; use webrender_api::ExternalScrollId; /// Synchronous messages that script can send to layout. @@ -39,6 +41,8 @@ pub trait LayoutRPC { fn nodes_from_point_response(&self) -> Vec<UntrustedNodeAddress>; /// Query layout to get the inner text for a given element. fn element_inner_text(&self) -> String; + /// Get the dimensions of an iframe's inner window. + fn inner_window_dimensions(&self) -> Option<Size2D<f32, CSSPixel>>; } pub struct ContentBoxResponse(pub Option<Rect<Au>>); diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 9dd0ba04134..468cfb19fb3 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -739,6 +739,8 @@ pub struct IFrameLoadInfoWithData { pub old_pipeline_id: Option<PipelineId>, /// Sandbox type of this iframe pub sandbox: IFrameSandboxState, + /// The initial viewport size for this iframe. + pub window_size: WindowSizeData, } /// Specifies whether the script or layout thread needs to be ticked for animation. @@ -760,7 +762,7 @@ pub struct ScrollState { } /// Data about the window size. -#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, Serialize)] +#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)] pub struct WindowSizeData { /// The size of the initial layout viewport, before parsing an /// <http://www.w3.org/TR/css-device-adapt/#initial-viewport> diff --git a/components/servo/lib.rs b/components/servo/lib.rs index 71430b3f6f4..9a39856c762 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -84,7 +84,7 @@ use constellation::{FromCompositorLogger, FromScriptLogger}; use crossbeam_channel::{unbounded, Sender}; use embedder_traits::{EmbedderMsg, EmbedderProxy, EmbedderReceiver, EventLoopWaker}; use env_logger::Builder as EnvLoggerBuilder; -use euclid::Size2D; +use euclid::{Scale, Size2D}; #[cfg(all( not(target_os = "windows"), not(target_os = "ios"), @@ -104,7 +104,9 @@ use profile::mem as profile_mem; use profile::time as profile_time; use profile_traits::mem; use profile_traits::time; -use script_traits::{ConstellationMsg, SWManagerSenders, ScriptToConstellationChan}; +use script_traits::{ + ConstellationMsg, SWManagerSenders, ScriptToConstellationChan, WindowSizeData, +}; use servo_config::opts; use servo_config::{pref, prefs}; use servo_media::player::context::GlContext; @@ -313,11 +315,7 @@ impl<Window> Servo<Window> where Window: WindowMethods + 'static + ?Sized, { - pub fn new( - mut embedder: Box<dyn EmbedderMethods>, - window: Rc<Window>, - device_pixels_per_px: Option<f32>, - ) -> Servo<Window> { + pub fn new(mut embedder: Box<dyn EmbedderMethods>, window: Rc<Window>) -> Servo<Window> { // Global configuration options, parsed from the command line. let opts = opts::get(); @@ -358,6 +356,8 @@ where let devtools_chan = opts.devtools_port.map(|port| devtools::start_server(port)); let coordinates = window.get_coordinates(); + let device_pixel_ratio = coordinates.hidpi_factor.get(); + let viewport_size = coordinates.viewport.size.to_f32() / device_pixel_ratio; let (mut webrender, webrender_api_sender) = { let renderer_kind = if opts::get().should_use_osmesa() { @@ -380,12 +380,7 @@ where let render_notifier = Box::new(RenderNotifier::new(compositor_proxy.clone())); // Cast from `DeviceIndependentPixel` to `DevicePixel` - let device_pixel_ratio = coordinates.hidpi_factor.get(); - let window_size = Size2D::from_untyped( - (opts.initial_window_size.to_f32() / device_pixel_ratio) - .to_i32() - .to_untyped(), - ); + let window_size = Size2D::from_untyped(viewport_size.to_i32().to_untyped()); webrender::Renderer::new( window.gl(), @@ -492,6 +487,13 @@ where let event_loop_waker = None; + // The division by 1 represents the page's default zoom of 100%, + // and gives us the appropriate CSSPixel type for the viewport. + let window_size = WindowSizeData { + initial_viewport: viewport_size / Scale::new(1.0), + device_pixel_ratio: Scale::new(device_pixel_ratio), + }; + // Create the constellation, which maintains the engine // pipelines, including the script and layout threads, as well // as the navigation context. @@ -513,7 +515,7 @@ where webvr_constellation_sender, glplayer_threads, event_loop_waker, - device_pixels_per_px, + window_size, ); // Send the constellation's swmanager sender to service worker manager thread @@ -545,7 +547,6 @@ where opts.is_running_problem_test, opts.exit_after_load, opts.convert_mouse_to_touch, - device_pixels_per_px, ); Servo { @@ -828,7 +829,7 @@ fn create_constellation( webvr_constellation_sender: Option<Sender<Sender<ConstellationMsg>>>, glplayer_threads: Option<GLPlayerThreads>, event_loop_waker: Option<Box<dyn EventLoopWaker>>, - device_pixels_per_px: Option<f32>, + initial_window_size: WindowSizeData, ) -> (Sender<ConstellationMsg>, SWManagerSenders) { // Global configuration options, parsed from the command line. let opts = opts::get(); @@ -871,7 +872,6 @@ fn create_constellation( glplayer_threads, player_context, event_loop_waker, - device_pixels_per_px, }; let (constellation_chan, from_swmanager_sender) = Constellation::< script_layout_interface::message::Msg, @@ -879,8 +879,7 @@ fn create_constellation( script::script_thread::ScriptThread, >::start( initial_state, - opts.initial_window_size, - device_pixels_per_px, + initial_window_size, opts.random_pipeline_closure_probability, opts.random_pipeline_closure_seed, opts.is_running_problem_test, |