@paulirish/trace_engine 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/analyze-trace.mjs +1 -1
  2. package/core/platform/DevToolsPath.d.ts +4 -13
  3. package/core/platform/DevToolsPath.js +7 -4
  4. package/core/platform/DevToolsPath.js.map +1 -7
  5. package/core/platform/MimeType.d.ts +27 -0
  6. package/core/platform/MimeType.js +119 -86
  7. package/core/platform/MimeType.js.map +1 -7
  8. package/core/platform/Timing.d.ts +7 -0
  9. package/core/platform/Timing.js +7 -4
  10. package/core/platform/Timing.js.map +1 -7
  11. package/core/platform/UIString.d.ts +2 -5
  12. package/core/platform/UIString.js +5 -2
  13. package/core/platform/UIString.js.map +1 -7
  14. package/core/platform/UserVisibleError.js +19 -10
  15. package/core/platform/UserVisibleError.js.map +1 -7
  16. package/core/platform/array-utilities.d.ts +48 -10
  17. package/core/platform/array-utilities.js +160 -124
  18. package/core/platform/array-utilities.js.map +1 -7
  19. package/core/platform/brand.d.ts +14 -0
  20. package/core/platform/brand.js +5 -1
  21. package/core/platform/brand.js.map +1 -7
  22. package/core/platform/date-utilities.js +10 -6
  23. package/core/platform/date-utilities.js.map +1 -7
  24. package/core/platform/dom-utilities.d.ts +3 -1
  25. package/core/platform/dom-utilities.js +94 -83
  26. package/core/platform/dom-utilities.js.map +1 -7
  27. package/core/platform/keyboard-utilities.d.ts +2 -0
  28. package/core/platform/keyboard-utilities.js +15 -24
  29. package/core/platform/keyboard-utilities.js.map +1 -7
  30. package/core/platform/map-utilities.d.ts +4 -0
  31. package/core/platform/map-utilities.js +66 -60
  32. package/core/platform/map-utilities.js.map +1 -7
  33. package/core/platform/number-utilities.js +66 -55
  34. package/core/platform/number-utilities.js.map +1 -7
  35. package/core/platform/platform.d.ts +5 -1
  36. package/core/platform/platform.js +54 -37
  37. package/core/platform/platform.js.map +1 -7
  38. package/core/platform/promise-utilities.d.ts +10 -0
  39. package/core/platform/promise-utilities.js +16 -8
  40. package/core/platform/promise-utilities.js.map +1 -7
  41. package/core/platform/set-utilities.js +20 -17
  42. package/core/platform/set-utilities.js.map +1 -7
  43. package/core/platform/string-utilities.d.ts +32 -1
  44. package/core/platform/string-utilities.js +453 -379
  45. package/core/platform/string-utilities.js.map +1 -7
  46. package/core/platform/typescript-utilities.d.ts +5 -5
  47. package/core/platform/typescript-utilities.js +19 -7
  48. package/core/platform/typescript-utilities.js.map +1 -7
  49. package/generated/protocol.d.ts +2081 -347
  50. package/generated/protocol.js +5 -2230
  51. package/models/cpu_profile/CPUProfileDataModel.d.ts +77 -0
  52. package/models/cpu_profile/CPUProfileDataModel.js +492 -359
  53. package/models/cpu_profile/CPUProfileDataModel.js.map +1 -7
  54. package/models/cpu_profile/ProfileTreeModel.d.ts +29 -0
  55. package/models/cpu_profile/ProfileTreeModel.js +87 -82
  56. package/models/cpu_profile/ProfileTreeModel.js.map +1 -7
  57. package/models/cpu_profile/cpu_profile.d.ts +3 -0
  58. package/models/cpu_profile/cpu_profile.js +7 -7
  59. package/models/cpu_profile/cpu_profile.js.map +1 -7
  60. package/models/trace/EntriesFilter.d.ts +55 -0
  61. package/models/trace/EntriesFilter.js +227 -166
  62. package/models/trace/EntriesFilter.js.map +1 -7
  63. package/models/trace/LegacyTracingModel.js.map +1 -7
  64. package/models/trace/ModelImpl.d.ts +110 -0
  65. package/models/trace/ModelImpl.js +161 -102
  66. package/models/trace/ModelImpl.js.map +1 -7
  67. package/models/trace/Processor.d.ts +36 -0
  68. package/models/trace/Processor.js +197 -163
  69. package/models/trace/Processor.js.map +1 -7
  70. package/models/trace/TracingManager.js.map +1 -7
  71. package/models/trace/extras/FetchNodes.d.ts +46 -0
  72. package/models/trace/extras/FetchNodes.js +132 -91
  73. package/models/trace/extras/FetchNodes.js.map +1 -7
  74. package/models/trace/extras/FilmStrip.d.ts +19 -0
  75. package/models/trace/extras/FilmStrip.js +38 -31
  76. package/models/trace/extras/FilmStrip.js.map +1 -7
  77. package/models/trace/extras/MainThreadActivity.d.ts +2 -0
  78. package/models/trace/extras/MainThreadActivity.js +72 -56
  79. package/models/trace/extras/MainThreadActivity.js.map +1 -7
  80. package/models/trace/extras/Metadata.d.ts +2 -0
  81. package/models/trace/extras/Metadata.js +42 -26
  82. package/models/trace/extras/Metadata.js.map +1 -7
  83. package/models/trace/extras/extras.js.map +1 -7
  84. package/models/trace/handlers/AnimationHandler.d.ts +8 -0
  85. package/models/trace/handlers/AnimationHandler.js +22 -20
  86. package/models/trace/handlers/AnimationHandler.js.map +1 -7
  87. package/models/trace/handlers/AuctionWorkletsHandler.d.ts +8 -0
  88. package/models/trace/handlers/AuctionWorkletsHandler.js +143 -89
  89. package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -7
  90. package/models/trace/handlers/FramesHandler.d.ts +76 -0
  91. package/models/trace/handlers/FramesHandler.js +424 -355
  92. package/models/trace/handlers/FramesHandler.js.map +1 -7
  93. package/models/trace/handlers/GPUHandler.d.ts +11 -0
  94. package/models/trace/handlers/GPUHandler.js +41 -37
  95. package/models/trace/handlers/GPUHandler.js.map +1 -7
  96. package/models/trace/handlers/InitiatorsHandler.d.ts +10 -0
  97. package/models/trace/handlers/InitiatorsHandler.js +164 -113
  98. package/models/trace/handlers/InitiatorsHandler.js.map +1 -7
  99. package/models/trace/handlers/InvalidationsHandler.d.ts +10 -0
  100. package/models/trace/handlers/InvalidationsHandler.js +101 -79
  101. package/models/trace/handlers/InvalidationsHandler.js.map +1 -7
  102. package/models/trace/handlers/LargestImagePaintHandler.d.ts +5 -0
  103. package/models/trace/handlers/LargestImagePaintHandler.js +32 -12
  104. package/models/trace/handlers/LargestImagePaintHandler.js.map +1 -7
  105. package/models/trace/handlers/LargestTextPaintHandler.d.ts +5 -0
  106. package/models/trace/handlers/LargestTextPaintHandler.js +20 -12
  107. package/models/trace/handlers/LargestTextPaintHandler.js.map +1 -7
  108. package/models/trace/handlers/LayerTreeHandler.d.ts +13 -0
  109. package/models/trace/handlers/LayerTreeHandler.js +96 -70
  110. package/models/trace/handlers/LayerTreeHandler.js.map +1 -7
  111. package/models/trace/handlers/LayoutShiftsHandler.d.ts +44 -0
  112. package/models/trace/handlers/LayoutShiftsHandler.js +304 -227
  113. package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -7
  114. package/models/trace/handlers/MemoryHandler.d.ts +7 -0
  115. package/models/trace/handlers/MemoryHandler.js +14 -11
  116. package/models/trace/handlers/MemoryHandler.js.map +1 -7
  117. package/models/trace/handlers/MetaHandler.d.ts +37 -0
  118. package/models/trace/handlers/MetaHandler.js +314 -226
  119. package/models/trace/handlers/MetaHandler.js.map +1 -7
  120. package/models/trace/handlers/ModelHandlers.d.ts +21 -0
  121. package/models/trace/handlers/ModelHandlers.js +25 -22
  122. package/models/trace/handlers/ModelHandlers.js.map +1 -7
  123. package/models/trace/handlers/NetworkRequestsHandler.d.ts +17 -0
  124. package/models/trace/handlers/NetworkRequestsHandler.js +342 -218
  125. package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -7
  126. package/models/trace/handlers/PageLoadMetricsHandler.d.ts +67 -0
  127. package/models/trace/handlers/PageLoadMetricsHandler.js +357 -284
  128. package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -7
  129. package/models/trace/handlers/RendererHandler.d.ts +101 -0
  130. package/models/trace/handlers/RendererHandler.js +295 -191
  131. package/models/trace/handlers/RendererHandler.js.map +1 -7
  132. package/models/trace/handlers/SamplesHandler.d.ts +46 -0
  133. package/models/trace/handlers/SamplesHandler.js +195 -158
  134. package/models/trace/handlers/SamplesHandler.js.map +1 -7
  135. package/models/trace/handlers/ScreenshotsHandler.d.ts +7 -0
  136. package/models/trace/handlers/ScreenshotsHandler.js +63 -41
  137. package/models/trace/handlers/ScreenshotsHandler.js.map +1 -7
  138. package/models/trace/handlers/Threads.d.ts +33 -0
  139. package/models/trace/handlers/Threads.js +85 -67
  140. package/models/trace/handlers/Threads.js.map +1 -7
  141. package/models/trace/handlers/UserInteractionsHandler.d.ts +57 -0
  142. package/models/trace/handlers/UserInteractionsHandler.js +240 -141
  143. package/models/trace/handlers/UserInteractionsHandler.js.map +1 -7
  144. package/models/trace/handlers/UserTimingsHandler.d.ts +28 -0
  145. package/models/trace/handlers/UserTimingsHandler.js +91 -80
  146. package/models/trace/handlers/UserTimingsHandler.js.map +1 -7
  147. package/models/trace/handlers/WarningsHandler.d.ts +14 -0
  148. package/models/trace/handlers/WarningsHandler.js +100 -62
  149. package/models/trace/handlers/WarningsHandler.js.map +1 -7
  150. package/models/trace/handlers/WorkersHandler.d.ts +11 -0
  151. package/models/trace/handlers/WorkersHandler.js +40 -38
  152. package/models/trace/handlers/WorkersHandler.js.map +1 -7
  153. package/models/trace/handlers/handlers.d.ts +3 -0
  154. package/models/trace/handlers/handlers.js +7 -4
  155. package/models/trace/handlers/handlers.js.map +1 -7
  156. package/models/trace/handlers/types.d.ts +45 -0
  157. package/models/trace/handlers/types.js +15 -15
  158. package/models/trace/handlers/types.js.map +1 -7
  159. package/models/trace/helpers/SamplesIntegrator.d.ts +49 -0
  160. package/models/trace/helpers/SamplesIntegrator.js +381 -204
  161. package/models/trace/helpers/SamplesIntegrator.js.map +1 -7
  162. package/models/trace/helpers/Timing.d.ts +26 -0
  163. package/models/trace/helpers/Timing.js +131 -110
  164. package/models/trace/helpers/Timing.js.map +1 -7
  165. package/models/trace/helpers/Trace.d.ts +37 -0
  166. package/models/trace/helpers/Trace.js +200 -166
  167. package/models/trace/helpers/Trace.js.map +1 -7
  168. package/models/trace/helpers/TreeHelpers.d.ts +90 -0
  169. package/models/trace/helpers/TreeHelpers.js +203 -100
  170. package/models/trace/helpers/TreeHelpers.js.map +1 -7
  171. package/models/trace/helpers/helpers.d.ts +4 -0
  172. package/models/trace/helpers/helpers.js +8 -5
  173. package/models/trace/helpers/helpers.js.map +1 -7
  174. package/models/trace/root-causes/LayoutShift.d.ts +119 -0
  175. package/models/trace/root-causes/LayoutShift.js +470 -323
  176. package/models/trace/root-causes/LayoutShift.js.map +1 -7
  177. package/models/trace/root-causes/RootCauses.d.ts +14 -0
  178. package/models/trace/root-causes/RootCauses.js +9 -6
  179. package/models/trace/root-causes/RootCauses.js.map +1 -7
  180. package/models/trace/root-causes/root-causes.d.ts +1 -0
  181. package/models/trace/root-causes/root-causes.js +5 -2
  182. package/models/trace/root-causes/root-causes.js.map +1 -7
  183. package/models/trace/trace.d.ts +11 -0
  184. package/models/trace/trace.js +17 -23
  185. package/models/trace/trace.js.map +1 -7
  186. package/models/trace/types/Configuration.d.ts +33 -0
  187. package/models/trace/types/Configuration.js +25 -14
  188. package/models/trace/types/Configuration.js.map +1 -7
  189. package/models/trace/types/File.d.ts +23 -0
  190. package/models/trace/types/File.js +5 -6
  191. package/models/trace/types/File.js.map +1 -7
  192. package/models/trace/types/Timing.d.ts +25 -0
  193. package/models/trace/types/Timing.js +10 -11
  194. package/models/trace/types/Timing.js.map +1 -7
  195. package/models/trace/types/TraceEvents.d.ts +1571 -0
  196. package/models/trace/types/TraceEvents.js +174 -381
  197. package/models/trace/types/TraceEvents.js.map +1 -7
  198. package/models/trace/types/types.d.ts +4 -0
  199. package/models/trace/types/types.js +8 -5
  200. package/models/trace/types/types.js.map +1 -7
  201. package/package.json +1 -1
  202. package/TracingManager.js +0 -0
  203. package/extras/extras.js +0 -0
  204. package/trace.mjs +0 -6980
  205. package/trace.mjs.map +0 -8
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../../front_end/models/trace/handlers/ScreenshotsHandler.ts"],
4
- "sourcesContent": ["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {type TraceEventHandlerName} from './types.js';\n\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nconst unpairedAsyncEvents: Types.TraceEvents.TraceEventPipelineReporter[] = [];\n\nconst snapshotEvents: Types.TraceEvents.TraceEventScreenshot[] = [];\nconst syntheticScreenshotEvents: Types.TraceEvents.SyntheticScreenshot[] = [];\nlet frameSequenceToTs: Record<string, Types.Timing.MicroSeconds> = {};\n\nexport function reset(): void {\n unpairedAsyncEvents.length = 0;\n snapshotEvents.length = 0;\n syntheticScreenshotEvents.length = 0;\n frameSequenceToTs = {};\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventScreenshot(event)) {\n snapshotEvents.push(event);\n } else if (Types.TraceEvents.isTraceEventPipelineReporter(event)) {\n unpairedAsyncEvents.push(event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n const pipelineReporterEvents = Helpers.Trace.createMatchedSortedSyntheticEvents(unpairedAsyncEvents);\n\n frameSequenceToTs = Object.fromEntries(pipelineReporterEvents.map(evt => {\n const frameSequenceId = evt.args.data.beginEvent.args.chrome_frame_reporter.frame_sequence;\n const presentationTs = Types.Timing.MicroSeconds(evt.ts + evt.dur);\n return [frameSequenceId, presentationTs];\n }));\n\n for (const snapshotEvent of snapshotEvents) {\n const {cat, name, ph, pid, tid} = snapshotEvent;\n const syntheticEvent: Types.TraceEvents.SyntheticScreenshot = {\n cat,\n name,\n ph,\n pid,\n tid,\n // `getPresentationTimestamp(snapshotEvent) - snapshotEvent.ts` is how many microsec the screenshot was adjusted to the right/later\n ts: getPresentationTimestamp(snapshotEvent),\n args: {\n dataUri: `data:image/jpg;base64,${snapshotEvent.args.snapshot}`,\n },\n };\n syntheticScreenshotEvents.push(syntheticEvent);\n }\n}\n\n/**\n * Correct the screenshot timestamps\n * The screenshot 'snapshot object' trace event has the \"frame sequence number\" attached as an ID.\n * We match that up with the \"PipelineReporter\" trace events as they terminate at presentation.\n * Presentation == when the pixels hit the screen. AKA Swap on the GPU\n */\nfunction getPresentationTimestamp(screenshotEvent: Types.TraceEvents.TraceEventScreenshot): Types.Timing.MicroSeconds {\n const frameSequence = parseInt(screenshotEvent.id, 16);\n // If it's 1, then it's an old trace (before https://crrev.com/c/4957973) and cannot be corrected.\n if (frameSequence === 1) {\n return screenshotEvent.ts;\n }\n // The screenshot trace event's `ts` reflects the \"expected display time\" which is ESTIMATE.\n // It is set by the compositor frame sink from the `expected_display_time`, which is based on a previously known\n // frame start PLUS the vsync interval (eg 16.6ms)\n const updatedTs = frameSequenceToTs[frameSequence];\n // Do we always find a match? No...\n // We generally don't match the very first screenshot and, sometimes, the last\n // The very first screenshot is requested immediately (even if nothing is painting). As a result there's no compositor\n // instrumentation running alongside.\n // The last one is sometimes missing as because the trace terminates right before the associated PipelineReporter is emitted.\n return updatedTs ?? screenshotEvent.ts;\n}\n\nexport function data(): Types.TraceEvents.SyntheticScreenshot[] {\n return [...syntheticScreenshotEvents];\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n"],
5
- "mappings": "AAIA;AACA;AAMA,MAAM,sBAAsE;AAE5E,MAAM,iBAA2D;AACjE,MAAM,4BAAqE;AAC3E,IAAI,oBAA+D;AAE5D,wBAAuB;AAC5B,sBAAoB,SAAS;AAC7B,iBAAe,SAAS;AACxB,4BAA0B,SAAS;AACnC,sBAAoB;AAAA;AAGf,4BAAqB,OAA+C;AACzE,MAAI,MAAM,YAAY,uBAAuB,QAAQ;AACnD,mBAAe,KAAK;AAAA,aACX,MAAM,YAAY,6BAA6B,QAAQ;AAChE,wBAAoB,KAAK;AAAA;AAAA;AAI7B,iCAAgD;AAC9C,QAAM,yBAAyB,QAAQ,MAAM,mCAAmC;AAEhF,sBAAoB,OAAO,YAAY,uBAAuB,IAAI,SAAO;AACvE,UAAM,kBAAkB,IAAI,KAAK,KAAK,WAAW,KAAK,sBAAsB;AAC5E,UAAM,iBAAiB,MAAM,OAAO,aAAa,IAAI,KAAK,IAAI;AAC9D,WAAO,CAAC,iBAAiB;AAAA;AAG3B,aAAW,iBAAiB,gBAAgB;AAC1C,UAAM,EAAC,KAAK,MAAM,IAAI,KAAK,QAAO;AAClC,UAAM,iBAAwD;AAAA,MAC5D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEA,IAAI,yBAAyB;AAAA,MAC7B,MAAM;AAAA,QACJ,SAAS,yBAAyB,cAAc,KAAK;AAAA;AAAA;AAGzD,8BAA0B,KAAK;AAAA;AAAA;AAUnC,kCAAkC,iBAAoF;AACpH,QAAM,gBAAgB,SAAS,gBAAgB,IAAI;AAEnD,MAAI,kBAAkB,GAAG;AACvB,WAAO,gBAAgB;AAAA;AAKzB,QAAM,YAAY,kBAAkB;AAMpC,SAAO,aAAa,gBAAgB;AAAA;AAG/B,uBAAyD;AAC9D,SAAO,CAAC,GAAG;AAAA;AAGN,uBAAyC;AAC9C,SAAO,CAAC;AAAA;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"ScreenshotsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ScreenshotsHandler.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAC;AACjD,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAI3C,qFAAqF;AACrF,qEAAqE;AACrE,MAAM,mBAAmB,GAAmD,EAAE,CAAC;AAE/E,MAAM,cAAc,GAA6C,EAAE,CAAC;AACpE,MAAM,yBAAyB,GAA4C,EAAE,CAAC;AAC9E,IAAI,iBAAiB,GAA8C,EAAE,CAAC;AAEtE,MAAM,UAAU,KAAK;IACnB,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/B,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B,yBAAyB,CAAC,MAAM,GAAG,CAAC,CAAC;IACrC,iBAAiB,GAAG,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAuC;IACjE,IAAI,KAAK,CAAC,WAAW,CAAC,sBAAsB,CAAC,KAAK,CAAC,EAAE;QACnD,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KAC5B;SAAM,IAAI,KAAK,CAAC,WAAW,CAAC,4BAA4B,CAAC,KAAK,CAAC,EAAE;QAChE,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KACjC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,sBAAsB,GAAG,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,mBAAmB,CAAC,CAAC;IAErG,iBAAiB,GAAG,MAAM,CAAC,WAAW,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QACtE,MAAM,eAAe,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,qBAAqB,CAAC,cAAc,CAAC;QAC3F,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACnE,OAAO,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC,CAAC;IAEJ,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE;QAC1C,MAAM,EAAC,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAC,GAAG,aAAa,CAAC;QAChD,MAAM,cAAc,GAA0C;YAC5D,GAAG;YACH,IAAI;YACJ,EAAE;YACF,GAAG;YACH,GAAG;YACH,mIAAmI;YACnI,EAAE,EAAE,wBAAwB,CAAC,aAAa,CAAC;YAC3C,IAAI,EAAE;gBACJ,OAAO,EAAE,yBAAyB,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE;aAChE;SACF,CAAC;QACF,yBAAyB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;KAChD;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,wBAAwB,CAAC,eAAuD;IACvF,MAAM,aAAa,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACvD,kGAAkG;IAClG,IAAI,aAAa,KAAK,CAAC,EAAE;QACvB,OAAO,eAAe,CAAC,EAAE,CAAC;KAC3B;IACD,4FAA4F;IAC5F,gHAAgH;IAChH,kDAAkD;IAClD,MAAM,SAAS,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;IACnD,mCAAmC;IACnC,8EAA8E;IAC9E,sHAAsH;IACtH,qCAAqC;IACrC,6HAA6H;IAC7H,OAAO,SAAS,IAAI,eAAe,CAAC,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,GAAG,yBAAyB,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,IAAI;IAClB,OAAO,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC","sourcesContent":["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {type TraceEventHandlerName} from './types.js';\n\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nconst unpairedAsyncEvents: Types.TraceEvents.TraceEventPipelineReporter[] = [];\n\nconst snapshotEvents: Types.TraceEvents.TraceEventScreenshot[] = [];\nconst syntheticScreenshotEvents: Types.TraceEvents.SyntheticScreenshot[] = [];\nlet frameSequenceToTs: Record<string, Types.Timing.MicroSeconds> = {};\n\nexport function reset(): void {\n unpairedAsyncEvents.length = 0;\n snapshotEvents.length = 0;\n syntheticScreenshotEvents.length = 0;\n frameSequenceToTs = {};\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventScreenshot(event)) {\n snapshotEvents.push(event);\n } else if (Types.TraceEvents.isTraceEventPipelineReporter(event)) {\n unpairedAsyncEvents.push(event);\n }\n}\n\nexport async function finalize(): Promise<void> {\n const pipelineReporterEvents = Helpers.Trace.createMatchedSortedSyntheticEvents(unpairedAsyncEvents);\n\n frameSequenceToTs = Object.fromEntries(pipelineReporterEvents.map(evt => {\n const frameSequenceId = evt.args.data.beginEvent.args.chrome_frame_reporter.frame_sequence;\n const presentationTs = Types.Timing.MicroSeconds(evt.ts + evt.dur);\n return [frameSequenceId, presentationTs];\n }));\n\n for (const snapshotEvent of snapshotEvents) {\n const {cat, name, ph, pid, tid} = snapshotEvent;\n const syntheticEvent: Types.TraceEvents.SyntheticScreenshot = {\n cat,\n name,\n ph,\n pid,\n tid,\n // `getPresentationTimestamp(snapshotEvent) - snapshotEvent.ts` is how many microsec the screenshot was adjusted to the right/later\n ts: getPresentationTimestamp(snapshotEvent),\n args: {\n dataUri: `data:image/jpg;base64,${snapshotEvent.args.snapshot}`,\n },\n };\n syntheticScreenshotEvents.push(syntheticEvent);\n }\n}\n\n/**\n * Correct the screenshot timestamps\n * The screenshot 'snapshot object' trace event has the \"frame sequence number\" attached as an ID.\n * We match that up with the \"PipelineReporter\" trace events as they terminate at presentation.\n * Presentation == when the pixels hit the screen. AKA Swap on the GPU\n */\nfunction getPresentationTimestamp(screenshotEvent: Types.TraceEvents.TraceEventScreenshot): Types.Timing.MicroSeconds {\n const frameSequence = parseInt(screenshotEvent.id, 16);\n // If it's 1, then it's an old trace (before https://crrev.com/c/4957973) and cannot be corrected.\n if (frameSequence === 1) {\n return screenshotEvent.ts;\n }\n // The screenshot trace event's `ts` reflects the \"expected display time\" which is ESTIMATE.\n // It is set by the compositor frame sink from the `expected_display_time`, which is based on a previously known\n // frame start PLUS the vsync interval (eg 16.6ms)\n const updatedTs = frameSequenceToTs[frameSequence];\n // Do we always find a match? No...\n // We generally don't match the very first screenshot and, sometimes, the last\n // The very first screenshot is requested immediately (even if nothing is painting). As a result there's no compositor\n // instrumentation running alongside.\n // The last one is sometimes missing as because the trace terminates right before the associated PipelineReporter is emitted.\n return updatedTs ?? screenshotEvent.ts;\n}\n\nexport function data(): Types.TraceEvents.SyntheticScreenshot[] {\n return [...syntheticScreenshotEvents];\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n"]}
@@ -0,0 +1,33 @@
1
+ import type * as Helpers from '../helpers/helpers.js';
2
+ import type * as Types from '../types/types.js';
3
+ import { type AuctionWorkletsData } from './AuctionWorkletsHandler.js';
4
+ import type * as Renderer from './RendererHandler.js';
5
+ import { type TraceParseData } from './types.js';
6
+ export interface ThreadData {
7
+ pid: Types.TraceEvents.ProcessID;
8
+ tid: Types.TraceEvents.ThreadID;
9
+ entries: readonly Types.TraceEvents.SyntheticTraceEntry[];
10
+ processIsOnMainFrame: boolean;
11
+ tree: Helpers.TreeHelpers.TraceEntryTree;
12
+ type: ThreadType;
13
+ name: string | null;
14
+ entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, Helpers.TreeHelpers.TraceEntryNode>;
15
+ }
16
+ export declare const enum ThreadType {
17
+ MAIN_THREAD = "MAIN_THREAD",
18
+ WORKER = "WORKER",
19
+ RASTERIZER = "RASTERIZER",
20
+ AUCTION_WORKLET = "AUCTION_WORKLET",
21
+ OTHER = "OTHER",
22
+ CPU_PROFILE = "CPU_PROFILE",
23
+ THREAD_POOL = "THREAD_POOL"
24
+ }
25
+ export declare function threadsInRenderer(rendererData: Renderer.RendererHandlerData, auctionWorkletsData: AuctionWorkletsData): readonly ThreadData[];
26
+ /**
27
+ * Given trace parsed data, this helper will return a high level array of
28
+ * ThreadData. This is useful because it allows you to get a list of threads
29
+ * regardless of if the trace is a CPU Profile or a Tracing profile. Thus you
30
+ * can use this helper to iterate over threads in confidence that it will work
31
+ * for both trace types.
32
+ */
33
+ export declare function threadsInTrace(traceParseData: TraceParseData): readonly ThreadData[];
@@ -1,77 +1,95 @@
1
- export var ThreadType = /* @__PURE__ */ ((ThreadType2) => {
2
- ThreadType2["MAIN_THREAD"] = "MAIN_THREAD";
3
- ThreadType2["WORKER"] = "WORKER";
4
- ThreadType2["RASTERIZER"] = "RASTERIZER";
5
- ThreadType2["AUCTION_WORKLET"] = "AUCTION_WORKLET";
6
- ThreadType2["OTHER"] = "OTHER";
7
- ThreadType2["CPU_PROFILE"] = "CPU_PROFILE";
8
- ThreadType2["THREAD_POOL"] = "THREAD_POOL";
9
- return ThreadType2;
10
- })(ThreadType || {});
11
1
  function getThreadTypeForRendererThread(auctionWorkletsData, pid, thread) {
12
- let threadType = "OTHER" /* OTHER */;
13
- if (thread.name === "CrRendererMain") {
14
- threadType = "MAIN_THREAD" /* MAIN_THREAD */;
15
- } else if (thread.name === "DedicatedWorker thread") {
16
- threadType = "WORKER" /* WORKER */;
17
- } else if (thread.name?.startsWith("CompositorTileWorker")) {
18
- threadType = "RASTERIZER" /* RASTERIZER */;
19
- } else if (auctionWorkletsData.worklets.has(pid)) {
20
- threadType = "AUCTION_WORKLET" /* AUCTION_WORKLET */;
21
- } else if (thread.name?.startsWith("ThreadPool")) {
22
- threadType = "THREAD_POOL" /* THREAD_POOL */;
23
- }
24
- return threadType;
2
+ let threadType = "OTHER" /* ThreadType.OTHER */;
3
+ if (thread.name === 'CrRendererMain') {
4
+ threadType = "MAIN_THREAD" /* ThreadType.MAIN_THREAD */;
5
+ }
6
+ else if (thread.name === 'DedicatedWorker thread') {
7
+ threadType = "WORKER" /* ThreadType.WORKER */;
8
+ }
9
+ else if (thread.name?.startsWith('CompositorTileWorker')) {
10
+ threadType = "RASTERIZER" /* ThreadType.RASTERIZER */;
11
+ }
12
+ else if (auctionWorkletsData.worklets.has(pid)) {
13
+ threadType = "AUCTION_WORKLET" /* ThreadType.AUCTION_WORKLET */;
14
+ }
15
+ else if (thread.name?.startsWith('ThreadPool')) {
16
+ // TODO(paulirish): perhaps exclude ThreadPoolServiceThread entirely
17
+ threadType = "THREAD_POOL" /* ThreadType.THREAD_POOL */;
18
+ }
19
+ return threadType;
25
20
  }
26
21
  export function threadsInRenderer(rendererData, auctionWorkletsData) {
27
- const foundThreads = [];
28
- if (rendererData.processes.size) {
29
- for (const [pid, process] of rendererData.processes) {
30
- for (const [tid, thread] of process.threads) {
31
- if (!thread.tree) {
32
- continue;
22
+ const foundThreads = [];
23
+ // If we have Renderer threads, we prefer to use those. In the event that a
24
+ // trace is a CPU Profile trace, we will never have Renderer threads, so we
25
+ // know if there are no Renderer threads that we can fallback to using the
26
+ // data from the SamplesHandler.
27
+ if (rendererData.processes.size) {
28
+ for (const [pid, process] of rendererData.processes) {
29
+ for (const [tid, thread] of process.threads) {
30
+ if (!thread.tree) {
31
+ // Drop threads where we could not create the tree; this indicates
32
+ // unexpected data and we won't be able to support all the UI
33
+ // filtering we need.
34
+ continue;
35
+ }
36
+ const threadType = getThreadTypeForRendererThread(auctionWorkletsData, pid, thread);
37
+ foundThreads.push({
38
+ name: thread.name,
39
+ pid,
40
+ tid,
41
+ processIsOnMainFrame: process.isOnMainFrame,
42
+ entries: thread.entries,
43
+ tree: thread.tree,
44
+ type: threadType,
45
+ entryToNode: rendererData.entryToNode,
46
+ });
47
+ }
33
48
  }
34
- const threadType = getThreadTypeForRendererThread(auctionWorkletsData, pid, thread);
35
- foundThreads.push({
36
- name: thread.name,
37
- pid,
38
- tid,
39
- processIsOnMainFrame: process.isOnMainFrame,
40
- entries: thread.entries,
41
- tree: thread.tree,
42
- type: threadType,
43
- entryToNode: rendererData.entryToNode
44
- });
45
- }
46
49
  }
47
- }
48
- return foundThreads;
50
+ return foundThreads;
49
51
  }
52
+ /**
53
+ * Given trace parsed data, this helper will return a high level array of
54
+ * ThreadData. This is useful because it allows you to get a list of threads
55
+ * regardless of if the trace is a CPU Profile or a Tracing profile. Thus you
56
+ * can use this helper to iterate over threads in confidence that it will work
57
+ * for both trace types.
58
+ */
50
59
  export function threadsInTrace(traceParseData) {
51
- const threadsFromRenderer = threadsInRenderer(traceParseData.Renderer, traceParseData.AuctionWorklets);
52
- if (threadsFromRenderer.length) {
53
- return threadsFromRenderer;
54
- }
55
- const foundThreads = [];
56
- if (traceParseData.Samples.profilesInProcess.size) {
57
- for (const [pid, process] of traceParseData.Samples.profilesInProcess) {
58
- for (const [tid, thread] of process) {
59
- if (!thread.profileTree) {
60
- continue;
60
+ // If we have Renderer threads, we prefer to use those. In the event that a
61
+ // trace is a CPU Profile trace, we will never have Renderer threads, so we
62
+ // know if there are no Renderer threads that we can fallback to using the
63
+ // data from the SamplesHandler.
64
+ const threadsFromRenderer = threadsInRenderer(traceParseData.Renderer, traceParseData.AuctionWorklets);
65
+ if (threadsFromRenderer.length) {
66
+ return threadsFromRenderer;
67
+ }
68
+ const foundThreads = [];
69
+ if (traceParseData.Samples.profilesInProcess.size) {
70
+ for (const [pid, process] of traceParseData.Samples.profilesInProcess) {
71
+ for (const [tid, thread] of process) {
72
+ if (!thread.profileTree) {
73
+ // Drop threads where we could not create the tree; this indicates
74
+ // unexpected data and we won't be able to support all the UI
75
+ // filtering we need.
76
+ continue;
77
+ }
78
+ foundThreads.push({
79
+ pid,
80
+ tid,
81
+ // CPU Profile threads do not have a name.
82
+ name: null,
83
+ entries: thread.profileCalls,
84
+ // There is no concept of a "Main Frame" in a CPU profile.
85
+ processIsOnMainFrame: false,
86
+ tree: thread.profileTree,
87
+ type: "CPU_PROFILE" /* ThreadType.CPU_PROFILE */,
88
+ entryToNode: traceParseData.Samples.entryToNode,
89
+ });
90
+ }
61
91
  }
62
- foundThreads.push({
63
- pid,
64
- tid,
65
- name: null,
66
- entries: thread.profileCalls,
67
- processIsOnMainFrame: false,
68
- tree: thread.profileTree,
69
- type: "CPU_PROFILE" /* CPU_PROFILE */,
70
- entryToNode: traceParseData.Samples.entryToNode
71
- });
72
- }
73
92
  }
74
- }
75
- return foundThreads;
93
+ return foundThreads;
76
94
  }
77
- //# sourceMappingURL=Threads.js.map
95
+ //# sourceMappingURL=Threads.js.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../../../../front_end/models/trace/handlers/Threads.ts"],
4
- "sourcesContent": ["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n//\nimport type * as Helpers from '../helpers/helpers.js';\nimport type * as Types from '../types/types.js';\n\nimport {type AuctionWorkletsData} from './AuctionWorkletsHandler.js';\nimport type * as Renderer from './RendererHandler.js';\nimport {type TraceParseData} from './types.js';\n\nexport interface ThreadData {\n pid: Types.TraceEvents.ProcessID;\n tid: Types.TraceEvents.ThreadID;\n entries: readonly Types.TraceEvents.SyntheticTraceEntry[];\n processIsOnMainFrame: boolean;\n tree: Helpers.TreeHelpers.TraceEntryTree;\n type: ThreadType;\n name: string|null;\n entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, Helpers.TreeHelpers.TraceEntryNode>;\n}\n\nexport const enum ThreadType {\n MAIN_THREAD = 'MAIN_THREAD',\n WORKER = 'WORKER',\n RASTERIZER = 'RASTERIZER',\n AUCTION_WORKLET = 'AUCTION_WORKLET',\n OTHER = 'OTHER',\n CPU_PROFILE = 'CPU_PROFILE',\n THREAD_POOL = 'THREAD_POOL',\n}\n\nfunction getThreadTypeForRendererThread(\n auctionWorkletsData: AuctionWorkletsData, pid: Types.TraceEvents.ProcessID,\n thread: Renderer.RendererThread): ThreadType {\n let threadType = ThreadType.OTHER;\n if (thread.name === 'CrRendererMain') {\n threadType = ThreadType.MAIN_THREAD;\n } else if (thread.name === 'DedicatedWorker thread') {\n threadType = ThreadType.WORKER;\n } else if (thread.name?.startsWith('CompositorTileWorker')) {\n threadType = ThreadType.RASTERIZER;\n } else if (auctionWorkletsData.worklets.has(pid)) {\n threadType = ThreadType.AUCTION_WORKLET;\n } else if (thread.name?.startsWith('ThreadPool')) {\n // TODO(paulirish): perhaps exclude ThreadPoolServiceThread entirely\n threadType = ThreadType.THREAD_POOL;\n }\n return threadType;\n}\n\nexport function threadsInRenderer(\n rendererData: Renderer.RendererHandlerData, auctionWorkletsData: AuctionWorkletsData): readonly ThreadData[] {\n const foundThreads: ThreadData[] = [];\n // If we have Renderer threads, we prefer to use those. In the event that a\n // trace is a CPU Profile trace, we will never have Renderer threads, so we\n // know if there are no Renderer threads that we can fallback to using the\n // data from the SamplesHandler.\n if (rendererData.processes.size) {\n for (const [pid, process] of rendererData.processes) {\n for (const [tid, thread] of process.threads) {\n if (!thread.tree) {\n // Drop threads where we could not create the tree; this indicates\n // unexpected data and we won't be able to support all the UI\n // filtering we need.\n continue;\n }\n const threadType = getThreadTypeForRendererThread(auctionWorkletsData, pid, thread);\n foundThreads.push({\n name: thread.name,\n pid,\n tid,\n processIsOnMainFrame: process.isOnMainFrame,\n entries: thread.entries,\n tree: thread.tree,\n type: threadType,\n entryToNode: rendererData.entryToNode,\n });\n }\n }\n }\n return foundThreads;\n}\n\n/**\n * Given trace parsed data, this helper will return a high level array of\n * ThreadData. This is useful because it allows you to get a list of threads\n * regardless of if the trace is a CPU Profile or a Tracing profile. Thus you\n * can use this helper to iterate over threads in confidence that it will work\n * for both trace types.\n */\nexport function threadsInTrace(traceParseData: TraceParseData): readonly ThreadData[] {\n // If we have Renderer threads, we prefer to use those. In the event that a\n // trace is a CPU Profile trace, we will never have Renderer threads, so we\n // know if there are no Renderer threads that we can fallback to using the\n // data from the SamplesHandler.\n const threadsFromRenderer = threadsInRenderer(traceParseData.Renderer, traceParseData.AuctionWorklets);\n if (threadsFromRenderer.length) {\n return threadsFromRenderer;\n }\n\n const foundThreads: ThreadData[] = [];\n if (traceParseData.Samples.profilesInProcess.size) {\n for (const [pid, process] of traceParseData.Samples.profilesInProcess) {\n for (const [tid, thread] of process) {\n if (!thread.profileTree) {\n // Drop threads where we could not create the tree; this indicates\n // unexpected data and we won't be able to support all the UI\n // filtering we need.\n continue;\n }\n\n foundThreads.push({\n pid,\n tid,\n // CPU Profile threads do not have a name.\n name: null,\n entries: thread.profileCalls,\n // There is no concept of a \"Main Frame\" in a CPU profile.\n processIsOnMainFrame: false,\n tree: thread.profileTree,\n type: ThreadType.CPU_PROFILE,\n entryToNode: traceParseData.Samples.entryToNode,\n });\n }\n }\n }\n\n return foundThreads;\n}\n"],
5
- "mappings": "AAsBO,WAAW,aAAX,kBAAW,gBAAX;AACL,+BAAc;AACd,0BAAS;AACT,8BAAa;AACb,mCAAkB;AAClB,yBAAQ;AACR,+BAAc;AACd,+BAAc;AAPE;AAAA;AAUlB,wCACI,qBAA0C,KAC1C,QAA6C;AAC/C,MAAI,aAAa;AACjB,MAAI,OAAO,SAAS,kBAAkB;AACpC,iBAAa;AAAA,aACJ,OAAO,SAAS,0BAA0B;AACnD,iBAAa;AAAA,aACJ,OAAO,MAAM,WAAW,yBAAyB;AAC1D,iBAAa;AAAA,aACJ,oBAAoB,SAAS,IAAI,MAAM;AAChD,iBAAa;AAAA,aACJ,OAAO,MAAM,WAAW,eAAe;AAEhD,iBAAa;AAAA;AAEf,SAAO;AAAA;AAGF,kCACH,cAA4C,qBAAiE;AAC/G,QAAM,eAA6B;AAKnC,MAAI,aAAa,UAAU,MAAM;AAC/B,eAAW,CAAC,KAAK,YAAY,aAAa,WAAW;AACnD,iBAAW,CAAC,KAAK,WAAW,QAAQ,SAAS;AAC3C,YAAI,CAAC,OAAO,MAAM;AAIhB;AAAA;AAEF,cAAM,aAAa,+BAA+B,qBAAqB,KAAK;AAC5E,qBAAa,KAAK;AAAA,UAChB,MAAM,OAAO;AAAA,UACb;AAAA,UACA;AAAA,UACA,sBAAsB,QAAQ;AAAA,UAC9B,SAAS,OAAO;AAAA,UAChB,MAAM,OAAO;AAAA,UACb,MAAM;AAAA,UACN,aAAa,aAAa;AAAA;AAAA;AAAA;AAAA;AAKlC,SAAO;AAAA;AAUF,+BAAwB,gBAAuD;AAKpF,QAAM,sBAAsB,kBAAkB,eAAe,UAAU,eAAe;AACtF,MAAI,oBAAoB,QAAQ;AAC9B,WAAO;AAAA;AAGT,QAAM,eAA6B;AACnC,MAAI,eAAe,QAAQ,kBAAkB,MAAM;AACjD,eAAW,CAAC,KAAK,YAAY,eAAe,QAAQ,mBAAmB;AACrE,iBAAW,CAAC,KAAK,WAAW,SAAS;AACnC,YAAI,CAAC,OAAO,aAAa;AAIvB;AAAA;AAGF,qBAAa,KAAK;AAAA,UAChB;AAAA,UACA;AAAA,UAEA,MAAM;AAAA,UACN,SAAS,OAAO;AAAA,UAEhB,sBAAsB;AAAA,UACtB,MAAM,OAAO;AAAA,UACb,MAAM;AAAA,UACN,aAAa,eAAe,QAAQ;AAAA;AAAA;AAAA;AAAA;AAM5C,SAAO;AAAA;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"Threads.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/Threads.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n//\nimport type * as Helpers from '../helpers/helpers.js';\nimport type * as Types from '../types/types.js';\n\nimport {type AuctionWorkletsData} from './AuctionWorkletsHandler.js';\nimport type * as Renderer from './RendererHandler.js';\nimport {type TraceParseData} from './types.js';\n\nexport interface ThreadData {\n pid: Types.TraceEvents.ProcessID;\n tid: Types.TraceEvents.ThreadID;\n entries: readonly Types.TraceEvents.SyntheticTraceEntry[];\n processIsOnMainFrame: boolean;\n tree: Helpers.TreeHelpers.TraceEntryTree;\n type: ThreadType;\n name: string|null;\n entryToNode: Map<Types.TraceEvents.SyntheticTraceEntry, Helpers.TreeHelpers.TraceEntryNode>;\n}\n\nexport const enum ThreadType {\n MAIN_THREAD = 'MAIN_THREAD',\n WORKER = 'WORKER',\n RASTERIZER = 'RASTERIZER',\n AUCTION_WORKLET = 'AUCTION_WORKLET',\n OTHER = 'OTHER',\n CPU_PROFILE = 'CPU_PROFILE',\n THREAD_POOL = 'THREAD_POOL',\n}\n\nfunction getThreadTypeForRendererThread(\n auctionWorkletsData: AuctionWorkletsData, pid: Types.TraceEvents.ProcessID,\n thread: Renderer.RendererThread): ThreadType {\n let threadType = ThreadType.OTHER;\n if (thread.name === 'CrRendererMain') {\n threadType = ThreadType.MAIN_THREAD;\n } else if (thread.name === 'DedicatedWorker thread') {\n threadType = ThreadType.WORKER;\n } else if (thread.name?.startsWith('CompositorTileWorker')) {\n threadType = ThreadType.RASTERIZER;\n } else if (auctionWorkletsData.worklets.has(pid)) {\n threadType = ThreadType.AUCTION_WORKLET;\n } else if (thread.name?.startsWith('ThreadPool')) {\n // TODO(paulirish): perhaps exclude ThreadPoolServiceThread entirely\n threadType = ThreadType.THREAD_POOL;\n }\n return threadType;\n}\n\nexport function threadsInRenderer(\n rendererData: Renderer.RendererHandlerData, auctionWorkletsData: AuctionWorkletsData): readonly ThreadData[] {\n const foundThreads: ThreadData[] = [];\n // If we have Renderer threads, we prefer to use those. In the event that a\n // trace is a CPU Profile trace, we will never have Renderer threads, so we\n // know if there are no Renderer threads that we can fallback to using the\n // data from the SamplesHandler.\n if (rendererData.processes.size) {\n for (const [pid, process] of rendererData.processes) {\n for (const [tid, thread] of process.threads) {\n if (!thread.tree) {\n // Drop threads where we could not create the tree; this indicates\n // unexpected data and we won't be able to support all the UI\n // filtering we need.\n continue;\n }\n const threadType = getThreadTypeForRendererThread(auctionWorkletsData, pid, thread);\n foundThreads.push({\n name: thread.name,\n pid,\n tid,\n processIsOnMainFrame: process.isOnMainFrame,\n entries: thread.entries,\n tree: thread.tree,\n type: threadType,\n entryToNode: rendererData.entryToNode,\n });\n }\n }\n }\n return foundThreads;\n}\n\n/**\n * Given trace parsed data, this helper will return a high level array of\n * ThreadData. This is useful because it allows you to get a list of threads\n * regardless of if the trace is a CPU Profile or a Tracing profile. Thus you\n * can use this helper to iterate over threads in confidence that it will work\n * for both trace types.\n */\nexport function threadsInTrace(traceParseData: TraceParseData): readonly ThreadData[] {\n // If we have Renderer threads, we prefer to use those. In the event that a\n // trace is a CPU Profile trace, we will never have Renderer threads, so we\n // know if there are no Renderer threads that we can fallback to using the\n // data from the SamplesHandler.\n const threadsFromRenderer = threadsInRenderer(traceParseData.Renderer, traceParseData.AuctionWorklets);\n if (threadsFromRenderer.length) {\n return threadsFromRenderer;\n }\n\n const foundThreads: ThreadData[] = [];\n if (traceParseData.Samples.profilesInProcess.size) {\n for (const [pid, process] of traceParseData.Samples.profilesInProcess) {\n for (const [tid, thread] of process) {\n if (!thread.profileTree) {\n // Drop threads where we could not create the tree; this indicates\n // unexpected data and we won't be able to support all the UI\n // filtering we need.\n continue;\n }\n\n foundThreads.push({\n pid,\n tid,\n // CPU Profile threads do not have a name.\n name: null,\n entries: thread.profileCalls,\n // There is no concept of a \"Main Frame\" in a CPU profile.\n processIsOnMainFrame: false,\n tree: thread.profileTree,\n type: ThreadType.CPU_PROFILE,\n entryToNode: traceParseData.Samples.entryToNode,\n });\n }\n }\n }\n\n return foundThreads;\n}\n"]}
@@ -0,0 +1,57 @@
1
+ import * as Types from '../types/types.js';
2
+ export declare const LONG_INTERACTION_THRESHOLD: Types.Timing.MicroSeconds;
3
+ export interface UserInteractionsData {
4
+ /** All the user events we found in the trace */
5
+ allEvents: readonly Types.TraceEvents.TraceEventEventTiming[];
6
+ /** All the interaction events we found in the trace that had an
7
+ * interactionId and a duration > 0
8
+ **/
9
+ interactionEvents: readonly Types.TraceEvents.SyntheticInteractionPair[];
10
+ /** If the user rapidly generates interaction events (think typing into a
11
+ * text box), in the UI we only really want to show the user the longest
12
+ * interaction in that set.
13
+ * For example picture interactions like this:
14
+ * ===[interaction A]==========
15
+ * =[interaction B]======
16
+ * =[interaction C]=
17
+ *
18
+ * These events all end at the same time, and so in this instance we only want
19
+ * to show the first interaction A on the timeline, as that is the longest one
20
+ * and the one the developer should be focusing on. So this array of events is
21
+ * all the interaction events filtered down, removing any nested interactions
22
+ * entirely.
23
+ **/
24
+ interactionEventsWithNoNesting: readonly Types.TraceEvents.SyntheticInteractionPair[];
25
+ longestInteractionEvent: Readonly<Types.TraceEvents.SyntheticInteractionPair> | null;
26
+ interactionsOverThreshold: Readonly<Set<Types.TraceEvents.SyntheticInteractionPair>>;
27
+ }
28
+ export declare function reset(): void;
29
+ export declare function handleEvent(event: Types.TraceEvents.TraceEventData): void;
30
+ export type InteractionCategory = 'KEYBOARD' | 'POINTER' | 'OTHER';
31
+ export declare function categoryOfInteraction(interaction: Types.TraceEvents.SyntheticInteractionPair): InteractionCategory;
32
+ /**
33
+ * We define a set of interactions as nested where:
34
+ * 1. Their end times align.
35
+ * 2. The longest interaction's start time is earlier than all other
36
+ * interactions with the same end time.
37
+ * 3. The interactions are of the same category [each interaction is either
38
+ * categorised as keyboard, or pointer.]
39
+ *
40
+ * =============A=[pointerup]=
41
+ * ====B=[pointerdown]=
42
+ * ===C=[pointerdown]==
43
+ * ===D=[pointerup]===
44
+ *
45
+ * In this example, B, C and D are all nested and therefore should not be
46
+ * returned from this function.
47
+ *
48
+ * However, in this example we would only consider B nested (under A) and D
49
+ * nested (under C). A and C both stay because they are of different types.
50
+ * ========A=[keydown]====
51
+ * =======B=[keyup]=====
52
+ * ====C=[pointerdown]=
53
+ * =D=[pointerup]=
54
+ **/
55
+ export declare function removeNestedInteractions(interactions: readonly Types.TraceEvents.SyntheticInteractionPair[]): readonly Types.TraceEvents.SyntheticInteractionPair[];
56
+ export declare function finalize(): Promise<void>;
57
+ export declare function data(): UserInteractionsData;