Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(197)

Unified Diff: tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py

Issue 1647513002: Delete tools/telemetry. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py
diff --git a/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py b/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py
deleted file mode 100644
index 65bdbee87c5582f7bd91403b20b81548786d5585..0000000000000000000000000000000000000000
--- a/tools/telemetry/telemetry/web_perf/metrics/rendering_stats.py
+++ /dev/null
@@ -1,296 +0,0 @@
-# Copyright 2014 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.
-import itertools
-
-from operator import attrgetter
-
-from telemetry.web_perf.metrics import rendering_frame
-
-# These are LatencyInfo component names indicating the various components
-# that the input event has travelled through.
-# This is when the input event first reaches chrome.
-UI_COMP_NAME = 'INPUT_EVENT_LATENCY_UI_COMPONENT'
-# This is when the input event was originally created by OS.
-ORIGINAL_COMP_NAME = 'INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT'
-# This is when the input event was sent from browser to renderer.
-BEGIN_COMP_NAME = 'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT'
-# This is when an input event is turned into a scroll update.
-BEGIN_SCROLL_UPDATE_COMP_NAME = (
- 'LATENCY_BEGIN_SCROLL_LISTENER_UPDATE_MAIN_COMPONENT')
-# This is when a scroll update is forwarded to the main thread.
-FORWARD_SCROLL_UPDATE_COMP_NAME = (
- 'INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT')
-# This is when the input event has reached swap buffer.
-END_COMP_NAME = 'INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT'
-
-# Name for a main thread scroll update latency event.
-MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME = 'Latency::ScrollUpdate'
-# Name for a gesture scroll update latency event.
-GESTURE_SCROLL_UPDATE_EVENT_NAME = 'InputLatency::GestureScrollUpdate'
-
-# These are keys used in the 'data' field dictionary located in
-# BenchmarkInstrumentation::ImplThreadRenderingStats.
-VISIBLE_CONTENT_DATA = 'visible_content_area'
-APPROXIMATED_VISIBLE_CONTENT_DATA = 'approximated_visible_content_area'
-CHECKERBOARDED_VISIBLE_CONTENT_DATA = 'checkerboarded_visible_content_area'
-# These are keys used in the 'errors' field dictionary located in
-# RenderingStats in this file.
-APPROXIMATED_PIXEL_ERROR = 'approximated_pixel_percentages'
-CHECKERBOARDED_PIXEL_ERROR = 'checkerboarded_pixel_percentages'
-
-
-def GetLatencyEvents(process, timeline_range):
- """Get LatencyInfo trace events from the process's trace buffer that are
- within the timeline_range.
-
- Input events dump their LatencyInfo into trace buffer as async trace event
- of name starting with "InputLatency". Non-input events with name starting
- with "Latency". The trace event has a member 'data' containing its latency
- history.
-
- """
- latency_events = []
- if not process:
- return latency_events
- for event in itertools.chain(
- process.IterAllAsyncSlicesStartsWithName('InputLatency'),
- process.IterAllAsyncSlicesStartsWithName('Latency')):
- if event.start >= timeline_range.min and event.end <= timeline_range.max:
- for ss in event.sub_slices:
- if 'data' in ss.args:
- latency_events.append(ss)
- return latency_events
-
-
-def ComputeEventLatencies(input_events):
- """ Compute input event latencies.
-
- Input event latency is the time from when the input event is created to
- when its resulted page is swap buffered.
- Input event on different platforms uses different LatencyInfo component to
- record its creation timestamp. We go through the following component list
- to find the creation timestamp:
- 1. INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT -- when event is created in OS
- 2. INPUT_EVENT_LATENCY_UI_COMPONENT -- when event reaches Chrome
- 3. INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT -- when event reaches RenderWidget
-
- If the latency starts with a
- LATENCY_BEGIN_SCROLL_UPDATE_MAIN_COMPONENT component, then it is
- classified as a scroll update instead of a normal input latency measure.
-
- Returns:
- A list sorted by increasing start time of latencies which are tuples of
- (input_event_name, latency_in_ms).
- """
- input_event_latencies = []
- for event in input_events:
- data = event.args['data']
- if END_COMP_NAME in data:
- end_time = data[END_COMP_NAME]['time']
- if ORIGINAL_COMP_NAME in data:
- start_time = data[ORIGINAL_COMP_NAME]['time']
- elif UI_COMP_NAME in data:
- start_time = data[UI_COMP_NAME]['time']
- elif BEGIN_COMP_NAME in data:
- start_time = data[BEGIN_COMP_NAME]['time']
- elif BEGIN_SCROLL_UPDATE_COMP_NAME in data:
- start_time = data[BEGIN_SCROLL_UPDATE_COMP_NAME]['time']
- else:
- raise ValueError('LatencyInfo has no begin component')
- latency = (end_time - start_time) / 1000.0
- input_event_latencies.append((start_time, event.name, latency))
-
- input_event_latencies.sort()
- return [(name, latency) for _, name, latency in input_event_latencies]
-
-
-def HasRenderingStats(process):
- """ Returns True if the process contains at least one
- BenchmarkInstrumentation::*RenderingStats event with a frame.
- """
- if not process:
- return False
- for event in process.IterAllSlicesOfName(
- 'BenchmarkInstrumentation::DisplayRenderingStats'):
- if 'data' in event.args and event.args['data']['frame_count'] == 1:
- return True
- for event in process.IterAllSlicesOfName(
- 'BenchmarkInstrumentation::ImplThreadRenderingStats'):
- if 'data' in event.args and event.args['data']['frame_count'] == 1:
- return True
- return False
-
-def GetTimestampEventName(process):
- """ Returns the name of the events used to count frame timestamps. """
- if process.name == 'SurfaceFlinger':
- return 'vsync_before'
-
- event_name = 'BenchmarkInstrumentation::DisplayRenderingStats'
- for event in process.IterAllSlicesOfName(event_name):
- if 'data' in event.args and event.args['data']['frame_count'] == 1:
- return event_name
-
- return 'BenchmarkInstrumentation::ImplThreadRenderingStats'
-
-class RenderingStats(object):
- def __init__(self, renderer_process, browser_process, surface_flinger_process,
- timeline_ranges):
- """
- Utility class for extracting rendering statistics from the timeline (or
- other loggin facilities), and providing them in a common format to classes
- that compute benchmark metrics from this data.
-
- Stats are lists of lists of numbers. The outer list stores one list per
- timeline range.
-
- All *_time values are measured in milliseconds.
- """
- assert len(timeline_ranges) > 0
- self.refresh_period = None
-
- # Find the top level process with rendering stats (browser or renderer).
- if surface_flinger_process:
- timestamp_process = surface_flinger_process
- self._GetRefreshPeriodFromSurfaceFlingerProcess(surface_flinger_process)
- elif HasRenderingStats(browser_process):
- timestamp_process = browser_process
- else:
- timestamp_process = renderer_process
-
- timestamp_event_name = GetTimestampEventName(timestamp_process)
-
- # A lookup from list names below to any errors or exceptions encountered
- # in attempting to generate that list.
- self.errors = {}
-
- self.frame_timestamps = []
- self.frame_times = []
- self.approximated_pixel_percentages = []
- self.checkerboarded_pixel_percentages = []
- # End-to-end latency for input event - from when input event is
- # generated to when the its resulted page is swap buffered.
- self.input_event_latency = []
- self.frame_queueing_durations = []
- # Latency from when a scroll update is sent to the main thread until the
- # resulting frame is swapped.
- self.main_thread_scroll_latency = []
- # Latency for a GestureScrollUpdate input event.
- self.gesture_scroll_update_latency = []
-
- for timeline_range in timeline_ranges:
- self.frame_timestamps.append([])
- self.frame_times.append([])
- self.approximated_pixel_percentages.append([])
- self.checkerboarded_pixel_percentages.append([])
- self.input_event_latency.append([])
- self.main_thread_scroll_latency.append([])
- self.gesture_scroll_update_latency.append([])
-
- if timeline_range.is_empty:
- continue
- self._InitFrameTimestampsFromTimeline(
- timestamp_process, timestamp_event_name, timeline_range)
- self._InitImplThreadRenderingStatsFromTimeline(
- renderer_process, timeline_range)
- self._InitInputLatencyStatsFromTimeline(
- browser_process, renderer_process, timeline_range)
- self._InitFrameQueueingDurationsFromTimeline(
- renderer_process, timeline_range)
-
- def _GetRefreshPeriodFromSurfaceFlingerProcess(self, surface_flinger_process):
- for event in surface_flinger_process.IterAllEventsOfName('vsync_before'):
- self.refresh_period = event.args['data']['refresh_period']
- return
-
- def _InitInputLatencyStatsFromTimeline(
- self, browser_process, renderer_process, timeline_range):
- latency_events = GetLatencyEvents(browser_process, timeline_range)
- # Plugin input event's latency slice is generated in renderer process.
- latency_events.extend(GetLatencyEvents(renderer_process, timeline_range))
- event_latencies = ComputeEventLatencies(latency_events)
- # Don't include scroll updates in the overall input latency measurement,
- # because scroll updates can take much more time to process than other
- # input events and would therefore add noise to overall latency numbers.
- self.input_event_latency[-1] = [
- latency for name, latency in event_latencies
- if name != MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME]
- self.main_thread_scroll_latency[-1] = [
- latency for name, latency in event_latencies
- if name == MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME]
- self.gesture_scroll_update_latency[-1] = [
- latency for name, latency in event_latencies
- if name == GESTURE_SCROLL_UPDATE_EVENT_NAME]
-
- def _GatherEvents(self, event_name, process, timeline_range):
- events = []
- for event in process.IterAllSlicesOfName(event_name):
- if event.start >= timeline_range.min and event.end <= timeline_range.max:
- if 'data' not in event.args:
- continue
- events.append(event)
- events.sort(key=attrgetter('start'))
- return events
-
- def _AddFrameTimestamp(self, event):
- frame_count = event.args['data']['frame_count']
- if frame_count > 1:
- raise ValueError('trace contains multi-frame render stats')
- if frame_count == 1:
- self.frame_timestamps[-1].append(
- event.start)
- if len(self.frame_timestamps[-1]) >= 2:
- self.frame_times[-1].append(
- self.frame_timestamps[-1][-1] - self.frame_timestamps[-1][-2])
-
- def _InitFrameTimestampsFromTimeline(
- self, process, timestamp_event_name, timeline_range):
- for event in self._GatherEvents(
- timestamp_event_name, process, timeline_range):
- self._AddFrameTimestamp(event)
-
- def _InitImplThreadRenderingStatsFromTimeline(self, process, timeline_range):
- event_name = 'BenchmarkInstrumentation::ImplThreadRenderingStats'
- for event in self._GatherEvents(event_name, process, timeline_range):
- data = event.args['data']
- if VISIBLE_CONTENT_DATA not in data:
- self.errors[APPROXIMATED_PIXEL_ERROR] = (
- 'Calculating approximated_pixel_percentages not possible because '
- 'visible_content_area was missing.')
- self.errors[CHECKERBOARDED_PIXEL_ERROR] = (
- 'Calculating checkerboarded_pixel_percentages not possible because '
- 'visible_content_area was missing.')
- return
- visible_content_area = data[VISIBLE_CONTENT_DATA]
- if visible_content_area == 0:
- self.errors[APPROXIMATED_PIXEL_ERROR] = (
- 'Calculating approximated_pixel_percentages would have caused '
- 'a divide-by-zero')
- self.errors[CHECKERBOARDED_PIXEL_ERROR] = (
- 'Calculating checkerboarded_pixel_percentages would have caused '
- 'a divide-by-zero')
- return
- if APPROXIMATED_VISIBLE_CONTENT_DATA in data:
- self.approximated_pixel_percentages[-1].append(
- round(float(data[APPROXIMATED_VISIBLE_CONTENT_DATA]) /
- float(data[VISIBLE_CONTENT_DATA]) * 100.0, 3))
- else:
- self.errors[APPROXIMATED_PIXEL_ERROR] = (
- 'approximated_pixel_percentages was not recorded')
- if CHECKERBOARDED_VISIBLE_CONTENT_DATA in data:
- self.checkerboarded_pixel_percentages[-1].append(
- round(float(data[CHECKERBOARDED_VISIBLE_CONTENT_DATA]) /
- float(data[VISIBLE_CONTENT_DATA]) * 100.0, 3))
- else:
- self.errors[CHECKERBOARDED_PIXEL_ERROR] = (
- 'checkerboarded_pixel_percentages was not recorded')
-
- def _InitFrameQueueingDurationsFromTimeline(self, process, timeline_range):
- try:
- events = rendering_frame.GetFrameEventsInsideRange(process,
- timeline_range)
- new_frame_queueing_durations = [e.queueing_duration for e in events]
- self.frame_queueing_durations.append(new_frame_queueing_durations)
- except rendering_frame.NoBeginFrameIdException:
- self.errors['frame_queueing_durations'] = (
- 'Current chrome version does not support the queueing delay metric.')

Powered by Google App Engine
This is Rietveld 408576698