def __init__(self, trace_data=None, shift_world_to_zero=True): """Initializes a TimelineModel. This class is deprecated, no new clients should use it. Args: trace_data: Either a TraceDataBuilder object, or a readable trace data value as generated by its AsData() method. When passing a builder, the data will be extracted from it, and the resources used by the builder cleaned up. This is to support legacy clients which were not aware of the responsibility to clean up trace data. shift_world_to_zero: If true, the events will be shifted such that the first event starts at time 0. """ super(TimelineModel, self).__init__(name='TimelineModel', parent=None) self._bounds = bounds.Bounds() self._thread_time_bounds = {} self._processes = {} self._browser_process = None self._gpu_process = None self._surface_flinger_process = None self._frozen = False self.import_errors = [] self.metadata = [] self.flow_events = [] self._global_memory_dumps = None if trace_data is not None: self._ImportTraces(_ExtractTraceData(trace_data), shift_world_to_zero=shift_world_to_zero)
def __init__(self, trace_data=None, shift_world_to_zero=True): """Initializes a TimelineModel. This class is deprecated, no new clients should use it. Args: trace_data: A readable trace data value, e.g. as generated by trace_builder.AsData(), containing events to import. shift_world_to_zero: If true, the events will be shifted such that the first event starts at time 0. """ super(TimelineModel, self).__init__(name='TimelineModel', parent=None) self._bounds = bounds.Bounds() self._thread_time_bounds = {} self._processes = {} self._browser_process = None self._gpu_process = None self._surface_flinger_process = None self._frozen = False self.import_errors = [] self.metadata = [] self.flow_events = [] self._global_memory_dumps = None if trace_data is not None: self._ImportTraces(trace_data, shift_world_to_zero=shift_world_to_zero)
def testFrameEventMissingBeginFrameId(self): timeline = model.TimelineModel() process = timeline.GetOrCreateProcess(pid=1) main_thread = process.GetOrCreateThread(tid=11) timeline_range = timeline_bounds.Bounds() # Create an event without the begin_frame_id argument event = tracing_slice.Slice(None, 'cc,benchmark', RenderingFrame.begin_main_frame_event, 0) main_thread.PushSlice(event) process.FinalizeImport() self.assertRaises(Exception, GetFrameEventsInsideRange, process, timeline_range)
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._tab_ids_to_renderer_threads_map = {} self.import_errors = [] self.metadata = [] self.flow_events = [] if timeline_data is not None: self.ImportTraces(timeline_data, shift_world_to_zero=shift_world_to_zero)
def __init__(self, trace_data=None, shift_world_to_zero=True): """ Initializes a TimelineModel. Args: trace_data: trace_data.TraceData containing events to import shift_world_to_zero: If true, the events will be shifted such that the first event starts at time 0. """ super(TimelineModel, self).__init__(name='TimelineModel', parent=None) self._bounds = bounds.Bounds() self._thread_time_bounds = {} self._processes = {} self._browser_process = None self._gpu_process = None self._surface_flinger_process = None self._frozen = False self.import_errors = [] self.metadata = [] self.flow_events = [] self._global_memory_dumps = None if trace_data is not None: self.ImportTraces(trace_data, shift_world_to_zero=shift_world_to_zero)
def __init__(self, events): all_send_begin_frame_events = [ e for e in events if e.name == self.send_begin_frame_event ] if len(all_send_begin_frame_events) != 1: raise MissingData('There must be at exactly one %s event.' % self.send_begin_frame_event) all_begin_main_frame_events = [ e for e in events if e.name == self.begin_main_frame_event ] if not all_begin_main_frame_events: raise MissingData('There must be at least one %s event.' % self.begin_main_frame_event) all_begin_main_frame_events.sort(key=lambda e: e.start) self._send_begin_frame = all_send_begin_frame_events[0] self._begin_main_frame = all_begin_main_frame_events[-1] self._bounds = bounds.Bounds() self._bounds.AddEvent(self._begin_main_frame) self._bounds.AddEvent(self._send_begin_frame)
def _CreateMergedEventsBoundaries(events, max_start_time): """ Merge events with the given |event_name| and return a list of MergedEvent objects. All events that are overlapping are megred together. Same as a union operation. Note: When merging multiple events, we approximate the thread_duration: duration = (last.thread_start + last.thread_duration) - first.thread_start Args: events: a list of TimelineEvents max_start_time: the maximum time that a TimelineEvent's start value can be. Events past this this time will be ignored. Returns: a sorted list of MergedEvent objects which contain a Bounds object of the wall time boundary and a thread_or_wall_duration which contains the thread duration if possible, and otherwise the wall duration. """ event_boundaries = [] # Contains EventBoundary objects. merged_event_boundaries = [] # Contains MergedEvent objects. # Deconstruct our trace events into boundaries, sort, and then create # MergedEvents. # This is O(N*log(N)), although this can be done in O(N) with fancy # datastructures. # Note: When merging multiple events, we approximate the thread_duration: # dur = (last.thread_start + last.thread_duration) - first.thread_start for event in events: # Handle events where thread duration is None (async events). thread_start = None thread_end = None if event.thread_start and event.thread_duration: thread_start = event.thread_start thread_end = event.thread_start + event.thread_duration event_boundaries.append( EventBoundary("start", event.start, thread_start)) event_boundaries.append(EventBoundary("end", event.end, thread_end)) event_boundaries.sort(key=lambda e: e[1]) # Merge all trace events that overlap. event_counter = 0 curr_bounds = None curr_thread_start = None for event_boundary in event_boundaries: if event_boundary.type == "start": event_counter += 1 else: event_counter -= 1 # Initialization if curr_bounds is None: assert event_boundary.type == "start" # Exit early if we reach the max time. if event_boundary.wall_time > max_start_time: return merged_event_boundaries curr_bounds = bounds.Bounds() curr_bounds.AddValue(event_boundary.wall_time) curr_thread_start = event_boundary.thread_time continue # Create a the final bounds and thread duration when our event grouping # is over. if event_counter == 0: curr_bounds.AddValue(event_boundary.wall_time) thread_or_wall_duration = curr_bounds.bounds if curr_thread_start and event_boundary.thread_time: thread_or_wall_duration = event_boundary.thread_time - curr_thread_start merged_event_boundaries.append( MergedEvent(curr_bounds, thread_or_wall_duration)) curr_bounds = None return merged_event_boundaries
def GetBounds(self): bounds = timeline_bounds.Bounds() bounds.AddValue(self.start) bounds.AddValue(self.end) return bounds
def GenerateTimelineRange(start=0, end=100): timeline_range = timeline_bounds.Bounds() timeline_range.AddValue(start) timeline_range.AddValue(end) return timeline_range