diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/main/compositing/compositor.rs | 24 | ||||
-rw-r--r-- | src/components/main/compositing/compositor_task.rs | 5 | ||||
-rw-r--r-- | src/components/main/compositing/headless.rs | 2 | ||||
-rw-r--r-- | src/components/main/constellation.rs | 13 | ||||
-rw-r--r-- | src/components/msg/constellation_msg.rs | 3 | ||||
-rw-r--r-- | src/components/script/script_task.rs | 8 |
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> { |