summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/catapult/tracing/tracing/metrics/rendering/frame_segment_filter.html
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/catapult/tracing/tracing/metrics/rendering/frame_segment_filter.html')
-rw-r--r--chromium/third_party/catapult/tracing/tracing/metrics/rendering/frame_segment_filter.html112
1 files changed, 112 insertions, 0 deletions
diff --git a/chromium/third_party/catapult/tracing/tracing/metrics/rendering/frame_segment_filter.html b/chromium/third_party/catapult/tracing/tracing/metrics/rendering/frame_segment_filter.html
new file mode 100644
index 00000000000..9ebaa87d003
--- /dev/null
+++ b/chromium/third_party/catapult/tracing/tracing/metrics/rendering/frame_segment_filter.html
@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<!--
+Copyright 2022 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+-->
+
+<link rel="import" href="/tracing/base/math/statistics.html">
+<link rel="import" href="/tracing/base/unit.html">
+<link rel="import" href="/tracing/base/unit_scale.html">
+<link rel="import" href="/tracing/metrics/rendering/cpu_utilization.html">
+<link rel="import" href="/tracing/model/helpers/chrome_model_helper.html">
+<link rel="import" href="/tracing/model/user_model/segment.html">
+<link rel="import" href="/tracing/value/diagnostics/generic_set.html">
+<link rel="import" href="/tracing/value/diagnostics/related_event_set.html">
+<link rel="import" href="/tracing/value/histogram.html">
+
+<script>
+'use strict';
+
+/**
+ * @fileoverview This file contains helper methods to filter Segments to just
+ * those for the displaying of frames.
+ */
+tr.exportTo('tr.metrics.rendering', function() {
+ // Various tracing events.
+ const DISPLAY_EVENT = 'BenchmarkInstrumentation::DisplayRenderingStats';
+ const DRM_EVENT = 'DrmEventFlipComplete';
+ const SURFACE_FLINGER_EVENT = 'vsync_before';
+
+
+ // The least number of frames needed to report frame_times.
+ // Measurements done with very few frames tend to be unstable.
+ // See crbug.com/954984 for example.
+ const MIN_FRAME_COUNT = 10;
+
+
+ class FrameEvent {
+ constructor(event) {
+ this.event_ = event;
+ }
+
+ get eventStart() {
+ return this.event_.start;
+ }
+
+ get frameStart() {
+ if (this.event_.title !== DRM_EVENT) return this.event_.start;
+ const data = this.event_.args.data;
+ const TIME = tr.b.UnitScale.TIME;
+ return tr.b.convertUnit(data['vblank.tv_sec'], TIME.SEC, TIME.MILLI_SEC) +
+ tr.b.convertUnit(
+ data['vblank.tv_usec'], TIME.MICRO_SEC, TIME.MILLI_SEC);
+ }
+
+ get event() { return this.event_; }
+ }
+
+
+ function getDisplayCompositorPresentationEvents_(model) {
+ const modelHelper = model.getOrCreateHelper(
+ tr.model.helpers.ChromeModelHelper);
+ if (!modelHelper || !modelHelper.browserProcess) return [];
+ // On ChromeOS, DRM events, if they exist, are the source of truth. On
+ // Android, Surface Flinger events are the source of truth. Otherwise, look
+ // for display rendering stats. With viz, display rendering stats are
+ // emitted from the GPU process; otherwise, they are emitted from the
+ // browser process.
+ let events = [];
+ if (modelHelper.surfaceFlingerProcess) {
+ events = [...modelHelper.surfaceFlingerProcess.findTopmostSlicesNamed(
+ SURFACE_FLINGER_EVENT)];
+ if (events.length > 0) return events;
+ }
+ if (modelHelper.gpuHelper) {
+ const gpuProcess = modelHelper.gpuHelper.process;
+ events = [...gpuProcess.findTopmostSlicesNamed(DRM_EVENT)];
+ if (events.length > 0) return events;
+ events = [...gpuProcess.findTopmostSlicesNamed(DISPLAY_EVENT)];
+ if (events.length > 0) return events;
+ }
+ return [...modelHelper.browserProcess.findTopmostSlicesNamed(
+ DISPLAY_EVENT)];
+ }
+
+
+ function computeFrameSegments(model, segments) {
+ const events = getDisplayCompositorPresentationEvents_(model);
+ if (!events) return [];
+ // We use filterArray for the sake of a cleaner code. The time complexity
+ // will be O(m + n log m), where m is |timestamps| and n is |segments|.
+ // Alternatively, we could directly loop through the timestamps and segments
+ // here for a slightly better time complexity of O(m + n).
+ const frameEvents = events.map(e => new FrameEvent(e));
+ const frameSegments = [];
+ for (const segment of segments) {
+ const filtered = segment.boundsRange.filterArray(
+ frameEvents, x => x.eventStart);
+ if (filtered.length < MIN_FRAME_COUNT) continue;
+ for (let i = 1; i < filtered.length; i++) {
+ const duration = filtered[i].frameStart - filtered[i - 1].frameStart;
+ frameSegments.push(new tr.model.um.Segment(filtered[i - 1].eventStart, duration));
+ }
+ }
+ return frameSegments;
+ }
+
+ return {
+ computeFrameSegments,
+ };
+});
+</script>