parameters: (self)
return_statement: return (refresh_period, timestamps)
docstring: Returns collected SurfaceFlinger frame timing data.
  
      Returns:
        A tuple containing:
        - The display's nominal refresh period in milliseconds.
        - A list of timestamps signifying frame presentation times in
          milliseconds.
        The return value may be (None, None) if there was no data collected (for
        example, if the app was closed before the collector thread has finished).
docstring_summary: Returns collected SurfaceFlinger frame timing data.
docstring_tokens: Returns collected SurfaceFlinger frame timing data .
function: def _GetSurfaceFlingerFrameData(self):
      """Returns collected SurfaceFlinger frame timing data.
  
      Returns:
        A tuple containing:
        - The display's nominal refresh period in milliseconds.
        - A list of timestamps signifying frame presentation times in
          milliseconds.
        The return value may be (None, None) if there was no data collected (for
        example, if the app was closed before the collector thread has finished).
      """
      # adb shell dumpsys SurfaceFlinger --latency <window name>
      # prints some information about the last 128 frames displayed in
      # that window.
      # The data returned looks like this:
      # 16954612
      # 7657467895508   7657482691352   7657493499756
      # 7657484466553   7657499645964   7657511077881
      # 7657500793457   7657516600576   7657527404785
      # (...)
      #
      # The first line is the refresh period (here 16.95 ms), it is followed
      # by 128 lines w/ 3 timestamps in nanosecond each:
      # A) when the app started to draw
      # B) the vsync immediately preceding SF submitting the frame to the h/w
      # C) timestamp immediately after SF submitted that frame to the h/w
      #
      # The difference between the 1st and 3rd timestamp is the frame-latency.
      # An interesting data is when the frame latency crosses a refresh period
      # boundary, this can be calculated this way:
      #
      # ceil((C - A) / refresh-period)
      #
      # (each time the number above changes, we have a "jank").
      # If this happens a lot during an animation, the animation appears
      # janky, even if it runs at 60 fps in average.
      #
      # We use the special "SurfaceView" window name because the statistics for
      # the activity's main window are not updated when the main web content is
      # composited into a SurfaceView.
      results = self._device.RunShellCommand(
          ['dumpsys', 'SurfaceFlinger', '--latency', 'SurfaceView'],
          check_return=True)
      if not len(results):
        return (None, None)
  
      timestamps = []
      nanoseconds_per_millisecond = 1e6
      refresh_period = long(results[0]) / nanoseconds_per_millisecond
  
      # If a fence associated with a frame is still pending when we query the
      # latency data, SurfaceFlinger gives the frame a timestamp of INT64_MAX.
      # Since we only care about completed frames, we will ignore any timestamps
      # with this value.
      pending_fence_timestamp = (1 << 63) - 1
  
      for line in results[1:]:
        fields = line.split()
        if len(fields) != 3:
          continue
        timestamp = long(fields[1])
        if timestamp == pending_fence_timestamp:
          continue
        timestamp /= nanoseconds_per_millisecond
        timestamps.append(timestamp)
  
      return (refresh_period, timestamps)
function_tokens: def _GetSurfaceFlingerFrameData ( self ) : # adb shell dumpsys SurfaceFlinger --latency <window name> # prints some information about the last 128 frames displayed in # that window. # The data returned looks like this: # 16954612 # 7657467895508   7657482691352   7657493499756 # 7657484466553   7657499645964   7657511077881 # 7657500793457   7657516600576   7657527404785 # (...) # # The first line is the refresh period (here 16.95 ms), it is followed # by 128 lines w/ 3 timestamps in nanosecond each: # A) when the app started to draw # B) the vsync immediately preceding SF submitting the frame to the h/w # C) timestamp immediately after SF submitted that frame to the h/w # # The difference between the 1st and 3rd timestamp is the frame-latency. # An interesting data is when the frame latency crosses a refresh period # boundary, this can be calculated this way: # # ceil((C - A) / refresh-period) # # (each time the number above changes, we have a "jank"). # If this happens a lot during an animation, the animation appears # janky, even if it runs at 60 fps in average. # # We use the special "SurfaceView" window name because the statistics for # the activity's main window are not updated when the main web content is # composited into a SurfaceView. results = self . _device . RunShellCommand ( [ 'dumpsys' , 'SurfaceFlinger' , '--latency' , 'SurfaceView' ] , check_return = True ) if not len ( results ) : return ( None , None ) timestamps = [ ] nanoseconds_per_millisecond = 1e6 refresh_period = long ( results [ 0 ] ) / nanoseconds_per_millisecond # If a fence associated with a frame is still pending when we query the # latency data, SurfaceFlinger gives the frame a timestamp of INT64_MAX. # Since we only care about completed frames, we will ignore any timestamps # with this value. pending_fence_timestamp = ( 1 << 63 ) - 1 for line in results [ 1 : ] : fields = line . split ( ) if len ( fields ) != 3 : continue timestamp = long ( fields [ 1 ] ) if timestamp == pending_fence_timestamp : continue timestamp /= nanoseconds_per_millisecond timestamps . append ( timestamp ) return ( refresh_period , timestamps )