Bug 1506748 - Record profiler markers for scene building and blob rasterization. r=mstange
☠☠ backed out by 4e24a409bacb ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Tue, 13 Nov 2018 22:44:13 +0000
changeset 446105 6afbbb6e200f89465fe64a17b07a28f4f283c8c0
parent 446104 b691e65265da0177283f763fd477836d222c643b
child 446106 9c729de094ae62eef1507147490306d209133198
push id35034
push userccoroiu@mozilla.com
push dateWed, 14 Nov 2018 09:49:38 +0000
treeherdermozilla-central@d8a262837cd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1506748
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1506748 - Record profiler markers for scene building and blob rasterization. r=mstange MozReview-Commit-ID: IA2ooFX5jtA Differential Revision: https://phabricator.services.mozilla.com/D11723
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/webrender_bindings/Moz2DImageRenderer.cpp
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/src/moz2d_renderer.rs
gfx/webrender_bindings/webrender_ffi.h
gfx/webrender_bindings/webrender_ffi_generated.h
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -49,16 +49,26 @@ bool is_in_compositor_thread()
   return mozilla::layers::CompositorThreadHolder::IsInCompositorThread();
 }
 
 bool is_in_render_thread()
 {
   return mozilla::wr::RenderThread::IsInRenderThread();
 }
 
