Bug 1767257: Migrate existing WebRender telemetry probes to use Glean directly. r=jrmuizel

Differential Revision: https://phabricator.services.mozilla.com/D145315
This commit is contained in:
Bas Schouten 2022-05-09 15:23:11 +00:00
parent 4ea22f7d19
commit ef6615b08f
11 changed files with 85 additions and 55 deletions

View file

@ -115,28 +115,6 @@ void* get_proc_address_from_glcontext(void* glcontext_ptr,
return reinterpret_cast<void*>(ret);
}
void record_telemetry_time(mozilla::wr::TelemetryProbe aProbe,
uint64_t aTimeNs) {
uint32_t time_ms = (uint32_t)(aTimeNs / 1000000);
switch (aProbe) {
case mozilla::wr::TelemetryProbe::SceneBuildTime:
mozilla::Telemetry::Accumulate(mozilla::Telemetry::WR_SCENEBUILD_TIME,
time_ms);
break;
case mozilla::wr::TelemetryProbe::SceneSwapTime:
mozilla::Telemetry::Accumulate(mozilla::Telemetry::WR_SCENESWAP_TIME,
time_ms);
break;
case mozilla::wr::TelemetryProbe::FrameBuildTime:
mozilla::Telemetry::Accumulate(mozilla::Telemetry::WR_FRAMEBUILD_TIME,
time_ms);
break;
default:
MOZ_ASSERT(false);
break;
}
}
static CrashReporter::Annotation FromWrCrashAnnotation(
mozilla::wr::CrashAnnotation aAnnotation) {
switch (aAnnotation) {

View file

@ -43,3 +43,53 @@ wr:
- gfx-telemetry-alerts@mozilla.com
expires: never
telemetry_mirror: WR_RASTERIZE_GLYPHS_TIME
framebuild_time:
type: timing_distribution
description: >
The time to rasterize glyphs for consumption by WebRender.
time_unit: microsecond
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1470901
- https://bugzilla.mozilla.org/show_bug.cgi?id=1584109
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1470901
- https://bugzilla.mozilla.org/show_bug.cgi?id=1584109
data_sensitivity:
- technical
notification_emails:
- gfx-telemetry-alerts@mozilla.com
- jmuizelaar@mozilla.com
expires: never
telemetry_mirror: WR_FRAMEBUILD_TIME
scenebuild_time:
type: timing_distribution
description: >
WebRender scene build time.
time_unit: microsecond
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1470901
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1470901
data_sensitivity:
- technical
notification_emails:
- gfx-telemetry-alerts@mozilla.com
- jmuizelaar@mozilla.com
expires: never
telemetry_mirror: WR_SCENEBUILD_TIME
sceneswap_time:
type: timing_distribution
description: >
WebRender scene swap time.
time_unit: microsecond
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1470901
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1470901
data_sensitivity:
- technical
notification_emails:
- gfx-telemetry-alerts@mozilla.com
- jmuizelaar@mozilla.com
expires: never
telemetry_mirror: WR_SCENESWAP_TIME

View file

@ -512,7 +512,6 @@ extern "C" {
#[allow(dead_code)]
fn gfx_critical_error(msg: *const c_char);
fn gfx_critical_note(msg: *const c_char);
fn record_telemetry_time(probe: TelemetryProbe, time_ns: u64);
fn gfx_wr_set_crash_annotation(annotation: CrashAnnotation, value: *const c_char);
fn gfx_wr_clear_crash_annotation(annotation: CrashAnnotation);
}
@ -548,11 +547,8 @@ impl RenderNotifier for CppNotifier {
}
}
fn new_frame_ready(&self, _: DocumentId, _scrolled: bool, composite_needed: bool, render_time_ns: Option<u64>) {
fn new_frame_ready(&self, _: DocumentId, _scrolled: bool, composite_needed: bool) {
unsafe {
if let Some(time) = render_time_ns {
record_telemetry_time(TelemetryProbe::FrameBuildTime, time);
}
if composite_needed {
wr_notifier_new_frame_ready(self.window_id);
} else {
@ -988,17 +984,15 @@ impl SceneBuilderHooks for APZCallbacks {
gecko_profiler_start_marker("SceneBuilding");
}
fn pre_scene_swap(&self, scenebuild_time: u64) {
fn pre_scene_swap(&self) {
unsafe {
record_telemetry_time(TelemetryProbe::SceneBuildTime, scenebuild_time);
apz_pre_scene_swap(self.window_id);
}
}
fn post_scene_swap(&self, _document_ids: &Vec<DocumentId>, info: PipelineInfo, sceneswap_time: u64) {
fn post_scene_swap(&self, _document_ids: &Vec<DocumentId>, info: PipelineInfo) {
let mut info = WrPipelineInfo::new(&info);
unsafe {
record_telemetry_time(TelemetryProbe::SceneSwapTime, sceneswap_time);
apz_post_scene_swap(self.window_id, &info);
}

View file

@ -110,13 +110,6 @@ template struct mozilla::wr::Point2D<float, mozilla::wr::WorldPixel>;
template struct mozilla::wr::Box2D<int32_t, mozilla::wr::DevicePixel>;
template struct mozilla::wr::Box2D<int, mozilla::wr::LayoutPixel>;
// More functions invoked from Rust code. These are down here because they
// refer to data structures from webrender_ffi_generated.h
extern "C" {
void record_telemetry_time(mozilla::wr::TelemetryProbe aProbe,
uint64_t aTimeNs);
}
namespace mozilla {
namespace wr {

View file

@ -54,6 +54,7 @@ use crate::scene_builder_thread::*;
use crate::spatial_tree::SpatialTree;
#[cfg(feature = "replay")]
use crate::spatial_tree::SceneSpatialTree;
use crate::telemetry::Telemetry;
#[cfg(feature = "serialize")]
use serde::{Serialize, Deserialize};
#[cfg(feature = "replay")]
@ -1370,7 +1371,6 @@ impl RenderBackend {
}
}
let mut frame_build_time = None;
if build_frame {
profile_scope!("generate frame");
@ -1378,7 +1378,7 @@ impl RenderBackend {
// borrow ck hack for profile_counters
let (pending_update, mut rendered_document) = {
let frame_build_start_time = precise_time_ns();
let timer_id = Telemetry::start_framebuild_time();
let frame_stats = doc.frame_stats.take();
@ -1397,7 +1397,7 @@ impl RenderBackend {
let msg = ResultMsg::UpdateGpuCache(self.gpu_cache.extract_updates());
self.result_tx.send(msg).unwrap();
frame_build_time = Some(precise_time_ns() - frame_build_start_time);
Telemetry::stop_and_accumulate_framebuild_time(timer_id);
let pending_update = self.resource_cache.pending_updates();
(pending_update, rendered_document)
@ -1488,7 +1488,7 @@ impl RenderBackend {
} else if render_frame {
doc.rendered_frame_is_valid = true;
}
self.notifier.new_frame_ready(document_id, scroll, render_frame, frame_build_time);
self.notifier.new_frame_ready(document_id, scroll, render_frame);
}
if !doc.hit_tester_is_valid {
@ -1862,7 +1862,7 @@ impl RenderBackend {
);
self.result_tx.send(msg_publish).unwrap();
self.notifier.new_frame_ready(id, false, true, None);
self.notifier.new_frame_ready(id, false, true);
// We deserialized the state of the frame so we don't want to build
// it (but we do want to update the scene builder's state)

View file

@ -5643,11 +5643,11 @@ pub trait SceneBuilderHooks {
/// This is called before each scene build starts.
fn pre_scene_build(&self);
/// This is called before each scene swap occurs.
fn pre_scene_swap(&self, scenebuild_time: u64);
fn pre_scene_swap(&self);
/// 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, document_id: &Vec<DocumentId>, info: PipelineInfo, sceneswap_time: u64);
fn post_scene_swap(&self, document_id: &Vec<DocumentId>, info: PipelineInfo);
/// 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.

View file

@ -1,4 +1,4 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
/* This Source Code Form is subject to the terms of the Mozilla Publi
* 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/. */
@ -31,6 +31,7 @@ use crate::render_backend::SceneView;
use crate::renderer::{FullFrameStats, PipelineInfo, SceneBuilderHooks};
use crate::scene::{Scene, BuiltScene, SceneStats};
use crate::spatial_tree::{SceneSpatialTree, SpatialTreeUpdates};
use crate::telemetry::Telemetry;
use std::iter;
use time::precise_time_ns;
use crate::util::drain_filter;
@ -682,7 +683,8 @@ impl SceneBuilderThread {
let (tx, rx) = single_msg_channel();
let txn = txns.iter().find(|txn| txn.built_scene.is_some()).unwrap();
hooks.pre_scene_swap((txn.profile.get(profiler::SCENE_BUILD_TIME).unwrap() * 1000000.0) as u64);
Telemetry::record_scenebuild_time(Duration::from_millis(txn.profile.get(profiler::SCENE_BUILD_TIME).unwrap() as u64));
hooks.pre_scene_swap();
(Some(info), Some(tx), Some(rx))
} else {
@ -692,7 +694,7 @@ impl SceneBuilderThread {
_ => (None, None, None)
};
let scene_swap_start_time = precise_time_ns();
let timer_id = Telemetry::start_sceneswap_time();
let document_ids = txns.iter().map(|txn| txn.document_id).collect();
let have_resources_updates : Vec<DocumentId> = if pipeline_info.is_none() {
txns.iter()
@ -715,18 +717,20 @@ impl SceneBuilderThread {
if let Some(pipeline_info) = pipeline_info {
// Block until the swap is done, then invoke the hook.
let swap_result = result_rx.unwrap().recv();
let scene_swap_time = precise_time_ns() - scene_swap_start_time;
Telemetry::stop_and_accumulate_sceneswap_time(timer_id);
self.hooks.as_ref().unwrap().post_scene_swap(&document_ids,
pipeline_info, scene_swap_time);
pipeline_info);
// Once the hook is done, allow the RB thread to resume
if let Ok(SceneSwapResult::Complete(resume_tx)) = swap_result {
resume_tx.send(()).ok();
}
} else if !have_resources_updates.is_empty() {
Telemetry::cancel_sceneswap_time(timer_id);
if let Some(ref hooks) = self.hooks {
hooks.post_resource_update(&have_resources_updates);
}
} else if let Some(ref hooks) = self.hooks {
Telemetry::cancel_sceneswap_time(timer_id);
hooks.post_empty_scene_build();
}
}

View file

@ -5,6 +5,7 @@
use glean::TimerId;
#[cfg(feature = "gecko")]
use fog::metrics::wr;
use std::time::Duration;
pub struct Telemetry;
@ -15,10 +16,22 @@ impl Telemetry {
pub fn start_rasterize_glyphs_time() -> TimerId { return 0; }
// End rasterize glyph time collection
pub fn stop_and_accumulate_rasterize_glyphs_time(_id: TimerId) { }
pub fn start_framebuild_time() -> TimerId { 0 }
pub fn stop_and_accumulate_framebuild_time(_id: TimerId) { }
pub fn record_scenebuild_time(_duration: Duration) { }
pub fn start_sceneswap_time() -> TimerId { 0 }
pub fn stop_and_accumulate_sceneswap_time(_id: TimerId) { }
pub fn cancel_sceneswap_time(_id: TimerId) { }
}
#[cfg(feature = "gecko")]
impl Telemetry {
pub fn start_rasterize_glyphs_time() -> TimerId { wr::rasterize_glyphs_time.start() }
pub fn stop_and_accumulate_rasterize_glyphs_time(id: TimerId) { wr::rasterize_glyphs_time.stop_and_accumulate(id); }
pub fn start_framebuild_time() -> TimerId { wr::framebuild_time.start() }
pub fn stop_and_accumulate_framebuild_time(id: TimerId) { wr::framebuild_time.stop_and_accumulate(id); }
pub fn record_scenebuild_time(duration: Duration) { wr::scenebuild_time.accumulate_raw_duration(duration); }
pub fn start_sceneswap_time() -> TimerId { wr::sceneswap_time.start() }
pub fn stop_and_accumulate_sceneswap_time(id: TimerId) { wr::sceneswap_time.stop_and_accumulate(id); }
pub fn cancel_sceneswap_time(id: TimerId) { wr::sceneswap_time.cancel(id); }
}

View file

@ -219,7 +219,7 @@ pub trait RenderNotifier: Send {
composite_needed: bool,
);
/// Notify the thread containing the `Renderer` that a new frame is ready.
fn new_frame_ready(&self, _: DocumentId, scrolled: bool, composite_needed: bool, render_time_ns: Option<u64>);
fn new_frame_ready(&self, _: DocumentId, scrolled: bool, composite_needed: bool);
/// A Gecko-specific notification mechanism to get some code executed on the
/// `Renderer`'s thread, mostly replaced by `NotificationHandler`. You should
/// probably use the latter instead.

View file

@ -464,8 +464,7 @@ impl RenderNotifier for Notifier {
fn new_frame_ready(&self,
_: DocumentId,
_scrolled: bool,
composite_needed: bool,
_render_time: Option<u64>) {
composite_needed: bool) {
// TODO(gw): Refactor wrench so that it can take advantage of cases
// where no composite is required when appropriate.
self.wake_up(composite_needed);

View file

@ -100,8 +100,7 @@ impl RenderNotifier for Notifier {
fn new_frame_ready(&self, _: DocumentId,
scrolled: bool,
_composite_needed: bool,
_render_time: Option<u64>) {
_composite_needed: bool) {
self.update(!scrolled);
}
}