• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[
2  {
3    "cmd": [
4      "vpython",
5      "-u",
6      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
7      "--json-output",
8      "/path/to/tmp/json",
9      "listdir",
10      "[START_DIR]/lottie-samples"
11    ],
12    "infra_step": true,
13    "name": "list lottie files",
14    "~followup_annotations": [
15      "@@@STEP_LOG_LINE@listdir@[START_DIR]/lottie-samples/LICENSE@@@",
16      "@@@STEP_LOG_LINE@listdir@[START_DIR]/lottie-samples/lottie1.json@@@",
17      "@@@STEP_LOG_LINE@listdir@[START_DIR]/lottie-samples/lottie2.json@@@",
18      "@@@STEP_LOG_LINE@listdir@[START_DIR]/lottie-samples/lottie3.json@@@",
19      "@@@STEP_LOG_END@listdir@@@"
20    ]
21  },
22  {
23    "cmd": [
24      "npm",
25      "install"
26    ],
27    "cwd": "[START_DIR]/skia/tools/lottie-web-perf",
28    "env_prefixes": {
29      "PATH": [
30        "[START_DIR]/node/node/bin"
31      ]
32    },
33    "name": "npm install"
34  },
35  {
36    "cmd": [
37      "[START_DIR]/node/node/bin/node",
38      "[START_DIR]/skia/tools/lottie-web-perf/lottie-web-perf.js",
39      "--backend",
40      "svg",
41      "--input",
42      "[START_DIR]/lottie-samples/lottie1.json",
43      "--output",
44      "[CLEANUP]/g3_try_tmp_1/lottie1.json"
45    ],
46    "cwd": "[START_DIR]/skia/tools/lottie-web-perf",
47    "env": {
48      "CHROME_HEADLESS": "1",
49      "DISPLAY": ":0",
50      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
51    },
52    "infra_step": true,
53    "name": "Run perf cmd line app"
54  },
55  {
56    "cmd": [
57      "python",
58      "-u",
59      "\nimport json\nimport sys\n\ntrace_output = sys.argv[1]\nwith open(trace_output, 'r') as f:\n  trace_json = json.load(f)\noutput_json_file = sys.argv[2]\nrenderer = sys.argv[3]  # Unused for now but might be useful in the future.\n\n# Output data about the GPU that was used.\nprint('GPU data:')\nprint(trace_json['metadata'].get('gpu-gl-renderer'))\nprint(trace_json['metadata'].get('gpu-driver'))\nprint(trace_json['metadata'].get('gpu-gl-vendor'))\n\nerroneous_termination_statuses = [\n    'replaced_by_new_reporter_at_same_stage',\n    'did_not_produce_frame',\n]\naccepted_termination_statuses = [\n    'missed_frame',\n    'submitted_frame',\n    'main_frame_aborted'\n]\n\ncurrent_frame_duration = 0\ntotal_frames = 0\nframe_id_to_start_ts = {}\n# Will contain tuples of frame_ids and their duration and status.\ncompleted_frame_id_and_duration_status = []\n# Will contain tuples of drawn frame_ids and their duration.\ndrawn_frame_id_and_duration = []\nfor trace in trace_json['traceEvents']:\n  if 'PipelineReporter' in trace['name']:\n    frame_id = trace['id']\n    args = trace.get('args')\n    if args and args.get('step') == 'BeginImplFrameToSendBeginMainFrame':\n      frame_id_to_start_ts[frame_id] = trace['ts']\n    elif args and (args.get('termination_status') in\n                   accepted_termination_statuses):\n      if not frame_id_to_start_ts.get(frame_id):\n        print('[No start ts found for %s]' % frame_id)\n        continue\n      current_frame_duration = trace['ts'] - frame_id_to_start_ts[frame_id]\n      total_frames += 1\n      completed_frame_id_and_duration_status.append(\n          (frame_id, current_frame_duration, args['termination_status']))\n      if(args['termination_status'] == 'missed_frame' or\n       args['termination_status'] == 'submitted_frame'):\n        drawn_frame_id_and_duration.append((frame_id, current_frame_duration))\n\n      # We are done with this frame_id so remove it from the dict.\n      frame_id_to_start_ts.pop(frame_id)\n      print('%d (%s with %s): %d' % (\n          total_frames, frame_id, args['termination_status'],\n          current_frame_duration))\n    elif args and (args.get('termination_status') in\n                   erroneous_termination_statuses):\n      # Invalidate previously collected results for this frame_id.\n      if frame_id_to_start_ts.get(frame_id):\n        print('[Invalidating %s due to %s]' % (\n            frame_id, args['termination_status']))\n        frame_id_to_start_ts.pop(frame_id)\n\n# Calculate metrics for total completed frames.\ntotal_completed_frames = len(completed_frame_id_and_duration_status)\nif total_completed_frames < 25:\n  raise Exception('Even with 3 loops found only %d frames' %\n                  total_completed_frames)\n# Get frame avg/min/max for the middle 25 frames.\nstart = (total_completed_frames - 25)/2\nprint('Got %d total completed frames. Using indexes [%d, %d).' % (\n    total_completed_frames, start, start+25))\nframe_max = 0\nframe_min = 0\nframe_cumulative = 0\naborted_frames = 0\nfor frame_id, duration, status in (\n    completed_frame_id_and_duration_status[start:start+25]):\n  frame_max = max(frame_max, duration)\n  frame_min = min(frame_min, duration) if frame_min else duration\n  frame_cumulative += duration\n  if status == 'main_frame_aborted':\n    aborted_frames += 1\n\nperf_results = {}\nperf_results['frame_max_us'] = frame_max\nperf_results['frame_min_us'] = frame_min\nperf_results['frame_avg_us'] = frame_cumulative/25\nperf_results['aborted_frames'] = aborted_frames\n\n# Now calculate metrics for only drawn frames.\ndrawn_frame_max = 0\ndrawn_frame_min = 0\ndrawn_frame_cumulative = 0\ntotal_drawn_frames = len(drawn_frame_id_and_duration)\nif total_drawn_frames < 25:\n  raise Exception('Even with 3 loops found only %d drawn frames' %\n                  total_drawn_frames)\n# Get drawn frame avg/min/max from the middle 25 frames.\nstart = (total_drawn_frames - 25)/2\nprint('Got %d total drawn frames. Using indexes [%d-%d).' % (\n      total_drawn_frames, start, start+25))\nfor frame_id, duration in drawn_frame_id_and_duration[start:start+25]:\n  drawn_frame_max = max(drawn_frame_max, duration)\n  drawn_frame_min = (min(drawn_frame_min, duration)\n                     if drawn_frame_min else duration)\n  drawn_frame_cumulative += duration\n# Add metrics to perf_results.\nperf_results['drawn_frame_max_us'] = drawn_frame_max\nperf_results['drawn_frame_min_us'] = drawn_frame_min\nperf_results['drawn_frame_avg_us'] = drawn_frame_cumulative/25\n\nprint('Final perf_results dict: %s' % perf_results)\n\n# Write perf_results to the output json.\nwith open(output_json_file, 'w') as f:\n  f.write(json.dumps(perf_results))\n",
60      "[CLEANUP]/g3_try_tmp_1/lottie1.json",
61      "/path/to/tmp/json",
62      "lottie-web"
63    ],
64    "env": {
65      "CHROME_HEADLESS": "1",
66      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
67    },
68    "name": "parse lottie1.json trace",
69    "~followup_annotations": [
70      "@@@STEP_LOG_LINE@json.output@{@@@",
71      "@@@STEP_LOG_LINE@json.output@  \"frame_avg_us\": 179.71, @@@",
72      "@@@STEP_LOG_LINE@json.output@  \"frame_max_us\": 218.25, @@@",
73      "@@@STEP_LOG_LINE@json.output@  \"frame_min_us\": 141.17@@@",
74      "@@@STEP_LOG_LINE@json.output@}@@@",
75      "@@@STEP_LOG_END@json.output@@@",
76      "@@@STEP_LOG_LINE@python.inline@@@@",
77      "@@@STEP_LOG_LINE@python.inline@import json@@@",
78      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
79      "@@@STEP_LOG_LINE@python.inline@@@@",
80      "@@@STEP_LOG_LINE@python.inline@trace_output = sys.argv[1]@@@",
81      "@@@STEP_LOG_LINE@python.inline@with open(trace_output, 'r') as f:@@@",
82      "@@@STEP_LOG_LINE@python.inline@  trace_json = json.load(f)@@@",
83      "@@@STEP_LOG_LINE@python.inline@output_json_file = sys.argv[2]@@@",
84      "@@@STEP_LOG_LINE@python.inline@renderer = sys.argv[3]  # Unused for now but might be useful in the future.@@@",
85      "@@@STEP_LOG_LINE@python.inline@@@@",
86      "@@@STEP_LOG_LINE@python.inline@# Output data about the GPU that was used.@@@",
87      "@@@STEP_LOG_LINE@python.inline@print('GPU data:')@@@",
88      "@@@STEP_LOG_LINE@python.inline@print(trace_json['metadata'].get('gpu-gl-renderer'))@@@",
89      "@@@STEP_LOG_LINE@python.inline@print(trace_json['metadata'].get('gpu-driver'))@@@",
90      "@@@STEP_LOG_LINE@python.inline@print(trace_json['metadata'].get('gpu-gl-vendor'))@@@",
91      "@@@STEP_LOG_LINE@python.inline@@@@",
92      "@@@STEP_LOG_LINE@python.inline@erroneous_termination_statuses = [@@@",
93      "@@@STEP_LOG_LINE@python.inline@    'replaced_by_new_reporter_at_same_stage',@@@",
94      "@@@STEP_LOG_LINE@python.inline@    'did_not_produce_frame',@@@",
95      "@@@STEP_LOG_LINE@python.inline@]@@@",
96      "@@@STEP_LOG_LINE@python.inline@accepted_termination_statuses = [@@@",
97      "@@@STEP_LOG_LINE@python.inline@    'missed_frame',@@@",
98      "@@@STEP_LOG_LINE@python.inline@    'submitted_frame',@@@",
99      "@@@STEP_LOG_LINE@python.inline@    'main_frame_aborted'@@@",
100      "@@@STEP_LOG_LINE@python.inline@]@@@",
101      "@@@STEP_LOG_LINE@python.inline@@@@",
102      "@@@STEP_LOG_LINE@python.inline@current_frame_duration = 0@@@",
103      "@@@STEP_LOG_LINE@python.inline@total_frames = 0@@@",
104      "@@@STEP_LOG_LINE@python.inline@frame_id_to_start_ts = {}@@@",
105      "@@@STEP_LOG_LINE@python.inline@# Will contain tuples of frame_ids and their duration and status.@@@",
106      "@@@STEP_LOG_LINE@python.inline@completed_frame_id_and_duration_status = []@@@",
107      "@@@STEP_LOG_LINE@python.inline@# Will contain tuples of drawn frame_ids and their duration.@@@",
108      "@@@STEP_LOG_LINE@python.inline@drawn_frame_id_and_duration = []@@@",
109      "@@@STEP_LOG_LINE@python.inline@for trace in trace_json['traceEvents']:@@@",
110      "@@@STEP_LOG_LINE@python.inline@  if 'PipelineReporter' in trace['name']:@@@",
111      "@@@STEP_LOG_LINE@python.inline@    frame_id = trace['id']@@@",
112      "@@@STEP_LOG_LINE@python.inline@    args = trace.get('args')@@@",
113      "@@@STEP_LOG_LINE@python.inline@    if args and args.get('step') == 'BeginImplFrameToSendBeginMainFrame':@@@",
114      "@@@STEP_LOG_LINE@python.inline@      frame_id_to_start_ts[frame_id] = trace['ts']@@@",
115      "@@@STEP_LOG_LINE@python.inline@    elif args and (args.get('termination_status') in@@@",
116      "@@@STEP_LOG_LINE@python.inline@                   accepted_termination_statuses):@@@",
117      "@@@STEP_LOG_LINE@python.inline@      if not frame_id_to_start_ts.get(frame_id):@@@",
118      "@@@STEP_LOG_LINE@python.inline@        print('[No start ts found for %s]' % frame_id)@@@",
119      "@@@STEP_LOG_LINE@python.inline@        continue@@@",
120      "@@@STEP_LOG_LINE@python.inline@      current_frame_duration = trace['ts'] - frame_id_to_start_ts[frame_id]@@@",
121      "@@@STEP_LOG_LINE@python.inline@      total_frames += 1@@@",
122      "@@@STEP_LOG_LINE@python.inline@      completed_frame_id_and_duration_status.append(@@@",
123      "@@@STEP_LOG_LINE@python.inline@          (frame_id, current_frame_duration, args['termination_status']))@@@",
124      "@@@STEP_LOG_LINE@python.inline@      if(args['termination_status'] == 'missed_frame' or@@@",
125      "@@@STEP_LOG_LINE@python.inline@       args['termination_status'] == 'submitted_frame'):@@@",
126      "@@@STEP_LOG_LINE@python.inline@        drawn_frame_id_and_duration.append((frame_id, current_frame_duration))@@@",
127      "@@@STEP_LOG_LINE@python.inline@@@@",
128      "@@@STEP_LOG_LINE@python.inline@      # We are done with this frame_id so remove it from the dict.@@@",
129      "@@@STEP_LOG_LINE@python.inline@      frame_id_to_start_ts.pop(frame_id)@@@",
130      "@@@STEP_LOG_LINE@python.inline@      print('%d (%s with %s): %d' % (@@@",
131      "@@@STEP_LOG_LINE@python.inline@          total_frames, frame_id, args['termination_status'],@@@",
132      "@@@STEP_LOG_LINE@python.inline@          current_frame_duration))@@@",
133      "@@@STEP_LOG_LINE@python.inline@    elif args and (args.get('termination_status') in@@@",
134      "@@@STEP_LOG_LINE@python.inline@                   erroneous_termination_statuses):@@@",
135      "@@@STEP_LOG_LINE@python.inline@      # Invalidate previously collected results for this frame_id.@@@",
136      "@@@STEP_LOG_LINE@python.inline@      if frame_id_to_start_ts.get(frame_id):@@@",
137      "@@@STEP_LOG_LINE@python.inline@        print('[Invalidating %s due to %s]' % (@@@",
138      "@@@STEP_LOG_LINE@python.inline@            frame_id, args['termination_status']))@@@",
139      "@@@STEP_LOG_LINE@python.inline@        frame_id_to_start_ts.pop(frame_id)@@@",
140      "@@@STEP_LOG_LINE@python.inline@@@@",
141      "@@@STEP_LOG_LINE@python.inline@# Calculate metrics for total completed frames.@@@",
142      "@@@STEP_LOG_LINE@python.inline@total_completed_frames = len(completed_frame_id_and_duration_status)@@@",
143      "@@@STEP_LOG_LINE@python.inline@if total_completed_frames < 25:@@@",
144      "@@@STEP_LOG_LINE@python.inline@  raise Exception('Even with 3 loops found only %d frames' %@@@",
145      "@@@STEP_LOG_LINE@python.inline@                  total_completed_frames)@@@",
146      "@@@STEP_LOG_LINE@python.inline@# Get frame avg/min/max for the middle 25 frames.@@@",
147      "@@@STEP_LOG_LINE@python.inline@start = (total_completed_frames - 25)/2@@@",
148      "@@@STEP_LOG_LINE@python.inline@print('Got %d total completed frames. Using indexes [%d, %d).' % (@@@",
149      "@@@STEP_LOG_LINE@python.inline@    total_completed_frames, start, start+25))@@@",
150      "@@@STEP_LOG_LINE@python.inline@frame_max = 0@@@",
151      "@@@STEP_LOG_LINE@python.inline@frame_min = 0@@@",
152      "@@@STEP_LOG_LINE@python.inline@frame_cumulative = 0@@@",
153      "@@@STEP_LOG_LINE@python.inline@aborted_frames = 0@@@",
154      "@@@STEP_LOG_LINE@python.inline@for frame_id, duration, status in (@@@",
155      "@@@STEP_LOG_LINE@python.inline@    completed_frame_id_and_duration_status[start:start+25]):@@@",
156      "@@@STEP_LOG_LINE@python.inline@  frame_max = max(frame_max, duration)@@@",
157      "@@@STEP_LOG_LINE@python.inline@  frame_min = min(frame_min, duration) if frame_min else duration@@@",
158      "@@@STEP_LOG_LINE@python.inline@  frame_cumulative += duration@@@",
159      "@@@STEP_LOG_LINE@python.inline@  if status == 'main_frame_aborted':@@@",
160      "@@@STEP_LOG_LINE@python.inline@    aborted_frames += 1@@@",
161      "@@@STEP_LOG_LINE@python.inline@@@@",
162      "@@@STEP_LOG_LINE@python.inline@perf_results = {}@@@",
163      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_max_us'] = frame_max@@@",
164      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_min_us'] = frame_min@@@",
165      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_avg_us'] = frame_cumulative/25@@@",
166      "@@@STEP_LOG_LINE@python.inline@perf_results['aborted_frames'] = aborted_frames@@@",
167      "@@@STEP_LOG_LINE@python.inline@@@@",
168      "@@@STEP_LOG_LINE@python.inline@# Now calculate metrics for only drawn frames.@@@",
169      "@@@STEP_LOG_LINE@python.inline@drawn_frame_max = 0@@@",
170      "@@@STEP_LOG_LINE@python.inline@drawn_frame_min = 0@@@",
171      "@@@STEP_LOG_LINE@python.inline@drawn_frame_cumulative = 0@@@",
172      "@@@STEP_LOG_LINE@python.inline@total_drawn_frames = len(drawn_frame_id_and_duration)@@@",
173      "@@@STEP_LOG_LINE@python.inline@if total_drawn_frames < 25:@@@",
174      "@@@STEP_LOG_LINE@python.inline@  raise Exception('Even with 3 loops found only %d drawn frames' %@@@",
175      "@@@STEP_LOG_LINE@python.inline@                  total_drawn_frames)@@@",
176      "@@@STEP_LOG_LINE@python.inline@# Get drawn frame avg/min/max from the middle 25 frames.@@@",
177      "@@@STEP_LOG_LINE@python.inline@start = (total_drawn_frames - 25)/2@@@",
178      "@@@STEP_LOG_LINE@python.inline@print('Got %d total drawn frames. Using indexes [%d-%d).' % (@@@",
179      "@@@STEP_LOG_LINE@python.inline@      total_drawn_frames, start, start+25))@@@",
180      "@@@STEP_LOG_LINE@python.inline@for frame_id, duration in drawn_frame_id_and_duration[start:start+25]:@@@",
181      "@@@STEP_LOG_LINE@python.inline@  drawn_frame_max = max(drawn_frame_max, duration)@@@",
182      "@@@STEP_LOG_LINE@python.inline@  drawn_frame_min = (min(drawn_frame_min, duration)@@@",
183      "@@@STEP_LOG_LINE@python.inline@                     if drawn_frame_min else duration)@@@",
184      "@@@STEP_LOG_LINE@python.inline@  drawn_frame_cumulative += duration@@@",
185      "@@@STEP_LOG_LINE@python.inline@# Add metrics to perf_results.@@@",
186      "@@@STEP_LOG_LINE@python.inline@perf_results['drawn_frame_max_us'] = drawn_frame_max@@@",
187      "@@@STEP_LOG_LINE@python.inline@perf_results['drawn_frame_min_us'] = drawn_frame_min@@@",
188      "@@@STEP_LOG_LINE@python.inline@perf_results['drawn_frame_avg_us'] = drawn_frame_cumulative/25@@@",
189      "@@@STEP_LOG_LINE@python.inline@@@@",
190      "@@@STEP_LOG_LINE@python.inline@print('Final perf_results dict: %s' % perf_results)@@@",
191      "@@@STEP_LOG_LINE@python.inline@@@@",
192      "@@@STEP_LOG_LINE@python.inline@# Write perf_results to the output json.@@@",
193      "@@@STEP_LOG_LINE@python.inline@with open(output_json_file, 'w') as f:@@@",
194      "@@@STEP_LOG_LINE@python.inline@  f.write(json.dumps(perf_results))@@@",
195      "@@@STEP_LOG_END@python.inline@@@"
196    ]
197  },
198  {
199    "cmd": [
200      "[START_DIR]/node/node/bin/node",
201      "[START_DIR]/skia/tools/lottie-web-perf/lottie-web-perf.js",
202      "--backend",
203      "svg",
204      "--input",
205      "[START_DIR]/lottie-samples/lottie2.json",
206      "--output",
207      "[CLEANUP]/g3_try_tmp_1/lottie2.json"
208    ],
209    "cwd": "[START_DIR]/skia/tools/lottie-web-perf",
210    "env": {
211      "CHROME_HEADLESS": "1",
212      "DISPLAY": ":0",
213      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
214    },
215    "infra_step": true,
216    "name": "Run perf cmd line app (2)"
217  },
218  {
219    "cmd": [
220      "python",
221      "-u",
222      "\nimport json\nimport sys\n\ntrace_output = sys.argv[1]\nwith open(trace_output, 'r') as f:\n  trace_json = json.load(f)\noutput_json_file = sys.argv[2]\nrenderer = sys.argv[3]  # Unused for now but might be useful in the future.\n\n# Output data about the GPU that was used.\nprint('GPU data:')\nprint(trace_json['metadata'].get('gpu-gl-renderer'))\nprint(trace_json['metadata'].get('gpu-driver'))\nprint(trace_json['metadata'].get('gpu-gl-vendor'))\n\nerroneous_termination_statuses = [\n    'replaced_by_new_reporter_at_same_stage',\n    'did_not_produce_frame',\n]\naccepted_termination_statuses = [\n    'missed_frame',\n    'submitted_frame',\n    'main_frame_aborted'\n]\n\ncurrent_frame_duration = 0\ntotal_frames = 0\nframe_id_to_start_ts = {}\n# Will contain tuples of frame_ids and their duration and status.\ncompleted_frame_id_and_duration_status = []\n# Will contain tuples of drawn frame_ids and their duration.\ndrawn_frame_id_and_duration = []\nfor trace in trace_json['traceEvents']:\n  if 'PipelineReporter' in trace['name']:\n    frame_id = trace['id']\n    args = trace.get('args')\n    if args and args.get('step') == 'BeginImplFrameToSendBeginMainFrame':\n      frame_id_to_start_ts[frame_id] = trace['ts']\n    elif args and (args.get('termination_status') in\n                   accepted_termination_statuses):\n      if not frame_id_to_start_ts.get(frame_id):\n        print('[No start ts found for %s]' % frame_id)\n        continue\n      current_frame_duration = trace['ts'] - frame_id_to_start_ts[frame_id]\n      total_frames += 1\n      completed_frame_id_and_duration_status.append(\n          (frame_id, current_frame_duration, args['termination_status']))\n      if(args['termination_status'] == 'missed_frame' or\n       args['termination_status'] == 'submitted_frame'):\n        drawn_frame_id_and_duration.append((frame_id, current_frame_duration))\n\n      # We are done with this frame_id so remove it from the dict.\n      frame_id_to_start_ts.pop(frame_id)\n      print('%d (%s with %s): %d' % (\n          total_frames, frame_id, args['termination_status'],\n          current_frame_duration))\n    elif args and (args.get('termination_status') in\n                   erroneous_termination_statuses):\n      # Invalidate previously collected results for this frame_id.\n      if frame_id_to_start_ts.get(frame_id):\n        print('[Invalidating %s due to %s]' % (\n            frame_id, args['termination_status']))\n        frame_id_to_start_ts.pop(frame_id)\n\n# Calculate metrics for total completed frames.\ntotal_completed_frames = len(completed_frame_id_and_duration_status)\nif total_completed_frames < 25:\n  raise Exception('Even with 3 loops found only %d frames' %\n                  total_completed_frames)\n# Get frame avg/min/max for the middle 25 frames.\nstart = (total_completed_frames - 25)/2\nprint('Got %d total completed frames. Using indexes [%d, %d).' % (\n    total_completed_frames, start, start+25))\nframe_max = 0\nframe_min = 0\nframe_cumulative = 0\naborted_frames = 0\nfor frame_id, duration, status in (\n    completed_frame_id_and_duration_status[start:start+25]):\n  frame_max = max(frame_max, duration)\n  frame_min = min(frame_min, duration) if frame_min else duration\n  frame_cumulative += duration\n  if status == 'main_frame_aborted':\n    aborted_frames += 1\n\nperf_results = {}\nperf_results['frame_max_us'] = frame_max\nperf_results['frame_min_us'] = frame_min\nperf_results['frame_avg_us'] = frame_cumulative/25\nperf_results['aborted_frames'] = aborted_frames\n\n# Now calculate metrics for only drawn frames.\ndrawn_frame_max = 0\ndrawn_frame_min = 0\ndrawn_frame_cumulative = 0\ntotal_drawn_frames = len(drawn_frame_id_and_duration)\nif total_drawn_frames < 25:\n  raise Exception('Even with 3 loops found only %d drawn frames' %\n                  total_drawn_frames)\n# Get drawn frame avg/min/max from the middle 25 frames.\nstart = (total_drawn_frames - 25)/2\nprint('Got %d total drawn frames. Using indexes [%d-%d).' % (\n      total_drawn_frames, start, start+25))\nfor frame_id, duration in drawn_frame_id_and_duration[start:start+25]:\n  drawn_frame_max = max(drawn_frame_max, duration)\n  drawn_frame_min = (min(drawn_frame_min, duration)\n                     if drawn_frame_min else duration)\n  drawn_frame_cumulative += duration\n# Add metrics to perf_results.\nperf_results['drawn_frame_max_us'] = drawn_frame_max\nperf_results['drawn_frame_min_us'] = drawn_frame_min\nperf_results['drawn_frame_avg_us'] = drawn_frame_cumulative/25\n\nprint('Final perf_results dict: %s' % perf_results)\n\n# Write perf_results to the output json.\nwith open(output_json_file, 'w') as f:\n  f.write(json.dumps(perf_results))\n",
223      "[CLEANUP]/g3_try_tmp_1/lottie2.json",
224      "/path/to/tmp/json",
225      "lottie-web"
226    ],
227    "env": {
228      "CHROME_HEADLESS": "1",
229      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
230    },
231    "name": "parse lottie2.json trace",
232    "~followup_annotations": [
233      "@@@STEP_LOG_LINE@json.output@{@@@",
234      "@@@STEP_LOG_LINE@json.output@  \"frame_avg_us\": 179.71, @@@",
235      "@@@STEP_LOG_LINE@json.output@  \"frame_max_us\": 218.25, @@@",
236      "@@@STEP_LOG_LINE@json.output@  \"frame_min_us\": 141.17@@@",
237      "@@@STEP_LOG_LINE@json.output@}@@@",
238      "@@@STEP_LOG_END@json.output@@@",
239      "@@@STEP_LOG_LINE@python.inline@@@@",
240      "@@@STEP_LOG_LINE@python.inline@import json@@@",
241      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
242      "@@@STEP_LOG_LINE@python.inline@@@@",
243      "@@@STEP_LOG_LINE@python.inline@trace_output = sys.argv[1]@@@",
244      "@@@STEP_LOG_LINE@python.inline@with open(trace_output, 'r') as f:@@@",
245      "@@@STEP_LOG_LINE@python.inline@  trace_json = json.load(f)@@@",
246      "@@@STEP_LOG_LINE@python.inline@output_json_file = sys.argv[2]@@@",
247      "@@@STEP_LOG_LINE@python.inline@renderer = sys.argv[3]  # Unused for now but might be useful in the future.@@@",
248      "@@@STEP_LOG_LINE@python.inline@@@@",
249      "@@@STEP_LOG_LINE@python.inline@# Output data about the GPU that was used.@@@",
250      "@@@STEP_LOG_LINE@python.inline@print('GPU data:')@@@",
251      "@@@STEP_LOG_LINE@python.inline@print(trace_json['metadata'].get('gpu-gl-renderer'))@@@",
252      "@@@STEP_LOG_LINE@python.inline@print(trace_json['metadata'].get('gpu-driver'))@@@",
253      "@@@STEP_LOG_LINE@python.inline@print(trace_json['metadata'].get('gpu-gl-vendor'))@@@",
254      "@@@STEP_LOG_LINE@python.inline@@@@",
255      "@@@STEP_LOG_LINE@python.inline@erroneous_termination_statuses = [@@@",
256      "@@@STEP_LOG_LINE@python.inline@    'replaced_by_new_reporter_at_same_stage',@@@",
257      "@@@STEP_LOG_LINE@python.inline@    'did_not_produce_frame',@@@",
258      "@@@STEP_LOG_LINE@python.inline@]@@@",
259      "@@@STEP_LOG_LINE@python.inline@accepted_termination_statuses = [@@@",
260      "@@@STEP_LOG_LINE@python.inline@    'missed_frame',@@@",
261      "@@@STEP_LOG_LINE@python.inline@    'submitted_frame',@@@",
262      "@@@STEP_LOG_LINE@python.inline@    'main_frame_aborted'@@@",
263      "@@@STEP_LOG_LINE@python.inline@]@@@",
264      "@@@STEP_LOG_LINE@python.inline@@@@",
265      "@@@STEP_LOG_LINE@python.inline@current_frame_duration = 0@@@",
266      "@@@STEP_LOG_LINE@python.inline@total_frames = 0@@@",
267      "@@@STEP_LOG_LINE@python.inline@frame_id_to_start_ts = {}@@@",
268      "@@@STEP_LOG_LINE@python.inline@# Will contain tuples of frame_ids and their duration and status.@@@",
269      "@@@STEP_LOG_LINE@python.inline@completed_frame_id_and_duration_status = []@@@",
270      "@@@STEP_LOG_LINE@python.inline@# Will contain tuples of drawn frame_ids and their duration.@@@",
271      "@@@STEP_LOG_LINE@python.inline@drawn_frame_id_and_duration = []@@@",
272      "@@@STEP_LOG_LINE@python.inline@for trace in trace_json['traceEvents']:@@@",
273      "@@@STEP_LOG_LINE@python.inline@  if 'PipelineReporter' in trace['name']:@@@",
274      "@@@STEP_LOG_LINE@python.inline@    frame_id = trace['id']@@@",
275      "@@@STEP_LOG_LINE@python.inline@    args = trace.get('args')@@@",
276      "@@@STEP_LOG_LINE@python.inline@    if args and args.get('step') == 'BeginImplFrameToSendBeginMainFrame':@@@",
277      "@@@STEP_LOG_LINE@python.inline@      frame_id_to_start_ts[frame_id] = trace['ts']@@@",
278      "@@@STEP_LOG_LINE@python.inline@    elif args and (args.get('termination_status') in@@@",
279      "@@@STEP_LOG_LINE@python.inline@                   accepted_termination_statuses):@@@",
280      "@@@STEP_LOG_LINE@python.inline@      if not frame_id_to_start_ts.get(frame_id):@@@",
281      "@@@STEP_LOG_LINE@python.inline@        print('[No start ts found for %s]' % frame_id)@@@",
282      "@@@STEP_LOG_LINE@python.inline@        continue@@@",
283      "@@@STEP_LOG_LINE@python.inline@      current_frame_duration = trace['ts'] - frame_id_to_start_ts[frame_id]@@@",
284      "@@@STEP_LOG_LINE@python.inline@      total_frames += 1@@@",
285      "@@@STEP_LOG_LINE@python.inline@      completed_frame_id_and_duration_status.append(@@@",
286      "@@@STEP_LOG_LINE@python.inline@          (frame_id, current_frame_duration, args['termination_status']))@@@",
287      "@@@STEP_LOG_LINE@python.inline@      if(args['termination_status'] == 'missed_frame' or@@@",
288      "@@@STEP_LOG_LINE@python.inline@       args['termination_status'] == 'submitted_frame'):@@@",
289      "@@@STEP_LOG_LINE@python.inline@        drawn_frame_id_and_duration.append((frame_id, current_frame_duration))@@@",
290      "@@@STEP_LOG_LINE@python.inline@@@@",
291      "@@@STEP_LOG_LINE@python.inline@      # We are done with this frame_id so remove it from the dict.@@@",
292      "@@@STEP_LOG_LINE@python.inline@      frame_id_to_start_ts.pop(frame_id)@@@",
293      "@@@STEP_LOG_LINE@python.inline@      print('%d (%s with %s): %d' % (@@@",
294      "@@@STEP_LOG_LINE@python.inline@          total_frames, frame_id, args['termination_status'],@@@",
295      "@@@STEP_LOG_LINE@python.inline@          current_frame_duration))@@@",
296      "@@@STEP_LOG_LINE@python.inline@    elif args and (args.get('termination_status') in@@@",
297      "@@@STEP_LOG_LINE@python.inline@                   erroneous_termination_statuses):@@@",
298      "@@@STEP_LOG_LINE@python.inline@      # Invalidate previously collected results for this frame_id.@@@",
299      "@@@STEP_LOG_LINE@python.inline@      if frame_id_to_start_ts.get(frame_id):@@@",
300      "@@@STEP_LOG_LINE@python.inline@        print('[Invalidating %s due to %s]' % (@@@",
301      "@@@STEP_LOG_LINE@python.inline@            frame_id, args['termination_status']))@@@",
302      "@@@STEP_LOG_LINE@python.inline@        frame_id_to_start_ts.pop(frame_id)@@@",
303      "@@@STEP_LOG_LINE@python.inline@@@@",
304      "@@@STEP_LOG_LINE@python.inline@# Calculate metrics for total completed frames.@@@",
305      "@@@STEP_LOG_LINE@python.inline@total_completed_frames = len(completed_frame_id_and_duration_status)@@@",
306      "@@@STEP_LOG_LINE@python.inline@if total_completed_frames < 25:@@@",
307      "@@@STEP_LOG_LINE@python.inline@  raise Exception('Even with 3 loops found only %d frames' %@@@",
308      "@@@STEP_LOG_LINE@python.inline@                  total_completed_frames)@@@",
309      "@@@STEP_LOG_LINE@python.inline@# Get frame avg/min/max for the middle 25 frames.@@@",
310      "@@@STEP_LOG_LINE@python.inline@start = (total_completed_frames - 25)/2@@@",
311      "@@@STEP_LOG_LINE@python.inline@print('Got %d total completed frames. Using indexes [%d, %d).' % (@@@",
312      "@@@STEP_LOG_LINE@python.inline@    total_completed_frames, start, start+25))@@@",
313      "@@@STEP_LOG_LINE@python.inline@frame_max = 0@@@",
314      "@@@STEP_LOG_LINE@python.inline@frame_min = 0@@@",
315      "@@@STEP_LOG_LINE@python.inline@frame_cumulative = 0@@@",
316      "@@@STEP_LOG_LINE@python.inline@aborted_frames = 0@@@",
317      "@@@STEP_LOG_LINE@python.inline@for frame_id, duration, status in (@@@",
318      "@@@STEP_LOG_LINE@python.inline@    completed_frame_id_and_duration_status[start:start+25]):@@@",
319      "@@@STEP_LOG_LINE@python.inline@  frame_max = max(frame_max, duration)@@@",
320      "@@@STEP_LOG_LINE@python.inline@  frame_min = min(frame_min, duration) if frame_min else duration@@@",
321      "@@@STEP_LOG_LINE@python.inline@  frame_cumulative += duration@@@",
322      "@@@STEP_LOG_LINE@python.inline@  if status == 'main_frame_aborted':@@@",
323      "@@@STEP_LOG_LINE@python.inline@    aborted_frames += 1@@@",
324      "@@@STEP_LOG_LINE@python.inline@@@@",
325      "@@@STEP_LOG_LINE@python.inline@perf_results = {}@@@",
326      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_max_us'] = frame_max@@@",
327      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_min_us'] = frame_min@@@",
328      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_avg_us'] = frame_cumulative/25@@@",
329      "@@@STEP_LOG_LINE@python.inline@perf_results['aborted_frames'] = aborted_frames@@@",
330      "@@@STEP_LOG_LINE@python.inline@@@@",
331      "@@@STEP_LOG_LINE@python.inline@# Now calculate metrics for only drawn frames.@@@",
332      "@@@STEP_LOG_LINE@python.inline@drawn_frame_max = 0@@@",
333      "@@@STEP_LOG_LINE@python.inline@drawn_frame_min = 0@@@",
334      "@@@STEP_LOG_LINE@python.inline@drawn_frame_cumulative = 0@@@",
335      "@@@STEP_LOG_LINE@python.inline@total_drawn_frames = len(drawn_frame_id_and_duration)@@@",
336      "@@@STEP_LOG_LINE@python.inline@if total_drawn_frames < 25:@@@",
337      "@@@STEP_LOG_LINE@python.inline@  raise Exception('Even with 3 loops found only %d drawn frames' %@@@",
338      "@@@STEP_LOG_LINE@python.inline@                  total_drawn_frames)@@@",
339      "@@@STEP_LOG_LINE@python.inline@# Get drawn frame avg/min/max from the middle 25 frames.@@@",
340      "@@@STEP_LOG_LINE@python.inline@start = (total_drawn_frames - 25)/2@@@",
341      "@@@STEP_LOG_LINE@python.inline@print('Got %d total drawn frames. Using indexes [%d-%d).' % (@@@",
342      "@@@STEP_LOG_LINE@python.inline@      total_drawn_frames, start, start+25))@@@",
343      "@@@STEP_LOG_LINE@python.inline@for frame_id, duration in drawn_frame_id_and_duration[start:start+25]:@@@",
344      "@@@STEP_LOG_LINE@python.inline@  drawn_frame_max = max(drawn_frame_max, duration)@@@",
345      "@@@STEP_LOG_LINE@python.inline@  drawn_frame_min = (min(drawn_frame_min, duration)@@@",
346      "@@@STEP_LOG_LINE@python.inline@                     if drawn_frame_min else duration)@@@",
347      "@@@STEP_LOG_LINE@python.inline@  drawn_frame_cumulative += duration@@@",
348      "@@@STEP_LOG_LINE@python.inline@# Add metrics to perf_results.@@@",
349      "@@@STEP_LOG_LINE@python.inline@perf_results['drawn_frame_max_us'] = drawn_frame_max@@@",
350      "@@@STEP_LOG_LINE@python.inline@perf_results['drawn_frame_min_us'] = drawn_frame_min@@@",
351      "@@@STEP_LOG_LINE@python.inline@perf_results['drawn_frame_avg_us'] = drawn_frame_cumulative/25@@@",
352      "@@@STEP_LOG_LINE@python.inline@@@@",
353      "@@@STEP_LOG_LINE@python.inline@print('Final perf_results dict: %s' % perf_results)@@@",
354      "@@@STEP_LOG_LINE@python.inline@@@@",
355      "@@@STEP_LOG_LINE@python.inline@# Write perf_results to the output json.@@@",
356      "@@@STEP_LOG_LINE@python.inline@with open(output_json_file, 'w') as f:@@@",
357      "@@@STEP_LOG_LINE@python.inline@  f.write(json.dumps(perf_results))@@@",
358      "@@@STEP_LOG_END@python.inline@@@"
359    ]
360  },
361  {
362    "cmd": [
363      "[START_DIR]/node/node/bin/node",
364      "[START_DIR]/skia/tools/lottie-web-perf/lottie-web-perf.js",
365      "--backend",
366      "svg",
367      "--input",
368      "[START_DIR]/lottie-samples/lottie3.json",
369      "--output",
370      "[CLEANUP]/g3_try_tmp_1/lottie3.json"
371    ],
372    "cwd": "[START_DIR]/skia/tools/lottie-web-perf",
373    "env": {
374      "CHROME_HEADLESS": "1",
375      "DISPLAY": ":0",
376      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
377    },
378    "infra_step": true,
379    "name": "Run perf cmd line app (3)"
380  },
381  {
382    "cmd": [
383      "python",
384      "-u",
385      "\nimport json\nimport sys\n\ntrace_output = sys.argv[1]\nwith open(trace_output, 'r') as f:\n  trace_json = json.load(f)\noutput_json_file = sys.argv[2]\nrenderer = sys.argv[3]  # Unused for now but might be useful in the future.\n\n# Output data about the GPU that was used.\nprint('GPU data:')\nprint(trace_json['metadata'].get('gpu-gl-renderer'))\nprint(trace_json['metadata'].get('gpu-driver'))\nprint(trace_json['metadata'].get('gpu-gl-vendor'))\n\nerroneous_termination_statuses = [\n    'replaced_by_new_reporter_at_same_stage',\n    'did_not_produce_frame',\n]\naccepted_termination_statuses = [\n    'missed_frame',\n    'submitted_frame',\n    'main_frame_aborted'\n]\n\ncurrent_frame_duration = 0\ntotal_frames = 0\nframe_id_to_start_ts = {}\n# Will contain tuples of frame_ids and their duration and status.\ncompleted_frame_id_and_duration_status = []\n# Will contain tuples of drawn frame_ids and their duration.\ndrawn_frame_id_and_duration = []\nfor trace in trace_json['traceEvents']:\n  if 'PipelineReporter' in trace['name']:\n    frame_id = trace['id']\n    args = trace.get('args')\n    if args and args.get('step') == 'BeginImplFrameToSendBeginMainFrame':\n      frame_id_to_start_ts[frame_id] = trace['ts']\n    elif args and (args.get('termination_status') in\n                   accepted_termination_statuses):\n      if not frame_id_to_start_ts.get(frame_id):\n        print('[No start ts found for %s]' % frame_id)\n        continue\n      current_frame_duration = trace['ts'] - frame_id_to_start_ts[frame_id]\n      total_frames += 1\n      completed_frame_id_and_duration_status.append(\n          (frame_id, current_frame_duration, args['termination_status']))\n      if(args['termination_status'] == 'missed_frame' or\n       args['termination_status'] == 'submitted_frame'):\n        drawn_frame_id_and_duration.append((frame_id, current_frame_duration))\n\n      # We are done with this frame_id so remove it from the dict.\n      frame_id_to_start_ts.pop(frame_id)\n      print('%d (%s with %s): %d' % (\n          total_frames, frame_id, args['termination_status'],\n          current_frame_duration))\n    elif args and (args.get('termination_status') in\n                   erroneous_termination_statuses):\n      # Invalidate previously collected results for this frame_id.\n      if frame_id_to_start_ts.get(frame_id):\n        print('[Invalidating %s due to %s]' % (\n            frame_id, args['termination_status']))\n        frame_id_to_start_ts.pop(frame_id)\n\n# Calculate metrics for total completed frames.\ntotal_completed_frames = len(completed_frame_id_and_duration_status)\nif total_completed_frames < 25:\n  raise Exception('Even with 3 loops found only %d frames' %\n                  total_completed_frames)\n# Get frame avg/min/max for the middle 25 frames.\nstart = (total_completed_frames - 25)/2\nprint('Got %d total completed frames. Using indexes [%d, %d).' % (\n    total_completed_frames, start, start+25))\nframe_max = 0\nframe_min = 0\nframe_cumulative = 0\naborted_frames = 0\nfor frame_id, duration, status in (\n    completed_frame_id_and_duration_status[start:start+25]):\n  frame_max = max(frame_max, duration)\n  frame_min = min(frame_min, duration) if frame_min else duration\n  frame_cumulative += duration\n  if status == 'main_frame_aborted':\n    aborted_frames += 1\n\nperf_results = {}\nperf_results['frame_max_us'] = frame_max\nperf_results['frame_min_us'] = frame_min\nperf_results['frame_avg_us'] = frame_cumulative/25\nperf_results['aborted_frames'] = aborted_frames\n\n# Now calculate metrics for only drawn frames.\ndrawn_frame_max = 0\ndrawn_frame_min = 0\ndrawn_frame_cumulative = 0\ntotal_drawn_frames = len(drawn_frame_id_and_duration)\nif total_drawn_frames < 25:\n  raise Exception('Even with 3 loops found only %d drawn frames' %\n                  total_drawn_frames)\n# Get drawn frame avg/min/max from the middle 25 frames.\nstart = (total_drawn_frames - 25)/2\nprint('Got %d total drawn frames. Using indexes [%d-%d).' % (\n      total_drawn_frames, start, start+25))\nfor frame_id, duration in drawn_frame_id_and_duration[start:start+25]:\n  drawn_frame_max = max(drawn_frame_max, duration)\n  drawn_frame_min = (min(drawn_frame_min, duration)\n                     if drawn_frame_min else duration)\n  drawn_frame_cumulative += duration\n# Add metrics to perf_results.\nperf_results['drawn_frame_max_us'] = drawn_frame_max\nperf_results['drawn_frame_min_us'] = drawn_frame_min\nperf_results['drawn_frame_avg_us'] = drawn_frame_cumulative/25\n\nprint('Final perf_results dict: %s' % perf_results)\n\n# Write perf_results to the output json.\nwith open(output_json_file, 'w') as f:\n  f.write(json.dumps(perf_results))\n",
386      "[CLEANUP]/g3_try_tmp_1/lottie3.json",
387      "/path/to/tmp/json",
388      "lottie-web"
389    ],
390    "env": {
391      "CHROME_HEADLESS": "1",
392      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
393    },
394    "name": "parse lottie3.json trace",
395    "~followup_annotations": [
396      "@@@STEP_LOG_LINE@json.output@{@@@",
397      "@@@STEP_LOG_LINE@json.output@  \"frame_avg_us\": 179.71, @@@",
398      "@@@STEP_LOG_LINE@json.output@  \"frame_max_us\": 218.25, @@@",
399      "@@@STEP_LOG_LINE@json.output@  \"frame_min_us\": 141.17@@@",
400      "@@@STEP_LOG_LINE@json.output@}@@@",
401      "@@@STEP_LOG_END@json.output@@@",
402      "@@@STEP_LOG_LINE@python.inline@@@@",
403      "@@@STEP_LOG_LINE@python.inline@import json@@@",
404      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
405      "@@@STEP_LOG_LINE@python.inline@@@@",
406      "@@@STEP_LOG_LINE@python.inline@trace_output = sys.argv[1]@@@",
407      "@@@STEP_LOG_LINE@python.inline@with open(trace_output, 'r') as f:@@@",
408      "@@@STEP_LOG_LINE@python.inline@  trace_json = json.load(f)@@@",
409      "@@@STEP_LOG_LINE@python.inline@output_json_file = sys.argv[2]@@@",
410      "@@@STEP_LOG_LINE@python.inline@renderer = sys.argv[3]  # Unused for now but might be useful in the future.@@@",
411      "@@@STEP_LOG_LINE@python.inline@@@@",
412      "@@@STEP_LOG_LINE@python.inline@# Output data about the GPU that was used.@@@",
413      "@@@STEP_LOG_LINE@python.inline@print('GPU data:')@@@",
414      "@@@STEP_LOG_LINE@python.inline@print(trace_json['metadata'].get('gpu-gl-renderer'))@@@",
415      "@@@STEP_LOG_LINE@python.inline@print(trace_json['metadata'].get('gpu-driver'))@@@",
416      "@@@STEP_LOG_LINE@python.inline@print(trace_json['metadata'].get('gpu-gl-vendor'))@@@",
417      "@@@STEP_LOG_LINE@python.inline@@@@",
418      "@@@STEP_LOG_LINE@python.inline@erroneous_termination_statuses = [@@@",
419      "@@@STEP_LOG_LINE@python.inline@    'replaced_by_new_reporter_at_same_stage',@@@",
420      "@@@STEP_LOG_LINE@python.inline@    'did_not_produce_frame',@@@",
421      "@@@STEP_LOG_LINE@python.inline@]@@@",
422      "@@@STEP_LOG_LINE@python.inline@accepted_termination_statuses = [@@@",
423      "@@@STEP_LOG_LINE@python.inline@    'missed_frame',@@@",
424      "@@@STEP_LOG_LINE@python.inline@    'submitted_frame',@@@",
425      "@@@STEP_LOG_LINE@python.inline@    'main_frame_aborted'@@@",
426      "@@@STEP_LOG_LINE@python.inline@]@@@",
427      "@@@STEP_LOG_LINE@python.inline@@@@",
428      "@@@STEP_LOG_LINE@python.inline@current_frame_duration = 0@@@",
429      "@@@STEP_LOG_LINE@python.inline@total_frames = 0@@@",
430      "@@@STEP_LOG_LINE@python.inline@frame_id_to_start_ts = {}@@@",
431      "@@@STEP_LOG_LINE@python.inline@# Will contain tuples of frame_ids and their duration and status.@@@",
432      "@@@STEP_LOG_LINE@python.inline@completed_frame_id_and_duration_status = []@@@",
433      "@@@STEP_LOG_LINE@python.inline@# Will contain tuples of drawn frame_ids and their duration.@@@",
434      "@@@STEP_LOG_LINE@python.inline@drawn_frame_id_and_duration = []@@@",
435      "@@@STEP_LOG_LINE@python.inline@for trace in trace_json['traceEvents']:@@@",
436      "@@@STEP_LOG_LINE@python.inline@  if 'PipelineReporter' in trace['name']:@@@",
437      "@@@STEP_LOG_LINE@python.inline@    frame_id = trace['id']@@@",
438      "@@@STEP_LOG_LINE@python.inline@    args = trace.get('args')@@@",
439      "@@@STEP_LOG_LINE@python.inline@    if args and args.get('step') == 'BeginImplFrameToSendBeginMainFrame':@@@",
440      "@@@STEP_LOG_LINE@python.inline@      frame_id_to_start_ts[frame_id] = trace['ts']@@@",
441      "@@@STEP_LOG_LINE@python.inline@    elif args and (args.get('termination_status') in@@@",
442      "@@@STEP_LOG_LINE@python.inline@                   accepted_termination_statuses):@@@",
443      "@@@STEP_LOG_LINE@python.inline@      if not frame_id_to_start_ts.get(frame_id):@@@",
444      "@@@STEP_LOG_LINE@python.inline@        print('[No start ts found for %s]' % frame_id)@@@",
445      "@@@STEP_LOG_LINE@python.inline@        continue@@@",
446      "@@@STEP_LOG_LINE@python.inline@      current_frame_duration = trace['ts'] - frame_id_to_start_ts[frame_id]@@@",
447      "@@@STEP_LOG_LINE@python.inline@      total_frames += 1@@@",
448      "@@@STEP_LOG_LINE@python.inline@      completed_frame_id_and_duration_status.append(@@@",
449      "@@@STEP_LOG_LINE@python.inline@          (frame_id, current_frame_duration, args['termination_status']))@@@",
450      "@@@STEP_LOG_LINE@python.inline@      if(args['termination_status'] == 'missed_frame' or@@@",
451      "@@@STEP_LOG_LINE@python.inline@       args['termination_status'] == 'submitted_frame'):@@@",
452      "@@@STEP_LOG_LINE@python.inline@        drawn_frame_id_and_duration.append((frame_id, current_frame_duration))@@@",
453      "@@@STEP_LOG_LINE@python.inline@@@@",
454      "@@@STEP_LOG_LINE@python.inline@      # We are done with this frame_id so remove it from the dict.@@@",
455      "@@@STEP_LOG_LINE@python.inline@      frame_id_to_start_ts.pop(frame_id)@@@",
456      "@@@STEP_LOG_LINE@python.inline@      print('%d (%s with %s): %d' % (@@@",
457      "@@@STEP_LOG_LINE@python.inline@          total_frames, frame_id, args['termination_status'],@@@",
458      "@@@STEP_LOG_LINE@python.inline@          current_frame_duration))@@@",
459      "@@@STEP_LOG_LINE@python.inline@    elif args and (args.get('termination_status') in@@@",
460      "@@@STEP_LOG_LINE@python.inline@                   erroneous_termination_statuses):@@@",
461      "@@@STEP_LOG_LINE@python.inline@      # Invalidate previously collected results for this frame_id.@@@",
462      "@@@STEP_LOG_LINE@python.inline@      if frame_id_to_start_ts.get(frame_id):@@@",
463      "@@@STEP_LOG_LINE@python.inline@        print('[Invalidating %s due to %s]' % (@@@",
464      "@@@STEP_LOG_LINE@python.inline@            frame_id, args['termination_status']))@@@",
465      "@@@STEP_LOG_LINE@python.inline@        frame_id_to_start_ts.pop(frame_id)@@@",
466      "@@@STEP_LOG_LINE@python.inline@@@@",
467      "@@@STEP_LOG_LINE@python.inline@# Calculate metrics for total completed frames.@@@",
468      "@@@STEP_LOG_LINE@python.inline@total_completed_frames = len(completed_frame_id_and_duration_status)@@@",
469      "@@@STEP_LOG_LINE@python.inline@if total_completed_frames < 25:@@@",
470      "@@@STEP_LOG_LINE@python.inline@  raise Exception('Even with 3 loops found only %d frames' %@@@",
471      "@@@STEP_LOG_LINE@python.inline@                  total_completed_frames)@@@",
472      "@@@STEP_LOG_LINE@python.inline@# Get frame avg/min/max for the middle 25 frames.@@@",
473      "@@@STEP_LOG_LINE@python.inline@start = (total_completed_frames - 25)/2@@@",
474      "@@@STEP_LOG_LINE@python.inline@print('Got %d total completed frames. Using indexes [%d, %d).' % (@@@",
475      "@@@STEP_LOG_LINE@python.inline@    total_completed_frames, start, start+25))@@@",
476      "@@@STEP_LOG_LINE@python.inline@frame_max = 0@@@",
477      "@@@STEP_LOG_LINE@python.inline@frame_min = 0@@@",
478      "@@@STEP_LOG_LINE@python.inline@frame_cumulative = 0@@@",
479      "@@@STEP_LOG_LINE@python.inline@aborted_frames = 0@@@",
480      "@@@STEP_LOG_LINE@python.inline@for frame_id, duration, status in (@@@",
481      "@@@STEP_LOG_LINE@python.inline@    completed_frame_id_and_duration_status[start:start+25]):@@@",
482      "@@@STEP_LOG_LINE@python.inline@  frame_max = max(frame_max, duration)@@@",
483      "@@@STEP_LOG_LINE@python.inline@  frame_min = min(frame_min, duration) if frame_min else duration@@@",
484      "@@@STEP_LOG_LINE@python.inline@  frame_cumulative += duration@@@",
485      "@@@STEP_LOG_LINE@python.inline@  if status == 'main_frame_aborted':@@@",
486      "@@@STEP_LOG_LINE@python.inline@    aborted_frames += 1@@@",
487      "@@@STEP_LOG_LINE@python.inline@@@@",
488      "@@@STEP_LOG_LINE@python.inline@perf_results = {}@@@",
489      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_max_us'] = frame_max@@@",
490      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_min_us'] = frame_min@@@",
491      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_avg_us'] = frame_cumulative/25@@@",
492      "@@@STEP_LOG_LINE@python.inline@perf_results['aborted_frames'] = aborted_frames@@@",
493      "@@@STEP_LOG_LINE@python.inline@@@@",
494      "@@@STEP_LOG_LINE@python.inline@# Now calculate metrics for only drawn frames.@@@",
495      "@@@STEP_LOG_LINE@python.inline@drawn_frame_max = 0@@@",
496      "@@@STEP_LOG_LINE@python.inline@drawn_frame_min = 0@@@",
497      "@@@STEP_LOG_LINE@python.inline@drawn_frame_cumulative = 0@@@",
498      "@@@STEP_LOG_LINE@python.inline@total_drawn_frames = len(drawn_frame_id_and_duration)@@@",
499      "@@@STEP_LOG_LINE@python.inline@if total_drawn_frames < 25:@@@",
500      "@@@STEP_LOG_LINE@python.inline@  raise Exception('Even with 3 loops found only %d drawn frames' %@@@",
501      "@@@STEP_LOG_LINE@python.inline@                  total_drawn_frames)@@@",
502      "@@@STEP_LOG_LINE@python.inline@# Get drawn frame avg/min/max from the middle 25 frames.@@@",
503      "@@@STEP_LOG_LINE@python.inline@start = (total_drawn_frames - 25)/2@@@",
504      "@@@STEP_LOG_LINE@python.inline@print('Got %d total drawn frames. Using indexes [%d-%d).' % (@@@",
505      "@@@STEP_LOG_LINE@python.inline@      total_drawn_frames, start, start+25))@@@",
506      "@@@STEP_LOG_LINE@python.inline@for frame_id, duration in drawn_frame_id_and_duration[start:start+25]:@@@",
507      "@@@STEP_LOG_LINE@python.inline@  drawn_frame_max = max(drawn_frame_max, duration)@@@",
508      "@@@STEP_LOG_LINE@python.inline@  drawn_frame_min = (min(drawn_frame_min, duration)@@@",
509      "@@@STEP_LOG_LINE@python.inline@                     if drawn_frame_min else duration)@@@",
510      "@@@STEP_LOG_LINE@python.inline@  drawn_frame_cumulative += duration@@@",
511      "@@@STEP_LOG_LINE@python.inline@# Add metrics to perf_results.@@@",
512      "@@@STEP_LOG_LINE@python.inline@perf_results['drawn_frame_max_us'] = drawn_frame_max@@@",
513      "@@@STEP_LOG_LINE@python.inline@perf_results['drawn_frame_min_us'] = drawn_frame_min@@@",
514      "@@@STEP_LOG_LINE@python.inline@perf_results['drawn_frame_avg_us'] = drawn_frame_cumulative/25@@@",
515      "@@@STEP_LOG_LINE@python.inline@@@@",
516      "@@@STEP_LOG_LINE@python.inline@print('Final perf_results dict: %s' % perf_results)@@@",
517      "@@@STEP_LOG_LINE@python.inline@@@@",
518      "@@@STEP_LOG_LINE@python.inline@# Write perf_results to the output json.@@@",
519      "@@@STEP_LOG_LINE@python.inline@with open(output_json_file, 'w') as f:@@@",
520      "@@@STEP_LOG_LINE@python.inline@  f.write(json.dumps(perf_results))@@@",
521      "@@@STEP_LOG_END@python.inline@@@"
522    ]
523  },
524  {
525    "cmd": [
526      "python",
527      "-u",
528      "import os\nprint(os.environ.get('SWARMING_BOT_ID', ''))\n"
529    ],
530    "name": "get swarming bot id",
531    "~followup_annotations": [
532      "@@@STEP_LOG_LINE@python.inline@import os@@@",
533      "@@@STEP_LOG_LINE@python.inline@print(os.environ.get('SWARMING_BOT_ID', ''))@@@",
534      "@@@STEP_LOG_END@python.inline@@@"
535    ]
536  },
537  {
538    "cmd": [
539      "python",
540      "-u",
541      "import os\nprint(os.environ.get('SWARMING_TASK_ID', ''))\n"
542    ],
543    "name": "get swarming task id",
544    "~followup_annotations": [
545      "@@@STEP_LOG_LINE@python.inline@import os@@@",
546      "@@@STEP_LOG_LINE@python.inline@print(os.environ.get('SWARMING_TASK_ID', ''))@@@",
547      "@@@STEP_LOG_END@python.inline@@@"
548    ]
549  },
550  {
551    "cmd": [
552      "vpython",
553      "-u",
554      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
555      "--json-output",
556      "/path/to/tmp/json",
557      "ensure-directory",
558      "--mode",
559      "0777",
560      "[START_DIR]/[SWARM_OUT_DIR]"
561    ],
562    "infra_step": true,
563    "name": "makedirs perf_dir"
564  },
565  {
566    "cmd": [
567      "vpython",
568      "-u",
569      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
570      "--json-output",
571      "/path/to/tmp/json",
572      "copy",
573      "{\n    \"gitHash\": \"abc123\",\n    \"key\": {\n        \"arch\": \"x86_64\",\n        \"bench_type\": \"tracing\",\n        \"compiler\": \"none\",\n        \"configuration\": \"Release\",\n        \"cpu_or_gpu\": \"CPU\",\n        \"cpu_or_gpu_value\": \"AVX2\",\n        \"extra_config\": \"LottieWeb\",\n        \"model\": \"GCE\",\n        \"os\": \"Debian10\",\n        \"source_type\": \"lottie-web\"\n    },\n    \"renderer\": \"lottie-web\",\n    \"results\": {\n        \"lottie1.json\": {\n            \"gl\": {\n                \"frame_avg_us\": 179.71,\n                \"frame_max_us\": 218.25,\n                \"frame_min_us\": 141.17\n            }\n        },\n        \"lottie2.json\": {\n            \"gl\": {\n                \"frame_avg_us\": 179.71,\n                \"frame_max_us\": 218.25,\n                \"frame_min_us\": 141.17\n            }\n        },\n        \"lottie3.json\": {\n            \"gl\": {\n                \"frame_avg_us\": 179.71,\n                \"frame_max_us\": 218.25,\n                \"frame_min_us\": 141.17\n            }\n        }\n    },\n    \"swarming_bot_id\": \"\",\n    \"swarming_task_id\": \"\"\n}",
574      "[START_DIR]/[SWARM_OUT_DIR]/perf_abc123_1337000001.json"
575    ],
576    "infra_step": true,
577    "name": "write output JSON",
578    "~followup_annotations": [
579      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@{@@@",
580      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@    \"gitHash\": \"abc123\",@@@",
581      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@    \"key\": {@@@",
582      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"arch\": \"x86_64\",@@@",
583      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"bench_type\": \"tracing\",@@@",
584      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"compiler\": \"none\",@@@",
585      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"configuration\": \"Release\",@@@",
586      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"cpu_or_gpu\": \"CPU\",@@@",
587      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"cpu_or_gpu_value\": \"AVX2\",@@@",
588      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"extra_config\": \"LottieWeb\",@@@",
589      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"model\": \"GCE\",@@@",
590      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"os\": \"Debian10\",@@@",
591      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"source_type\": \"lottie-web\"@@@",
592      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@    },@@@",
593      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@    \"renderer\": \"lottie-web\",@@@",
594      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@    \"results\": {@@@",
595      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"lottie1.json\": {@@@",
596      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@            \"gl\": {@@@",
597      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@                \"frame_avg_us\": 179.71,@@@",
598      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@                \"frame_max_us\": 218.25,@@@",
599      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@                \"frame_min_us\": 141.17@@@",
600      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@            }@@@",
601      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        },@@@",
602      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"lottie2.json\": {@@@",
603      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@            \"gl\": {@@@",
604      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@                \"frame_avg_us\": 179.71,@@@",
605      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@                \"frame_max_us\": 218.25,@@@",
606      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@                \"frame_min_us\": 141.17@@@",
607      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@            }@@@",
608      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        },@@@",
609      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        \"lottie3.json\": {@@@",
610      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@            \"gl\": {@@@",
611      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@                \"frame_avg_us\": 179.71,@@@",
612      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@                \"frame_max_us\": 218.25,@@@",
613      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@                \"frame_min_us\": 141.17@@@",
614      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@            }@@@",
615      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@        }@@@",
616      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@    },@@@",
617      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@    \"swarming_bot_id\": \"\",@@@",
618      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@    \"swarming_task_id\": \"\"@@@",
619      "@@@STEP_LOG_LINE@perf_abc123_1337000001.json@}@@@",
620      "@@@STEP_LOG_END@perf_abc123_1337000001.json@@@"
621    ]
622  },
623  {
624    "name": "$result"
625  }
626]