+void gecko_profiler_start_marker(const char* name)
+{
+  profiler_tracing("WebRender", name, TRACING_INTERVAL_START);
+}
+
+void gecko_profiler_end_marker(const char* name)
+{
+  profiler_tracing("WebRender", name, TRACING_INTERVAL_END);
+}
+
 bool is_glcontext_egl(void* glcontext_ptr)
 {
   MOZ_ASSERT(glcontext_ptr);
 
   mozilla::gl::GLContext* glcontext = reinterpret_cast<mozilla::gl::GLContext*>(glcontext_ptr);
   if (!glcontext) {
     return false;
   }
--- a/gfx/webrender_bindings/Moz2DImageRenderer.cpp
+++ b/gfx/webrender_bindings/Moz2DImageRenderer.cpp
@@ -10,16 +10,17 @@
 #include "mozilla/Range.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/RectAbsolute.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/gfx/RecordedEvent.h"
 #include "mozilla/layers/WebRenderDrawEventRecorder.h"
 #include "WebRenderTypes.h"
 #include "webrender_ffi.h"
+#include "GeckoProfiler.h"
 
 #include <unordered_map>
 
 #ifdef XP_MACOSX
 #include "mozilla/gfx/UnscaledFontMac.h"
 #elif defined(XP_WIN)
 #include "mozilla/gfx/UnscaledFontDWrite.h"
 #else
@@ -320,16 +321,17 @@ GetScaledFont(Translator* aTranslator, W
 static bool Moz2DRenderCallback(const Range<const uint8_t> aBlob,
                                 gfx::IntSize aSize,
                                 gfx::SurfaceFormat aFormat,
                                 const uint16_t *aTileSize,
                                 const mozilla::wr::TileOffset *aTileOffset,
                                 const mozilla::wr::DeviceUintRect *aDirtyRect,
                                 Range<uint8_t> aOutput)
 {
+  AUTO_PROFILER_TRACING("WebRender", "RasterizeSingleBlob");
   MOZ_ASSERT(aSize.width > 0 && aSize.height > 0);
   if (aSize.width <= 0 || aSize.height <= 0) {
     return false;
   }
 
   auto stride = aSize.width * gfx::BytesPerPixel(aFormat);
 
   if (aOutput.length() < static_cast<size_t>(aSize.height * stride)) {
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -744,16 +744,21 @@ pub unsafe extern "C" fn wr_renderer_flu
 
 /// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC
 #[no_mangle]
 pub unsafe extern "C" fn wr_pipeline_info_delete(_info: WrPipelineInfo) {
     // _info will be dropped here, and the drop impl on FfiVec will free
     // the underlying vec memory
 }
 
+extern "C" {
+    pub fn gecko_profiler_start_marker(name: *const c_char);
+    pub fn gecko_profiler_end_marker(name: *const c_char);
+}
+
 #[allow(improper_ctypes)] // this is needed so that rustc doesn't complain about passing the &mut Transaction to an extern function
 extern "C" {
     // These callbacks are invoked from the scene builder thread (aka the APZ
     // updater thread)
     fn apz_register_updater(window_id: WrWindowId);
     fn apz_pre_scene_swap(window_id: WrWindowId);
     // This function takes ownership of the pipeline_info and is responsible for
     // freeing it via wr_pipeline_info_delete.
@@ -781,16 +786,17 @@ impl APZCallbacks {
 }
 
 impl SceneBuilderHooks for APZCallbacks {
     fn register(&self) {
         unsafe { apz_register_updater(self.window_id) }
     }
 
     fn pre_scene_build(&self) {
+        unsafe { gecko_profiler_start_marker(b"SceneBuilding\0".as_ptr() as *const c_char); }
     }
 
     fn pre_scene_swap(&self, scenebuild_time: u64) {
         unsafe {
             record_telemetry_time(TelemetryProbe::SceneBuildTime, scenebuild_time);
             apz_pre_scene_swap(self.window_id);
         }
     }
@@ -801,23 +807,26 @@ impl SceneBuilderHooks for APZCallbacks 
             record_telemetry_time(TelemetryProbe::SceneSwapTime, sceneswap_time);
             apz_post_scene_swap(self.window_id, info);
         }
 
         // After a scene swap we should schedule a render for the next vsync,
         // otherwise there's no guarantee that the new scene will get rendered
         // anytime soon
         unsafe { wr_schedule_render(self.window_id) }
+        unsafe { gecko_profiler_end_marker(b"SceneBuilding\0".as_ptr() as *const c_char); }
     }
 
     fn post_resource_update(&self) {
         unsafe { wr_schedule_render(self.window_id) }
+        unsafe { gecko_profiler_end_marker(b"SceneBuilding\0".as_ptr() as *const c_char); }
     }
 
     fn post_empty_scene_build(&self) {
+        unsafe { gecko_profiler_end_marker(b"SceneBuilding\0".as_ptr() as *const c_char); }
     }
 
     fn poke(&self) {
         unsafe { apz_run_updater(self.window_id) }
     }
 
     fn deregister(&self) {
         unsafe { apz_deregister_updater(self.window_id) }
--- a/gfx/webrender_bindings/src/moz2d_renderer.rs
+++ b/gfx/webrender_bindings/src/moz2d_renderer.rs
@@ -2,26 +2,26 @@
 
 //! Provides the webrender-side implementation of gecko blob images.
 //!
 //! Pretty much this is just a shim that calls back into Moz2DImageRenderer, but
 //! it also handles merging "partial" blob images (see `merge_blob_images`) and
 //! registering fonts found in the blob (see `prepare_request`).
 
 use webrender::api::*;
-use bindings::{ByteSlice, MutByteSlice, wr_moz2d_render_cb, ArcVecU8};
+use bindings::{ByteSlice, MutByteSlice, wr_moz2d_render_cb, ArcVecU8, gecko_profiler_start_marker, gecko_profiler_end_marker};
 use rayon::ThreadPool;
 use rayon::prelude::*;
 
 use std::collections::hash_map::HashMap;
 use std::collections::hash_map;
 use std::collections::btree_map::BTreeMap;
 use std::collections::Bound::Included;
 use std::mem;
-use std::os::raw::c_void;
+use std::os::raw::{c_void, c_char};
 use std::ptr;
 use std::sync::Arc;
 use std;
 
 #[cfg(target_os = "windows")]
 use dwrote;
 
 #[cfg(target_os = "macos")]
@@ -448,20 +448,38 @@ struct BlobCommand {
 /// Rasterizes gecko blob images.
 struct Moz2dBlobRasterizer {
     /// Pool of rasterizers.
     workers: Arc<ThreadPool>,
     /// Blobs to rasterize.
     blob_commands: HashMap<ImageKey, BlobCommand>,
 }
 
+struct GeckoProfilerMarker {
+    name: &'static [u8],
+}
+
+impl GeckoProfilerMarker {
+    pub fn new(name: &'static [u8]) -> GeckoProfilerMarker {
+        unsafe { gecko_profiler_start_marker(name.as_ptr() as *const c_char); }
+        GeckoProfilerMarker { name }
+    }
+}
+
+impl Drop for GeckoProfilerMarker {
+    fn drop(&mut self) {
+        unsafe { gecko_profiler_end_marker(self.name.as_ptr() as *const c_char); }
+    }
+}
+
 impl AsyncBlobImageRasterizer for Moz2dBlobRasterizer {
    
     fn rasterize(&mut self, requests: &[BlobImageParams], 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 requests: Vec<Job> = requests.into_iter().map(|params| {
             let command = &self.blob_commands[&params.request.key];
             let blob = Arc::clone(&command.data);
             Job {
                 request: params.request,
                 descriptor: params.descriptor,
                 commands: blob,
@@ -599,16 +617,17 @@ extern "C" {
         size: f32,
         options: Option<&FontInstanceOptions>,
         platform_options: Option<&FontInstancePlatformOptions>,
         variations: *const FontVariation,
         num_variations: usize,
     );
     fn DeleteBlobFont(key: WrFontInstanceKey);
     fn ClearBlobImageResources(namespace: WrIdNamespace);
+
 }
 
 impl Moz2dBlobImageHandler {
     /// Create a new BlobImageHandler with the given thread pool.
     pub fn new(workers: Arc<ThreadPool>) -> Self {
         Moz2dBlobImageHandler {
             blob_commands: HashMap::new(),
             workers: workers,
--- a/gfx/webrender_bindings/webrender_ffi.h
+++ b/gfx/webrender_bindings/webrender_ffi.h
@@ -25,16 +25,19 @@ bool gfx_use_wrench();
 const char* gfx_wr_resource_path_override();
 void gfx_critical_note(const char* msg);
 void gfx_critical_error(const char* msg);
 void gecko_printf_stderr_output(const char* msg);
 void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname);
 void gecko_profiler_register_thread(const char* threadname);
 void gecko_profiler_unregister_thread();
 
+void gecko_profiler_start_marker(const char* name);
+void gecko_profiler_end_marker(const char* name);
+
 // Prelude of types necessary before including webrender_ffi_generated.h
 namespace mozilla {
 namespace wr {
 
 struct FontInstanceFlags {
   uint32_t bits;
 
   bool operator==(const FontInstanceFlags& aOther) const {
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -1151,16 +1151,19 @@ extern bool is_glcontext_angle(void *aGl
 extern bool is_glcontext_egl(void *aGlcontextPtr);
 
 extern bool is_in_compositor_thread();
 
 extern bool is_in_main_thread();
 
 extern bool is_in_render_thread();
 
+extern void gecko_profiler_start_marker(const char* name);
+extern void gecko_profiler_end_marker(const char* name);
+
 extern void record_telemetry_time(TelemetryProbe aProbe,
                                   uint64_t aTimeNs);
 
 WR_INLINE
 bool remove_program_binary_disk_cache(const nsAString *aProfPath)
 WR_FUNC;
 
 WR_INLINE