servo/components/metrics/lib.rs
Fernando Jiménez Moreno 585d0e52af PWM tests
2017-07-21 15:10:04 +02:00

125 lines
4 KiB
Rust

/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
extern crate gfx;
extern crate profile_traits;
extern crate servo_config;
extern crate time;
use gfx::display_list::{DisplayItem, DisplayList};
use profile_traits::time::{ProfilerChan, ProfilerCategory, send_profile_data};
use profile_traits::time::TimerMetadata;
use servo_config::opts;
use std::cell::Cell;
pub trait ProfilerMetadataFactory {
fn new_metadata(&self) -> Option<TimerMetadata>;
}
macro_rules! make_time_setter(
( $attr:ident, $func:ident, $category:ident, $label:expr ) => (
fn $func<T>(&self, profiler_metadata_factory: &T)
where T: ProfilerMetadataFactory {
let navigation_start = match self.navigation_start {
Some(time) => time,
None => {
println!("Trying to set metric before navigation start");
return;
}
};
let now = time::precise_time_ns() as f64;
let time = now - navigation_start;
self.$attr.set(Some(time));
// Send the metric to the time profiler.
send_profile_data(ProfilerCategory::$category,
profiler_metadata_factory.new_metadata(),
&self.time_profiler_chan,
time as u64, time as u64, 0, 0);
// Print the metric to console if the print-pwm option was given.
if opts::get().print_pwm {
println!("{:?} {:?}", $label, time);
}
}
);
);
pub struct PaintTimeMetrics {
navigation_start: Option<f64>,
first_paint: Cell<Option<f64>>,
first_contentful_paint: Cell<Option<f64>>,
time_profiler_chan: ProfilerChan,
}
impl PaintTimeMetrics {
pub fn new(time_profiler_chan: ProfilerChan)
-> PaintTimeMetrics {
PaintTimeMetrics {
navigation_start: None,
first_paint: Cell::new(None),
first_contentful_paint: Cell::new(None),
time_profiler_chan: time_profiler_chan,
}
}
pub fn set_navigation_start(&mut self, time: f64) {
self.navigation_start = Some(time);
}
make_time_setter!(first_paint, set_first_paint,
TimeToFirstPaint,
"first-paint");
make_time_setter!(first_contentful_paint, set_first_contentful_paint,
TimeToFirstContentfulPaint,
"first-contentful-paint");
pub fn maybe_set_first_paint<T>(&self, profiler_metadata_factory: &T)
where T: ProfilerMetadataFactory {
{
if self.first_paint.get().is_some() {
return;
}
}
self.set_first_paint(profiler_metadata_factory);
}
pub fn maybe_set_first_contentful_paint<T>(&self, profiler_metadata_factory: &T,
display_list: &DisplayList)
where T: ProfilerMetadataFactory {
{
if self.first_contentful_paint.get().is_some() {
return;
}
}
// Analyze display list to figure out if this is the first contentful
// paint (i.e. the display list contains items of type text, image,
// non-white canvas or SVG)
for item in &display_list.list {
match item {
&DisplayItem::Text(_) |
&DisplayItem::Image(_) => {
self.set_first_contentful_paint(profiler_metadata_factory);
return;
},
_ => (),
}
}
}
pub fn get_navigation_start(&self) -> Option<f64> {
self.navigation_start
}
pub fn get_first_paint(&self) -> Option<f64> {
self.first_paint.get()
}
pub fn get_first_contentful_paint(&self) -> Option<f64> {
self.first_contentful_paint.get()
}
}