diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp index 2cfad38859f0..576e72a3b2bb 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -65,36 +65,6 @@ bool is_in_render_thread() { return mozilla::wr::RenderThread::IsInRenderThread(); } -void gecko_profiler_start_marker(const char* name) { - PROFILER_MARKER(mozilla::ProfilerString8View::WrapNullTerminatedString(name), - GRAPHICS, mozilla::MarkerTiming::IntervalStart(), Tracing, - "WebRender"); -} - -void gecko_profiler_end_marker(const char* name) { - PROFILER_MARKER(mozilla::ProfilerString8View::WrapNullTerminatedString(name), - GRAPHICS, mozilla::MarkerTiming::IntervalEnd(), Tracing, - "WebRender"); -} - -void gecko_profiler_event_marker(const char* name) { - PROFILER_MARKER(mozilla::ProfilerString8View::WrapNullTerminatedString(name), - GRAPHICS, {}, Tracing, "WebRender"); -} - -void gecko_profiler_add_text_marker(const char* name, const char* text_bytes, - size_t text_len, uint64_t microseconds) { - if (profiler_thread_is_being_profiled()) { - auto now = mozilla::TimeStamp::Now(); - [[maybe_unused]] auto start = - now - mozilla::TimeDuration::FromMicroseconds(microseconds); - PROFILER_MARKER_TEXT( - mozilla::ProfilerString8View::WrapNullTerminatedString(name), GRAPHICS, - mozilla::MarkerTiming::Interval(start, now), - mozilla::ProfilerString8View(text_bytes, text_len)); - } -} - bool gecko_profiler_thread_is_being_profiled() { return profiler_thread_is_being_profiled(); } diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index 59d08ebd8a12..eb677d5960bf 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -856,18 +856,63 @@ pub unsafe extern "C" fn wr_renderer_flush_pipeline_info(renderer: &mut Renderer } extern "C" { - pub fn gecko_profiler_start_marker(name: *const c_char); - pub fn gecko_profiler_end_marker(name: *const c_char); - pub fn gecko_profiler_event_marker(name: *const c_char); - pub fn gecko_profiler_add_text_marker( - name: *const c_char, - text_bytes: *const c_char, - text_len: usize, - microseconds: u64, - ); pub fn gecko_profiler_thread_is_being_profiled() -> bool; } +pub fn gecko_profiler_start_marker(name: &str) { + use gecko_profiler::{gecko_profiler_category, MarkerOptions, MarkerTiming, ProfilerTime, Tracing}; + gecko_profiler::add_marker( + name, + gecko_profiler_category!(Graphics), + MarkerOptions { + timing: MarkerTiming::interval_start(ProfilerTime::now()), + ..Default::default() + }, + Tracing("Webrender".to_string()), + ); +} +pub fn gecko_profiler_end_marker(name: &str) { + use gecko_profiler::{gecko_profiler_category, MarkerOptions, MarkerTiming, ProfilerTime, Tracing}; + gecko_profiler::add_marker( + name, + gecko_profiler_category!(Graphics), + MarkerOptions { + timing: MarkerTiming::interval_end(ProfilerTime::now()), + ..Default::default() + }, + Tracing("Webrender".to_string()), + ); +} + +pub fn gecko_profiler_event_marker(name: &str) { + use gecko_profiler::{gecko_profiler_category, Tracing}; + gecko_profiler::add_marker( + name, + gecko_profiler_category!(Graphics), + Default::default(), + Tracing("Webrender".to_string()), + ); +} + +pub fn gecko_profiler_add_text_marker(name: &str, text: &str, microseconds: f64) { + use gecko_profiler::{gecko_profiler_category, MarkerOptions, MarkerTiming, ProfilerTime}; + if !gecko_profiler::can_accept_markers() { + return; + } + + let now = ProfilerTime::now(); + let start = now.clone().subtract_microseconds(microseconds); + gecko_profiler::add_text_marker( + name, + gecko_profiler_category!(Graphics), + MarkerOptions { + timing: MarkerTiming::interval(start, now), + ..Default::default() + }, + text, + ); +} + /// Simple implementation of the WR ProfilerHooks trait to allow profile /// markers to be seen in the Gecko profiler. struct GeckoProfilerHooks; @@ -881,36 +926,25 @@ impl ProfilerHooks for GeckoProfilerHooks { gecko_profiler::unregister_thread(); } + // TODO: Pass an &str directly instead. fn begin_marker(&self, label: &CStr) { - unsafe { - gecko_profiler_start_marker(label.as_ptr()); - } + gecko_profiler_start_marker(label.to_str().unwrap()); } + // TODO: Pass an &str directly instead. fn end_marker(&self, label: &CStr) { - unsafe { - gecko_profiler_end_marker(label.as_ptr()); - } + gecko_profiler_end_marker(label.to_str().unwrap()); } + // TODO: Pass an &str directly instead. fn event_marker(&self, label: &CStr) { - unsafe { - gecko_profiler_event_marker(label.as_ptr()); - } + gecko_profiler_event_marker(label.to_str().unwrap()); } + // TODO: Pass an &str directly instead. fn add_text_marker(&self, label: &CStr, text: &str, duration: Duration) { - unsafe { - // NB: This can be as_micros() once we require Rust 1.33. - let micros = duration.subsec_micros() as u64 + duration.as_secs() * 1000 * 1000; - let text_bytes = text.as_bytes(); - gecko_profiler_add_text_marker( - label.as_ptr(), - text_bytes.as_ptr() as *const c_char, - text_bytes.len(), - micros, - ); - } + let micros = duration.as_micros() as f64; + gecko_profiler_add_text_marker(label.to_str().unwrap(), text, micros); } fn thread_is_being_profiled(&self) -> bool { @@ -957,9 +991,7 @@ impl SceneBuilderHooks for APZCallbacks { } fn pre_scene_build(&self) { - unsafe { - gecko_profiler_start_marker(b"SceneBuilding\0".as_ptr() as *const c_char); - } + gecko_profiler_start_marker("SceneBuilding"); } fn pre_scene_swap(&self, scenebuild_time: u64) { @@ -980,22 +1012,16 @@ impl SceneBuilderHooks for APZCallbacks { // otherwise there's no guarantee that the new scene will get rendered // anytime soon unsafe { wr_finished_scene_build(self.window_id, &mut info) } - unsafe { - gecko_profiler_end_marker(b"SceneBuilding\0".as_ptr() as *const c_char); - } + gecko_profiler_end_marker("SceneBuilding"); } fn post_resource_update(&self, _document_ids: &Vec) { unsafe { wr_schedule_render(self.window_id, RenderReasons::POST_RESOURCE_UPDATES_HOOK) } - unsafe { - gecko_profiler_end_marker(b"SceneBuilding\0".as_ptr() as *const c_char); - } + gecko_profiler_end_marker("SceneBuilding"); } fn post_empty_scene_build(&self) { - unsafe { - gecko_profiler_end_marker(b"SceneBuilding\0".as_ptr() as *const c_char); - } + gecko_profiler_end_marker("SceneBuilding"); } fn poke(&self) { diff --git a/gfx/webrender_bindings/src/lib.rs b/gfx/webrender_bindings/src/lib.rs index b9b565f297d3..9e94302e0f90 100644 --- a/gfx/webrender_bindings/src/lib.rs +++ b/gfx/webrender_bindings/src/lib.rs @@ -8,6 +8,7 @@ extern crate app_units; extern crate bincode; extern crate euclid; extern crate fxhash; +extern crate gecko_profiler; extern crate gleam; extern crate nsstring; extern crate num_cpus; diff --git a/gfx/webrender_bindings/src/moz2d_renderer.rs b/gfx/webrender_bindings/src/moz2d_renderer.rs index 45d22022a8c6..8674109b3022 100644 --- a/gfx/webrender_bindings/src/moz2d_renderer.rs +++ b/gfx/webrender_bindings/src/moz2d_renderer.rs @@ -25,7 +25,7 @@ use std::collections::hash_map::HashMap; use std::collections::Bound::Included; use std::i32; use std::mem; -use std::os::raw::{c_char, c_void}; +use std::os::raw::c_void; use std::ptr; use std::sync::Arc; @@ -504,23 +504,19 @@ struct Moz2dBlobRasterizer { } struct GeckoProfilerMarker { - name: &'static [u8], + name: &'static str, } impl GeckoProfilerMarker { - pub fn new(name: &'static [u8]) -> GeckoProfilerMarker { - unsafe { - gecko_profiler_start_marker(name.as_ptr() as *const c_char); - } + pub fn new(name: &'static str) -> GeckoProfilerMarker { + gecko_profiler_start_marker(name); GeckoProfilerMarker { name } } } impl Drop for GeckoProfilerMarker { fn drop(&mut self) { - unsafe { - gecko_profiler_end_marker(self.name.as_ptr() as *const c_char); - } + gecko_profiler_end_marker(self.name); } } @@ -531,7 +527,7 @@ impl AsyncBlobImageRasterizer for Moz2dBlobRasterizer { low_priority: bool, ) -> Vec<(BlobImageRequest, BlobImageResult)> { // All we do here is spin up our workers to callback into gecko to replay the drawing commands. - let _marker = GeckoProfilerMarker::new(b"BlobRasterization\0"); + let _marker = GeckoProfilerMarker::new("BlobRasterization"); let requests: Vec = requests .iter() diff --git a/gfx/webrender_bindings/webrender_ffi.h b/gfx/webrender_bindings/webrender_ffi.h index 006aa154d568..5b1a6ea9fe1b 100644 --- a/gfx/webrender_bindings/webrender_ffi.h +++ b/gfx/webrender_bindings/webrender_ffi.h @@ -30,11 +30,6 @@ void gecko_printf_stderr_output(const char* msg); void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname); -void gecko_profiler_start_marker(const char* name); -void gecko_profiler_end_marker(const char* name); -void gecko_profiler_event_marker(const char* name); -void gecko_profiler_add_text_marker(const char* name, const char* text_ptr, - size_t text_len, uint64_t microseconds); bool gecko_profiler_thread_is_being_profiled(); // IMPORTANT: Keep this synchronized with enumerate_interners in