Bug 1470901 - WR patch
MozReview-Commit-ID: 2Gq0Z9YeOeY
--- a/gfx/webrender/src/render_backend.rs
+++ b/gfx/webrender/src/render_backend.rs
@@ -1058,38 +1058,42 @@ impl RenderBackend {
// scroll at the same time. we should keep track of the fact that we skipped
// composition here and do it as soon as we receive the scene.
op.render = false;
op.composite = false;
}
debug_assert!(op.render || !op.composite);
+ let mut render_time = None;
if op.render && doc.has_pixels() {
profile_scope!("generate frame");
*frame_counter += 1;
// borrow ck hack for profile_counters
let (pending_update, rendered_document) = {
let _timer = profile_counters.total_time.timer();
+ let render_start_time = precise_time_ns();
let rendered_document = doc.render(
&mut self.resource_cache,
&mut self.gpu_cache,
&mut profile_counters.resources,
op.build || has_built_scene,
);
debug!("generated frame for document {:?} with {} passes",
document_id, rendered_document.frame.passes.len());
let msg = ResultMsg::UpdateGpuCache(self.gpu_cache.extract_updates());
self.result_tx.send(msg).unwrap();
+ render_time = Some(precise_time_ns() - render_start_time);
+
let pending_update = self.resource_cache.pending_updates();
(pending_update, rendered_document)
};
let msg = ResultMsg::PublishPipelineInfo(doc.updated_pipeline_info());
self.result_tx.send(msg).unwrap();
// Publish the frame
@@ -1106,17 +1110,17 @@ impl RenderBackend {
// there's no pixels. We still want to pretend to render and request
// a composite to make sure that the callbacks (particularly the
// new_frame_ready callback below) has the right flags.
let msg = ResultMsg::PublishPipelineInfo(doc.updated_pipeline_info());
self.result_tx.send(msg).unwrap();
}
if transaction_msg.generate_frame {
- self.notifier.new_frame_ready(document_id, op.scroll, op.composite);
+ self.notifier.new_frame_ready(document_id, op.scroll, op.composite, render_time);
}
}
#[cfg(not(feature = "debugger"))]
fn get_docs_for_debugger(&self) -> String {
String::new()
}
@@ -1405,14 +1409,14 @@ impl RenderBackend {
id,
render_doc,
self.resource_cache.pending_updates(),
profile_counters.clone(),
);
self.result_tx.send(msg_publish).unwrap();
profile_counters.reset();
- self.notifier.new_frame_ready(id, false, true);
+ self.notifier.new_frame_ready(id, false, true, None);
self.documents.insert(id, doc);
}
}
}
--- a/gfx/webrender/src/renderer.rs
+++ b/gfx/webrender/src/renderer.rs
@@ -4012,21 +4012,21 @@ pub trait ThreadListener {
/// Allows callers to hook in at certain points of the async scene build. These
/// functions are all called from the scene builder thread.
pub trait SceneBuilderHooks {
/// This is called exactly once, when the scene builder thread is started
/// and before it processes anything.
fn register(&self);
/// This is called before each scene swap occurs.
- fn pre_scene_swap(&self);
+ fn pre_scene_swap(&self, scenebuild_time: u64);
/// This is called after each scene swap occurs. The PipelineInfo contains
/// the updated epochs and pipelines removed in the new scene compared to
/// the old scene.
- fn post_scene_swap(&self, info: PipelineInfo);
+ fn post_scene_swap(&self, info: PipelineInfo, sceneswap_time: u64);
/// This is called after a resource update operation on the scene builder
/// thread, in the case where resource updates were applied without a scene
/// build.
fn post_resource_update(&self);
/// This is a generic callback which provides an opportunity to run code
/// on the scene builder thread. This is called as part of the main message
/// loop of the scene builder thread, but outside of any specific message
/// handler.
--- a/gfx/webrender/src/scene_builder.rs
+++ b/gfx/webrender/src/scene_builder.rs
@@ -8,16 +8,17 @@ use display_list_flattener::build_scene;
use frame_builder::{FrameBuilderConfig, FrameBuilder};
use clip_scroll_tree::ClipScrollTree;
use internal_types::FastHashSet;
use resource_cache::FontInstanceMap;
use render_backend::DocumentView;
use renderer::{PipelineInfo, SceneBuilderHooks};
use scene::Scene;
use std::sync::mpsc::{channel, Receiver, Sender};
+use time::precise_time_ns;
// Message from render backend to scene builder.
pub enum SceneBuilderRequest {
Transaction {
document_id: DocumentId,
scene: Option<SceneRequest>,
resource_updates: Vec<ResourceUpdate>,
frame_ops: Vec<FrameMsg>,
@@ -132,16 +133,17 @@ impl SceneBuilder {
}
SceneBuilderRequest::Transaction {
document_id,
scene,
resource_updates,
frame_ops,
render,
} => {
+ let scenebuild_start_time = precise_time_ns();
let built_scene = scene.map(|request|{
build_scene(&self.config, request)
});
// TODO: pre-rasterization.
// We only need the pipeline info and the result channel if we
// have a hook callback *and* if this transaction actually built
@@ -151,39 +153,42 @@ impl SceneBuilder {
let (pipeline_info, result_tx, result_rx) = match (&self.hooks, &built_scene) {
(&Some(ref hooks), &Some(ref built)) => {
let info = PipelineInfo {
epochs: built.scene.pipeline_epochs.clone(),
removed_pipelines: built.removed_pipelines.clone(),
};
let (tx, rx) = channel();
- hooks.pre_scene_swap();
+ let scenebuild_time = precise_time_ns() - scenebuild_start_time;
+ hooks.pre_scene_swap(scenebuild_time);
(Some(info), Some(tx), Some(rx))
}
_ => (None, None, None),
};
+ let sceneswap_start_time = precise_time_ns();
let has_resources_updates = !resource_updates.is_empty();
self.tx.send(SceneBuilderResult::Transaction {
document_id,
built_scene,
resource_updates,
frame_ops,
render,
result_tx,
}).unwrap();
let _ = self.api_tx.send(ApiMsg::WakeUp);
if let Some(pipeline_info) = pipeline_info {
// Block until the swap is done, then invoke the hook.
let swap_result = result_rx.unwrap().recv();
- self.hooks.as_ref().unwrap().post_scene_swap(pipeline_info);
+ let sceneswap_time = precise_time_ns() - sceneswap_start_time;
+ self.hooks.as_ref().unwrap().post_scene_swap(pipeline_info, sceneswap_time);
// Once the hook is done, allow the RB thread to resume
match swap_result {
Ok(SceneSwapResult::Complete(resume_tx)) => {
resume_tx.send(()).ok();
},
_ => (),
};
} else if has_resources_updates {
--- a/gfx/webrender_api/src/api.rs
+++ b/gfx/webrender_api/src/api.rs
@@ -1098,14 +1098,14 @@ pub struct PropertyValue<T> {
pub struct DynamicProperties {
pub transforms: Vec<PropertyValue<LayoutTransform>>,
pub floats: Vec<PropertyValue<f32>>,
}
pub trait RenderNotifier: Send {
fn clone(&self) -> Box<RenderNotifier>;
fn wake_up(&self);
- fn new_frame_ready(&self, DocumentId, scrolled: bool, composite_needed: bool);
+ fn new_frame_ready(&self, DocumentId, scrolled: bool, composite_needed: bool, render_time_ns: Option<u64>);
fn external_event(&self, _evt: ExternalEvent) {
unimplemented!()
}
fn shut_down(&self) {}
}