зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #1597 - Ensure ref tests wait to write their PNG until the page has fully loaded and reflowed (from larsbergstrom:add_page_loaded); r=pcwalton
Add a LoadComplete message so that script informs the constellation, which can then inform the compositor (and anyone else, later) about the completion of loading a page. This is important for ref tests, which should not emit a PNG until load has completed, even if we perform a composite before then. Note that we must *also* wait for the `ready_state` to indicate that additionally layout has completed any associated reflow with the page, otherwise we could get the `LoadComplete` while the final reflow is still in progress and thus would write out the `n-1`'th reflow result. r? @pcwalton Source-Repo: https://github.com/servo/servo Source-Revision: e9a0c8184f1af460583fe5ab2615e01d08ffc22f
This commit is contained in:
Родитель
acce5f3c6f
Коммит
77a80051d5
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -63,7 +63,7 @@ impl NullCompositor {
|
|||
|
||||
NewLayer(..) | SetLayerPageSize(..) | SetLayerClipRect(..) | DeleteLayer(..) |
|
||||
Paint(..) | InvalidateRect(..) | ChangeReadyState(..) | ChangeRenderState(..)|
|
||||
ScrollFragmentPoint(..) | SetUnRenderedColor(..)
|
||||
ScrollFragmentPoint(..) | SetUnRenderedColor(..) | LoadComplete(..)
|
||||
=> ()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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> {
|
||||
|
|
Загрузка…
Ссылка в новой задаче