Bug 1470901 - Record scene build, scene swap, and render times in telemetry. r?sotaro
MozReview-Commit-ID: 1a6pqa0sSrU
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -24,16 +24,17 @@
#include "mozilla/layers/ImageBridgeParent.h"
#include "mozilla/layers/ImageDataSerializer.h"
#include "mozilla/layers/IpcResourceUpdateQueue.h"
#include "mozilla/layers/SharedSurfacesParent.h"
#include "mozilla/layers/TextureHost.h"
#include "mozilla/layers/AsyncImagePipelineManager.h"
#include "mozilla/layers/WebRenderImageHost.h"
#include "mozilla/layers/WebRenderTextureHost.h"
+#include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Unused.h"
#include "mozilla/webrender/RenderThread.h"
#include "mozilla/widget/CompositorWidget.h"
bool is_in_main_thread()
{
return NS_IsMainThread();
@@ -119,16 +120,36 @@ gecko_profiler_register_thread(const cha
}
void
gecko_profiler_unregister_thread()
{
PROFILER_UNREGISTER_THREAD();
}
+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::RenderTime:
+ mozilla::Telemetry::Accumulate(mozilla::Telemetry::WR_RENDER_TIME, time_ms);
+ break;
+ default:
+ MOZ_ASSERT(false);
+ break;
+ }
+}
+
namespace mozilla {
namespace layers {
using namespace mozilla::gfx;
class MOZ_STACK_CLASS AutoWebRenderBridgeParentAsyncMessageSender
{
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -457,16 +457,23 @@ fn get_proc_address(glcontext_ptr: *mut
if symbol.is_null() {
// XXX Bug 1322949 Make whitelist for extensions
warn!("Could not find symbol {:?} by glcontext", symbol_name);
}
symbol as *const _
}
+#[repr(C)]
+pub enum TelemetryProbe {
+ SceneBuildTime = 0,
+ SceneSwapTime = 1,
+ RenderTime = 2,
+}
+
extern "C" {
fn is_in_compositor_thread() -> bool;
fn is_in_render_thread() -> bool;
fn is_in_main_thread() -> bool;
fn is_glcontext_egl(glcontext_ptr: *mut c_void) -> bool;
fn is_glcontext_angle(glcontext_ptr: *mut c_void) -> bool;
// Enables binary recording that can be used with `wrench replay`
// Outputs a wr-record-*.bin file for each window that is shown
@@ -476,16 +483,17 @@ extern "C" {
fn gfx_use_wrench() -> bool;
fn gfx_wr_resource_path_override() -> *const c_char;
// TODO: make gfx_critical_error() work.
// We still have problem to pass the error message from render/render_backend
// thread to main thread now.
#[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);
}
struct CppNotifier {
window_id: WrWindowId,
}
unsafe impl Send for CppNotifier {}
@@ -510,18 +518,21 @@ impl RenderNotifier for CppNotifier {
wr_notifier_wake_up(self.window_id);
}
}
fn new_frame_ready(&self,
_: DocumentId,
_scrolled: bool,
composite_needed: bool,
- _render_time_ns: Option<u64>) {
+ render_time_ns: Option<u64>) {
unsafe {
+ if let Some(time) = render_time_ns {
+ record_telemetry_time(TelemetryProbe::RenderTime, time);
+ }
if composite_needed {
wr_notifier_new_frame_ready(self.window_id);
} else {
wr_notifier_nop_frame_done(self.window_id);
}
}
}
@@ -713,23 +724,29 @@ impl APZCallbacks {
}
}
impl SceneBuilderHooks for APZCallbacks {
fn register(&self) {
unsafe { apz_register_updater(self.window_id) }
}
- fn pre_scene_swap(&self, _scenebuild_time: u64) {
- unsafe { apz_pre_scene_swap(self.window_id) }
+ fn pre_scene_swap(&self, scenebuild_time: u64) {
+ unsafe {
+ record_telemetry_time(TelemetryProbe::SceneBuildTime, scenebuild_time);
+ apz_pre_scene_swap(self.window_id);
+ }
}
- fn post_scene_swap(&self, info: PipelineInfo, _sceneswap_time: u64) {
+ fn post_scene_swap(&self, info: PipelineInfo, sceneswap_time: u64) {
let info = WrPipelineInfo::new(info);
- unsafe { apz_post_scene_swap(self.window_id, info) }
+ unsafe {
+ 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) }
}
fn post_resource_update(&self) {
--- a/gfx/webrender_bindings/webrender_ffi.h
+++ b/gfx/webrender_bindings/webrender_ffi.h
@@ -122,9 +122,15 @@ void apz_deregister_sampler(mozilla::wr:
# define WR_DESTRUCTOR_SAFE_FUNC {}
#endif
#include "webrender_ffi_generated.h"
#undef WR_FUNC
#undef WR_DESTRUCTOR_SAFE_FUNC
+// 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);
+}
+
#endif // WR_h
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -147,16 +147,24 @@ enum class RepeatMode : uint32_t {
Stretch,
Repeat,
Round,
Space,
Sentinel /* this must be last for serialization purposes. */
};
+enum class TelemetryProbe {
+ SceneBuildTime = 0,
+ SceneSwapTime = 1,
+ RenderTime = 2,
+
+ Sentinel /* this must be last for serialization purposes. */
+};
+
enum class TransformStyle : uint32_t {
Flat = 0,
Preserve3D = 1,
Sentinel /* this must be last for serialization purposes. */
};
enum class WrAnimationType : uint32_t {
@@ -1000,16 +1008,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 record_telemetry_time(TelemetryProbe aProbe,
+ uint64_t aTimeNs);
+
WR_INLINE
bool remove_program_binary_disk_cache(const nsAString *aProfPath)
WR_FUNC;
WR_INLINE
const VecU8 *wr_add_ref_arc(const ArcVecU8 *aArc)
WR_FUNC;