Skip to content

Commit

Permalink
Suppress iframe size messages from layout that include unchanged sizes.
Browse files Browse the repository at this point in the history
  • Loading branch information
jdm committed Jan 14, 2019
1 parent b1a4913 commit 49a100c
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 21 deletions.
13 changes: 5 additions & 8 deletions components/constellation/constellation.rs
Expand Up @@ -146,9 +146,9 @@ use script_traits::{DocumentActivity, DocumentState, LayoutControlMsg, LoadData}
use script_traits::{
IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState, TimerSchedulerMsg,
};
use script_traits::{IFrameSizeMsg, WindowSizeData, WindowSizeType};
use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory};
use script_traits::{SWManagerMsg, ScopeThings, UpdatePipelineIdReason, WebDriverCommandMsg};
use script_traits::{WindowSizeData, WindowSizeType};
use serde::{Deserialize, Serialize};
use servo_config::opts;
use servo_config::prefs::PREFS;
Expand Down Expand Up @@ -1837,17 +1837,14 @@ where
}
}

fn handle_iframe_size_msg(
&mut self,
iframe_sizes: Vec<(BrowsingContextId, TypedSize2D<f32, CSSPixel>)>,
) {
for (browsing_context_id, size) in iframe_sizes {
fn handle_iframe_size_msg(&mut self, iframe_sizes: Vec<IFrameSizeMsg>) {
for IFrameSizeMsg { data, type_ } in iframe_sizes {
let window_size = WindowSizeData {
initial_viewport: size,
initial_viewport: data.size,
device_pixel_ratio: self.window_size.device_pixel_ratio,
};

self.resize_browsing_context(window_size, WindowSizeType::Initial, browsing_context_id);
self.resize_browsing_context(window_size, type_, data.id);
}
}

Expand Down
13 changes: 7 additions & 6 deletions components/layout/display_list/builder.rs
Expand Up @@ -39,9 +39,10 @@ use gfx::text::glyph::ByteIndex;
use gfx::text::TextRun;
use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId};
use ipc_channel::ipc;
use msg::constellation_msg::{BrowsingContextId, PipelineId};
use msg::constellation_msg::PipelineId;
use net_traits::image_cache::UsePlaceholder;
use range::Range;
use script_traits::IFrameSize;
use servo_config::opts;
use servo_geometry::MaxRect;
use std::default::Default;
Expand All @@ -64,7 +65,6 @@ use style::values::generics::image::{GradientKind, Image, PaintWorklet};
use style::values::generics::ui::Cursor;
use style::values::{Either, RGBA};
use style_traits::cursor::CursorKind;
use style_traits::CSSPixel;
use style_traits::ToCss;
use webrender_api::{self, BorderDetails, BorderRadius, BorderSide, BoxShadowClipMode, ColorF};
use webrender_api::{ExternalScrollId, FilterOp, GlyphInstance, ImageRendering, LayoutRect};
Expand Down Expand Up @@ -347,7 +347,7 @@ pub struct DisplayListBuildState<'a> {

/// Vector containing iframe sizes, used to inform the constellation about
/// new iframe sizes
pub iframe_sizes: Vec<(BrowsingContextId, TypedSize2D<f32, CSSPixel>)>,
pub iframe_sizes: Vec<IFrameSize>,

/// Stores text runs to answer text queries used to place a cursor inside text.
pub indexable_text: IndexableText,
Expand Down Expand Up @@ -2001,9 +2001,10 @@ impl FragmentDisplayListBuilding for Fragment {
}));

let size = Size2D::new(item.bounds().size.width, item.bounds().size.height);
state
.iframe_sizes
.push((browsing_context_id, TypedSize2D::from_untyped(&size)));
state.iframe_sizes.push(IFrameSize {
id: browsing_context_id,
size: TypedSize2D::from_untyped(&size),
});

state.add_display_item(item);
}
Expand Down
46 changes: 41 additions & 5 deletions components/layout_thread/lib.rs
Expand Up @@ -68,8 +68,8 @@ use metrics::{PaintTimeMetrics, ProfilerMetadataFactory, ProgressiveWebMetric};
use msg::constellation_msg::{
BackgroundHangMonitor, BackgroundHangMonitorRegister, HangAnnotation,
};
use msg::constellation_msg::{BrowsingContextId, MonitoredComponentId, TopLevelBrowsingContextId};
use msg::constellation_msg::{LayoutHangAnnotation, MonitoredComponentType, PipelineId};
use msg::constellation_msg::{MonitoredComponentId, TopLevelBrowsingContextId};
use net_traits::image_cache::{ImageCache, UsePlaceholder};
use parking_lot::RwLock;
use profile_traits::mem::{self as profile_mem, Report, ReportKind, ReportsChan};
Expand All @@ -82,7 +82,7 @@ use script_layout_interface::rpc::{LayoutRPC, OffsetParentResponse, StyleRespons
use script_layout_interface::wrapper_traits::LayoutNode;
use script_traits::Painter;
use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg};
use script_traits::{DrawAPaintImageResult, PaintWorkletError};
use script_traits::{DrawAPaintImageResult, IFrameSizeMsg, PaintWorkletError, WindowSizeType};
use script_traits::{ScrollState, UntrustedNodeAddress};
use selectors::Element;
use servo_arc::Arc as ServoArc;
Expand Down Expand Up @@ -241,6 +241,9 @@ pub struct LayoutThread {

/// The time a layout query has waited before serviced by layout thread.
layout_query_waiting_time: Histogram,

/// The sizes of all iframes encountered during the last layout operation.
last_iframe_sizes: RefCell<HashMap<BrowsingContextId, TypedSize2D<f32, CSSPixel>>>,
}

