Exemple #1
0
class TimelineController(object):
  def __init__(self):
    super(TimelineController, self).__init__()
    self.trace_categories = DEFAULT_TRACE_CATEGORIES
    self._model = None
    self._renderer_process = None
    self._actions = []
    self._action_ranges = []

  def Start(self, page, tab):
    """Starts gathering timeline data.

    """
    # Resets these member variables incase this object is reused.
    self._model = None
    self._renderer_process = None
    self._actions = []
    self._action_ranges = []
    if not tab.browser.supports_tracing:
      raise Exception('Not supported')
    if self.trace_categories:
      categories = [self.trace_categories] + \
          page.GetSyntheticDelayCategories()
    else:
      categories = page.GetSyntheticDelayCategories()
    tab.browser.StartTracing(','.join(categories))

  def Stop(self, tab):
    timeline_data = tab.browser.StopTracing()
    self._model = TimelineModel(timeline_data)
    self._renderer_process = self._model.GetRendererProcessFromTab(tab)
    self._action_ranges = [ action.GetActiveRangeOnTimeline(self._model)
                            for action in self._actions ]
    # Make sure no action ranges overlap
    for combo in itertools.combinations(self._action_ranges, 2):
      assert not combo[0].Intersects(combo[1])

  def CleanUp(self, tab):
    if tab.browser.is_tracing_running:
      tab.browser.StopTracing()

  def AddActionToIncludeInMetric(self, action):
    self._actions.append(action)

  @property
  def model(self):
    return self._model

  @property
  def renderer_process(self):
    return self._renderer_process

  @property
  def action_ranges(self):
    return self._action_ranges
  def MeasurePage(self, page, tab, results):
    if not self._compositing_features_enabled:
      raise page_test.TestNotSupportedOnPlatformFailure(
          'Compositing feature status unknown or not '+
          'forced and threaded. Skipping measurement.')

    # Rasterize only what's visible.
    tab.ExecuteJavaScript(
        'chrome.gpuBenchmarking.setRasterizeOnlyVisibleContent();')

    # Wait until the page has loaded and come to a somewhat steady state.
    # Needs to be adjusted for every device (~2 seconds for workstation).
    time.sleep(self.options.start_wait_time)

    # Render one frame before we start gathering a trace. On some pages, the
    # first frame requested has more variance in the number of pixels
    # rasterized.
    tab.ExecuteJavaScript(
        'window.__rafFired = false;'
        'window.webkitRequestAnimationFrame(function() {'
          'chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers();'
          'window.__rafFired  = true;'
        '});')

    time.sleep(self.options.stop_wait_time)
    tab.browser.StartTracing('webkit.console,benchmark', 60)

    tab.ExecuteJavaScript(
        'window.__rafFired = false;'
        'window.webkitRequestAnimationFrame(function() {'
          'chrome.gpuBenchmarking.setNeedsDisplayOnAllLayers();'
          'console.time("' + TIMELINE_MARKER + '");'
          'window.__rafFired  = true;'
        '});')
    # Wait until the frame was drawn.
    # Needs to be adjusted for every device and for different
    # raster_record_repeat counts.
    # TODO(ernstm): replace by call-back.
    time.sleep(self.options.stop_wait_time)
    tab.ExecuteJavaScript(
        'console.timeEnd("' + TIMELINE_MARKER + '")')

    tracing_timeline_data = tab.browser.StopTracing()
    timeline = TimelineModel(timeline_data=tracing_timeline_data)
    try:
      timeline_markers = timeline.FindTimelineMarkers(TIMELINE_MARKER)
    except (MarkerMismatchError, MarkerOverlapError) as e:
      raise page_measurement.MeasurementFailure(str(e))
    timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker)
                        for marker in timeline_markers ]
    renderer_process = timeline.GetRendererProcessFromTab(tab)

    stats = rendering_stats.RenderingStats(
        renderer_process, timeline.browser_process, timeline_ranges)

    results.Add('rasterize_time', 'ms', max(FlattenList(stats.rasterize_times)))
    results.Add('record_time', 'ms', max(FlattenList(stats.record_times)))
    results.Add('rasterized_pixels', 'pixels',
                max(FlattenList(stats.rasterized_pixel_counts)))
    results.Add('recorded_pixels', 'pixels',
                max(FlattenList(stats.recorded_pixel_counts)))
class TimelineController(object):
  def __init__(self):
    super(TimelineController, self).__init__()
    self.trace_categories = tracing_backend.DEFAULT_TRACE_CATEGORIES
    self._model = None
    self._renderer_process = None
    self._smooth_records = []

  def Start(self, page, tab):
    """Starts gathering timeline data.

    """
    # Resets these member variables incase this object is reused.
    self._model = None
    self._renderer_process = None
    if not tab.browser.supports_tracing:
      raise Exception('Not supported')
    if self.trace_categories:
      categories = [self.trace_categories] + \
          page.GetSyntheticDelayCategories()
    else:
      categories = page.GetSyntheticDelayCategories()
    tab.browser.StartTracing(','.join(categories))
    # Start the smooth marker for all actions.
    runner = action_runner.ActionRunner(None, tab)
    runner.BeginInteraction(RUN_SMOOTH_ACTIONS, [tir_module.IS_SMOOTH])

  def Stop(self, tab):
    # End the smooth marker for all actions.
    runner = action_runner.ActionRunner(None, tab)
    runner.EndInteraction(RUN_SMOOTH_ACTIONS, [tir_module.IS_SMOOTH])
    # Stop tracing.
    timeline_data = tab.browser.StopTracing()
    self._model = TimelineModel(timeline_data)
    self._renderer_process = self._model.GetRendererProcessFromTab(tab)
    renderer_thread = self.model.GetRendererThreadFromTab(tab)

    run_smooth_actions_record = None
    self._smooth_records = []
    for event in renderer_thread.async_slices:
      if not tir_module.IsTimelineInteractionRecord(event.name):
        continue
      r = tir_module.TimelineInteractionRecord.FromEvent(event)
      if r.logical_name == RUN_SMOOTH_ACTIONS:
        assert run_smooth_actions_record is None, (
          'TimelineController cannot issue more than 1 %s record' %
          RUN_SMOOTH_ACTIONS)
        run_smooth_actions_record = r
      elif r.is_smooth:
        self._smooth_records.append(
          smooth_gesture_util.GetAdjustedInteractionIfContainGesture(
            self.model, r))

    # If there is no other smooth records, we make measurements on time range
    # marked by timeline_controller itself.
    # TODO(nednguyen): when crbug.com/239179 is marked fixed, makes sure that
    # page sets are responsible for issueing the markers themselves.
    if len(self._smooth_records) == 0 and run_smooth_actions_record:
      self._smooth_records = [run_smooth_actions_record]


  def CleanUp(self, tab):
    if tab.browser.is_tracing_running:
      tab.browser.StopTracing()

  @property
  def model(self):
    return self._model

  @property
  def renderer_process(self):
    return self._renderer_process

  @property
  def smooth_records(self):
    return self._smooth_records