aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/main/compositing/compositor.rs24
-rw-r--r--src/components/main/compositing/compositor_task.rs5
-rw-r--r--src/components/main/compositing/headless.rs2
-rw-r--r--src/components/main/constellation.rs13
-rw-r--r--src/components/msg/constellation_msg.rs3
-rw-r--r--src/components/script/script_task.rs8
6 files changed, 43 insertions, 12 deletions
diff --git a/src/components/main/compositing/compositor.rs b/src/components/main/compositing/compositor.rs
index d6abea53368..99a4ef88c2a 100644
--- a/src/components/main/compositing/compositor.rs
+++ b/src/components/main/compositing/compositor.rs
@@ -31,7 +31,7 @@ use layers::rendergl::RenderContext;
use layers::scene::Scene;
use opengles::gl2;
use png;
-use servo_msg::compositor_msg::{Epoch, IdleRenderState, LayerBufferSet, RenderState};
+use servo_msg::compositor_msg::{Blank, Epoch, FinishedLoading, IdleRenderState, LayerBufferSet, ReadyState, RenderState};
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, NavigateMsg, ResizedWindowMsg, LoadUrlMsg, PipelineId};
use servo_msg::constellation_msg;
use servo_util::time::{profile, ProfilerChan, Timer};
@@ -84,6 +84,14 @@ pub struct IOCompositor {
/// The time of the last zoom action has started.
zoom_time: f64,
+ /// Current display/reflow status of the page
+ ready_state: ReadyState,
+
+ /// Whether the page being rendered has loaded completely.
+ /// Differs from ReadyState because we can finish loading (ready)
+ /// many times for a single page.
+ load_complete: bool,
+
/// The command line option flags.
opts: Opts,
@@ -132,6 +140,8 @@ impl IOCompositor {
world_zoom: 1f32,
zoom_action: false,
zoom_time: 0f64,
+ ready_state: Blank,
+ load_complete: false,
compositor_layer: None,
constellation_chan: constellation_chan,
profiler_chan: profiler_chan,
@@ -222,6 +232,7 @@ impl IOCompositor {
(Some(ChangeReadyState(ready_state)), false) => {
self.window.set_ready_state(ready_state);
+ self.ready_state = ready_state;
}
(Some(ChangeRenderState(render_state)), false) => {
@@ -269,6 +280,10 @@ impl IOCompositor {
self.scroll_fragment_to_point(id, point);
}
+ (Some(LoadComplete(..)), false) => {
+ self.load_complete = true;
+ }
+
// When we are shutting_down, we need to avoid performing operations
// such as Paint that may crash because we have begun tearing down
// the rest of our resources.
@@ -540,8 +555,9 @@ impl IOCompositor {
}
}
- fn on_load_url_window_event(&self, url_string: ~str) {
+ fn on_load_url_window_event(&mut self, url_string: ~str) {
debug!("osmain: loading URL `{:s}`", url_string);
+ self.load_complete = false;
let root_pipeline_id = match self.compositor_layer {
Some(ref layer) => layer.pipeline.id.clone(),
None => fail!("Compositor: Received LoadUrlWindowEvent without initialized compositor layers"),
@@ -650,8 +666,8 @@ impl IOCompositor {
// Render to PNG. We must read from the back buffer (ie, before
// self.window.present()) as OpenGL ES 2 does not have glReadBuffer().
- let write_png = self.opts.output_file.is_some();
- if write_png {
+ if self.load_complete && self.ready_state == FinishedLoading
+ && self.opts.output_file.is_some() {
let (width, height) = (self.window_size.width as uint, self.window_size.height as uint);
let path = from_str::<Path>(*self.opts.output_file.get_ref()).unwrap();
let mut pixels = gl2::read_pixels(0, 0,
diff --git a/src/components/main/compositing/compositor_task.rs b/src/components/main/compositing/compositor_task.rs
index 87f9a6b90ca..5cbcf45e8d3 100644
--- a/src/components/main/compositing/compositor_task.rs
+++ b/src/components/main/compositing/compositor_task.rs
@@ -21,6 +21,8 @@ use servo_util::time::ProfilerChan;
use std::comm::{Chan, SharedChan, Port};
use std::num::Orderable;
+use extra::url::Url;
+
#[cfg(target_os="linux")]
use azure::azure_hl;
@@ -151,6 +153,9 @@ pub enum Msg {
SetIds(SendableFrameTree, Chan<()>, ConstellationChan),
SetUnRenderedColor(PipelineId, Color),
+
+ /// The load of a page for a given URL has completed.
+ LoadComplete(PipelineId, Url),
}
pub enum CompositorMode {
diff --git a/src/components/main/compositing/headless.rs b/src/components/main/compositing/headless.rs
index 7cc299fd88d..43455e0d0c4 100644
--- a/src/components/main/compositing/headless.rs
+++ b/src/components/main/compositing/headless.rs
@@ -63,7 +63,7 @@ impl NullCompositor {
NewLayer(..) | SetLayerPageSize(..) | SetLayerClipRect(..) | DeleteLayer(..) |
Paint(..) | InvalidateRect(..) | ChangeReadyState(..) | ChangeRenderState(..)|
- ScrollFragmentPoint(..) | SetUnRenderedColor(..)
+ ScrollFragmentPoint(..) | SetUnRenderedColor(..) | LoadComplete(..)
=> ()
}
}
diff --git a/src/components/main/constellation.rs b/src/components/main/constellation.rs
index 81e9e8bb4aa..761abfb6164 100644
--- a/src/components/main/constellation.rs
+++ b/src/components/main/constellation.rs
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use compositing::{CompositorChan, SetIds, SetLayerClipRect, ShutdownComplete};
+use compositing::{CompositorChan, LoadComplete, SetIds, SetLayerClipRect, ShutdownComplete};
use extra::url::Url;
use geom::rect::Rect;
@@ -12,8 +12,9 @@ use pipeline::{Pipeline, CompositionPipeline};
use script::script_task::{ResizeMsg, ResizeInactiveMsg};
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, FailureMsg, FrameRectMsg};
use servo_msg::constellation_msg::{IFrameSandboxState, IFrameUnsandboxed, InitLoadUrlMsg};
-use servo_msg::constellation_msg::{LoadIframeUrlMsg, LoadUrlMsg, Msg, NavigateMsg, NavigationType};
-use servo_msg::constellation_msg::{PipelineId, RendererReadyMsg, ResizedWindowMsg, SubpageId};
+use servo_msg::constellation_msg::{LoadCompleteMsg, LoadIframeUrlMsg, LoadUrlMsg, Msg, NavigateMsg};
+use servo_msg::constellation_msg::{NavigationType, PipelineId, RendererReadyMsg, ResizedWindowMsg};
+use servo_msg::constellation_msg::SubpageId;
use servo_msg::constellation_msg;
use servo_net::image_cache_task::{ImageCacheTask, ImageCacheTaskClient};
use servo_net::resource_task::ResourceTask;
@@ -345,6 +346,12 @@ impl Constellation {
debug!("constellation got URL load message");
self.handle_load_url_msg(source_id, url);
}
+ // A page loaded through one of several methods above has completed all parsing,
+ // script, and reflow messages have been sent.
+ LoadCompleteMsg(pipeline_id, url) => {
+ debug!("constellation got load complete message");
+ self.compositor_chan.send(LoadComplete(pipeline_id, url));
+ }
// Handle a forward or back request
NavigateMsg(direction) => {
debug!("constellation got navigation message");
diff --git a/src/components/msg/constellation_msg.rs b/src/components/msg/constellation_msg.rs
index 0aea8963c92..74c2c282d6f 100644
--- a/src/components/msg/constellation_msg.rs
+++ b/src/components/msg/constellation_msg.rs
@@ -26,11 +26,12 @@ pub enum IFrameSandboxState {
IFrameUnsandboxed
}
-/// Messages from the compositor to the constellation.
+/// Messages from the compositor and script to the constellation.
pub enum Msg {
ExitMsg,
FailureMsg(PipelineId, Option<SubpageId>),
InitLoadUrlMsg(Url),
+ LoadCompleteMsg(PipelineId, Url),
FrameRectMsg(PipelineId, SubpageId, Rect<f32>),
LoadUrlMsg(PipelineId, Url),
LoadIframeUrlMsg(Url, PipelineId, SubpageId, IFrameSandboxState),
diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs
index 02ffdc49f75..639f0cc15d9 100644
--- a/src/components/script/script_task.rs
+++ b/src/components/script/script_task.rs
@@ -38,8 +38,8 @@ use js::rust::{Compartment, Cx};
use js;
use servo_msg::compositor_msg::{FinishedLoading, Loading, PerformingLayout, ScriptListener};
use servo_msg::constellation_msg::{ConstellationChan, IFrameSandboxed, IFrameUnsandboxed};
-use servo_msg::constellation_msg::{LoadIframeUrlMsg, LoadUrlMsg, NavigationDirection, PipelineId};
-use servo_msg::constellation_msg::{SubpageId};
+use servo_msg::constellation_msg::{LoadIframeUrlMsg, LoadCompleteMsg, LoadUrlMsg, NavigationDirection};
+use servo_msg::constellation_msg::{PipelineId, SubpageId};
use servo_msg::constellation_msg;
use servo_net::image_cache_task::ImageCacheTask;
use servo_net::resource_task::ResourceTask;
@@ -745,7 +745,7 @@ impl ScriptTask {
let fragment = url.fragment.as_ref().map(|ref fragment| fragment.to_owned());
// No more reflow required
- page.url = Some((url, false));
+ page.url = Some((url.clone(), false));
// Receive the JavaScript scripts.
assert!(js_scripts.is_some());
@@ -775,6 +775,8 @@ impl ScriptTask {
window.eventtarget.dispatch_event_with_target(wintarget, Some(doctarget), event);
page.fragment_node = fragment.map_default(None, |fragid| self.find_fragment_node(page, fragid));
+
+ self.constellation_chan.send(LoadCompleteMsg(page.id, url));
}
fn find_fragment_node(&self, page: &mut Page, fragid: ~str) -> Option<AbstractNode> {