servo: Merge #15164 - Revert several changes that broke tests (from mbrubeck:revert); r=emilio
authorMatt Brubeck <mbrubeck@limpet.net>
Tue, 24 Jan 2017 11:14:28 -0800
changeset 340640 22807e73e5de8936d1bf55546b03e2c7288c6c97
parent 340639 42eabfccaec10644da88c8d5154b098b19db486d
child 340641 40589816acd1c822814e4c2d58c306de7f5b7b81
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
servo: Merge #15164 - Revert several changes that broke tests (from mbrubeck:revert); r=emilio This is based on #15158 by @aneeshusa, with additional reverts. This reverts #15064, which is causing many tests not to run, and #15129 and #15155 which landed while tests were not running and may have caused some new failures in iframe tests. Source-Repo: https://github.com/servo/servo Source-Revision: 185759f87a8dec88f5f65c49ac9df90b47014b19
servo/components/compositing/compositor.rs
servo/components/config/opts.rs
servo/components/constellation/constellation.rs
servo/components/layout/display_list_builder.rs
servo/components/layout_thread/lib.rs
servo/components/script_traits/lib.rs
servo/components/script_traits/script_msg.rs
servo/tests/heartbeats/characterize.py
servo/tests/heartbeats/characterize_android.py
--- a/servo/components/compositing/compositor.rs
+++ b/servo/components/compositing/compositor.rs
@@ -337,39 +337,49 @@ fn initialize_png(width: usize, height: 
         framebuffer_ids: framebuffer_ids,
         renderbuffer_ids: renderbuffer_ids,
         texture_ids: texture_ids,
     }
 }
 
 struct RenderNotifier {
     compositor_proxy: Box<CompositorProxy>,
+    constellation_chan: Sender<ConstellationMsg>,
 }
 
 impl RenderNotifier {
     fn new(compositor_proxy: Box<CompositorProxy>,
-           _: Sender<ConstellationMsg>) -> RenderNotifier {
+           constellation_chan: Sender<ConstellationMsg>) -> RenderNotifier {
         RenderNotifier {
             compositor_proxy: compositor_proxy,
+            constellation_chan: constellation_chan,
         }
     }
 }
 
 impl webrender_traits::RenderNotifier for RenderNotifier {
     fn new_frame_ready(&mut self) {
         self.compositor_proxy.recomposite(CompositingReason::NewWebRenderFrame);
     }
 
     fn new_scroll_frame_ready(&mut self, composite_needed: bool) {
         self.compositor_proxy.send(Msg::NewScrollFrameReady(composite_needed));
     }
 
     fn pipeline_size_changed(&mut self,
-                             _: webrender_traits::PipelineId,
-                             _: Option<webrender_traits::LayoutSize>) {
+                             pipeline_id: webrender_traits::PipelineId,
+                             size: Option<webrender_traits::LayoutSize>) {
+        let pipeline_id = pipeline_id.from_webrender();
+
+        if let Some(size) = size {
+            let msg = ConstellationMsg::FrameSize(pipeline_id, size.to_untyped());
+            if let Err(e) = self.constellation_chan.send(msg) {
+                warn!("Compositor resize to constellation failed ({}).", e);
+            }
+        }
     }
 }
 
 // Used to dispatch functions from webrender to the main thread's event loop.
 struct CompositorThreadDispatcher {
     compositor_proxy: Box<CompositorProxy>
 }
 
--- a/servo/components/config/opts.rs
+++ b/servo/components/config/opts.rs
@@ -568,16 +568,18 @@ pub fn default_opts() -> Opts {
         signpost: false,
     }
 }
 
 pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
     let (app_name, args) = args.split_first().unwrap();
 
     let mut opts = Options::new();
