aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2015-11-05 04:08:30 +0530
committerbors-servo <lbergstrom+bors@mozilla.com>2015-11-05 04:08:30 +0530
commitc78da15abbffd223290300b6b985d65cd6f03d08 (patch)
tree7e074e6e1aac7fef676966ceb0ee4a367b1b002f /components
parent50e0c36eeb8cd52b90dba24b5b3692abc25d8d4d (diff)
parent19a1e57c9019d363a5391c5a93722b4206c95440 (diff)
downloadservo-c78da15abbffd223290300b6b985d65cd6f03d08.tar.gz
servo-c78da15abbffd223290300b6b985d65cd6f03d08.zip
Auto merge of #8314 - jdm:timeoutinvestigations, r=metajack
Investigations for #7787 I'm just going to keep throwing stuff at try, because running directly on the builders isn't yielding results. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8314) <!-- Reviewable:end -->
Diffstat (limited to 'components')
-rw-r--r--components/compositing/compositor.rs75
-rw-r--r--components/compositing/constellation.rs31
-rw-r--r--components/util/opts.rs13
3 files changed, 93 insertions, 26 deletions
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index e8576e70e57..a0cc3059bc6 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -55,6 +55,24 @@ use util::opts;
use util::print_tree::PrintTree;
use windowing::{self, MouseWindowEvent, WindowEvent, WindowMethods, WindowNavigateMsg};
+#[derive(Debug)]
+enum UnableToComposite {
+ NoContext,
+ WindowUnprepared,
+ NotReadyToPaintImage(NotReadyToPaint),
+}
+
+#[derive(Debug)]
+enum NotReadyToPaint {
+ LayerHasOutstandingPaintMessages,
+ MissingRoot,
+ PendingSubpages(usize),
+ AnimationsRunning,
+ AnimationCallbacksRunning,
+ JustNotifiedConstellation,
+ WaitingOnConstellation,
+}
+
const BUFFER_MAP_SIZE: usize = 10000000;
// Default viewport constraints
@@ -211,7 +229,7 @@ pub struct ScrollEvent {
cursor: TypedPoint2D<DevicePixel, i32>,
}
-#[derive(PartialEq)]
+#[derive(PartialEq, Debug)]
enum CompositionRequest {
NoCompositingNecessary,
CompositeOnScrollTimeout(u64),
@@ -579,8 +597,14 @@ impl<Window: WindowMethods> IOCompositor<Window> {
assert!(self.ready_to_save_state == ReadyState::WaitingForConstellationReply);
if is_ready {
self.ready_to_save_state = ReadyState::ReadyToSaveImage;
+ if opts::get().is_running_problem_test {
+ println!("ready to save image!");
+ }
} else {
self.ready_to_save_state = ReadyState::Unknown;
+ if opts::get().is_running_problem_test {
+ println!("resetting ready_to_save_state!");
+ }
}
self.composite_if_necessary(CompositingReason::Headless);
}
@@ -1678,7 +1702,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
/// Query the constellation to see if the current compositor
/// output matches the current frame tree output, and if the
/// associated script tasks are idle.
- fn is_ready_to_paint_image_output(&mut self) -> bool {
+ fn is_ready_to_paint_image_output(&mut self) -> Result<(), NotReadyToPaint> {
match self.ready_to_save_state {
ReadyState::Unknown => {
// Unsure if the output image is stable.
@@ -1689,17 +1713,17 @@ impl<Window: WindowMethods> IOCompositor<Window> {
match self.scene.root {
Some(ref root_layer) => {
if self.does_layer_have_outstanding_paint_messages(root_layer) {
- return false;
+ return Err(NotReadyToPaint::LayerHasOutstandingPaintMessages);
}
}
None => {
- return false;
+ return Err(NotReadyToPaint::MissingRoot);
}
}
// Check if there are any pending frames. If so, the image is not stable yet.
if self.pending_subpages.len() > 0 {
- return false
+ return Err(NotReadyToPaint::PendingSubpages(self.pending_subpages.len()));
}
// Collect the currently painted epoch of each pipeline that is
@@ -1710,8 +1734,11 @@ impl<Window: WindowMethods> IOCompositor<Window> {
for (id, details) in &self.pipeline_details {
// If animations are currently running, then don't bother checking
// with the constellation if the output image is stable.
- if details.animations_running || details.animation_callbacks_running {
- return false;
+ if details.animations_running {
+ return Err(NotReadyToPaint::AnimationsRunning);
+ }
+ if details.animation_callbacks_running {
+ return Err(NotReadyToPaint::AnimationCallbacksRunning);
}
pipeline_epochs.insert(*id, details.current_epoch);
@@ -1722,12 +1749,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
let ConstellationChan(ref chan) = self.constellation_chan;
chan.send(ConstellationMsg::IsReadyToSaveImage(pipeline_epochs)).unwrap();
self.ready_to_save_state = ReadyState::WaitingForConstellationReply;
- false
+ Err(NotReadyToPaint::JustNotifiedConstellation)
}
ReadyState::WaitingForConstellationReply => {
// If waiting on a reply from the constellation to the last
// query if the image is stable, then assume not ready yet.
- false
+ Err(NotReadyToPaint::WaitingOnConstellation)
}
ReadyState::ReadyToSaveImage => {
// Constellation has replied at some point in the past
@@ -1735,8 +1762,9 @@ impl<Window: WindowMethods> IOCompositor<Window> {
// for saving.
// Reset the flag so that we check again in the future
// TODO: only reset this if we load a new document?
+ println!("was ready to save, resetting ready_to_save_state");
self.ready_to_save_state = ReadyState::Unknown;
- true
+ Ok(())
}
}
}
@@ -1746,8 +1774,10 @@ impl<Window: WindowMethods> IOCompositor<Window> {
let composited = self.composite_specific_target(target);
if composited.is_ok() &&
(opts::get().output_file.is_some() || opts::get().exit_after_load) {
- debug!("Shutting down the Constellation after generating an output file or exit flag specified");
+ println!("Shutting down the Constellation after generating an output file or exit flag specified");
self.start_shutting_down();
+ } else if composited.is_err() && opts::get().is_running_problem_test {
+ println!("not ready to composite: {:?}", composited.err().unwrap());
}
}
@@ -1756,26 +1786,28 @@ impl<Window: WindowMethods> IOCompositor<Window> {
/// for some reason. If CompositeTarget is Window or Png no image data is returned;
/// in the latter case the image is written directly to a file. If CompositeTarget
/// is WindowAndPng Ok(Some(png::Image)) is returned.
- pub fn composite_specific_target(&mut self, target: CompositeTarget) -> Result<Option<Image>, ()> {
+ pub fn composite_specific_target(&mut self, target: CompositeTarget) -> Result<Option<Image>, UnableToComposite> {
if !self.context.is_some() {
- return Err(())
+ return Err(UnableToComposite::NoContext)
}
let (width, height) =
(self.window_size.width.get() as usize, self.window_size.height.get() as usize);
if !self.window.prepare_for_composite(width, height) {
- return Err(())
+ return Err(UnableToComposite::WindowUnprepared)
}
match target {
CompositeTarget::WindowAndPng | CompositeTarget::PngFile => {
- if !self.is_ready_to_paint_image_output() {
- return Err(())
+ if let Err(result) = self.is_ready_to_paint_image_output() {
+ return Err(UnableToComposite::NotReadyToPaintImage(result))
}
}
CompositeTarget::Window => {
- if opts::get().exit_after_load && !self.is_ready_to_paint_image_output() {
- return Err(())
+ if opts::get().exit_after_load {
+ if let Err(result) = self.is_ready_to_paint_image_output() {
+ return Err(UnableToComposite::NotReadyToPaintImage(result))
+ }
}
}
}
@@ -1892,7 +1924,12 @@ impl<Window: WindowMethods> IOCompositor<Window> {
fn composite_if_necessary(&mut self, reason: CompositingReason) {
if self.composition_request == CompositionRequest::NoCompositingNecessary {
+ if opts::get().is_running_problem_test {
+ println!("updating composition_request ({:?})", reason);
+ }
self.composition_request = CompositionRequest::CompositeNow(reason)
+ } else if opts::get().is_running_problem_test {
+ println!("composition_request is already {:?}", self.composition_request);
}
}
@@ -2145,7 +2182,7 @@ impl<Window> CompositorEventListener for IOCompositor<Window> where Window: Wind
}
/// Why we performed a composite. This is used for debugging.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, PartialEq, Debug)]
pub enum CompositingReason {
/// We hit the scroll timeout and are therefore drawing unrendered content.
HitScrollTimeout,
diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs
index d578fac7832..adfb9fb5b21 100644
--- a/components/compositing/constellation.rs
+++ b/components/compositing/constellation.rs
@@ -57,6 +57,16 @@ use util::geometry::PagePx;
use util::task::spawn_named;
use util::{opts, prefs};
+#[derive(Debug, PartialEq)]
+enum ReadyToSave {
+ NoRootFrame,
+ WebFontNotLoaded,
+ DocumentLoading,
+ EpochMismatch,
+ PipelineUnknown,
+ Ready,
+}
+
/// Maintains the pipelines and navigation context and grants permission to composite.
///
/// It is parameterized over a `LayoutTaskFactory` and a
@@ -516,7 +526,14 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
}
ConstellationMsg::IsReadyToSaveImage(pipeline_states) => {
let is_ready = self.handle_is_ready_to_save_image(pipeline_states);
+ if opts::get().is_running_problem_test {
+ println!("got ready to save image query, result is {:?}", is_ready);
+ }
+ let is_ready = is_ready == ReadyToSave::Ready;
self.compositor_proxy.send(CompositorMsg::IsReadyToSaveImageReply(is_ready));
+ if opts::get().is_running_problem_test {
+ println!("sent response");
+ }
}
ConstellationMsg::RemoveIFrame(pipeline_id) => {
debug!("constellation got remove iframe message");
@@ -1188,11 +1205,11 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
/// to check if the output image is "stable" and can be written as a screenshot
/// for reftests.
fn handle_is_ready_to_save_image(&mut self,
- pipeline_states: HashMap<PipelineId, Epoch>) -> bool {
+ pipeline_states: HashMap<PipelineId, Epoch>) -> ReadyToSave {
// If there is no root frame yet, the initial page has
// not loaded, so there is nothing to save yet.
if self.root_frame_id.is_none() {
- return false;
+ return ReadyToSave::NoRootFrame;
}
// Step through the current frame tree, checking that the script
@@ -1215,7 +1232,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
let msg = LayoutControlMsg::GetWebFontLoadState(sender);
pipeline.layout_chan.0.send(msg).unwrap();
if receiver.recv().unwrap() {
- return false;
+ return ReadyToSave::WebFontNotLoaded;
}
// Synchronously query the script task for this pipeline
@@ -1225,7 +1242,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
pipeline.script_chan.send(msg).unwrap();
let result = receiver.recv().unwrap();
if result == ScriptState::DocumentLoading {
- return false;
+ return ReadyToSave::DocumentLoading;
}
// Check the visible rectangle for this pipeline. If the constellation has received a
@@ -1253,20 +1270,20 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
layout_chan.send(LayoutControlMsg::GetCurrentEpoch(sender)).unwrap();
let layout_task_epoch = receiver.recv().unwrap();
if layout_task_epoch != *compositor_epoch {
- return false;
+ return ReadyToSave::EpochMismatch;
}
}
None => {
// The compositor doesn't know about this pipeline yet.
// Assume it hasn't rendered yet.
- return false;
+ return ReadyToSave::PipelineUnknown;
}
}
}
}
// All script tasks are idle and layout epochs match compositor, so output image!
- true
+ ReadyToSave::Ready
}
// Close a frame (and all children)
diff --git a/components/util/opts.rs b/components/util/opts.rs
index 31e3eb899ea..fb68c24964d 100644
--- a/components/util/opts.rs
+++ b/components/util/opts.rs
@@ -23,6 +23,8 @@ use url::{self, Url};
/// Global flags for Servo, currently set on the command line.
#[derive(Clone)]
pub struct Opts {
+ pub is_running_problem_test: bool,
+
/// The initial URL to load.
pub url: Option<Url>,
@@ -397,6 +399,7 @@ const DEFAULT_USER_AGENT: UserAgent = UserAgent::Desktop;
pub fn default_opts() -> Opts {
Opts {
+ is_running_problem_test: false,
url: Some(Url::parse("about:blank").unwrap()),
paint_threads: 1,
gpu_painting: false,
@@ -518,6 +521,15 @@ pub fn from_cmdline_args(args: &[String]) {
} else {
homepage_pref.as_string()
};
+ let is_running_problem_test =
+ url_opt
+ .as_ref()
+ .map(|url|
+ url.starts_with("http://web-platform.test:8000/2dcontext/drawing-images-to-the-canvas/") ||
+ url.starts_with("http://web-platform.test:8000/_mozilla/mozilla/canvas/") ||
+ url.starts_with("http://web-platform.test:8000/_mozilla/css/canvas_over_area.html"))
+ .unwrap_or(false);
+
let url = match url_opt {
Some(url_string) => {
parse_url_or_filename(&cwd, url_string)
@@ -605,6 +617,7 @@ pub fn from_cmdline_args(args: &[String]) {
}).collect();
let opts = Opts {
+ is_running_problem_test: is_running_problem_test,
url: Some(url),
paint_threads: paint_threads,
gpu_painting: gpu_painting,