impl LayoutThreadFactory for LayoutThread {
Expand Down Expand Up @@ -544,6 +547,7 @@ impl LayoutThread {
},
paint_time_metrics: paint_time_metrics,
layout_query_waiting_time: Histogram::new(),
last_iframe_sizes: Default::default(),
}
}

Expand Down Expand Up @@ -1054,9 +1058,41 @@ impl LayoutThread {
// it with an empty vector
let iframe_sizes =
std::mem::replace(&mut build_state.iframe_sizes, vec![]);
let msg = ConstellationMsg::IFrameSizes(iframe_sizes);
if let Err(e) = self.constellation_chan.send(msg) {
warn!("Layout resize to constellation failed ({}).", e);
// Collect the last frame's iframe sizes to compute any differences.
// Every frame starts with a fresh collection so that any removed
// iframes do not linger.
let last_iframe_sizes = std::mem::replace(
&mut *self.last_iframe_sizes.borrow_mut(),
HashMap::default(),
);
let mut size_messages = vec![];
for new_size in iframe_sizes {
// Only notify the constellation about existing iframes
// that have a new size, or iframes that did not previously
// exist.
if let Some(old_size) = last_iframe_sizes.get(&new_size.id) {
if *old_size != new_size.size {
size_messages.push(IFrameSizeMsg {
data: new_size,
type_: WindowSizeType::Resize,
});
}
} else {
size_messages.push(IFrameSizeMsg {
data: new_size,
type_: WindowSizeType::Initial,
});
}
self.last_iframe_sizes
.borrow_mut()
.insert(new_size.id, new_size.size);
}

if !size_messages.is_empty() {
let msg = ConstellationMsg::IFrameSizes(size_messages);
if let Err(e) = self.constellation_chan.send(msg) {
warn!("Layout resize to constellation failed ({}).", e);
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion components/script_traits/lib.rs
Expand Up @@ -61,7 +61,9 @@ use webvr_traits::{WebVREvent, WebVRMsg};
pub use crate::script_msg::{
DOMMessage, SWManagerMsg, SWManagerSenders, ScopeThings, ServiceWorkerMsg,
};
pub use crate::script_msg::{EventResult, LayoutMsg, LogEntry, ScriptMsg};
pub use crate::script_msg::{
EventResult, IFrameSize, IFrameSizeMsg, LayoutMsg, LogEntry, ScriptMsg,
};

/// The address of a node. Layout sends these back. They must be validated via
/// `from_untrusted_node_address` before they can be used, because we do not trust layout.
Expand Down
21 changes: 20 additions & 1 deletion components/script_traits/script_msg.rs
Expand Up @@ -9,6 +9,7 @@ use crate::IFrameLoadInfo;
use crate::IFrameLoadInfoWithData;
use crate::LayoutControlMsg;
use crate::LoadData;
use crate::WindowSizeType;
use crate::WorkerGlobalScopeInit;
use crate::WorkerScriptLoadOrigin;
use canvas_traits::canvas::{CanvasId, CanvasMsg};
Expand All @@ -30,13 +31,31 @@ use style_traits::viewport::ViewportConstraints;
use style_traits::CSSPixel;
use webrender_api::{DeviceIntPoint, DeviceIntSize};

/// A particular iframe's size, associated with a browsing context.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct IFrameSize {
/// The child browsing context for this iframe.
pub id: BrowsingContextId,
/// The size of the iframe.
pub size: TypedSize2D<f32, CSSPixel>,
}

/// An iframe sizing operation.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct IFrameSizeMsg {
/// The iframe sizing data.
pub data: IFrameSize,
/// The kind of sizing operation.
pub type_: WindowSizeType,
}

/// Messages from the layout to the constellation.
#[derive(Deserialize, Serialize)]
pub enum LayoutMsg {
/// Indicates whether this pipeline is currently running animations.
ChangeRunningAnimationsState(PipelineId, AnimationState),
/// Inform the constellation of the size of the iframe's viewport.
IFrameSizes(Vec<(BrowsingContextId, TypedSize2D<f32, CSSPixel>)>),
IFrameSizes(Vec<IFrameSizeMsg>),
/// Requests that the constellation inform the compositor that it needs to record
/// the time when the frame with the given ID (epoch) is painted.
PendingPaintMetric(PipelineId, Epoch),
Expand Down

0 comments on commit 49a100c

Please sign in to comment.