+    opts.optflag("c", "cpu", "CPU painting");
+    opts.optflag("g", "gpu", "GPU painting");
     opts.optopt("o", "output", "Output file", "output.png");
     opts.optopt("s", "size", "Size of tiles", "512");
     opts.optopt("", "device-pixel-ratio", "Device pixels per px", "");
     opts.optopt("t", "threads", "Number of paint threads", "1");
     opts.optflagopt("p", "profile", "Time profiler flag and either a TSV output filename \
         OR an interval for output to Stdout (blank for Stdout with interval of 5s)", "10 \
         OR time.tsv");
     opts.optflagopt("", "profiler-trace-path",
@@ -613,16 +615,17 @@ pub fn from_cmdline_args(args: &[String]
                   "A comma-separated string of debug options. Pass help to show available options.", "");
     opts.optflag("h", "help", "Print this message");
     opts.optopt("", "resources-path", "Path to find static resources", "/home/servo/resources");
     opts.optopt("", "content-process" , "Run as a content process and connect to the given pipe",
                 "servo-ipc-channel.abcdefg");
     opts.optmulti("", "pref",
                   "A preference to set to enable", "dom.mozbrowser.enabled");
     opts.optflag("b", "no-native-titlebar", "Do not use native titlebar");
+    opts.optflag("w", "webrender", "Use webrender backend");
     opts.optopt("G", "graphics", "Select graphics backend (gl or es2)", "gl");
     opts.optopt("", "config-dir",
                     "config directory following xdg spec on linux platform", "");
     opts.optflag("v", "version", "Display servo version information");
 
     let opt_match = match opts.parse(args) {
         Ok(m) => m,
         Err(f) => args_fail(&f.to_string()),
--- a/servo/components/constellation/constellation.rs
+++ b/servo/components/constellation/constellation.rs
@@ -812,16 +812,22 @@ impl<Message, LTF, STF> Constellation<Me
     }
 
     fn handle_request_from_compositor(&mut self, message: FromCompositorMsg) {
         match message {
             FromCompositorMsg::Exit => {
                 debug!("constellation exiting");
                 self.handle_exit();
             }
+            // The compositor discovered the size of a subframe. This needs to be reflected by all
+            // frame trees in the navigation context containing the subframe.
+            FromCompositorMsg::FrameSize(pipeline_id, size) => {
+                debug!("constellation got frame size message");
+                self.handle_frame_size_msg(pipeline_id, &TypedSize2D::from_untyped(&size));
+            }
             FromCompositorMsg::GetFrame(pipeline_id, resp_chan) => {
                 debug!("constellation got get root pipeline message");
                 self.handle_get_frame(pipeline_id, resp_chan);
             }
             FromCompositorMsg::GetPipeline(frame_id, resp_chan) => {
                 debug!("constellation got get root pipeline message");
                 self.handle_get_pipeline(frame_id, resp_chan);
             }
@@ -1078,22 +1084,16 @@ impl<Message, LTF, STF> Constellation<Me
         }
     }
 
     fn handle_request_from_layout(&mut self, message: FromLayoutMsg) {
         match message {
             FromLayoutMsg::ChangeRunningAnimationsState(pipeline_id, animation_state) => {
                 self.handle_change_running_animations_state(pipeline_id, animation_state)
             }
-            // Layout sends new sizes for all subframes. This needs to be reflected by all
-            // frame trees in the navigation context containing the subframe.
-            FromLayoutMsg::FrameSizes(iframe_sizes) => {
-                debug!("constellation got frame size message");
-                self.handle_frame_size_msg(iframe_sizes);
-            }
             FromLayoutMsg::SetCursor(cursor) => {
                 self.handle_set_cursor_msg(cursor)
             }
             FromLayoutMsg::ViewportConstrained(pipeline_id, constraints) => {
                 debug!("constellation got viewport-constrained event message");
                 self.handle_viewport_constrained_msg(pipeline_id, constraints);
             }
         }
@@ -1322,40 +1322,40 @@ impl<Message, LTF, STF> Constellation<Me
             new_pipeline_id: root_pipeline_id,
             url: url.clone(),
             replace: None,
         });
         self.compositor_proxy.send(ToCompositorMsg::ChangePageUrl(root_pipeline_id, url));
     }
 
     fn handle_frame_size_msg(&mut self,
-                             iframe_sizes: Vec<(PipelineId, TypedSize2D<f32, PagePx>)>) {
-        for (pipeline_id, size) in iframe_sizes {
-            let result = {
-                let pipeline = match self.pipelines.get_mut(&pipeline_id) {
-                    Some(pipeline) => pipeline,
-                    None => continue,
-                };
-
-                if pipeline.size == Some(size) {
-                    continue;
-                }
+                             pipeline_id: PipelineId,
+                             size: &TypedSize2D<f32, PagePx>) {
+        let msg = ConstellationControlMsg::Resize(pipeline_id, WindowSizeData {
+            visible_viewport: *size,
+            initial_viewport: *size * ScaleFactor::new(1.0),
+            device_pixel_ratio: self.window_size.device_pixel_ratio,
+        }, WindowSizeType::Initial);
 
-                pipeline.size = Some(size);
-                let msg = ConstellationControlMsg::Resize(pipeline_id, WindowSizeData {
-                    visible_viewport: size,
-                    initial_viewport: size * ScaleFactor::new(1.0),
-                    device_pixel_ratio: self.window_size.device_pixel_ratio,
-                }, WindowSizeType::Initial);
+        // Store the new rect inside the pipeline
+        let result = {
+            // Find the pipeline that corresponds to this rectangle. It's possible that this
+            // pipeline may have already exited before we process this message, so just
+            // early exit if that occurs.
+            match self.pipelines.get_mut(&pipeline_id) {
+                Some(pipeline) => {
+                    pipeline.size = Some(*size);
+                    pipeline.event_loop.send(msg)
+                }
+                None => return,
+            }
+        };
 
-                pipeline.event_loop.send(msg)
-            };
-            if let Err(e) = result {
-                self.handle_send_error(pipeline_id, e);
-            }
+        if let Err(e) = result {
+            self.handle_send_error(pipeline_id, e);
         }
     }
 
     fn handle_subframe_loaded(&mut self, pipeline_id: PipelineId) {
         let (frame_id, parent_id) = match self.pipelines.get(&pipeline_id) {
             Some(pipeline) => match pipeline.parent_info {
                 Some((parent_id, _)) => (pipeline.frame_id, parent_id),
                 None => return warn!("Pipeline {} has no parent.", pipeline_id),
--- a/servo/components/layout/display_list_builder.rs
+++ b/servo/components/layout/display_list_builder.rs
@@ -9,17 +9,17 @@
 //! paint.
 
 #![deny(unsafe_code)]
 
 use app_units::{AU_PER_PX, Au};
 use block::{BlockFlow, BlockStackingContextType};
 use canvas_traits::{CanvasData, CanvasMsg, FromLayoutMsg};
 use context::SharedLayoutContext;
-use euclid::{Point2D, Rect, SideOffsets2D, Size2D, TypedSize2D};
+use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
 use flex::FlexFlow;
 use flow::{BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
 use flow_ref::FlowRef;
 use fragment::{CoordinateSystem, Fragment, ImageFragmentInfo, ScannedTextFragmentInfo};
 use fragment::{SpecificFragmentInfo, TruncatedFragmentInfo};
 use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDisplayItem};
 use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClippingRegion};
 use gfx::display_list::{DisplayItem, DisplayItemMetadata, DisplayList, DisplayListSection};
@@ -27,17 +27,16 @@ use gfx::display_list::{GradientDisplayI
 use gfx::display_list::{LineDisplayItem, OpaqueNode};
 use gfx::display_list::{SolidColorDisplayItem, ScrollRoot, StackingContext, StackingContextType};
 use gfx::display_list::{TextDisplayItem, TextOrientation, WebGLDisplayItem, WebRenderImageInfo};
 use gfx_traits::{ScrollRootId, StackingContextId};
 use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
 use ipc_channel::ipc;
 use list_item::ListItemFlow;
 use model::{self, MaybeAuto};
-use msg::constellation_msg::PipelineId;
 use net_traits::image::base::PixelFormat;
 use net_traits::image_cache_thread::UsePlaceholder;
 use range::Range;
 use servo_config::opts;
 use servo_url::ServoUrl;
 use std::{cmp, f32};
 use std::collections::HashMap;
 use std::default::Default;
@@ -52,17 +51,16 @@ use style::computed_values::filter::Filt
 use style::computed_values::text_shadow::TextShadow;
 use style::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize, WritingMode};
 use style::properties::{self, ServoComputedValues};
 use style::properties::style_structs;
 use style::servo::restyle_damage::REPAINT;
 use style::values::{RGBA, computed};
 use style::values::computed::{AngleOrCorner, Gradient, GradientKind, LengthOrPercentage, LengthOrPercentageOrAuto};
 use style::values::specified::{HorizontalDirection, VerticalDirection};
-use style_traits::PagePx;
 use style_traits::cursor::Cursor;
 use table_cell::CollapsedBordersForCell;
 use webrender_traits::{ColorF, GradientStop, ScrollPolicy};
 
 trait RgbColor {
     fn rgb(r: u8, g: u8, b: u8) -> Self;
 }
 
@@ -102,34 +100,29 @@ pub struct DisplayListBuildState<'a> {
 
     /// The current stacking context id, used to keep track of state when building.
     /// recursively building and processing the display list.
     pub current_stacking_context_id: StackingContextId,
 
     /// The current scroll root id, used to keep track of state when
     /// recursively building and processing the display list.
     pub current_scroll_root_id: ScrollRootId,
-
-    /// Vector containing iframe sizes, used to inform the constellation about
-    /// new iframe sizes
-    pub iframe_sizes: Vec<(PipelineId, TypedSize2D<f32, PagePx>)>,
 }
 
 impl<'a> DisplayListBuildState<'a> {
     pub fn new(shared_layout_context: &'a SharedLayoutContext) -> DisplayListBuildState<'a> {
         DisplayListBuildState {
             shared_layout_context: shared_layout_context,
             root_stacking_context: StackingContext::root(),
             items: HashMap::new(),
             stacking_context_children: HashMap::new(),
             scroll_roots: HashMap::new(),
             processing_scroll_root_element: false,
             current_stacking_context_id: StackingContextId::root(),
             current_scroll_root_id: ScrollRootId::root(),
-            iframe_sizes: Vec::new(),
         }
     }
 
     fn add_display_item(&mut self, display_item: DisplayItem) {
         let items = self.items.entry(display_item.stacking_context_id()).or_insert(Vec::new());
         items.push(display_item);
     }
 
@@ -1445,20 +1438,16 @@ impl FragmentDisplayListBuilding for Fra
                         self.node,
                         self.style.get_cursor(Cursor::Default),
                         DisplayListSection::Content);
                     let item = DisplayItem::Iframe(box IframeDisplayItem {
                         base: base,
                         iframe: fragment_info.pipeline_id,
                     });
 
-                    let size = Size2D::new(item.bounds().size.width.to_f32_px(),
-                                           item.bounds().size.height.to_f32_px());
-                    state.iframe_sizes.push((fragment_info.pipeline_id, TypedSize2D::from_untyped(&size)));
-
                     state.add_display_item(item);
                 }
             }
             SpecificFragmentInfo::Image(ref mut image_fragment) => {
                 // Place the image into the display list.
                 if let Some(ref image) = image_fragment.image {
                     let base = state.create_base_display_item(
                         &stacking_relative_content_box,
--- a/servo/components/layout_thread/lib.rs
+++ b/servo/components/layout_thread/lib.rs
@@ -928,27 +928,16 @@ impl LayoutThread {
                             } else {
                                 root_flow.overflow.scroll.size
                             }
                         };
 
                         let origin = Rect::new(Point2D::new(Au(0), Au(0)), root_size);
                         build_state.root_stacking_context.bounds = origin;
                         build_state.root_stacking_context.overflow = origin;
-
-                        if !build_state.iframe_sizes.is_empty() {
-                            // build_state.iframe_sizes is only used here, so its okay to replace
-                            // it with an empty vector
-                            let iframe_sizes = std::mem::replace(&mut build_state.iframe_sizes, vec![]);
-                            let msg = ConstellationMsg::FrameSizes(iframe_sizes);
-                            if let Err(e) = self.constellation_chan.send(msg) {
-                                warn!("Layout resize to constellation failed ({}).", e);
-                            }
-                        }
-
                         rw_data.display_list = Some(Arc::new(build_state.to_display_list()));
                     }
                     (ReflowGoal::ForScriptQuery, false) => {}
                 }
             }
 
             if data.goal != ReflowGoal::ForDisplay {
                 // Defer the paint step until the next ForDisplay.
--- a/servo/components/script_traits/lib.rs
+++ b/servo/components/script_traits/lib.rs
@@ -691,16 +691,18 @@ pub enum WebDriverCommandMsg {
     TakeScreenshot(PipelineId, IpcSender<Option<Image>>),
 }
 
 /// Messages to the constellation.
 #[derive(Deserialize, Serialize)]
 pub enum ConstellationMsg {
     /// Exit the constellation.
     Exit,
+    /// Inform the constellation of the size of the viewport.
+    FrameSize(PipelineId, Size2D<f32>),
     /// Request that the constellation send the FrameId corresponding to the document
     /// with the provided pipeline id
     GetFrame(PipelineId, IpcSender<Option<FrameId>>),
     /// Request that the constellation send the current pipeline id for the provided frame
     /// id, or for the root frame if this is None, over a provided channel.
     /// Also returns a boolean saying whether the document has finished loading or not.
     GetPipeline(Option<FrameId>, IpcSender<Option<PipelineId>>),
     /// Requests that the constellation inform the compositor of the title of the pipeline
--- a/servo/components/script_traits/script_msg.rs
+++ b/servo/components/script_traits/script_msg.rs
@@ -10,36 +10,33 @@ use IFrameLoadInfoWithData;
 use LayoutControlMsg;
 use LoadData;
 use MozBrowserEvent;
 use WorkerGlobalScopeInit;
 use WorkerScriptLoadOrigin;
 use canvas_traits::CanvasMsg;
 use devtools_traits::{ScriptToDevtoolsControlMsg, WorkerId};
 use euclid::point::Point2D;
-use euclid::size::{Size2D, TypedSize2D};
+use euclid::size::Size2D;
 use gfx_traits::ScrollRootId;
 use ipc_channel::ipc::IpcSender;
 use msg::constellation_msg::{FrameId, PipelineId, TraversalDirection};
 use msg::constellation_msg::{Key, KeyModifiers, KeyState};
 use net_traits::CoreResourceMsg;
 use net_traits::storage_thread::StorageType;
 use offscreen_gl_context::{GLContextAttributes, GLLimits};
 use servo_url::ServoUrl;
-use style_traits::PagePx;
 use style_traits::cursor::Cursor;
 use style_traits::viewport::ViewportConstraints;
 
 /// 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 pipeline's viewport.
-    FrameSizes(Vec<(PipelineId, TypedSize2D<f32, PagePx>)>),
     /// Requests that the constellation inform the compositor of the a cursor change.
     SetCursor(Cursor),
     /// Notifies the constellation that the viewport has been constrained in some manner
     ViewportConstrained(PipelineId, ViewportConstraints),
 }
 
 /// Whether a DOM event was prevented by web content
 #[derive(Deserialize, Serialize)]
--- a/servo/tests/heartbeats/characterize.py
+++ b/servo/tests/heartbeats/characterize.py
@@ -205,16 +205,19 @@ def main():
     # Parsing the input of the script
     parser = argparse.ArgumentParser(description="Characterize Servo timing and energy behavior")
     parser.add_argument("-b", "--benchmark",
                         default=benchmark,
                         help="Gets the benchmark, for example \"-b http://www.example.com\"")
     parser.add_argument("-d", "--debug",
                         action='store_true',
                         help="Use debug build instead of release build")
+    parser.add_argument("-w", "--webrender",
+                        action='store_true',
+                        help="Use webrender backend")
     parser.add_argument("-l", "--max_layout_threads",
                         help="Specify the maximum number of threads for layout, for example \"-l 5\"")
     parser.add_argument("-o", "--output",
                         help="Specify the log output directory, for example \"-o heartbeat_logs\"")
     parser.add_argument("-p", "--profile",
                         default=60,
                         help="Profiler output interval, for example \"-p 60\"")
     parser.add_argument("-s", "--single",
@@ -225,16 +228,18 @@ def main():
                         type=int,
                         help="Number of trials to run for each configuration, for example \"-t 1\"")
 
     args = parser.parse_args()
     if args.benchmark:
         benchmark = args.benchmark
     if args.debug:
         build_target = "debug"
+    if args.webrender:
+        renderer = "-w"
     if args.max_layout_threads:
         max_layout_threads = int(args.max_layout_threads)
     if args.output:
         output_dir = args.output
     if args.profile:
         profile = args.profile
     if args.single:
         single = True
--- a/servo/tests/heartbeats/characterize_android.py
+++ b/servo/tests/heartbeats/characterize_android.py
@@ -80,27 +80,32 @@ def main():
     # Default profile interval
     profile = 60
 
     # Parsing the input of the script
     parser = argparse.ArgumentParser(description="Characterize Servo timing and energy behavior on Android")
     parser.add_argument("-b", "--benchmark",
                         default=benchmark,
                         help="Gets the benchmark, for example \"-b http://www.example.com\"")
+    parser.add_argument("-w", "--webrender",
+                        action='store_true',
+                        help="Use webrender backend")
     parser.add_argument("-l", "--layout_threads",
                         help="Specify the number of threads for layout, for example \"-l 5\"")
     parser.add_argument("-o", "--output",
                         help="Specify the log output directory, for example \"-o heartbeat_logs\"")
     parser.add_argument("-p", "--profile",
                         default=60,
                         help="Profiler output interval, for example \"-p 60\"")
 
     args = parser.parse_args()
     if args.benchmark:
         benchmark = args.benchmark
+    if args.webrender:
+        renderer = "-w"
     if args.layout_threads:
         layout_threads = int(args.layout_threads)
     if args.output:
         output_dir = args.output
     if args.profile:
         profile = args.profile
 
     if os.path.exists(output_dir):