def AddResults(self, tab, results): # Add results of smoothness metric. This computes the smoothness metric for # the time range between the first action starts and the last action ends. # To get the measurement for each action, use # measurement.TimelineBasedMeasurement. time_bounds = timeline_bounds.Bounds() for action in self._actions: time_bounds.AddBounds( action.GetActiveRangeOnTimeline(self._timeline_model)) # Create an interaction_record for this legacy measurement. Since we don't # wrap the results that is sent to smoothnes metric, the logical_name will # not be used. interaction_record = tir_module.TimelineInteractionRecord( 'smoothness_interaction', time_bounds.min, time_bounds.max) renderer_thread = self._timeline_model.GetRendererThreadFromTab(tab) smoothness_metric = smoothness.SmoothnessMetric() smoothness_metric.AddResults(self._timeline_model, renderer_thread, interaction_record, results) if tab.browser.platform.IsRawDisplayFrameRateSupported(): for r in tab.browser.platform.GetRawDisplayFrameRateMeasurements(): if r.value is None: raise MissingDisplayFrameRateError(r.name) results.Add(r.name, r.unit, r.value)
def __init__(self, event_data=None, shift_world_to_zero=True): self._bounds = bounds.Bounds() self._thread_time_bounds = bounds.Bounds() self._processes = {} self._frozen = False self.import_errors = [] self.metadata = [] # Use a WeakKeyDictionary, because an ordinary dictionary could keep # references to Tab objects around until it gets garbage collected. # This would prevent telemetry from navigating to another page. self._core_object_to_timeline_container_map = weakref.WeakKeyDictionary( ) if event_data is not None: self.ImportTraces([event_data], shift_world_to_zero=shift_world_to_zero)
def __init__(self, event_data=None, shift_world_to_zero=True): self._bounds = bounds.Bounds() self._processes = {} self._frozen = False self.import_errors = [] self.metadata = [] if event_data is not None: self.ImportTraces([event_data], shift_world_to_zero=shift_world_to_zero)
def GetActiveRangeOnTimeline(self, timeline): active_range = timeline_bounds.Bounds() if self._GetUniqueTimelineMarkerName(): active_range.AddEvent( timeline.GetEventOfName(self._GetUniqueTimelineMarkerName(), True, True)) return active_range
def AddResults(self, model, renderer_thread, interaction_record, results): renderer_process = renderer_thread.parent time_bounds = bounds.Bounds() time_bounds.AddValue(interaction_record.start) time_bounds.AddValue(interaction_record.end) stats = rendering_stats.RenderingStats(renderer_process, model.browser_process, [time_bounds]) if stats.mouse_wheel_scroll_latency: mean_mouse_wheel_scroll_latency = statistics.ArithmeticMean( stats.mouse_wheel_scroll_latency) mouse_wheel_scroll_latency_discrepancy = statistics.DurationsDiscrepancy( stats.mouse_wheel_scroll_latency) results.Add('mean_mouse_wheel_scroll_latency', 'ms', round(mean_mouse_wheel_scroll_latency, 3)) results.Add('mouse_wheel_scroll_latency_discrepancy', '', round(mouse_wheel_scroll_latency_discrepancy, 4)) if stats.touch_scroll_latency: mean_touch_scroll_latency = statistics.ArithmeticMean( stats.touch_scroll_latency) touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy( stats.touch_scroll_latency) results.Add('mean_touch_scroll_latency', 'ms', round(mean_touch_scroll_latency, 3)) results.Add('touch_scroll_latency_discrepancy', '', round(touch_scroll_latency_discrepancy, 4)) if stats.js_touch_scroll_latency: mean_js_touch_scroll_latency = statistics.ArithmeticMean( stats.js_touch_scroll_latency) js_touch_scroll_latency_discrepancy = statistics.DurationsDiscrepancy( stats.js_touch_scroll_latency) results.Add('mean_js_touch_scroll_latency', 'ms', round(mean_js_touch_scroll_latency, 3)) results.Add('js_touch_scroll_latency_discrepancy', '', round(js_touch_scroll_latency_discrepancy, 4)) # List of raw frame times. frame_times = FlattenList(stats.frame_times) results.Add('frame_times', 'ms', frame_times) # Arithmetic mean of frame times. mean_frame_time = statistics.ArithmeticMean(frame_times) results.Add('mean_frame_time', 'ms', round(mean_frame_time, 3)) # Absolute discrepancy of frame time stamps. frame_discrepancy = statistics.TimestampsDiscrepancy( stats.frame_timestamps) results.Add('jank', 'ms', round(frame_discrepancy, 4)) # Are we hitting 60 fps for 95 percent of all frames? # We use 19ms as a somewhat looser threshold, instead of 1000.0/60.0. percentile_95 = statistics.Percentile(frame_times, 95.0) results.Add('mostly_smooth', 'score', 1.0 if percentile_95 < 19.0 else 0.0)
def UpdateBounds(self): self._bounds.Reset() for event in self.IterAllEvents(): self._bounds.AddValue(event.start) self._bounds.AddValue(event.end) self._thread_time_bounds = {} for thread in self.GetAllThreads(): self._thread_time_bounds[thread] = bounds.Bounds() for event in thread.IterEventsInThisContainer(): if event.thread_start != None: self._thread_time_bounds[thread].AddValue(event.thread_start) if event.thread_end != None: self._thread_time_bounds[thread].AddValue(event.thread_end)
def __init__(self, timeline_data=None, shift_world_to_zero=True): """ Initializes a TimelineModel. timeline_data can be a single TimelineData object, a list of TimelineData objects, or None. If timeline_data is not None, all events from it will be imported into the model. The events will be shifted such that the first event starts at time 0, if shift_world_to_zero is True. """ self._bounds = bounds.Bounds() self._thread_time_bounds = {} self._processes = {} self._browser_process = None self._frozen = False self.import_errors = [] self.metadata = [] self.flow_events = [] # Use a WeakKeyDictionary, because an ordinary dictionary could keep # references to Tab objects around until it gets garbage collected. # This would prevent telemetry from navigating to another page. self._core_object_to_timeline_container_map = weakref.WeakKeyDictionary() if timeline_data is not None: self.ImportTraces(timeline_data, shift_world_to_zero=shift_world_to_zero)
def GetActionRange(self, start, end): action_range = bounds.Bounds() action_range.AddValue(start) action_range.AddValue(end) return action_range