@paulirish/trace_engine 0.0.44 → 0.0.45

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 (272) hide show
  1. package/.tmp/tsbuildinfo/tsconfig.tsbuildinfo +1 -1
  2. package/core/platform/ArrayUtilities.d.ts +1 -1
  3. package/core/platform/ArrayUtilities.js.map +1 -1
  4. package/core/platform/DOMUtilities.js +1 -1
  5. package/core/platform/DOMUtilities.js.map +1 -1
  6. package/core/platform/MimeType.js.map +1 -1
  7. package/core/platform/NumberUtilities.js.map +1 -1
  8. package/core/platform/ServerTiming.d.ts +2 -2
  9. package/core/platform/ServerTiming.js.map +1 -1
  10. package/core/platform/StringUtilities.js +1 -1
  11. package/core/platform/StringUtilities.js.map +1 -1
  12. package/core/platform/Timing.d.ts +0 -1
  13. package/core/platform/Timing.js +0 -3
  14. package/core/platform/Timing.js.map +1 -1
  15. package/core/platform/TypedArrayUtilities.js +3 -2
  16. package/core/platform/TypedArrayUtilities.js.map +1 -1
  17. package/generated/protocol.d.ts +71 -4
  18. package/locales/af.json +184 -1
  19. package/locales/am.json +184 -1
  20. package/locales/ar.json +184 -1
  21. package/locales/as.json +184 -1
  22. package/locales/az.json +184 -1
  23. package/locales/be.json +184 -1
  24. package/locales/bg.json +184 -1
  25. package/locales/bn.json +184 -1
  26. package/locales/bs.json +184 -1
  27. package/locales/ca.json +184 -1
  28. package/locales/cs.json +184 -1
  29. package/locales/cy.json +184 -1
  30. package/locales/da.json +184 -1
  31. package/locales/de.json +184 -1
  32. package/locales/el.json +184 -1
  33. package/locales/en-GB.json +184 -1
  34. package/locales/en-US.json +201 -15
  35. package/locales/en-XL.json +201 -15
  36. package/locales/es-419.json +184 -1
  37. package/locales/es.json +184 -1
  38. package/locales/et.json +184 -1
  39. package/locales/eu.json +184 -1
  40. package/locales/fa.json +184 -1
  41. package/locales/fi.json +184 -1
  42. package/locales/fil.json +184 -1
  43. package/locales/fr-CA.json +184 -1
  44. package/locales/fr.json +184 -1
  45. package/locales/gl.json +184 -1
  46. package/locales/gu.json +184 -1
  47. package/locales/he.json +185 -2
  48. package/locales/hi.json +184 -1
  49. package/locales/hr.json +184 -1
  50. package/locales/hu.json +184 -1
  51. package/locales/hy.json +184 -1
  52. package/locales/id.json +184 -1
  53. package/locales/is.json +184 -1
  54. package/locales/it.json +184 -1
  55. package/locales/ja.json +184 -1
  56. package/locales/ka.json +184 -1
  57. package/locales/kk.json +184 -1
  58. package/locales/km.json +184 -1
  59. package/locales/kn.json +184 -1
  60. package/locales/ko.json +184 -1
  61. package/locales/ky.json +184 -1
  62. package/locales/lo.json +184 -1
  63. package/locales/lt.json +184 -1
  64. package/locales/lv.json +184 -1
  65. package/locales/mk.json +184 -1
  66. package/locales/ml.json +184 -1
  67. package/locales/mn.json +184 -1
  68. package/locales/mr.json +184 -1
  69. package/locales/ms.json +184 -1
  70. package/locales/my.json +184 -1
  71. package/locales/ne.json +184 -1
  72. package/locales/nl.json +184 -1
  73. package/locales/no.json +184 -1
  74. package/locales/or.json +184 -1
  75. package/locales/pa.json +184 -1
  76. package/locales/pl.json +184 -1
  77. package/locales/pt-PT.json +184 -1
  78. package/locales/pt.json +184 -1
  79. package/locales/ro.json +184 -1
  80. package/locales/ru.json +184 -1
  81. package/locales/si.json +184 -1
  82. package/locales/sk.json +184 -1
  83. package/locales/sl.json +184 -1
  84. package/locales/sq.json +184 -1
  85. package/locales/sr-Latn.json +184 -1
  86. package/locales/sr.json +184 -1
  87. package/locales/sv.json +184 -1
  88. package/locales/sw.json +184 -1
  89. package/locales/ta.json +184 -1
  90. package/locales/te.json +184 -1
  91. package/locales/th.json +184 -1
  92. package/locales/tr.json +184 -1
  93. package/locales/uk.json +184 -1
  94. package/locales/ur.json +184 -1
  95. package/locales/uz.json +184 -1
  96. package/locales/vi.json +184 -1
  97. package/locales/zh-HK.json +184 -1
  98. package/locales/zh-TW.json +184 -1
  99. package/locales/zh.json +184 -1
  100. package/locales/zu.json +184 -1
  101. package/models/cpu_profile/CPUProfileDataModel.js +10 -10
  102. package/models/cpu_profile/CPUProfileDataModel.js.map +1 -1
  103. package/models/trace/LanternComputationData.js.map +1 -1
  104. package/models/trace/ModelImpl.d.ts +1 -0
  105. package/models/trace/ModelImpl.js +1 -0
  106. package/models/trace/ModelImpl.js.map +1 -1
  107. package/models/trace/Processor.js +16 -11
  108. package/models/trace/Processor.js.map +1 -1
  109. package/models/trace/extras/FetchNodes.d.ts +1 -1
  110. package/models/trace/extras/FetchNodes.js +3 -3
  111. package/models/trace/extras/FetchNodes.js.map +1 -1
  112. package/models/trace/extras/ScriptDuplication.d.ts +34 -0
  113. package/models/trace/extras/ScriptDuplication.js +178 -0
  114. package/models/trace/extras/ScriptDuplication.js.map +1 -0
  115. package/models/trace/extras/StackTraceForEvent.js +25 -44
  116. package/models/trace/extras/StackTraceForEvent.js.map +1 -1
  117. package/models/trace/extras/ThirdParties.js +1 -0
  118. package/models/trace/extras/ThirdParties.js.map +1 -1
  119. package/models/trace/extras/TraceTree.d.ts +5 -2
  120. package/models/trace/extras/TraceTree.js +47 -17
  121. package/models/trace/extras/TraceTree.js.map +1 -1
  122. package/models/trace/extras/extras-tsconfig.json +1 -1
  123. package/models/trace/extras/extras.d.ts +1 -0
  124. package/models/trace/extras/extras.js +1 -0
  125. package/models/trace/extras/extras.js.map +1 -1
  126. package/models/trace/handlers/AnimationFramesHandler.js.map +1 -1
  127. package/models/trace/handlers/AsyncJSCallsHandler.js.map +1 -1
  128. package/models/trace/handlers/AuctionWorkletsHandler.js.map +1 -1
  129. package/models/trace/handlers/ExtensionTraceDataHandler.d.ts +1 -1
  130. package/models/trace/handlers/ExtensionTraceDataHandler.js +2 -1
  131. package/models/trace/handlers/ExtensionTraceDataHandler.js.map +1 -1
  132. package/models/trace/handlers/FramesHandler.js.map +1 -1
  133. package/models/trace/handlers/ImagePaintingHandler.js +1 -1
  134. package/models/trace/handlers/ImagePaintingHandler.js.map +1 -1
  135. package/models/trace/handlers/InitiatorsHandler.js.map +1 -1
  136. package/models/trace/handlers/InvalidationsHandler.js.map +1 -1
  137. package/models/trace/handlers/LayoutShiftsHandler.js.map +1 -1
  138. package/models/trace/handlers/MetaHandler.d.ts +2 -2
  139. package/models/trace/handlers/MetaHandler.js +4 -6
  140. package/models/trace/handlers/MetaHandler.js.map +1 -1
  141. package/models/trace/handlers/ModelHandlers.d.ts +1 -0
  142. package/models/trace/handlers/ModelHandlers.js +1 -0
  143. package/models/trace/handlers/ModelHandlers.js.map +1 -1
  144. package/models/trace/handlers/NetworkRequestsHandler.d.ts +9 -0
  145. package/models/trace/handlers/NetworkRequestsHandler.js +6 -6
  146. package/models/trace/handlers/NetworkRequestsHandler.js.map +1 -1
  147. package/models/trace/handlers/PageLoadMetricsHandler.js +1 -1
  148. package/models/trace/handlers/PageLoadMetricsHandler.js.map +1 -1
  149. package/models/trace/handlers/RendererHandler.js +3 -4
  150. package/models/trace/handlers/RendererHandler.js.map +1 -1
  151. package/models/trace/handlers/ScriptsHandler.d.ts +22 -0
  152. package/models/trace/handlers/ScriptsHandler.js +116 -0
  153. package/models/trace/handlers/ScriptsHandler.js.map +1 -0
  154. package/models/trace/handlers/UserTimingsHandler.d.ts +5 -0
  155. package/models/trace/handlers/UserTimingsHandler.js +16 -0
  156. package/models/trace/handlers/UserTimingsHandler.js.map +1 -1
  157. package/models/trace/handlers/WorkersHandler.js.map +1 -1
  158. package/models/trace/handlers/handlers-tsconfig.json +1 -0
  159. package/models/trace/handlers/helpers.d.ts +5 -1
  160. package/models/trace/handlers/helpers.js +28 -4
  161. package/models/trace/handlers/helpers.js.map +1 -1
  162. package/models/trace/helpers/Network.d.ts +1 -0
  163. package/models/trace/helpers/Network.js +8 -3
  164. package/models/trace/helpers/Network.js.map +1 -1
  165. package/models/trace/helpers/SamplesIntegrator.d.ts +8 -1
  166. package/models/trace/helpers/SamplesIntegrator.js +42 -2
  167. package/models/trace/helpers/SamplesIntegrator.js.map +1 -1
  168. package/models/trace/helpers/Timing.js.map +1 -1
  169. package/models/trace/helpers/Trace.d.ts +7 -10
  170. package/models/trace/helpers/Trace.js +25 -10
  171. package/models/trace/helpers/Trace.js.map +1 -1
  172. package/models/trace/insights/CLSCulprits.d.ts +12 -12
  173. package/models/trace/insights/CLSCulprits.js +15 -4
  174. package/models/trace/insights/CLSCulprits.js.map +1 -1
  175. package/models/trace/insights/Common.d.ts +7 -1
  176. package/models/trace/insights/Common.js +9 -3
  177. package/models/trace/insights/Common.js.map +1 -1
  178. package/models/trace/insights/DOMSize.d.ts +8 -8
  179. package/models/trace/insights/DOMSize.js +2 -1
  180. package/models/trace/insights/DOMSize.js.map +1 -1
  181. package/models/trace/insights/DocumentLatency.d.ts +11 -11
  182. package/models/trace/insights/DocumentLatency.js +2 -1
  183. package/models/trace/insights/DocumentLatency.js.map +1 -1
  184. package/models/trace/insights/DuplicateJavaScript.d.ts +18 -0
  185. package/models/trace/insights/DuplicateJavaScript.js +49 -0
  186. package/models/trace/insights/DuplicateJavaScript.js.map +1 -0
  187. package/models/trace/insights/FontDisplay.d.ts +4 -4
  188. package/models/trace/insights/FontDisplay.js +2 -1
  189. package/models/trace/insights/FontDisplay.js.map +1 -1
  190. package/models/trace/insights/ForcedReflow.d.ts +5 -5
  191. package/models/trace/insights/ForcedReflow.js +4 -1
  192. package/models/trace/insights/ForcedReflow.js.map +1 -1
  193. package/models/trace/insights/ImageDelivery.d.ts +19 -15
  194. package/models/trace/insights/ImageDelivery.js +26 -20
  195. package/models/trace/insights/ImageDelivery.js.map +1 -1
  196. package/models/trace/insights/InteractionToNextPaint.d.ts +8 -8
  197. package/models/trace/insights/InteractionToNextPaint.js +3 -2
  198. package/models/trace/insights/InteractionToNextPaint.js.map +1 -1
  199. package/models/trace/insights/LCPDiscovery.d.ts +9 -9
  200. package/models/trace/insights/LCPDiscovery.js +6 -3
  201. package/models/trace/insights/LCPDiscovery.js.map +1 -1
  202. package/models/trace/insights/LCPPhases.d.ts +15 -10
  203. package/models/trace/insights/LCPPhases.js +11 -4
  204. package/models/trace/insights/LCPPhases.js.map +1 -1
  205. package/models/trace/insights/Models.d.ts +2 -1
  206. package/models/trace/insights/Models.js +2 -1
  207. package/models/trace/insights/Models.js.map +1 -1
  208. package/models/trace/insights/NetworkDependencyTree.d.ts +33 -0
  209. package/models/trace/insights/NetworkDependencyTree.js +141 -0
  210. package/models/trace/insights/NetworkDependencyTree.js.map +1 -0
  211. package/models/trace/insights/RenderBlocking.d.ts +5 -5
  212. package/models/trace/insights/RenderBlocking.js +2 -1
  213. package/models/trace/insights/RenderBlocking.js.map +1 -1
  214. package/models/trace/insights/SlowCSSSelector.d.ts +8 -8
  215. package/models/trace/insights/SlowCSSSelector.js +4 -2
  216. package/models/trace/insights/SlowCSSSelector.js.map +1 -1
  217. package/models/trace/insights/ThirdParties.d.ts +6 -6
  218. package/models/trace/insights/ThirdParties.js +8 -5
  219. package/models/trace/insights/ThirdParties.js.map +1 -1
  220. package/models/trace/insights/Viewport.d.ts +2 -2
  221. package/models/trace/insights/Viewport.js +2 -1
  222. package/models/trace/insights/Viewport.js.map +1 -1
  223. package/models/trace/insights/insights-tsconfig.json +2 -1
  224. package/models/trace/insights/types.d.ts +25 -3
  225. package/models/trace/insights/types.js.map +1 -1
  226. package/models/trace/lantern/core/NetworkAnalyzer.d.ts +2 -2
  227. package/models/trace/lantern/core/NetworkAnalyzer.js +2 -2
  228. package/models/trace/lantern/core/NetworkAnalyzer.js.map +1 -1
  229. package/models/trace/lantern/graph/BaseNode.d.ts +1 -1
  230. package/models/trace/lantern/graph/BaseNode.js.map +1 -1
  231. package/models/trace/lantern/graph/CPUNode.js +1 -1
  232. package/models/trace/lantern/graph/CPUNode.js.map +1 -1
  233. package/models/trace/lantern/graph/NetworkNode.js +1 -1
  234. package/models/trace/lantern/graph/NetworkNode.js.map +1 -1
  235. package/models/trace/lantern/graph/PageDependencyGraph.d.ts +2 -2
  236. package/models/trace/lantern/graph/PageDependencyGraph.js.map +1 -1
  237. package/models/trace/lantern/metrics/Metric.js.map +1 -1
  238. package/models/trace/lantern/metrics/TotalBlockingTime.d.ts +2 -2
  239. package/models/trace/lantern/metrics/TotalBlockingTime.js.map +1 -1
  240. package/models/trace/lantern/types/Lantern.d.ts +2 -2
  241. package/models/trace/lantern/types/Lantern.js.map +1 -1
  242. package/models/trace/trace-tsconfig.json +3 -3
  243. package/models/trace/trace.d.ts +1 -2
  244. package/models/trace/trace.js +1 -2
  245. package/models/trace/trace.js.map +1 -1
  246. package/models/trace/types/Configuration.d.ts +10 -0
  247. package/models/trace/types/Configuration.js.map +1 -1
  248. package/models/trace/types/Extensions.d.ts +1 -1
  249. package/models/trace/types/Extensions.js.map +1 -1
  250. package/models/trace/types/TraceEvents.d.ts +87 -4
  251. package/models/trace/types/TraceEvents.js +20 -0
  252. package/models/trace/types/TraceEvents.js.map +1 -1
  253. package/package.json +1 -1
  254. package/test/test-trace-engine.mjs +3 -2
  255. package/models/trace/extras/TimelineJSProfile.d.ts +0 -13
  256. package/models/trace/extras/TimelineJSProfile.js +0 -60
  257. package/models/trace/extras/TimelineJSProfile.js.map +0 -1
  258. package/models/trace/insights/LongCriticalNetworkTree.d.ts +0 -22
  259. package/models/trace/insights/LongCriticalNetworkTree.js +0 -40
  260. package/models/trace/insights/LongCriticalNetworkTree.js.map +0 -1
  261. package/models/trace/root-causes/LayoutShift.d.ts +0 -125
  262. package/models/trace/root-causes/LayoutShift.js +0 -519
  263. package/models/trace/root-causes/LayoutShift.js.map +0 -1
  264. package/models/trace/root-causes/RootCauses.d.ts +0 -15
  265. package/models/trace/root-causes/RootCauses.js +0 -12
  266. package/models/trace/root-causes/RootCauses.js.map +0 -1
  267. package/models/trace/root-causes/bundle-tsconfig.json +0 -1
  268. package/models/trace/root-causes/devtools_entrypoint-bundle-typescript-tsconfig.json +0 -43
  269. package/models/trace/root-causes/root-causes-tsconfig.json +0 -56
  270. package/models/trace/root-causes/root-causes.d.ts +0 -1
  271. package/models/trace/root-causes/root-causes.js +0 -5
  272. package/models/trace/root-causes/root-causes.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ExtensionTraceDataHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ExtensionTraceDataHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 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 {HandlerName} from './types.js';\nimport {data as userTimingsData} from './UserTimingsHandler.js';\n\nconst extensionTrackEntries: Types.Extensions.SyntheticExtensionTrackEntry[] = [];\nconst extensionTrackData: Types.Extensions.ExtensionTrackData[] = [];\nconst extensionMarkers: Types.Extensions.SyntheticExtensionMarker[] = [];\nconst entryToNode: Map<Types.Events.Event, Helpers.TreeHelpers.TraceEntryNode> = new Map();\nconst timeStampByName: Map<string, Types.Events.ConsoleTimeStamp> = new Map();\n\nconst syntheticConsoleEntriesForTimingsTrack: Types.Events.SyntheticConsoleTimeStamp[] = [];\n\nexport interface ExtensionTraceData {\n extensionTrackData: readonly Types.Extensions.ExtensionTrackData[];\n extensionMarkers: readonly Types.Extensions.SyntheticExtensionMarker[];\n entryToNode: Map<Types.Events.Event, Helpers.TreeHelpers.TraceEntryNode>;\n syntheticConsoleEntriesForTimingsTrack: Types.Events.SyntheticConsoleTimeStamp[];\n}\n\nexport function handleEvent(_event: Types.Events.Event): void {\n // Implementation not needed because data is sourced from UserTimingsHandler\n}\n\nexport function reset(): void {\n extensionTrackEntries.length = 0;\n syntheticConsoleEntriesForTimingsTrack.length = 0;\n extensionTrackData.length = 0;\n extensionMarkers.length = 0;\n entryToNode.clear();\n timeStampByName.clear();\n}\n\nexport async function finalize(): Promise<void> {\n createExtensionFlameChartEntries();\n}\n\nfunction createExtensionFlameChartEntries(): void {\n const pairedMeasures: readonly Types.Events.SyntheticUserTimingPair[] = userTimingsData().performanceMeasures;\n const marks: readonly Types.Events.PerformanceMark[] = userTimingsData().performanceMarks;\n const mergedRawExtensionEvents = Helpers.Trace.mergeEventsInOrder(pairedMeasures, marks);\n\n extractPerformanceAPIExtensionEntries(mergedRawExtensionEvents);\n extractConsoleAPIExtensionEntries();\n // extensionTrackEntries is filled by the above two calls.\n Helpers.Trace.sortTraceEventsInPlace(extensionTrackEntries);\n Helpers.Extensions.buildTrackDataFromExtensionEntries(extensionTrackEntries, extensionTrackData, entryToNode);\n}\n\n/**\n * Extracts extension entries from console.timeStamp events.\n *\n * Entries are built by pairing `console.timeStamp` events based on\n * their names. When a `console.timeStamp` event includes a `start`\n * argument (and optionally an `end` argument), it attempts to find\n * previously recorded `console.timeStamp` events with names matching\n * the `start` and `end` values. These matching events are then used to\n * determine the start and end times of the new entry.\n *\n * If a `console.timeStamp` event includes data for a custom track\n * (specified by the `track` argument), an extension track entry is\n * created and added to the `extensionTrackEntries` array. These entries\n * are used to visualize custom tracks in the Performance panel.\n *\n * If a `console.timeStamp` event includes data for a custom track\n * (specified by the `track` argument), an extension track entry is\n * created and added to the `extensionTrackEntries` array. These entries\n * are used to visualize custom tracks in the Performance panel.\n *\n * If a `console.timeStamp` event does not specify a custom track but\n * includes a start and/or end time (referencing other\n * `console.timeStamp` names), a synthetic console time stamp entry is\n * created and added to the `syntheticConsoleEntriesForTimingsTrack`\n * array. These entries are displayed in the \"Timings\" track.\n */\nexport function extractConsoleAPIExtensionEntries(): void {\n const consoleTimeStamps: readonly Types.Events.ConsoleTimeStamp[] = userTimingsData().timestampEvents;\n for (const currentTimeStamp of consoleTimeStamps) {\n if (!currentTimeStamp.args.data) {\n continue;\n }\n const timeStampName = String(currentTimeStamp.args.data.name);\n timeStampByName.set(timeStampName, currentTimeStamp);\n const extensionData = extensionDataInConsoleTimeStamp(currentTimeStamp);\n const startName = currentTimeStamp.args.data.start;\n const endName = currentTimeStamp.args.data.end;\n if (!extensionData && !startName && !endName) {\n continue;\n }\n const startTimeStamp = startName ? timeStampByName.get(String(startName)) : undefined;\n const endTimeStamp = endName ? timeStampByName.get(String(endName)) : undefined;\n if (endTimeStamp && !startTimeStamp) {\n // Invalid data\n continue;\n }\n const entryStartTime = startTimeStamp?.ts ?? currentTimeStamp.ts;\n const entryEndTime = endTimeStamp?.ts ?? currentTimeStamp.ts;\n if (extensionData) {\n const unregisteredExtensionEntry: Omit<Types.Extensions.SyntheticExtensionTrackEntry, '_tag'> = {\n ...currentTimeStamp,\n name: timeStampName,\n cat: 'devtools.extension',\n args: extensionData,\n rawSourceEvent: currentTimeStamp,\n dur: Types.Timing.Micro(entryEndTime - entryStartTime),\n ts: entryStartTime,\n };\n const extensionEntry =\n Helpers.SyntheticEvents.SyntheticEventsManager.getActiveManager()\n .registerSyntheticEvent<Types.Extensions.SyntheticExtensionTrackEntry>(unregisteredExtensionEntry);\n extensionTrackEntries.push(extensionEntry);\n continue;\n }\n // If no extension data is found in the entry (no custom track name\n // was passed), but the entry has a duration. we still save it here\n // to be added in the timings track. Note that timings w/o duration\n // and extension data are already handled by the UserTimingsHandler.\n const unregisteredSyntheticTimeStamp: Omit<Types.Events.SyntheticConsoleTimeStamp, '_tag'> = {\n ...currentTimeStamp,\n name: timeStampName,\n cat: 'disabled-by-default-v8.inspector',\n ph: Types.Events.Phase.COMPLETE,\n ts: entryStartTime,\n dur: Types.Timing.Micro(entryEndTime - entryStartTime),\n rawSourceEvent: currentTimeStamp\n };\n const syntheticTimeStamp =\n Helpers.SyntheticEvents.SyntheticEventsManager.getActiveManager()\n .registerSyntheticEvent<Types.Events.SyntheticConsoleTimeStamp>(unregisteredSyntheticTimeStamp);\n syntheticConsoleEntriesForTimingsTrack.push(syntheticTimeStamp);\n }\n}\n\n/**\n * Extracts extension entries from Performance API events (marks and\n * measures).\n * It specifically looks for events that contain extension-specific data\n * within their `detail` property.\n *\n * If an event's `detail` property can be parsed as a JSON object and\n * contains a `devtools` field with a valid extension payload, a\n * synthetic extension entry is created. The type of extension entry\n * created depends on the payload:\n *\n * - If the payload conforms to `ExtensionPayloadMarker`, a\n * `SyntheticExtensionMarker` is created and added to the\n * `extensionMarkers` array. These markers represent single points in\n * time.\n * - If the payload conforms to `ExtensionPayloadTrackEntry`, a\n * `SyntheticExtensionTrackEntry` is created and added to the\n * `extensionTrackEntries` array. These entries represent events with\n * a duration and are displayed on custom tracks in the Performance\n * panel.\n *\n * **Note:** Only events with a `detail` property that contains valid\n * extension data are processed. Other `performance.mark` and\n * `performance.measure` events are ignored.\n *\n * @param timings An array of `SyntheticUserTimingPair` or\n * `PerformanceMark` events, typically obtained from the\n * `UserTimingsHandler`.\n */\nexport function extractPerformanceAPIExtensionEntries(\n timings: (Types.Events.SyntheticUserTimingPair|Types.Events.PerformanceMark)[]): void {\n for (const timing of timings) {\n const extensionPayload = extensionDataInPerformanceTiming(timing);\n if (!extensionPayload) {\n // Not an extension user timing.\n continue;\n }\n\n const extensionSyntheticEntry = {\n name: timing.name,\n ph: Types.Events.Phase.COMPLETE,\n pid: timing.pid,\n tid: timing.tid,\n ts: timing.ts,\n dur: timing.dur as Types.Timing.Micro,\n cat: 'devtools.extension',\n args: extensionPayload,\n rawSourceEvent: Types.Events.isSyntheticUserTiming(timing) ? timing.rawSourceEvent : timing,\n };\n\n if (Types.Extensions.isExtensionPayloadMarker(extensionPayload)) {\n const extensionMarker =\n Helpers.SyntheticEvents.SyntheticEventsManager.getActiveManager()\n .registerSyntheticEvent<Types.Extensions.SyntheticExtensionMarker>(\n extensionSyntheticEntry as Omit<Types.Extensions.SyntheticExtensionMarker, '_tag'>);\n extensionMarkers.push(extensionMarker);\n continue;\n }\n\n if (Types.Extensions.isExtensionPayloadTrackEntry(extensionSyntheticEntry.args)) {\n const extensionTrackEntry =\n Helpers.SyntheticEvents.SyntheticEventsManager.getActiveManager()\n .registerSyntheticEvent<Types.Extensions.SyntheticExtensionTrackEntry>(\n extensionSyntheticEntry as Omit<Types.Extensions.SyntheticExtensionTrackEntry, '_tag'>);\n extensionTrackEntries.push(extensionTrackEntry);\n continue;\n }\n }\n}\n\nexport function extensionDataInPerformanceTiming(timing: Types.Events.SyntheticUserTimingPair|\n Types.Events.PerformanceMark): Types.Extensions.ExtensionDataPayload|\n null {\n const timingDetail =\n Types.Events.isPerformanceMark(timing) ? timing.args.data?.detail : timing.args.data.beginEvent.args.detail;\n if (!timingDetail) {\n return null;\n }\n try {\n // Attempt to parse the detail as an object that might be coming from a\n // DevTools Perf extension.\n // Wrapped in a try-catch because timingDetail might either:\n // 1. Not be `json.parse`-able (it should, but just in case...)\n // 2.Not be an object - in which case the `in` check will error.\n // If we hit either of these cases, we just ignore this mark and move on.\n const detailObj = JSON.parse(timingDetail);\n if (!('devtools' in detailObj)) {\n return null;\n }\n if (!Types.Extensions.isValidExtensionPayload(detailObj.devtools)) {\n return null;\n }\n return detailObj.devtools;\n } catch {\n // No need to worry about this error, just discard this event and don't\n // treat it as having any useful information for the purposes of extensions\n return null;\n }\n}\n/**\n * Extracts extension data from a `console.timeStamp` event.\n *\n * Checks if a `console.timeStamp` event contains data intended for\n * creating a custom track entry in the DevTools Performance panel. It\n * specifically looks for a `track` argument within the event's data.\n *\n * If a `track` argument is present (and not an empty string), the\n * function constructs an `ExtensionTrackEntryPayload` object containing\n * the track name, an optional color, an optional track group. This\n * payload is then used to create a `SyntheticExtensionTrackEntry`.\n *\n * **Note:** The `color` argument is optional and its type is validated\n * against a predefined palette (see\n * `ExtensionUI::extensionEntryColor`).\n *\n * @param timeStamp The `ConsoleTimeStamp` event to extract data from.\n * @return An `ExtensionTrackEntryPayload` object if the event contains\n * valid extension data for a track entry, or `null` otherwise.\n */\nexport function extensionDataInConsoleTimeStamp(timeStamp: Types.Events.ConsoleTimeStamp):\n Types.Extensions.ExtensionTrackEntryPayload|null {\n if (!timeStamp.args.data) {\n return null;\n }\n const trackName = timeStamp.args.data.track;\n if (trackName === '' || trackName === undefined) {\n return null;\n }\n return {\n // the color is defaulted to primary if it's value isn't one from\n // the defined palette (see ExtensionUI::extensionEntryColor) so\n // we don't need to check the value is valid here.\n color: String(timeStamp.args.data.color) as Types.Extensions.ExtensionTrackEntryPayload['color'],\n track: String(trackName),\n dataType: 'track-entry',\n trackGroup: timeStamp.args.data.trackGroup !== undefined ? String(timeStamp.args.data.trackGroup) : undefined\n };\n}\n\nexport function data(): ExtensionTraceData {\n return {\n entryToNode,\n extensionTrackData,\n extensionMarkers,\n syntheticConsoleEntriesForTimingsTrack,\n };\n}\n\nexport function deps(): HandlerName[] {\n return ['UserTimings'];\n}\n"]}
1
+ {"version":3,"file":"ExtensionTraceDataHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ExtensionTraceDataHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 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 {HandlerName} from './types.js';\nimport {data as userTimingsData} from './UserTimingsHandler.js';\n\nconst extensionTrackEntries: Types.Extensions.SyntheticExtensionTrackEntry[] = [];\nconst extensionTrackData: Types.Extensions.ExtensionTrackData[] = [];\nconst extensionMarkers: Types.Extensions.SyntheticExtensionMarker[] = [];\nconst entryToNode = new Map<Types.Events.Event, Helpers.TreeHelpers.TraceEntryNode>();\nconst timeStampByName = new Map<string, Types.Events.ConsoleTimeStamp>();\n\nconst syntheticConsoleEntriesForTimingsTrack: Types.Events.SyntheticConsoleTimeStamp[] = [];\n\nexport interface ExtensionTraceData {\n extensionTrackData: readonly Types.Extensions.ExtensionTrackData[];\n extensionMarkers: readonly Types.Extensions.SyntheticExtensionMarker[];\n // TODO(andoli): Can we augment Renderer's entryToNode instead? To avoid the split of TimelineUIUtils's getEventSelfTime()?\n entryToNode: Map<Types.Events.Event, Helpers.TreeHelpers.TraceEntryNode>;\n syntheticConsoleEntriesForTimingsTrack: Types.Events.SyntheticConsoleTimeStamp[];\n}\n\nexport function handleEvent(_event: Types.Events.Event): void {\n // Implementation not needed because data is sourced from UserTimingsHandler\n}\n\nexport function reset(): void {\n extensionTrackEntries.length = 0;\n syntheticConsoleEntriesForTimingsTrack.length = 0;\n extensionTrackData.length = 0;\n extensionMarkers.length = 0;\n entryToNode.clear();\n timeStampByName.clear();\n}\n\nexport async function finalize(): Promise<void> {\n createExtensionFlameChartEntries();\n}\n\nfunction createExtensionFlameChartEntries(): void {\n const pairedMeasures: readonly Types.Events.SyntheticUserTimingPair[] = userTimingsData().performanceMeasures;\n const marks: readonly Types.Events.PerformanceMark[] = userTimingsData().performanceMarks;\n const mergedRawExtensionEvents = Helpers.Trace.mergeEventsInOrder(pairedMeasures, marks);\n\n extractPerformanceAPIExtensionEntries(mergedRawExtensionEvents);\n extractConsoleAPIExtensionEntries();\n // extensionTrackEntries is filled by the above two calls.\n Helpers.Trace.sortTraceEventsInPlace(extensionTrackEntries);\n Helpers.Extensions.buildTrackDataFromExtensionEntries(extensionTrackEntries, extensionTrackData, entryToNode);\n}\n\n/**\n * Extracts extension entries from console.timeStamp events.\n *\n * Entries are built by pairing `console.timeStamp` events based on\n * their names. When a `console.timeStamp` event includes a `start`\n * argument (and optionally an `end` argument), it attempts to find\n * previously recorded `console.timeStamp` events with names matching\n * the `start` and `end` values. These matching events are then used to\n * determine the start and end times of the new entry.\n *\n * If a `console.timeStamp` event includes data for a custom track\n * (specified by the `track` argument), an extension track entry is\n * created and added to the `extensionTrackEntries` array. These entries\n * are used to visualize custom tracks in the Performance panel.\n *\n * If a `console.timeStamp` event includes data for a custom track\n * (specified by the `track` argument), an extension track entry is\n * created and added to the `extensionTrackEntries` array. These entries\n * are used to visualize custom tracks in the Performance panel.\n *\n * If a `console.timeStamp` event does not specify a custom track but\n * includes a start and/or end time (referencing other\n * `console.timeStamp` names), a synthetic console time stamp entry is\n * created and added to the `syntheticConsoleEntriesForTimingsTrack`\n * array. These entries are displayed in the \"Timings\" track.\n */\nexport function extractConsoleAPIExtensionEntries(): void {\n const consoleTimeStamps: readonly Types.Events.ConsoleTimeStamp[] = userTimingsData().timestampEvents;\n for (const currentTimeStamp of consoleTimeStamps) {\n if (!currentTimeStamp.args.data) {\n continue;\n }\n const timeStampName = String(currentTimeStamp.args.data.name);\n timeStampByName.set(timeStampName, currentTimeStamp);\n const extensionData = extensionDataInConsoleTimeStamp(currentTimeStamp);\n const startName = currentTimeStamp.args.data.start;\n const endName = currentTimeStamp.args.data.end;\n if (!extensionData && !startName && !endName) {\n continue;\n }\n const startTimeStamp = startName ? timeStampByName.get(String(startName)) : undefined;\n const endTimeStamp = endName ? timeStampByName.get(String(endName)) : undefined;\n if (endTimeStamp && !startTimeStamp) {\n // Invalid data\n continue;\n }\n const entryStartTime = startTimeStamp?.ts ?? currentTimeStamp.ts;\n const entryEndTime = endTimeStamp?.ts ?? currentTimeStamp.ts;\n if (extensionData) {\n const unregisteredExtensionEntry: Omit<Types.Extensions.SyntheticExtensionTrackEntry, '_tag'> = {\n ...currentTimeStamp,\n name: timeStampName,\n cat: 'devtools.extension',\n args: extensionData,\n rawSourceEvent: currentTimeStamp,\n dur: Types.Timing.Micro(entryEndTime - entryStartTime),\n ts: entryStartTime,\n };\n const extensionEntry =\n Helpers.SyntheticEvents.SyntheticEventsManager.getActiveManager()\n .registerSyntheticEvent<Types.Extensions.SyntheticExtensionTrackEntry>(unregisteredExtensionEntry);\n extensionTrackEntries.push(extensionEntry);\n continue;\n }\n // If no extension data is found in the entry (no custom track name\n // was passed), but the entry has a duration. we still save it here\n // to be added in the timings track. Note that timings w/o duration\n // and extension data are already handled by the UserTimingsHandler.\n const unregisteredSyntheticTimeStamp: Omit<Types.Events.SyntheticConsoleTimeStamp, '_tag'> = {\n ...currentTimeStamp,\n name: timeStampName,\n cat: 'disabled-by-default-v8.inspector',\n ph: Types.Events.Phase.COMPLETE,\n ts: entryStartTime,\n dur: Types.Timing.Micro(entryEndTime - entryStartTime),\n rawSourceEvent: currentTimeStamp\n };\n const syntheticTimeStamp =\n Helpers.SyntheticEvents.SyntheticEventsManager.getActiveManager()\n .registerSyntheticEvent<Types.Events.SyntheticConsoleTimeStamp>(unregisteredSyntheticTimeStamp);\n syntheticConsoleEntriesForTimingsTrack.push(syntheticTimeStamp);\n }\n}\n\n/**\n * Extracts extension entries from Performance API events (marks and\n * measures).\n * It specifically looks for events that contain extension-specific data\n * within their `detail` property.\n *\n * If an event's `detail` property can be parsed as a JSON object and\n * contains a `devtools` field with a valid extension payload, a\n * synthetic extension entry is created. The type of extension entry\n * created depends on the payload:\n *\n * - If the payload conforms to `ExtensionPayloadMarker`, a\n * `SyntheticExtensionMarker` is created and added to the\n * `extensionMarkers` array. These markers represent single points in\n * time.\n * - If the payload conforms to `ExtensionPayloadTrackEntry`, a\n * `SyntheticExtensionTrackEntry` is created and added to the\n * `extensionTrackEntries` array. These entries represent events with\n * a duration and are displayed on custom tracks in the Performance\n * panel.\n *\n * **Note:** Only events with a `detail` property that contains valid\n * extension data are processed. Other `performance.mark` and\n * `performance.measure` events are ignored.\n *\n * @param timings An array of `SyntheticUserTimingPair` or\n * `PerformanceMark` events, typically obtained from the\n * `UserTimingsHandler`.\n */\nexport function extractPerformanceAPIExtensionEntries(\n timings: Array<Types.Events.SyntheticUserTimingPair|Types.Events.PerformanceMark>): void {\n for (const timing of timings) {\n const extensionPayload = extensionDataInPerformanceTiming(timing);\n if (!extensionPayload) {\n // Not an extension user timing.\n continue;\n }\n\n const extensionSyntheticEntry = {\n name: timing.name,\n ph: Types.Extensions.isExtensionPayloadMarker(extensionPayload) ? Types.Events.Phase.INSTANT :\n Types.Events.Phase.COMPLETE,\n pid: timing.pid,\n tid: timing.tid,\n ts: timing.ts,\n dur: timing.dur as Types.Timing.Micro,\n cat: 'devtools.extension',\n args: extensionPayload,\n rawSourceEvent: Types.Events.isSyntheticUserTiming(timing) ? timing.rawSourceEvent : timing,\n };\n\n if (Types.Extensions.isExtensionPayloadMarker(extensionPayload)) {\n const extensionMarker =\n Helpers.SyntheticEvents.SyntheticEventsManager.getActiveManager()\n .registerSyntheticEvent<Types.Extensions.SyntheticExtensionMarker>(\n extensionSyntheticEntry as Omit<Types.Extensions.SyntheticExtensionMarker, '_tag'>);\n extensionMarkers.push(extensionMarker);\n continue;\n }\n\n if (Types.Extensions.isExtensionPayloadTrackEntry(extensionSyntheticEntry.args)) {\n const extensionTrackEntry =\n Helpers.SyntheticEvents.SyntheticEventsManager.getActiveManager()\n .registerSyntheticEvent<Types.Extensions.SyntheticExtensionTrackEntry>(\n extensionSyntheticEntry as Omit<Types.Extensions.SyntheticExtensionTrackEntry, '_tag'>);\n extensionTrackEntries.push(extensionTrackEntry);\n continue;\n }\n }\n}\n\nexport function extensionDataInPerformanceTiming(\n timing: Types.Events.SyntheticUserTimingPair|Types.Events.PerformanceMark): Types.Extensions.ExtensionDataPayload|\n null {\n const timingDetail =\n Types.Events.isPerformanceMark(timing) ? timing.args.data?.detail : timing.args.data.beginEvent.args.detail;\n if (!timingDetail) {\n return null;\n }\n try {\n // Attempt to parse the detail as an object that might be coming from a\n // DevTools Perf extension.\n // Wrapped in a try-catch because timingDetail might either:\n // 1. Not be `json.parse`-able (it should, but just in case...)\n // 2.Not be an object - in which case the `in` check will error.\n // If we hit either of these cases, we just ignore this mark and move on.\n const detailObj = JSON.parse(timingDetail);\n if (!('devtools' in detailObj)) {\n return null;\n }\n if (!Types.Extensions.isValidExtensionPayload(detailObj.devtools)) {\n return null;\n }\n return detailObj.devtools;\n } catch {\n // No need to worry about this error, just discard this event and don't\n // treat it as having any useful information for the purposes of extensions\n return null;\n }\n}\n/**\n * Extracts extension data from a `console.timeStamp` event.\n *\n * Checks if a `console.timeStamp` event contains data intended for\n * creating a custom track entry in the DevTools Performance panel. It\n * specifically looks for a `track` argument within the event's data.\n *\n * If a `track` argument is present (and not an empty string), the\n * function constructs an `ExtensionTrackEntryPayload` object containing\n * the track name, an optional color, an optional track group. This\n * payload is then used to create a `SyntheticExtensionTrackEntry`.\n *\n * **Note:** The `color` argument is optional and its type is validated\n * against a predefined palette (see\n * `ExtensionUI::extensionEntryColor`).\n *\n * @param timeStamp The `ConsoleTimeStamp` event to extract data from.\n * @return An `ExtensionTrackEntryPayload` object if the event contains\n * valid extension data for a track entry, or `null` otherwise.\n */\nexport function extensionDataInConsoleTimeStamp(timeStamp: Types.Events.ConsoleTimeStamp):\n Types.Extensions.ExtensionTrackEntryPayload|null {\n if (!timeStamp.args.data) {\n return null;\n }\n const trackName = timeStamp.args.data.track;\n if (trackName === '' || trackName === undefined) {\n return null;\n }\n return {\n // the color is defaulted to primary if it's value isn't one from\n // the defined palette (see ExtensionUI::extensionEntryColor) so\n // we don't need to check the value is valid here.\n color: String(timeStamp.args.data.color) as Types.Extensions.ExtensionTrackEntryPayload['color'],\n track: String(trackName),\n dataType: 'track-entry',\n trackGroup: timeStamp.args.data.trackGroup !== undefined ? String(timeStamp.args.data.trackGroup) : undefined\n };\n}\n\nexport function data(): ExtensionTraceData {\n return {\n entryToNode,\n extensionTrackData,\n extensionMarkers,\n syntheticConsoleEntriesForTimingsTrack,\n };\n}\n\nexport function deps(): HandlerName[] {\n return ['UserTimings'];\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"FramesHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/FramesHandler.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 * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {type AuctionWorkletsData, data as auctionWorkletsData} from './AuctionWorkletsHandler.js';\nimport {data as layerTreeHandlerData, type LayerTreeData} from './LayerTreeHandler.js';\nimport {data as metaHandlerData, type MetaHandlerData} from './MetaHandler.js';\nimport {data as rendererHandlerData, type RendererHandlerData} from './RendererHandler.js';\nimport * as Threads from './Threads.js';\nimport type {HandlerName} from './types.js';\n\n/**\n * IMPORTANT: this handler is slightly different to the rest. This is because\n * it is an adaptation of the TimelineFrameModel that has been used in DevTools\n * for many years. Rather than re-implement all the logic from scratch, instead\n * this handler gathers up the events and instantitates the class in the\n * finalize() method. Once the class has parsed all events, it is used to then\n * return the array of frames.\n *\n * In time we expect to migrate this code to a more \"typical\" handler.\n */\n\nconst allEvents: Types.Events.Event[] = [];\nlet model: TimelineFrameModel|null = null;\n\nexport function reset(): void {\n allEvents.length = 0;\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n allEvents.push(event);\n}\n\nexport async function finalize(): Promise<void> {\n // Snapshot events can be emitted out of order, so we need to sort before\n // building the frames model.\n Helpers.Trace.sortTraceEventsInPlace(allEvents);\n\n const modelForTrace = new TimelineFrameModel(\n allEvents,\n rendererHandlerData(),\n auctionWorkletsData(),\n metaHandlerData(),\n layerTreeHandlerData(),\n );\n model = modelForTrace;\n}\n\nexport interface FramesData {\n frames: readonly Types.Events.LegacyTimelineFrame[];\n framesById: Readonly<Record<number, Types.Events.LegacyTimelineFrame|undefined>>;\n}\n\nexport function data(): FramesData {\n return {\n frames: model ? Array.from(model.frames()) : [],\n framesById: model ? {...model.framesById()} : {},\n };\n}\n\nexport function deps(): HandlerName[] {\n return ['Meta', 'Renderer', 'AuctionWorklets', 'LayerTree'];\n}\n\ntype FrameEvent = Types.Events.BeginFrame|Types.Events.DroppedFrame|Types.Events.RequestMainThreadFrame|\n Types.Events.BeginMainThreadFrame|Types.Events.Commit|Types.Events.CompositeLayers|\n Types.Events.ActivateLayerTree|Types.Events.NeedsBeginFrameChanged|Types.Events.DrawFrame;\n\nfunction isFrameEvent(event: Types.Events.Event): event is FrameEvent {\n return (\n Types.Events.isSetLayerId(event) || Types.Events.isBeginFrame(event) || Types.Events.isDroppedFrame(event) ||\n Types.Events.isRequestMainThreadFrame(event) || Types.Events.isBeginMainThreadFrame(event) ||\n Types.Events.isNeedsBeginFrameChanged(event) ||\n // Note that \"Commit\" is the replacement for \"CompositeLayers\" so in a trace\n // we wouldn't expect to see a combination of these. All \"new\" trace\n // recordings use \"Commit\", but we can easily support \"CompositeLayers\" too\n // to not break older traces being imported.\n Types.Events.isCommit(event) || Types.Events.isCompositeLayers(event) ||\n Types.Events.isActivateLayerTree(event) || Types.Events.isDrawFrame(event));\n}\n\nfunction entryIsTopLevel(entry: Types.Events.Event): boolean {\n const devtoolsTimelineCategory = 'disabled-by-default-devtools.timeline';\n return entry.name === Types.Events.Name.RUN_TASK && entry.cat.includes(devtoolsTimelineCategory);\n}\n\nexport class TimelineFrameModel {\n #frames: TimelineFrame[] = [];\n #frameById: {\n [x: number]: TimelineFrame,\n } = {};\n #beginFrameQueue: TimelineFrameBeginFrameQueue = new TimelineFrameBeginFrameQueue();\n #lastFrame: TimelineFrame|null = null;\n #mainFrameCommitted = false;\n #mainFrameRequested = false;\n #lastLayerTree: Types.Events.LegacyFrameLayerTreeData|null = null;\n #framePendingActivation: PendingFrame|null = null;\n #framePendingCommit: PendingFrame|null = null;\n #lastBeginFrame: number|null = null;\n #lastNeedsBeginFrame: number|null = null;\n #lastTaskBeginTime: Types.Timing.Micro|null = null;\n #layerTreeId: number|null = null;\n #activeProcessId: Types.Events.ProcessID|null = null;\n #activeThreadId: Types.Events.ThreadID|null = null;\n #layerTreeData: LayerTreeData;\n\n constructor(\n allEvents: readonly Types.Events.Event[], rendererData: RendererHandlerData,\n auctionWorkletsData: AuctionWorkletsData, metaData: MetaHandlerData, layerTreeData: LayerTreeData) {\n // We only care about getting threads from the Renderer, not Samples,\n // because Frames don't exist in a CPU Profile (which won't have Renderer\n // threads.)\n const mainThreads = Threads.threadsInRenderer(rendererData, auctionWorkletsData).filter(thread => {\n return thread.type === Threads.ThreadType.MAIN_THREAD && thread.processIsOnMainFrame;\n });\n const threadData = mainThreads.map(thread => {\n return {\n tid: thread.tid,\n pid: thread.pid,\n startTime: thread.entries[0].ts,\n };\n });\n\n this.#layerTreeData = layerTreeData;\n this.#addTraceEvents(allEvents, threadData, metaData.mainFrameId);\n }\n\n framesById(): Readonly<Record<number, TimelineFrame|undefined>> {\n return this.#frameById;\n }\n\n frames(): TimelineFrame[] {\n return this.#frames;\n }\n\n #handleBeginFrame(startTime: Types.Timing.Micro, seqId: number): void {\n if (!this.#lastFrame) {\n this.#startFrame(startTime, seqId);\n }\n this.#lastBeginFrame = startTime;\n\n this.#beginFrameQueue.addFrameIfNotExists(seqId, startTime, false, false);\n }\n\n #handleDroppedFrame(startTime: Types.Timing.Micro, seqId: number, isPartial: boolean): void {\n if (!this.#lastFrame) {\n this.#startFrame(startTime, seqId);\n }\n\n // This line handles the case where no BeginFrame event is issued for\n // the dropped frame. In this situation, add a BeginFrame to the queue\n // as if it actually occurred.\n this.#beginFrameQueue.addFrameIfNotExists(seqId, startTime, true, isPartial);\n this.#beginFrameQueue.setDropped(seqId, true);\n this.#beginFrameQueue.setPartial(seqId, isPartial);\n }\n\n #handleDrawFrame(startTime: Types.Timing.Micro, seqId: number): void {\n if (!this.#lastFrame) {\n this.#startFrame(startTime, seqId);\n return;\n }\n\n // - if it wasn't drawn, it didn't happen!\n // - only show frames that either did not wait for the main thread frame or had one committed.\n if (this.#mainFrameCommitted || !this.#mainFrameRequested) {\n if (this.#lastNeedsBeginFrame) {\n const idleTimeEnd = this.#framePendingActivation ? this.#framePendingActivation.triggerTime :\n (this.#lastBeginFrame || this.#lastNeedsBeginFrame);\n if (idleTimeEnd > this.#lastFrame.startTime) {\n this.#lastFrame.idle = true;\n this.#lastBeginFrame = null;\n }\n this.#lastNeedsBeginFrame = null;\n }\n\n const framesToVisualize = this.#beginFrameQueue.processPendingBeginFramesOnDrawFrame(seqId);\n\n // Visualize the current frame and all pending frames before it.\n for (const frame of framesToVisualize) {\n const isLastFrameIdle = this.#lastFrame.idle;\n\n // If |frame| is the first frame after an idle period, the CPU time\n // will be logged (\"committed\") under |frame| if applicable.\n this.#startFrame(frame.startTime, seqId);\n if (isLastFrameIdle && this.#framePendingActivation) {\n this.#commitPendingFrame();\n }\n if (frame.isDropped) {\n this.#lastFrame.dropped = true;\n }\n if (frame.isPartial) {\n this.#lastFrame.isPartial = true;\n }\n }\n }\n this.#mainFrameCommitted = false;\n }\n\n #handleActivateLayerTree(): void {\n if (!this.#lastFrame) {\n return;\n }\n if (this.#framePendingActivation && !this.#lastNeedsBeginFrame) {\n this.#commitPendingFrame();\n }\n }\n\n #handleRequestMainThreadFrame(): void {\n if (!this.#lastFrame) {\n return;\n }\n this.#mainFrameRequested = true;\n }\n\n #handleCommit(): void {\n if (!this.#framePendingCommit) {\n return;\n }\n this.#framePendingActivation = this.#framePendingCommit;\n this.#framePendingCommit = null;\n this.#mainFrameRequested = false;\n this.#mainFrameCommitted = true;\n }\n\n #handleLayerTreeSnapshot(layerTree: Types.Events.LegacyFrameLayerTreeData): void {\n this.#lastLayerTree = layerTree;\n }\n\n #handleNeedFrameChanged(startTime: Types.Timing.Micro, needsBeginFrame: boolean): void {\n if (needsBeginFrame) {\n this.#lastNeedsBeginFrame = startTime;\n }\n }\n\n #startFrame(startTime: Types.Timing.Micro, seqId: number): void {\n if (this.#lastFrame) {\n this.#flushFrame(this.#lastFrame, startTime);\n }\n this.#lastFrame =\n new TimelineFrame(seqId, startTime, Types.Timing.Micro(startTime - metaHandlerData().traceBounds.min));\n }\n\n #flushFrame(frame: TimelineFrame, endTime: Types.Timing.Micro): void {\n frame.setLayerTree(this.#lastLayerTree);\n frame.setEndTime(endTime);\n if (this.#lastLayerTree) {\n this.#lastLayerTree.paints = frame.paints;\n }\n const lastFrame = this.#frames[this.#frames.length - 1];\n if (this.#frames.length && lastFrame &&\n (frame.startTime !== lastFrame.endTime || frame.startTime > frame.endTime)) {\n console.assert(\n false, `Inconsistent frame time for frame ${this.#frames.length} (${frame.startTime} - ${frame.endTime})`);\n }\n const newFramesLength = this.#frames.push(frame);\n frame.setIndex(newFramesLength - 1);\n if (typeof frame.mainFrameId === 'number') {\n this.#frameById[frame.mainFrameId] = frame;\n }\n }\n\n #commitPendingFrame(): void {\n if (!this.#framePendingActivation || !this.#lastFrame) {\n return;\n }\n\n this.#lastFrame.paints = this.#framePendingActivation.paints;\n this.#lastFrame.mainFrameId = this.#framePendingActivation.mainFrameId;\n this.#framePendingActivation = null;\n }\n\n #addTraceEvents(\n events: readonly Types.Events.Event[], threadData: {\n pid: Types.Events.ProcessID,\n tid: Types.Events.ThreadID,\n startTime: Types.Timing.Micro,\n }[],\n mainFrameId: string): void {\n let j = 0;\n this.#activeThreadId = threadData.length && threadData[0].tid || null;\n this.#activeProcessId = threadData.length && threadData[0].pid || null;\n for (let i = 0; i < events.length; ++i) {\n while (j + 1 < threadData.length && threadData[j + 1].startTime <= events[i].ts) {\n this.#activeThreadId = threadData[++j].tid;\n this.#activeProcessId = threadData[j].pid;\n }\n this.#addTraceEvent(events[i], mainFrameId);\n }\n this.#activeThreadId = null;\n this.#activeProcessId = null;\n }\n\n #addTraceEvent(event: Types.Events.Event, mainFrameId: string): void {\n if (Types.Events.isSetLayerId(event) && event.args.data.frame === mainFrameId) {\n this.#layerTreeId = event.args.data.layerTreeId;\n } else if (Types.Events.isLayerTreeHostImplSnapshot(event) && Number(event.id) === this.#layerTreeId) {\n this.#handleLayerTreeSnapshot({\n entry: event,\n paints: [],\n });\n } else {\n if (isFrameEvent(event)) {\n this.#processCompositorEvents(event);\n }\n // Make sure we only use events from the main thread: we check the PID as\n // well in case two processes have a thread with the same TID.\n if (event.tid === this.#activeThreadId && event.pid === this.#activeProcessId) {\n this.#addMainThreadTraceEvent(event);\n }\n }\n }\n\n #processCompositorEvents(entry: FrameEvent): void {\n if (entry.args['layerTreeId'] !== this.#layerTreeId) {\n return;\n }\n if (Types.Events.isBeginFrame(entry)) {\n this.#handleBeginFrame(entry.ts, entry.args['frameSeqId']);\n } else if (Types.Events.isDrawFrame(entry)) {\n this.#handleDrawFrame(entry.ts, entry.args['frameSeqId']);\n } else if (Types.Events.isActivateLayerTree(entry)) {\n this.#handleActivateLayerTree();\n } else if (Types.Events.isRequestMainThreadFrame(entry)) {\n this.#handleRequestMainThreadFrame();\n } else if (Types.Events.isNeedsBeginFrameChanged(entry)) {\n // needsBeginFrame property will either be 0 or 1, which represents\n // true/false in this case, hence the Boolean() wrapper.\n this.#handleNeedFrameChanged(entry.ts, entry.args['data'] && Boolean(entry.args['data']['needsBeginFrame']));\n } else if (Types.Events.isDroppedFrame(entry)) {\n this.#handleDroppedFrame(entry.ts, entry.args['frameSeqId'], Boolean(entry.args['hasPartialUpdate']));\n }\n }\n\n #addMainThreadTraceEvent(entry: Types.Events.Event): void {\n if (entryIsTopLevel(entry)) {\n this.#lastTaskBeginTime = entry.ts;\n }\n if (!this.#framePendingCommit && MAIN_FRAME_MARKERS.has(entry.name as Types.Events.Name)) {\n this.#framePendingCommit = new PendingFrame(this.#lastTaskBeginTime || entry.ts);\n }\n if (!this.#framePendingCommit) {\n return;\n }\n\n if (Types.Events.isBeginMainThreadFrame(entry) && entry.args.data.frameId) {\n this.#framePendingCommit.mainFrameId = entry.args.data.frameId;\n }\n if (Types.Events.isPaint(entry)) {\n const snapshot = this.#layerTreeData.paintsToSnapshots.get(entry);\n if (snapshot) {\n this.#framePendingCommit.paints.push(new LayerPaintEvent(entry, snapshot));\n }\n }\n // Commit will be replacing CompositeLayers but CompositeLayers is kept\n // around for backwards compatibility.\n if ((Types.Events.isCompositeLayers(entry) || Types.Events.isCommit(entry)) &&\n entry.args['layerTreeId'] === this.#layerTreeId) {\n this.#handleCommit();\n }\n }\n}\n\nconst MAIN_FRAME_MARKERS = new Set<Types.Events.Name>([\n Types.Events.Name.SCHEDULE_STYLE_RECALCULATION,\n Types.Events.Name.INVALIDATE_LAYOUT,\n Types.Events.Name.BEGIN_MAIN_THREAD_FRAME,\n Types.Events.Name.SCROLL_LAYER,\n]);\n\n/**\n * Legacy class that represents TimelineFrames that was ported from the old SDK.\n * This class is purposefully not exported as it breaks the abstraction that\n * every event shown on the timeline is a trace event. Instead, we use the Type\n * LegacyTimelineFrame to represent frames in the codebase. These do implement\n * the right interface to be treated just like they were a trace event.\n */\nclass TimelineFrame implements Types.Events.LegacyTimelineFrame {\n // These fields exist to satisfy the base Event type which all\n // \"trace events\" must implement. They aren't used, but doing this means we\n // can pass `TimelineFrame` instances into places that expect\n // Types.Events.Event.\n cat = 'devtools.legacy_frame';\n name = 'frame';\n ph = Types.Events.Phase.COMPLETE;\n ts: Types.Timing.Micro;\n pid = Types.Events.ProcessID(-1);\n tid = Types.Events.ThreadID(-1);\n\n index: number = -1;\n startTime: Types.Timing.Micro;\n startTimeOffset: Types.Timing.Micro;\n endTime: Types.Timing.Micro;\n duration: Types.Timing.Micro;\n idle: boolean;\n dropped: boolean;\n isPartial: boolean;\n layerTree: Types.Events.LegacyFrameLayerTreeData|null;\n paints: LayerPaintEvent[];\n mainFrameId: number|undefined;\n readonly seqId: number;\n\n constructor(seqId: number, startTime: Types.Timing.Micro, startTimeOffset: Types.Timing.Micro) {\n this.seqId = seqId;\n this.startTime = startTime;\n this.ts = startTime;\n this.startTimeOffset = startTimeOffset;\n this.endTime = this.startTime;\n this.duration = Types.Timing.Micro(0);\n this.idle = false;\n this.dropped = false;\n this.isPartial = false;\n this.layerTree = null;\n this.paints = [];\n this.mainFrameId = undefined;\n }\n\n setIndex(i: number): void {\n this.index = i;\n }\n\n setEndTime(endTime: Types.Timing.Micro): void {\n this.endTime = endTime;\n this.duration = Types.Timing.Micro(this.endTime - this.startTime);\n }\n\n setLayerTree(layerTree: Types.Events.LegacyFrameLayerTreeData|null): void {\n this.layerTree = layerTree;\n }\n\n /**\n * Fake the `dur` field to meet the expected value given that we pretend\n * these TimelineFrame classes are trace events across the codebase.\n */\n get dur(): Types.Timing.Micro {\n return this.duration;\n }\n}\n\nexport class LayerPaintEvent implements Types.Events.LegacyLayerPaintEvent {\n readonly #event: Types.Events.Paint;\n #snapshot: Types.Events.DisplayItemListSnapshot;\n\n constructor(event: Types.Events.Paint, snapshot: Types.Events.DisplayItemListSnapshot) {\n this.#event = event;\n this.#snapshot = snapshot;\n }\n\n layerId(): number {\n return this.#event.args.data.layerId;\n }\n\n event(): Types.Events.Paint {\n return this.#event;\n }\n\n picture(): Types.Events.LegacyLayerPaintEventPicture|null {\n const rect = this.#snapshot.args.snapshot.params?.layer_rect;\n const pictureData = this.#snapshot.args.snapshot.skp64;\n return rect && pictureData ? {rect, serializedPicture: pictureData} : null;\n }\n}\n\nexport class PendingFrame {\n paints: LayerPaintEvent[];\n mainFrameId: number|undefined;\n triggerTime: number;\n constructor(triggerTime: number) {\n this.paints = [];\n this.mainFrameId = undefined;\n this.triggerTime = triggerTime;\n }\n}\n\n// The parameters of an impl-side BeginFrame.\nclass BeginFrameInfo {\n seqId: number;\n startTime: Types.Timing.Micro;\n isDropped: boolean;\n isPartial: boolean;\n constructor(seqId: number, startTime: Types.Timing.Micro, isDropped: boolean, isPartial: boolean) {\n this.seqId = seqId;\n this.startTime = startTime;\n this.isDropped = isDropped;\n this.isPartial = isPartial;\n }\n}\n\n// A queue of BeginFrames pending visualization.\n// BeginFrames are added into this queue as they occur; later when their\n// corresponding DrawFrames occur (or lack thereof), the BeginFrames are removed\n// from the queue and their timestamps are used for visualization.\nexport class TimelineFrameBeginFrameQueue {\n private queueFrames: number[] = [];\n\n // Maps frameSeqId to BeginFrameInfo.\n private mapFrames: {\n [x: number]: BeginFrameInfo,\n } = {};\n\n // Add a BeginFrame to the queue, if it does not already exit.\n addFrameIfNotExists(seqId: number, startTime: Types.Timing.Micro, isDropped: boolean, isPartial: boolean): void {\n if (!(seqId in this.mapFrames)) {\n this.mapFrames[seqId] = new BeginFrameInfo(seqId, startTime, isDropped, isPartial);\n this.queueFrames.push(seqId);\n }\n }\n\n // Set a BeginFrame in queue as dropped.\n setDropped(seqId: number, isDropped: boolean): void {\n if (seqId in this.mapFrames) {\n this.mapFrames[seqId].isDropped = isDropped;\n }\n }\n\n setPartial(seqId: number, isPartial: boolean): void {\n if (seqId in this.mapFrames) {\n this.mapFrames[seqId].isPartial = isPartial;\n }\n }\n\n processPendingBeginFramesOnDrawFrame(seqId: number): BeginFrameInfo[] {\n const framesToVisualize: BeginFrameInfo[] = [];\n\n // Do not visualize this frame in the rare case where the current DrawFrame\n // does not have a corresponding BeginFrame.\n if (seqId in this.mapFrames) {\n // Pop all BeginFrames before the current frame, and add only the dropped\n // ones in |frames_to_visualize|.\n // Non-dropped frames popped here are BeginFrames that are never\n // drawn (but not considered dropped either for some reason).\n // Those frames do not require an proactive visualization effort and will\n // be naturally presented as continuationss of other frames.\n while (this.queueFrames[0] !== seqId) {\n const currentSeqId = this.queueFrames[0];\n if (this.mapFrames[currentSeqId].isDropped) {\n framesToVisualize.push(this.mapFrames[currentSeqId]);\n }\n\n delete this.mapFrames[currentSeqId];\n this.queueFrames.shift();\n }\n\n // Pop the BeginFrame associated with the current DrawFrame.\n framesToVisualize.push(this.mapFrames[seqId]);\n delete this.mapFrames[seqId];\n this.queueFrames.shift();\n }\n return framesToVisualize;\n }\n}\n\nexport function framesWithinWindow(\n frames: readonly Types.Events.LegacyTimelineFrame[], startTime: Types.Timing.Micro,\n endTime: Types.Timing.Micro): Types.Events.LegacyTimelineFrame[] {\n const firstFrame = Platform.ArrayUtilities.lowerBound(frames, startTime || 0, (time, frame) => time - frame.endTime);\n const lastFrame =\n Platform.ArrayUtilities.lowerBound(frames, endTime || Infinity, (time, frame) => time - frame.startTime);\n return frames.slice(firstFrame, lastFrame);\n}\n"]}
1
+ {"version":3,"file":"FramesHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/FramesHandler.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 * as Platform from '../../../core/platform/platform.js';\nimport * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {type AuctionWorkletsData, data as auctionWorkletsData} from './AuctionWorkletsHandler.js';\nimport {data as layerTreeHandlerData, type LayerTreeData} from './LayerTreeHandler.js';\nimport {data as metaHandlerData, type MetaHandlerData} from './MetaHandler.js';\nimport {data as rendererHandlerData, type RendererHandlerData} from './RendererHandler.js';\nimport * as Threads from './Threads.js';\nimport type {HandlerName} from './types.js';\n\n/**\n * IMPORTANT: this handler is slightly different to the rest. This is because\n * it is an adaptation of the TimelineFrameModel that has been used in DevTools\n * for many years. Rather than re-implement all the logic from scratch, instead\n * this handler gathers up the events and instantitates the class in the\n * finalize() method. Once the class has parsed all events, it is used to then\n * return the array of frames.\n *\n * In time we expect to migrate this code to a more \"typical\" handler.\n */\n\nconst allEvents: Types.Events.Event[] = [];\nlet model: TimelineFrameModel|null = null;\n\nexport function reset(): void {\n allEvents.length = 0;\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n allEvents.push(event);\n}\n\nexport async function finalize(): Promise<void> {\n // Snapshot events can be emitted out of order, so we need to sort before\n // building the frames model.\n Helpers.Trace.sortTraceEventsInPlace(allEvents);\n\n const modelForTrace = new TimelineFrameModel(\n allEvents,\n rendererHandlerData(),\n auctionWorkletsData(),\n metaHandlerData(),\n layerTreeHandlerData(),\n );\n model = modelForTrace;\n}\n\nexport interface FramesData {\n frames: readonly Types.Events.LegacyTimelineFrame[];\n framesById: Readonly<Record<number, Types.Events.LegacyTimelineFrame|undefined>>;\n}\n\nexport function data(): FramesData {\n return {\n frames: model ? Array.from(model.frames()) : [],\n framesById: model ? {...model.framesById()} : {},\n };\n}\n\nexport function deps(): HandlerName[] {\n return ['Meta', 'Renderer', 'AuctionWorklets', 'LayerTree'];\n}\n\ntype FrameEvent = Types.Events.BeginFrame|Types.Events.DroppedFrame|Types.Events.RequestMainThreadFrame|\n Types.Events.BeginMainThreadFrame|Types.Events.Commit|Types.Events.CompositeLayers|\n Types.Events.ActivateLayerTree|Types.Events.NeedsBeginFrameChanged|Types.Events.DrawFrame;\n\nfunction isFrameEvent(event: Types.Events.Event): event is FrameEvent {\n return (\n Types.Events.isSetLayerId(event) || Types.Events.isBeginFrame(event) || Types.Events.isDroppedFrame(event) ||\n Types.Events.isRequestMainThreadFrame(event) || Types.Events.isBeginMainThreadFrame(event) ||\n Types.Events.isNeedsBeginFrameChanged(event) ||\n // Note that \"Commit\" is the replacement for \"CompositeLayers\" so in a trace\n // we wouldn't expect to see a combination of these. All \"new\" trace\n // recordings use \"Commit\", but we can easily support \"CompositeLayers\" too\n // to not break older traces being imported.\n Types.Events.isCommit(event) || Types.Events.isCompositeLayers(event) ||\n Types.Events.isActivateLayerTree(event) || Types.Events.isDrawFrame(event));\n}\n\nfunction entryIsTopLevel(entry: Types.Events.Event): boolean {\n const devtoolsTimelineCategory = 'disabled-by-default-devtools.timeline';\n return entry.name === Types.Events.Name.RUN_TASK && entry.cat.includes(devtoolsTimelineCategory);\n}\n\nexport class TimelineFrameModel {\n #frames: TimelineFrame[] = [];\n #frameById: {\n [x: number]: TimelineFrame,\n } = {};\n #beginFrameQueue: TimelineFrameBeginFrameQueue = new TimelineFrameBeginFrameQueue();\n #lastFrame: TimelineFrame|null = null;\n #mainFrameCommitted = false;\n #mainFrameRequested = false;\n #lastLayerTree: Types.Events.LegacyFrameLayerTreeData|null = null;\n #framePendingActivation: PendingFrame|null = null;\n #framePendingCommit: PendingFrame|null = null;\n #lastBeginFrame: number|null = null;\n #lastNeedsBeginFrame: number|null = null;\n #lastTaskBeginTime: Types.Timing.Micro|null = null;\n #layerTreeId: number|null = null;\n #activeProcessId: Types.Events.ProcessID|null = null;\n #activeThreadId: Types.Events.ThreadID|null = null;\n #layerTreeData: LayerTreeData;\n\n constructor(\n allEvents: readonly Types.Events.Event[], rendererData: RendererHandlerData,\n auctionWorkletsData: AuctionWorkletsData, metaData: MetaHandlerData, layerTreeData: LayerTreeData) {\n // We only care about getting threads from the Renderer, not Samples,\n // because Frames don't exist in a CPU Profile (which won't have Renderer\n // threads.)\n const mainThreads = Threads.threadsInRenderer(rendererData, auctionWorkletsData).filter(thread => {\n return thread.type === Threads.ThreadType.MAIN_THREAD && thread.processIsOnMainFrame;\n });\n const threadData = mainThreads.map(thread => {\n return {\n tid: thread.tid,\n pid: thread.pid,\n startTime: thread.entries[0].ts,\n };\n });\n\n this.#layerTreeData = layerTreeData;\n this.#addTraceEvents(allEvents, threadData, metaData.mainFrameId);\n }\n\n framesById(): Readonly<Record<number, TimelineFrame|undefined>> {\n return this.#frameById;\n }\n\n frames(): TimelineFrame[] {\n return this.#frames;\n }\n\n #handleBeginFrame(startTime: Types.Timing.Micro, seqId: number): void {\n if (!this.#lastFrame) {\n this.#startFrame(startTime, seqId);\n }\n this.#lastBeginFrame = startTime;\n\n this.#beginFrameQueue.addFrameIfNotExists(seqId, startTime, false, false);\n }\n\n #handleDroppedFrame(startTime: Types.Timing.Micro, seqId: number, isPartial: boolean): void {\n if (!this.#lastFrame) {\n this.#startFrame(startTime, seqId);\n }\n\n // This line handles the case where no BeginFrame event is issued for\n // the dropped frame. In this situation, add a BeginFrame to the queue\n // as if it actually occurred.\n this.#beginFrameQueue.addFrameIfNotExists(seqId, startTime, true, isPartial);\n this.#beginFrameQueue.setDropped(seqId, true);\n this.#beginFrameQueue.setPartial(seqId, isPartial);\n }\n\n #handleDrawFrame(startTime: Types.Timing.Micro, seqId: number): void {\n if (!this.#lastFrame) {\n this.#startFrame(startTime, seqId);\n return;\n }\n\n // - if it wasn't drawn, it didn't happen!\n // - only show frames that either did not wait for the main thread frame or had one committed.\n if (this.#mainFrameCommitted || !this.#mainFrameRequested) {\n if (this.#lastNeedsBeginFrame) {\n const idleTimeEnd = this.#framePendingActivation ? this.#framePendingActivation.triggerTime :\n (this.#lastBeginFrame || this.#lastNeedsBeginFrame);\n if (idleTimeEnd > this.#lastFrame.startTime) {\n this.#lastFrame.idle = true;\n this.#lastBeginFrame = null;\n }\n this.#lastNeedsBeginFrame = null;\n }\n\n const framesToVisualize = this.#beginFrameQueue.processPendingBeginFramesOnDrawFrame(seqId);\n\n // Visualize the current frame and all pending frames before it.\n for (const frame of framesToVisualize) {\n const isLastFrameIdle = this.#lastFrame.idle;\n\n // If |frame| is the first frame after an idle period, the CPU time\n // will be logged (\"committed\") under |frame| if applicable.\n this.#startFrame(frame.startTime, seqId);\n if (isLastFrameIdle && this.#framePendingActivation) {\n this.#commitPendingFrame();\n }\n if (frame.isDropped) {\n this.#lastFrame.dropped = true;\n }\n if (frame.isPartial) {\n this.#lastFrame.isPartial = true;\n }\n }\n }\n this.#mainFrameCommitted = false;\n }\n\n #handleActivateLayerTree(): void {\n if (!this.#lastFrame) {\n return;\n }\n if (this.#framePendingActivation && !this.#lastNeedsBeginFrame) {\n this.#commitPendingFrame();\n }\n }\n\n #handleRequestMainThreadFrame(): void {\n if (!this.#lastFrame) {\n return;\n }\n this.#mainFrameRequested = true;\n }\n\n #handleCommit(): void {\n if (!this.#framePendingCommit) {\n return;\n }\n this.#framePendingActivation = this.#framePendingCommit;\n this.#framePendingCommit = null;\n this.#mainFrameRequested = false;\n this.#mainFrameCommitted = true;\n }\n\n #handleLayerTreeSnapshot(layerTree: Types.Events.LegacyFrameLayerTreeData): void {\n this.#lastLayerTree = layerTree;\n }\n\n #handleNeedFrameChanged(startTime: Types.Timing.Micro, needsBeginFrame: boolean): void {\n if (needsBeginFrame) {\n this.#lastNeedsBeginFrame = startTime;\n }\n }\n\n #startFrame(startTime: Types.Timing.Micro, seqId: number): void {\n if (this.#lastFrame) {\n this.#flushFrame(this.#lastFrame, startTime);\n }\n this.#lastFrame =\n new TimelineFrame(seqId, startTime, Types.Timing.Micro(startTime - metaHandlerData().traceBounds.min));\n }\n\n #flushFrame(frame: TimelineFrame, endTime: Types.Timing.Micro): void {\n frame.setLayerTree(this.#lastLayerTree);\n frame.setEndTime(endTime);\n if (this.#lastLayerTree) {\n this.#lastLayerTree.paints = frame.paints;\n }\n const lastFrame = this.#frames[this.#frames.length - 1];\n if (this.#frames.length && lastFrame &&\n (frame.startTime !== lastFrame.endTime || frame.startTime > frame.endTime)) {\n console.assert(\n false, `Inconsistent frame time for frame ${this.#frames.length} (${frame.startTime} - ${frame.endTime})`);\n }\n const newFramesLength = this.#frames.push(frame);\n frame.setIndex(newFramesLength - 1);\n if (typeof frame.mainFrameId === 'number') {\n this.#frameById[frame.mainFrameId] = frame;\n }\n }\n\n #commitPendingFrame(): void {\n if (!this.#framePendingActivation || !this.#lastFrame) {\n return;\n }\n\n this.#lastFrame.paints = this.#framePendingActivation.paints;\n this.#lastFrame.mainFrameId = this.#framePendingActivation.mainFrameId;\n this.#framePendingActivation = null;\n }\n\n #addTraceEvents(\n events: readonly Types.Events.Event[], threadData: Array<{\n pid: Types.Events.ProcessID,\n tid: Types.Events.ThreadID,\n startTime: Types.Timing.Micro,\n }>,\n mainFrameId: string): void {\n let j = 0;\n this.#activeThreadId = threadData.length && threadData[0].tid || null;\n this.#activeProcessId = threadData.length && threadData[0].pid || null;\n for (let i = 0; i < events.length; ++i) {\n while (j + 1 < threadData.length && threadData[j + 1].startTime <= events[i].ts) {\n this.#activeThreadId = threadData[++j].tid;\n this.#activeProcessId = threadData[j].pid;\n }\n this.#addTraceEvent(events[i], mainFrameId);\n }\n this.#activeThreadId = null;\n this.#activeProcessId = null;\n }\n\n #addTraceEvent(event: Types.Events.Event, mainFrameId: string): void {\n if (Types.Events.isSetLayerId(event) && event.args.data.frame === mainFrameId) {\n this.#layerTreeId = event.args.data.layerTreeId;\n } else if (Types.Events.isLayerTreeHostImplSnapshot(event) && Number(event.id) === this.#layerTreeId) {\n this.#handleLayerTreeSnapshot({\n entry: event,\n paints: [],\n });\n } else {\n if (isFrameEvent(event)) {\n this.#processCompositorEvents(event);\n }\n // Make sure we only use events from the main thread: we check the PID as\n // well in case two processes have a thread with the same TID.\n if (event.tid === this.#activeThreadId && event.pid === this.#activeProcessId) {\n this.#addMainThreadTraceEvent(event);\n }\n }\n }\n\n #processCompositorEvents(entry: FrameEvent): void {\n if (entry.args['layerTreeId'] !== this.#layerTreeId) {\n return;\n }\n if (Types.Events.isBeginFrame(entry)) {\n this.#handleBeginFrame(entry.ts, entry.args['frameSeqId']);\n } else if (Types.Events.isDrawFrame(entry)) {\n this.#handleDrawFrame(entry.ts, entry.args['frameSeqId']);\n } else if (Types.Events.isActivateLayerTree(entry)) {\n this.#handleActivateLayerTree();\n } else if (Types.Events.isRequestMainThreadFrame(entry)) {\n this.#handleRequestMainThreadFrame();\n } else if (Types.Events.isNeedsBeginFrameChanged(entry)) {\n // needsBeginFrame property will either be 0 or 1, which represents\n // true/false in this case, hence the Boolean() wrapper.\n this.#handleNeedFrameChanged(entry.ts, entry.args['data'] && Boolean(entry.args['data']['needsBeginFrame']));\n } else if (Types.Events.isDroppedFrame(entry)) {\n this.#handleDroppedFrame(entry.ts, entry.args['frameSeqId'], Boolean(entry.args['hasPartialUpdate']));\n }\n }\n\n #addMainThreadTraceEvent(entry: Types.Events.Event): void {\n if (entryIsTopLevel(entry)) {\n this.#lastTaskBeginTime = entry.ts;\n }\n if (!this.#framePendingCommit && MAIN_FRAME_MARKERS.has(entry.name as Types.Events.Name)) {\n this.#framePendingCommit = new PendingFrame(this.#lastTaskBeginTime || entry.ts);\n }\n if (!this.#framePendingCommit) {\n return;\n }\n\n if (Types.Events.isBeginMainThreadFrame(entry) && entry.args.data.frameId) {\n this.#framePendingCommit.mainFrameId = entry.args.data.frameId;\n }\n if (Types.Events.isPaint(entry)) {\n const snapshot = this.#layerTreeData.paintsToSnapshots.get(entry);\n if (snapshot) {\n this.#framePendingCommit.paints.push(new LayerPaintEvent(entry, snapshot));\n }\n }\n // Commit will be replacing CompositeLayers but CompositeLayers is kept\n // around for backwards compatibility.\n if ((Types.Events.isCompositeLayers(entry) || Types.Events.isCommit(entry)) &&\n entry.args['layerTreeId'] === this.#layerTreeId) {\n this.#handleCommit();\n }\n }\n}\n\nconst MAIN_FRAME_MARKERS = new Set<Types.Events.Name>([\n Types.Events.Name.SCHEDULE_STYLE_RECALCULATION,\n Types.Events.Name.INVALIDATE_LAYOUT,\n Types.Events.Name.BEGIN_MAIN_THREAD_FRAME,\n Types.Events.Name.SCROLL_LAYER,\n]);\n\n/**\n * Legacy class that represents TimelineFrames that was ported from the old SDK.\n * This class is purposefully not exported as it breaks the abstraction that\n * every event shown on the timeline is a trace event. Instead, we use the Type\n * LegacyTimelineFrame to represent frames in the codebase. These do implement\n * the right interface to be treated just like they were a trace event.\n */\nclass TimelineFrame implements Types.Events.LegacyTimelineFrame {\n // These fields exist to satisfy the base Event type which all\n // \"trace events\" must implement. They aren't used, but doing this means we\n // can pass `TimelineFrame` instances into places that expect\n // Types.Events.Event.\n cat = 'devtools.legacy_frame';\n name = 'frame';\n ph = Types.Events.Phase.COMPLETE;\n ts: Types.Timing.Micro;\n pid = Types.Events.ProcessID(-1);\n tid = Types.Events.ThreadID(-1);\n\n index = -1;\n startTime: Types.Timing.Micro;\n startTimeOffset: Types.Timing.Micro;\n endTime: Types.Timing.Micro;\n duration: Types.Timing.Micro;\n idle: boolean;\n dropped: boolean;\n isPartial: boolean;\n layerTree: Types.Events.LegacyFrameLayerTreeData|null;\n paints: LayerPaintEvent[];\n mainFrameId: number|undefined;\n readonly seqId: number;\n\n constructor(seqId: number, startTime: Types.Timing.Micro, startTimeOffset: Types.Timing.Micro) {\n this.seqId = seqId;\n this.startTime = startTime;\n this.ts = startTime;\n this.startTimeOffset = startTimeOffset;\n this.endTime = this.startTime;\n this.duration = Types.Timing.Micro(0);\n this.idle = false;\n this.dropped = false;\n this.isPartial = false;\n this.layerTree = null;\n this.paints = [];\n this.mainFrameId = undefined;\n }\n\n setIndex(i: number): void {\n this.index = i;\n }\n\n setEndTime(endTime: Types.Timing.Micro): void {\n this.endTime = endTime;\n this.duration = Types.Timing.Micro(this.endTime - this.startTime);\n }\n\n setLayerTree(layerTree: Types.Events.LegacyFrameLayerTreeData|null): void {\n this.layerTree = layerTree;\n }\n\n /**\n * Fake the `dur` field to meet the expected value given that we pretend\n * these TimelineFrame classes are trace events across the codebase.\n */\n get dur(): Types.Timing.Micro {\n return this.duration;\n }\n}\n\nexport class LayerPaintEvent implements Types.Events.LegacyLayerPaintEvent {\n readonly #event: Types.Events.Paint;\n #snapshot: Types.Events.DisplayItemListSnapshot;\n\n constructor(event: Types.Events.Paint, snapshot: Types.Events.DisplayItemListSnapshot) {\n this.#event = event;\n this.#snapshot = snapshot;\n }\n\n layerId(): number {\n return this.#event.args.data.layerId;\n }\n\n event(): Types.Events.Paint {\n return this.#event;\n }\n\n picture(): Types.Events.LegacyLayerPaintEventPicture|null {\n const rect = this.#snapshot.args.snapshot.params?.layer_rect;\n const pictureData = this.#snapshot.args.snapshot.skp64;\n return rect && pictureData ? {rect, serializedPicture: pictureData} : null;\n }\n}\n\nexport class PendingFrame {\n paints: LayerPaintEvent[];\n mainFrameId: number|undefined;\n triggerTime: number;\n constructor(triggerTime: number) {\n this.paints = [];\n this.mainFrameId = undefined;\n this.triggerTime = triggerTime;\n }\n}\n\n// The parameters of an impl-side BeginFrame.\nclass BeginFrameInfo {\n seqId: number;\n startTime: Types.Timing.Micro;\n isDropped: boolean;\n isPartial: boolean;\n constructor(seqId: number, startTime: Types.Timing.Micro, isDropped: boolean, isPartial: boolean) {\n this.seqId = seqId;\n this.startTime = startTime;\n this.isDropped = isDropped;\n this.isPartial = isPartial;\n }\n}\n\n// A queue of BeginFrames pending visualization.\n// BeginFrames are added into this queue as they occur; later when their\n// corresponding DrawFrames occur (or lack thereof), the BeginFrames are removed\n// from the queue and their timestamps are used for visualization.\nexport class TimelineFrameBeginFrameQueue {\n private queueFrames: number[] = [];\n\n // Maps frameSeqId to BeginFrameInfo.\n private mapFrames: {\n [x: number]: BeginFrameInfo,\n } = {};\n\n // Add a BeginFrame to the queue, if it does not already exit.\n addFrameIfNotExists(seqId: number, startTime: Types.Timing.Micro, isDropped: boolean, isPartial: boolean): void {\n if (!(seqId in this.mapFrames)) {\n this.mapFrames[seqId] = new BeginFrameInfo(seqId, startTime, isDropped, isPartial);\n this.queueFrames.push(seqId);\n }\n }\n\n // Set a BeginFrame in queue as dropped.\n setDropped(seqId: number, isDropped: boolean): void {\n if (seqId in this.mapFrames) {\n this.mapFrames[seqId].isDropped = isDropped;\n }\n }\n\n setPartial(seqId: number, isPartial: boolean): void {\n if (seqId in this.mapFrames) {\n this.mapFrames[seqId].isPartial = isPartial;\n }\n }\n\n processPendingBeginFramesOnDrawFrame(seqId: number): BeginFrameInfo[] {\n const framesToVisualize: BeginFrameInfo[] = [];\n\n // Do not visualize this frame in the rare case where the current DrawFrame\n // does not have a corresponding BeginFrame.\n if (seqId in this.mapFrames) {\n // Pop all BeginFrames before the current frame, and add only the dropped\n // ones in |frames_to_visualize|.\n // Non-dropped frames popped here are BeginFrames that are never\n // drawn (but not considered dropped either for some reason).\n // Those frames do not require an proactive visualization effort and will\n // be naturally presented as continuationss of other frames.\n while (this.queueFrames[0] !== seqId) {\n const currentSeqId = this.queueFrames[0];\n if (this.mapFrames[currentSeqId].isDropped) {\n framesToVisualize.push(this.mapFrames[currentSeqId]);\n }\n\n delete this.mapFrames[currentSeqId];\n this.queueFrames.shift();\n }\n\n // Pop the BeginFrame associated with the current DrawFrame.\n framesToVisualize.push(this.mapFrames[seqId]);\n delete this.mapFrames[seqId];\n this.queueFrames.shift();\n }\n return framesToVisualize;\n }\n}\n\nexport function framesWithinWindow(\n frames: readonly Types.Events.LegacyTimelineFrame[], startTime: Types.Timing.Micro,\n endTime: Types.Timing.Micro): Types.Events.LegacyTimelineFrame[] {\n const firstFrame = Platform.ArrayUtilities.lowerBound(frames, startTime || 0, (time, frame) => time - frame.endTime);\n const lastFrame =\n Platform.ArrayUtilities.lowerBound(frames, endTime || Infinity, (time, frame) => time - frame.startTime);\n return frames.slice(firstFrame, lastFrame);\n}\n"]}
@@ -94,7 +94,7 @@ export function handleEvent(event) {
94
94
  }
95
95
  // 2. Find the last DecodeLazyPixelRef event and, if we find it, find its associated PaintImage event.
96
96
  const lastDecodeLazyPixelRef = decodeLazyPixelRefEvents.get(event.pid)?.get(event.tid)?.at(-1);
97
- if (!lastDecodeLazyPixelRef || typeof lastDecodeLazyPixelRef.args?.LazyPixelRef === 'undefined') {
97
+ if (typeof lastDecodeLazyPixelRef?.args?.LazyPixelRef === 'undefined') {
98
98
  return;
99
99
  }
100
100
  const paintEvent = paintImageByLazyPixelRef.get(lastDecodeLazyPixelRef.args.LazyPixelRef);
@@ -1 +1 @@
1
- {"version":3,"file":"ImagePaintingHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ImagePaintingHandler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 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 Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\n\n/**\n * This handler is responsible for the relationships between:\n * DecodeImage/ResizeImage, PaintImage and DrawLazyPixelRef events.\n *\n * When we get a DecodeImage event, we want to associate it to a PaintImage\n * event, primarily so we can determine the NodeID of the image that was\n * decoded.\n * We can do this in two ways:\n *\n * 1. If there is a PaintImage event on the same thread, use that\n * (if there are multiple, use the latest one).\n *\n * 2. If not, we can find the DecodeLazyPixelRef event on the same thread, and\n * use the PaintImage event associated with it via the `LazyPixelRef` key.\n */\n\n// Track paintImageEvents across threads.\nconst paintImageEvents: Map<Types.Events.ProcessID, Map<Types.Events.ThreadID, Types.Events.PaintImage[]>> = new Map();\nconst decodeLazyPixelRefEvents:\n Map<Types.Events.ProcessID, Map<Types.Events.ThreadID, Types.Events.DecodeLazyPixelRef[]>> = new Map();\n\n// A DrawLazyPixelRef event will contain a numerical reference in\n// args.LazyPixelRef. As we parse each DrawLazyPixelRef, we can assign it to a\n// paint event. Later we want to look up paint events by this reference, so we\n// store them in this map.\nconst paintImageByLazyPixelRef: Map<number, Types.Events.PaintImage> = new Map();\n\n// When we find events that we want to tie to a particular PaintImage event, we add them to this map.\n// These are currently only DecodeImage and ResizeImage events, but the type is\n// deliberately generic as in the future we might want to add more events that\n// have a relationship to a individual PaintImage event.\nconst eventToPaintImage: Map<Types.Events.Event, Types.Events.PaintImage> = new Map();\n\nconst urlToPaintImage: Map<string, Types.Events.PaintImage[]> = new Map();\n\nexport function reset(): void {\n paintImageEvents.clear();\n decodeLazyPixelRefEvents.clear();\n paintImageByLazyPixelRef.clear();\n eventToPaintImage.clear();\n urlToPaintImage.clear();\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n if (Types.Events.isPaintImage(event)) {\n const forProcess = paintImageEvents.get(event.pid) || new Map<Types.Events.ThreadID, Types.Events.PaintImage[]>();\n const forThread = forProcess.get(event.tid) || [];\n forThread.push(event);\n forProcess.set(event.tid, forThread);\n paintImageEvents.set(event.pid, forProcess);\n\n if (event.args.data.url) {\n const paintsForUrl = Platform.MapUtilities.getWithDefault(urlToPaintImage, event.args.data.url, () => []);\n paintsForUrl.push(event);\n }\n\n return;\n }\n\n if (Types.Events.isDecodeLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {\n // Store these because we use them to tie DecodeImage to a PaintEvent.\n const forProcess =\n decodeLazyPixelRefEvents.get(event.pid) || new Map<Types.Events.ThreadID, Types.Events.DecodeLazyPixelRef[]>();\n const forThread = forProcess.get(event.tid) || [];\n forThread.push(event);\n forProcess.set(event.tid, forThread);\n decodeLazyPixelRefEvents.set(event.pid, forProcess);\n }\n\n // If we see a DrawLazyPixelRef event, we need to find the last PaintImage\n // event on the thread and associate it to the LazyPixelRef that is supplied\n // in the DrawLazyPixelRef event.\n // This means that later on if we see a DecodeLazyPixelRef event with the\n // same LazyPixelRef key, we can find its associated PaintImage event by\n // looking it up.\n if (Types.Events.isDrawLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {\n const lastPaintEvent = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (!lastPaintEvent) {\n return;\n }\n paintImageByLazyPixelRef.set(event.args.LazyPixelRef, lastPaintEvent);\n return;\n }\n\n if (Types.Events.isDecodeImage(event)) {\n // When we see a DecodeImage, we want to associate it to a PaintImage\n // event. We try two approaches:\n //\n // 1. If the thread of the DecodeImage event has a previous PaintImage\n // event, that is the associated event.\n //\n // 2. If that is false, we then look on the thread for a DecodeLazyPixelRef\n // event. If we find that, we then look for its associated PaintImage\n // event, which we associate via DrawLazyPixelRef events (the code block\n // above this one)\n //\n // 1. Find a PaintImage event on the same thread. If we find it, that's our association done.\n const lastPaintImageEventOnThread = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (lastPaintImageEventOnThread) {\n eventToPaintImage.set(event, lastPaintImageEventOnThread);\n return;\n }\n\n // 2. Find the last DecodeLazyPixelRef event and, if we find it, find its associated PaintImage event.\n const lastDecodeLazyPixelRef = decodeLazyPixelRefEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (!lastDecodeLazyPixelRef || typeof lastDecodeLazyPixelRef.args?.LazyPixelRef === 'undefined') {\n return;\n }\n\n const paintEvent = paintImageByLazyPixelRef.get(lastDecodeLazyPixelRef.args.LazyPixelRef);\n if (!paintEvent) {\n return;\n }\n eventToPaintImage.set(event, paintEvent);\n }\n}\n\nexport async function finalize(): Promise<void> {\n}\n\nexport interface ImagePaintData {\n paintImageByDrawLazyPixelRef: Map<number, Types.Events.PaintImage>;\n paintImageForEvent: Map<Types.Events.Event, Types.Events.PaintImage>;\n paintImageEventForUrl: Map<string, Types.Events.PaintImage[]>;\n}\n\nexport function data(): ImagePaintData {\n return {\n paintImageByDrawLazyPixelRef: paintImageByLazyPixelRef,\n paintImageForEvent: eventToPaintImage,\n paintImageEventForUrl: urlToPaintImage,\n };\n}\n"]}
1
+ {"version":3,"file":"ImagePaintingHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/ImagePaintingHandler.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,yEAAyE;AACzE,6BAA6B;AAE7B,OAAO,KAAK,QAAQ,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C;;;;;;;;;;;;;;GAcG;AAEH,yCAAyC;AACzC,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAiF,CAAC;AAClH,MAAM,wBAAwB,GAC1B,IAAI,GAAG,EAAyF,CAAC;AAErG,iEAAiE;AACjE,8EAA8E;AAC9E,8EAA8E;AAC9E,0BAA0B;AAC1B,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAmC,CAAC;AAE5E,qGAAqG;AACrG,+EAA+E;AAC/E,8EAA8E;AAC9E,wDAAwD;AACxD,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAA+C,CAAC;AAEjF,MAAM,eAAe,GAAG,IAAI,GAAG,EAAqC,CAAC;AAErE,MAAM,UAAU,KAAK;IACnB,gBAAgB,CAAC,KAAK,EAAE,CAAC;IACzB,wBAAwB,CAAC,KAAK,EAAE,CAAC;IACjC,wBAAwB,CAAC,KAAK,EAAE,CAAC;IACjC,iBAAiB,CAAC,KAAK,EAAE,CAAC;IAC1B,eAAe,CAAC,KAAK,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAyB;IACnD,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAoD,CAAC;QAClH,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAClD,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACrC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAE5C,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,cAAc,CAAC,eAAe,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC1G,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QAED,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,EAAE,YAAY,KAAK,WAAW,EAAE,CAAC;QAChG,sEAAsE;QACtE,MAAM,UAAU,GACZ,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAA4D,CAAC;QACnH,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAClD,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACrC,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACtD,CAAC;IAED,0EAA0E;IAC1E,4EAA4E;IAC5E,iCAAiC;IACjC,yEAAyE;IACzE,wEAAwE;IACxE,iBAAiB;IACjB,IAAI,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,EAAE,YAAY,KAAK,WAAW,EAAE,CAAC;QAC9F,MAAM,cAAc,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/E,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QACD,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,qEAAqE;QACrE,gCAAgC;QAChC,EAAE;QACF,sEAAsE;QACtE,uCAAuC;QACvC,EAAE;QACF,2EAA2E;QAC3E,qEAAqE;QACrE,wEAAwE;QACxE,kBAAkB;QAClB,EAAE;QACF,6FAA6F;QAC7F,MAAM,2BAA2B,GAAG,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,IAAI,2BAA2B,EAAE,CAAC;YAChC,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,sGAAsG;QACtG,MAAM,sBAAsB,GAAG,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/F,IAAI,OAAO,sBAAsB,EAAE,IAAI,EAAE,YAAY,KAAK,WAAW,EAAE,CAAC;YACtE,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,wBAAwB,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1F,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QACD,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;AAC9B,CAAC;AAQD,MAAM,UAAU,IAAI;IAClB,OAAO;QACL,4BAA4B,EAAE,wBAAwB;QACtD,kBAAkB,EAAE,iBAAiB;QACrC,qBAAqB,EAAE,eAAe;KACvC,CAAC;AACJ,CAAC","sourcesContent":["// Copyright 2024 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 Platform from '../../../core/platform/platform.js';\nimport * as Types from '../types/types.js';\n\n/**\n * This handler is responsible for the relationships between:\n * DecodeImage/ResizeImage, PaintImage and DrawLazyPixelRef events.\n *\n * When we get a DecodeImage event, we want to associate it to a PaintImage\n * event, primarily so we can determine the NodeID of the image that was\n * decoded.\n * We can do this in two ways:\n *\n * 1. If there is a PaintImage event on the same thread, use that\n * (if there are multiple, use the latest one).\n *\n * 2. If not, we can find the DecodeLazyPixelRef event on the same thread, and\n * use the PaintImage event associated with it via the `LazyPixelRef` key.\n */\n\n// Track paintImageEvents across threads.\nconst paintImageEvents = new Map<Types.Events.ProcessID, Map<Types.Events.ThreadID, Types.Events.PaintImage[]>>();\nconst decodeLazyPixelRefEvents =\n new Map<Types.Events.ProcessID, Map<Types.Events.ThreadID, Types.Events.DecodeLazyPixelRef[]>>();\n\n// A DrawLazyPixelRef event will contain a numerical reference in\n// args.LazyPixelRef. As we parse each DrawLazyPixelRef, we can assign it to a\n// paint event. Later we want to look up paint events by this reference, so we\n// store them in this map.\nconst paintImageByLazyPixelRef = new Map<number, Types.Events.PaintImage>();\n\n// When we find events that we want to tie to a particular PaintImage event, we add them to this map.\n// These are currently only DecodeImage and ResizeImage events, but the type is\n// deliberately generic as in the future we might want to add more events that\n// have a relationship to a individual PaintImage event.\nconst eventToPaintImage = new Map<Types.Events.Event, Types.Events.PaintImage>();\n\nconst urlToPaintImage = new Map<string, Types.Events.PaintImage[]>();\n\nexport function reset(): void {\n paintImageEvents.clear();\n decodeLazyPixelRefEvents.clear();\n paintImageByLazyPixelRef.clear();\n eventToPaintImage.clear();\n urlToPaintImage.clear();\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n if (Types.Events.isPaintImage(event)) {\n const forProcess = paintImageEvents.get(event.pid) || new Map<Types.Events.ThreadID, Types.Events.PaintImage[]>();\n const forThread = forProcess.get(event.tid) || [];\n forThread.push(event);\n forProcess.set(event.tid, forThread);\n paintImageEvents.set(event.pid, forProcess);\n\n if (event.args.data.url) {\n const paintsForUrl = Platform.MapUtilities.getWithDefault(urlToPaintImage, event.args.data.url, () => []);\n paintsForUrl.push(event);\n }\n\n return;\n }\n\n if (Types.Events.isDecodeLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {\n // Store these because we use them to tie DecodeImage to a PaintEvent.\n const forProcess =\n decodeLazyPixelRefEvents.get(event.pid) || new Map<Types.Events.ThreadID, Types.Events.DecodeLazyPixelRef[]>();\n const forThread = forProcess.get(event.tid) || [];\n forThread.push(event);\n forProcess.set(event.tid, forThread);\n decodeLazyPixelRefEvents.set(event.pid, forProcess);\n }\n\n // If we see a DrawLazyPixelRef event, we need to find the last PaintImage\n // event on the thread and associate it to the LazyPixelRef that is supplied\n // in the DrawLazyPixelRef event.\n // This means that later on if we see a DecodeLazyPixelRef event with the\n // same LazyPixelRef key, we can find its associated PaintImage event by\n // looking it up.\n if (Types.Events.isDrawLazyPixelRef(event) && typeof event.args?.LazyPixelRef !== 'undefined') {\n const lastPaintEvent = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (!lastPaintEvent) {\n return;\n }\n paintImageByLazyPixelRef.set(event.args.LazyPixelRef, lastPaintEvent);\n return;\n }\n\n if (Types.Events.isDecodeImage(event)) {\n // When we see a DecodeImage, we want to associate it to a PaintImage\n // event. We try two approaches:\n //\n // 1. If the thread of the DecodeImage event has a previous PaintImage\n // event, that is the associated event.\n //\n // 2. If that is false, we then look on the thread for a DecodeLazyPixelRef\n // event. If we find that, we then look for its associated PaintImage\n // event, which we associate via DrawLazyPixelRef events (the code block\n // above this one)\n //\n // 1. Find a PaintImage event on the same thread. If we find it, that's our association done.\n const lastPaintImageEventOnThread = paintImageEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (lastPaintImageEventOnThread) {\n eventToPaintImage.set(event, lastPaintImageEventOnThread);\n return;\n }\n\n // 2. Find the last DecodeLazyPixelRef event and, if we find it, find its associated PaintImage event.\n const lastDecodeLazyPixelRef = decodeLazyPixelRefEvents.get(event.pid)?.get(event.tid)?.at(-1);\n if (typeof lastDecodeLazyPixelRef?.args?.LazyPixelRef === 'undefined') {\n return;\n }\n\n const paintEvent = paintImageByLazyPixelRef.get(lastDecodeLazyPixelRef.args.LazyPixelRef);\n if (!paintEvent) {\n return;\n }\n eventToPaintImage.set(event, paintEvent);\n }\n}\n\nexport async function finalize(): Promise<void> {\n}\n\nexport interface ImagePaintData {\n paintImageByDrawLazyPixelRef: Map<number, Types.Events.PaintImage>;\n paintImageForEvent: Map<Types.Events.Event, Types.Events.PaintImage>;\n paintImageEventForUrl: Map<string, Types.Events.PaintImage[]>;\n}\n\nexport function data(): ImagePaintData {\n return {\n paintImageByDrawLazyPixelRef: paintImageByLazyPixelRef,\n paintImageForEvent: eventToPaintImage,\n paintImageEventForUrl: urlToPaintImage,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"InitiatorsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/InitiatorsHandler.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 * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {data as AsyncJSCallsHandlerData} from './AsyncJSCallsHandler.js';\nimport {data as flowsHandlerData} from './FlowsHandler.js';\n\nconst lastScheduleStyleRecalcByFrame = new Map<string, Types.Events.ScheduleStyleRecalculation>();\n\n// This tracks the last event that is considered to have invalidated the layout\n// for a given frame.\n// Note that although there is an InvalidateLayout event, there are also other\n// events (ScheduleStyleRecalculation) that could be the reason a layout was\n// invalidated.\nconst lastInvalidationEventForFrame = new Map<string, Types.Events.Event>();\n\n// Important: although the event is called UpdateLayoutTree, in the UI we\n// present these to the user as \"Recalculate Style\". So don't get confused!\n// These are the same - just UpdateLayoutTree is what the event from Chromium\n// is called.\nconst lastUpdateLayoutTreeByFrame = new Map<string, Types.Events.UpdateLayoutTree>();\n\n// These two maps store the same data but in different directions.\n// For a given event, tell me what its initiator was. An event can only have one initiator.\nconst eventToInitiatorMap = new Map<Types.Events.Event, Types.Events.Event>();\n// For a given event, tell me what events it initiated. An event can initiate\n// multiple events, hence why the value for this map is an array.\nconst initiatorToEventsMap = new Map<Types.Events.Event, Types.Events.Event[]>();\n\nconst webSocketCreateEventsById: Map<number, Types.Events.WebSocketCreate> = new Map();\nconst schedulePostTaskCallbackEventsById: Map<number, Types.Events.SchedulePostTaskCallback> = new Map();\n\nexport function reset(): void {\n lastScheduleStyleRecalcByFrame.clear();\n lastInvalidationEventForFrame.clear();\n lastUpdateLayoutTreeByFrame.clear();\n eventToInitiatorMap.clear();\n initiatorToEventsMap.clear();\n webSocketCreateEventsById.clear();\n schedulePostTaskCallbackEventsById.clear();\n}\n\nfunction storeInitiator(data: {initiator: Types.Events.Event, event: Types.Events.Event}): void {\n eventToInitiatorMap.set(data.event, data.initiator);\n const eventsForInitiator = initiatorToEventsMap.get(data.initiator) || [];\n eventsForInitiator.push(data.event);\n initiatorToEventsMap.set(data.initiator, eventsForInitiator);\n}\n\n/**\n * IMPORTANT: Before adding support for new initiator relationships in\n * trace events consider using Perfetto's flow API on the events in\n * question, so that they get automatically computed.\n * @see {@link flowsHandlerData}\n *\n * The events manually computed here were added before we had support\n * for flow events. As such they should be migrated to use the flow\n * API so that no manual parsing is needed.\n */\nexport function handleEvent(event: Types.Events.Event): void {\n if (Types.Events.isScheduleStyleRecalculation(event)) {\n lastScheduleStyleRecalcByFrame.set(event.args.data.frame, event);\n } else if (Types.Events.isUpdateLayoutTree(event)) {\n // IMPORTANT: although the trace event is called UpdateLayoutTree, this\n // represents a Styles Recalculation. This event in the timeline is shown to\n // the user as \"Recalculate Styles.\"\n if (event.args.beginData) {\n // Store the last UpdateLayout event: we use this when we see an\n // InvalidateLayout and try to figure out its initiator.\n lastUpdateLayoutTreeByFrame.set(event.args.beginData.frame, event);\n\n // If this frame has seen a ScheduleStyleRecalc event, then that event is\n // considered to be the initiator of this StylesRecalc.\n const scheduledStyleForFrame = lastScheduleStyleRecalcByFrame.get(event.args.beginData.frame);\n if (scheduledStyleForFrame) {\n storeInitiator({\n event,\n initiator: scheduledStyleForFrame,\n });\n }\n }\n } else if (Types.Events.isInvalidateLayout(event)) {\n // By default, the InvalidateLayout event is what triggered the layout invalidation for this frame.\n let invalidationInitiator: Types.Events.Event = event;\n\n // However, if we have not had any prior invalidations for this frame, we\n // want to consider StyleRecalculation events as they might be the actual\n // cause of this layout invalidation.\n if (!lastInvalidationEventForFrame.has(event.args.data.frame)) {\n // 1. If we have not had an invalidation event for this frame\n // 2. AND we have had an UpdateLayoutTree for this frame\n // 3. AND the UpdateLayoutTree event ended AFTER the InvalidateLayout startTime\n // 4. AND we have an initiator for the UpdateLayoutTree event\n // 5. Then we set the last invalidation event for this frame to be the UpdateLayoutTree's initiator.\n const lastUpdateLayoutTreeForFrame = lastUpdateLayoutTreeByFrame.get(event.args.data.frame);\n if (lastUpdateLayoutTreeForFrame) {\n const {endTime} = Helpers.Timing.eventTimingsMicroSeconds(lastUpdateLayoutTreeForFrame);\n const initiatorOfUpdateLayout = eventToInitiatorMap.get(lastUpdateLayoutTreeForFrame);\n\n if (initiatorOfUpdateLayout && endTime && endTime > event.ts) {\n invalidationInitiator = initiatorOfUpdateLayout;\n }\n }\n }\n lastInvalidationEventForFrame.set(event.args.data.frame, invalidationInitiator);\n } else if (Types.Events.isLayout(event)) {\n // The initiator of a Layout event is the last Invalidation event.\n const lastInvalidation = lastInvalidationEventForFrame.get(event.args.beginData.frame);\n if (lastInvalidation) {\n storeInitiator({\n event,\n initiator: lastInvalidation,\n });\n }\n // Now clear the last invalidation for the frame: the last invalidation has been linked to a Layout event, so it cannot be the initiator for any future layouts.\n lastInvalidationEventForFrame.delete(event.args.beginData.frame);\n } else if (Types.Events.isWebSocketCreate(event)) {\n webSocketCreateEventsById.set(event.args.data.identifier, event);\n } else if (Types.Events.isWebSocketInfo(event) || Types.Events.isWebSocketTransfer(event)) {\n const matchingCreateEvent = webSocketCreateEventsById.get(event.args.data.identifier);\n if (matchingCreateEvent) {\n storeInitiator({\n event,\n initiator: matchingCreateEvent,\n });\n }\n } else if (Types.Events.isSchedulePostTaskCallback(event)) {\n schedulePostTaskCallbackEventsById.set(event.args.data.taskId, event);\n } else if (Types.Events.isRunPostTaskCallback(event) || Types.Events.isAbortPostTaskCallback(event)) {\n const matchingSchedule = schedulePostTaskCallbackEventsById.get(event.args.data.taskId);\n if (matchingSchedule) {\n storeInitiator({event, initiator: matchingSchedule});\n }\n }\n}\n\nfunction createRelationshipsFromFlows(): void {\n const flows = flowsHandlerData().flows;\n for (let i = 0; i < flows.length; i++) {\n const flow = flows[i];\n for (let j = 0; j < flow.length - 1; j++) {\n storeInitiator({event: flow[j + 1], initiator: flow[j]});\n }\n }\n}\n\nfunction createRelationshipsFromAsyncJSCalls(): void {\n const asyncCallEntries = AsyncJSCallsHandlerData().schedulerToRunEntryPoints.entries();\n for (const [asyncCaller, asyncCallees] of asyncCallEntries) {\n for (const asyncCallee of asyncCallees) {\n storeInitiator({event: asyncCallee, initiator: asyncCaller});\n }\n }\n}\n\nexport async function finalize(): Promise<void> {\n createRelationshipsFromFlows();\n createRelationshipsFromAsyncJSCalls();\n}\n\nexport interface InitiatorsData {\n eventToInitiator: Map<Types.Events.Event, Types.Events.Event>;\n initiatorToEvents: Map<Types.Events.Event, Types.Events.Event[]>;\n}\n\nexport function data(): InitiatorsData {\n return {\n eventToInitiator: eventToInitiatorMap,\n initiatorToEvents: initiatorToEventsMap,\n };\n}\n\nexport function deps(): ['Flows', 'AsyncJSCalls'] {\n return ['Flows', 'AsyncJSCalls'];\n}\n"]}
1
+ {"version":3,"file":"InitiatorsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/InitiatorsHandler.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 * as Helpers from '../helpers/helpers.js';\nimport * as Types from '../types/types.js';\n\nimport {data as AsyncJSCallsHandlerData} from './AsyncJSCallsHandler.js';\nimport {data as flowsHandlerData} from './FlowsHandler.js';\n\nconst lastScheduleStyleRecalcByFrame = new Map<string, Types.Events.ScheduleStyleRecalculation>();\n\n// This tracks the last event that is considered to have invalidated the layout\n// for a given frame.\n// Note that although there is an InvalidateLayout event, there are also other\n// events (ScheduleStyleRecalculation) that could be the reason a layout was\n// invalidated.\nconst lastInvalidationEventForFrame = new Map<string, Types.Events.Event>();\n\n// Important: although the event is called UpdateLayoutTree, in the UI we\n// present these to the user as \"Recalculate Style\". So don't get confused!\n// These are the same - just UpdateLayoutTree is what the event from Chromium\n// is called.\nconst lastUpdateLayoutTreeByFrame = new Map<string, Types.Events.UpdateLayoutTree>();\n\n// These two maps store the same data but in different directions.\n// For a given event, tell me what its initiator was. An event can only have one initiator.\nconst eventToInitiatorMap = new Map<Types.Events.Event, Types.Events.Event>();\n// For a given event, tell me what events it initiated. An event can initiate\n// multiple events, hence why the value for this map is an array.\nconst initiatorToEventsMap = new Map<Types.Events.Event, Types.Events.Event[]>();\n\nconst webSocketCreateEventsById = new Map<number, Types.Events.WebSocketCreate>();\nconst schedulePostTaskCallbackEventsById = new Map<number, Types.Events.SchedulePostTaskCallback>();\n\nexport function reset(): void {\n lastScheduleStyleRecalcByFrame.clear();\n lastInvalidationEventForFrame.clear();\n lastUpdateLayoutTreeByFrame.clear();\n eventToInitiatorMap.clear();\n initiatorToEventsMap.clear();\n webSocketCreateEventsById.clear();\n schedulePostTaskCallbackEventsById.clear();\n}\n\nfunction storeInitiator(data: {initiator: Types.Events.Event, event: Types.Events.Event}): void {\n eventToInitiatorMap.set(data.event, data.initiator);\n const eventsForInitiator = initiatorToEventsMap.get(data.initiator) || [];\n eventsForInitiator.push(data.event);\n initiatorToEventsMap.set(data.initiator, eventsForInitiator);\n}\n\n/**\n * IMPORTANT: Before adding support for new initiator relationships in\n * trace events consider using Perfetto's flow API on the events in\n * question, so that they get automatically computed.\n * @see {@link flowsHandlerData}\n *\n * The events manually computed here were added before we had support\n * for flow events. As such they should be migrated to use the flow\n * API so that no manual parsing is needed.\n */\nexport function handleEvent(event: Types.Events.Event): void {\n if (Types.Events.isScheduleStyleRecalculation(event)) {\n lastScheduleStyleRecalcByFrame.set(event.args.data.frame, event);\n } else if (Types.Events.isUpdateLayoutTree(event)) {\n // IMPORTANT: although the trace event is called UpdateLayoutTree, this\n // represents a Styles Recalculation. This event in the timeline is shown to\n // the user as \"Recalculate Styles.\"\n if (event.args.beginData) {\n // Store the last UpdateLayout event: we use this when we see an\n // InvalidateLayout and try to figure out its initiator.\n lastUpdateLayoutTreeByFrame.set(event.args.beginData.frame, event);\n\n // If this frame has seen a ScheduleStyleRecalc event, then that event is\n // considered to be the initiator of this StylesRecalc.\n const scheduledStyleForFrame = lastScheduleStyleRecalcByFrame.get(event.args.beginData.frame);\n if (scheduledStyleForFrame) {\n storeInitiator({\n event,\n initiator: scheduledStyleForFrame,\n });\n }\n }\n } else if (Types.Events.isInvalidateLayout(event)) {\n // By default, the InvalidateLayout event is what triggered the layout invalidation for this frame.\n let invalidationInitiator: Types.Events.Event = event;\n\n // However, if we have not had any prior invalidations for this frame, we\n // want to consider StyleRecalculation events as they might be the actual\n // cause of this layout invalidation.\n if (!lastInvalidationEventForFrame.has(event.args.data.frame)) {\n // 1. If we have not had an invalidation event for this frame\n // 2. AND we have had an UpdateLayoutTree for this frame\n // 3. AND the UpdateLayoutTree event ended AFTER the InvalidateLayout startTime\n // 4. AND we have an initiator for the UpdateLayoutTree event\n // 5. Then we set the last invalidation event for this frame to be the UpdateLayoutTree's initiator.\n const lastUpdateLayoutTreeForFrame = lastUpdateLayoutTreeByFrame.get(event.args.data.frame);\n if (lastUpdateLayoutTreeForFrame) {\n const {endTime} = Helpers.Timing.eventTimingsMicroSeconds(lastUpdateLayoutTreeForFrame);\n const initiatorOfUpdateLayout = eventToInitiatorMap.get(lastUpdateLayoutTreeForFrame);\n\n if (initiatorOfUpdateLayout && endTime && endTime > event.ts) {\n invalidationInitiator = initiatorOfUpdateLayout;\n }\n }\n }\n lastInvalidationEventForFrame.set(event.args.data.frame, invalidationInitiator);\n } else if (Types.Events.isLayout(event)) {\n // The initiator of a Layout event is the last Invalidation event.\n const lastInvalidation = lastInvalidationEventForFrame.get(event.args.beginData.frame);\n if (lastInvalidation) {\n storeInitiator({\n event,\n initiator: lastInvalidation,\n });\n }\n // Now clear the last invalidation for the frame: the last invalidation has been linked to a Layout event, so it cannot be the initiator for any future layouts.\n lastInvalidationEventForFrame.delete(event.args.beginData.frame);\n } else if (Types.Events.isWebSocketCreate(event)) {\n webSocketCreateEventsById.set(event.args.data.identifier, event);\n } else if (Types.Events.isWebSocketInfo(event) || Types.Events.isWebSocketTransfer(event)) {\n const matchingCreateEvent = webSocketCreateEventsById.get(event.args.data.identifier);\n if (matchingCreateEvent) {\n storeInitiator({\n event,\n initiator: matchingCreateEvent,\n });\n }\n } else if (Types.Events.isSchedulePostTaskCallback(event)) {\n schedulePostTaskCallbackEventsById.set(event.args.data.taskId, event);\n } else if (Types.Events.isRunPostTaskCallback(event) || Types.Events.isAbortPostTaskCallback(event)) {\n const matchingSchedule = schedulePostTaskCallbackEventsById.get(event.args.data.taskId);\n if (matchingSchedule) {\n storeInitiator({event, initiator: matchingSchedule});\n }\n }\n}\n\nfunction createRelationshipsFromFlows(): void {\n const flows = flowsHandlerData().flows;\n for (let i = 0; i < flows.length; i++) {\n const flow = flows[i];\n for (let j = 0; j < flow.length - 1; j++) {\n storeInitiator({event: flow[j + 1], initiator: flow[j]});\n }\n }\n}\n\nfunction createRelationshipsFromAsyncJSCalls(): void {\n const asyncCallEntries = AsyncJSCallsHandlerData().schedulerToRunEntryPoints.entries();\n for (const [asyncCaller, asyncCallees] of asyncCallEntries) {\n for (const asyncCallee of asyncCallees) {\n storeInitiator({event: asyncCallee, initiator: asyncCaller});\n }\n }\n}\n\nexport async function finalize(): Promise<void> {\n createRelationshipsFromFlows();\n createRelationshipsFromAsyncJSCalls();\n}\n\nexport interface InitiatorsData {\n eventToInitiator: Map<Types.Events.Event, Types.Events.Event>;\n initiatorToEvents: Map<Types.Events.Event, Types.Events.Event[]>;\n}\n\nexport function data(): InitiatorsData {\n return {\n eventToInitiator: eventToInitiatorMap,\n initiatorToEvents: initiatorToEventsMap,\n };\n}\n\nexport function deps(): ['Flows', 'AsyncJSCalls'] {\n return ['Flows', 'AsyncJSCalls'];\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"InvalidationsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/InvalidationsHandler.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 * as Types from '../types/types.js';\n\nconst invalidationsForEvent = new Map<Types.Events.Event, Types.Events.InvalidationTrackingEvent[]>();\nconst invalidationCountForEvent = new Map<Types.Events.Event, number>();\n\nlet lastRecalcStyleEvent: Types.Events.UpdateLayoutTree|null = null;\n\n// Used to track paints so we track invalidations correctly per paint.\nlet hasPainted = false;\n\nconst allInvalidationTrackingEvents: Array<Types.Events.InvalidationTrackingEvent> = [];\n\nexport function reset(): void {\n invalidationsForEvent.clear();\n lastRecalcStyleEvent = null;\n allInvalidationTrackingEvents.length = 0;\n hasPainted = false;\n maxInvalidationsPerEvent = null;\n}\n\nlet maxInvalidationsPerEvent: number|null = null;\nexport function handleUserConfig(userConfig: Types.Configuration.Configuration): void {\n maxInvalidationsPerEvent = userConfig.maxInvalidationEventsPerEvent;\n}\n\nfunction addInvalidationToEvent(event: Types.Events.Event, invalidation: Types.Events.InvalidationTrackingEvent): void {\n const existingInvalidations = invalidationsForEvent.get(event) || [];\n existingInvalidations.push(invalidation);\n\n if (maxInvalidationsPerEvent !== null && existingInvalidations.length > maxInvalidationsPerEvent) {\n existingInvalidations.shift();\n }\n invalidationsForEvent.set(event, existingInvalidations);\n\n const count = invalidationCountForEvent.get(event) ?? 0;\n invalidationCountForEvent.set(event, count + 1);\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n // Special case: if we have been configured to not store any invalidations,\n // we take that as a sign that we don't even want to gather any invalidations\n // data at all and early exit.\n if (maxInvalidationsPerEvent === 0) {\n return;\n }\n\n if (Types.Events.isUpdateLayoutTree(event)) {\n lastRecalcStyleEvent = event;\n\n // Associate any prior invalidations with this recalc event.\n for (const invalidation of allInvalidationTrackingEvents) {\n if (Types.Events.isLayoutInvalidationTracking(invalidation)) {\n // LayoutInvalidation events cannot be associated with a LayoutTree\n // event.\n continue;\n }\n\n const recalcFrameId = lastRecalcStyleEvent.args.beginData?.frame;\n\n if (recalcFrameId && invalidation.args.data.frame === recalcFrameId) {\n addInvalidationToEvent(event, invalidation);\n }\n }\n return;\n }\n\n if (Types.Events.isInvalidationTracking(event)) {\n if (hasPainted) {\n // If we have painted, then we can clear out the list of all existing\n // invalidations, as we cannot associate them across frames.\n allInvalidationTrackingEvents.length = 0;\n lastRecalcStyleEvent = null;\n hasPainted = false;\n }\n\n // Style invalidation events can occur before and during recalc styles. When we get a recalc style event (aka UpdateLayoutTree), we check and associate any prior invalidations with it.\n // But any invalidations that occur during a UpdateLayoutTree\n // event would be reported in trace events after. So each time we get an\n // invalidation that might be due to a style recalc, we check if the\n // timings overlap and if so associate them.\n if (lastRecalcStyleEvent &&\n (Types.Events.isScheduleStyleInvalidationTracking(event) ||\n Types.Events.isStyleRecalcInvalidationTracking(event) ||\n Types.Events.isStyleInvalidatorInvalidationTracking(event))) {\n const recalcEndTime = lastRecalcStyleEvent.ts + (lastRecalcStyleEvent.dur || 0);\n if (event.ts >= lastRecalcStyleEvent.ts && event.ts <= recalcEndTime &&\n lastRecalcStyleEvent.args.beginData?.frame === event.args.data.frame) {\n addInvalidationToEvent(lastRecalcStyleEvent, event);\n }\n }\n\n allInvalidationTrackingEvents.push(event);\n return;\n }\n\n if (Types.Events.isPaint(event)) {\n // Used to ensure that we do not create relationships across frames.\n hasPainted = true;\n return;\n }\n\n if (Types.Events.isLayout(event)) {\n const layoutFrame = event.args.beginData.frame;\n for (const invalidation of allInvalidationTrackingEvents) {\n // The only invalidations that cause a Layout are LayoutInvalidations :)\n if (!Types.Events.isLayoutInvalidationTracking(invalidation)) {\n continue;\n }\n\n if (invalidation.args.data.frame === layoutFrame) {\n addInvalidationToEvent(event, invalidation);\n }\n }\n }\n}\n\nexport async function finalize(): Promise<void> {\n}\n\ninterface InvalidationsData {\n invalidationsForEvent: Map<Types.Events.Event, Types.Events.InvalidationTrackingEvent[]>;\n invalidationCountForEvent: Map<Types.Events.Event, number>;\n}\n\nexport function data(): InvalidationsData {\n return {\n invalidationsForEvent,\n invalidationCountForEvent,\n };\n}\n"]}
1
+ {"version":3,"file":"InvalidationsHandler.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/InvalidationsHandler.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 * as Types from '../types/types.js';\n\nconst invalidationsForEvent = new Map<Types.Events.Event, Types.Events.InvalidationTrackingEvent[]>();\nconst invalidationCountForEvent = new Map<Types.Events.Event, number>();\n\nlet lastRecalcStyleEvent: Types.Events.UpdateLayoutTree|null = null;\n\n// Used to track paints so we track invalidations correctly per paint.\nlet hasPainted = false;\n\nconst allInvalidationTrackingEvents: Types.Events.InvalidationTrackingEvent[] = [];\n\nexport function reset(): void {\n invalidationsForEvent.clear();\n lastRecalcStyleEvent = null;\n allInvalidationTrackingEvents.length = 0;\n hasPainted = false;\n maxInvalidationsPerEvent = null;\n}\n\nlet maxInvalidationsPerEvent: number|null = null;\nexport function handleUserConfig(userConfig: Types.Configuration.Configuration): void {\n maxInvalidationsPerEvent = userConfig.maxInvalidationEventsPerEvent;\n}\n\nfunction addInvalidationToEvent(event: Types.Events.Event, invalidation: Types.Events.InvalidationTrackingEvent): void {\n const existingInvalidations = invalidationsForEvent.get(event) || [];\n existingInvalidations.push(invalidation);\n\n if (maxInvalidationsPerEvent !== null && existingInvalidations.length > maxInvalidationsPerEvent) {\n existingInvalidations.shift();\n }\n invalidationsForEvent.set(event, existingInvalidations);\n\n const count = invalidationCountForEvent.get(event) ?? 0;\n invalidationCountForEvent.set(event, count + 1);\n}\n\nexport function handleEvent(event: Types.Events.Event): void {\n // Special case: if we have been configured to not store any invalidations,\n // we take that as a sign that we don't even want to gather any invalidations\n // data at all and early exit.\n if (maxInvalidationsPerEvent === 0) {\n return;\n }\n\n if (Types.Events.isUpdateLayoutTree(event)) {\n lastRecalcStyleEvent = event;\n\n // Associate any prior invalidations with this recalc event.\n for (const invalidation of allInvalidationTrackingEvents) {\n if (Types.Events.isLayoutInvalidationTracking(invalidation)) {\n // LayoutInvalidation events cannot be associated with a LayoutTree\n // event.\n continue;\n }\n\n const recalcFrameId = lastRecalcStyleEvent.args.beginData?.frame;\n\n if (recalcFrameId && invalidation.args.data.frame === recalcFrameId) {\n addInvalidationToEvent(event, invalidation);\n }\n }\n return;\n }\n\n if (Types.Events.isInvalidationTracking(event)) {\n if (hasPainted) {\n // If we have painted, then we can clear out the list of all existing\n // invalidations, as we cannot associate them across frames.\n allInvalidationTrackingEvents.length = 0;\n lastRecalcStyleEvent = null;\n hasPainted = false;\n }\n\n // Style invalidation events can occur before and during recalc styles. When we get a recalc style event (aka UpdateLayoutTree), we check and associate any prior invalidations with it.\n // But any invalidations that occur during a UpdateLayoutTree\n // event would be reported in trace events after. So each time we get an\n // invalidation that might be due to a style recalc, we check if the\n // timings overlap and if so associate them.\n if (lastRecalcStyleEvent &&\n (Types.Events.isScheduleStyleInvalidationTracking(event) ||\n Types.Events.isStyleRecalcInvalidationTracking(event) ||\n Types.Events.isStyleInvalidatorInvalidationTracking(event))) {\n const recalcEndTime = lastRecalcStyleEvent.ts + (lastRecalcStyleEvent.dur || 0);\n if (event.ts >= lastRecalcStyleEvent.ts && event.ts <= recalcEndTime &&\n lastRecalcStyleEvent.args.beginData?.frame === event.args.data.frame) {\n addInvalidationToEvent(lastRecalcStyleEvent, event);\n }\n }\n\n allInvalidationTrackingEvents.push(event);\n return;\n }\n\n if (Types.Events.isPaint(event)) {\n // Used to ensure that we do not create relationships across frames.\n hasPainted = true;\n return;\n }\n\n if (Types.Events.isLayout(event)) {\n const layoutFrame = event.args.beginData.frame;\n for (const invalidation of allInvalidationTrackingEvents) {\n // The only invalidations that cause a Layout are LayoutInvalidations :)\n if (!Types.Events.isLayoutInvalidationTracking(invalidation)) {\n continue;\n }\n\n if (invalidation.args.data.frame === layoutFrame) {\n addInvalidationToEvent(event, invalidation);\n }\n }\n }\n}\n\nexport async function finalize(): Promise<void> {\n}\n\ninterface InvalidationsData {\n invalidationsForEvent: Map<Types.Events.Event, Types.Events.InvalidationTrackingEvent[]>;\n invalidationCountForEvent: Map<Types.Events.Event, number>;\n}\n\nexport function data(): InvalidationsData {\n return {\n invalidationsForEvent,\n invalidationCountForEvent,\n };\n}\n"]}