@paulirish/trace_engine 0.0.8 → 0.0.10
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.
- package/README.md +4 -4
- package/analyze-trace.mjs +7 -4
- package/core/platform/DevToolsPath.d.ts +32 -0
- package/core/platform/DevToolsPath.js +4 -0
- package/core/platform/DevToolsPath.js.map +7 -0
- package/core/platform/MimeType.js +104 -0
- package/core/platform/MimeType.js.map +7 -0
- package/core/platform/Timing.js +10 -0
- package/core/platform/Timing.js.map +7 -0
- package/core/platform/UIString.d.ts +6 -0
- package/core/platform/UIString.js +2 -0
- package/core/platform/UIString.js.map +7 -0
- package/core/platform/UserVisibleError.d.ts +12 -0
- package/core/platform/UserVisibleError.js +14 -0
- package/core/platform/UserVisibleError.js.map +7 -0
- package/core/platform/array-utilities.d.ts +28 -0
- package/core/platform/array-utilities.js +163 -0
- package/core/platform/array-utilities.js.map +7 -0
- package/core/platform/brand.js +1 -0
- package/core/platform/brand.js.map +7 -0
- package/core/platform/bundle-tsconfig.json +1 -0
- package/core/platform/date-utilities.d.ts +2 -0
- package/core/platform/date-utilities.js +10 -0
- package/core/platform/date-utilities.js.map +7 -0
- package/core/platform/dcheck-tsconfig.json +8 -0
- package/core/platform/dcheck.d.ts +4 -0
- package/core/platform/dcheck.js +5 -0
- package/core/platform/devtools_entrypoint-bundle-tsconfig-tsconfig.json +40 -0
- package/core/platform/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/core/platform/dom-utilities.d.ts +6 -0
- package/core/platform/dom-utilities.js +98 -0
- package/core/platform/dom-utilities.js.map +7 -0
- package/core/platform/keyboard-utilities.d.ts +15 -0
- package/core/platform/keyboard-utilities.js +31 -0
- package/core/platform/keyboard-utilities.js.map +7 -0
- package/core/platform/map-utilities.d.ts +14 -0
- package/core/platform/map-utilities.js +70 -0
- package/core/platform/map-utilities.js.map +7 -0
- package/core/platform/number-utilities.d.ts +15 -0
- package/core/platform/number-utilities.js +71 -0
- package/core/platform/number-utilities.js.map +7 -0
- package/core/platform/platform-tsconfig.json +59 -0
- package/core/platform/platform.d.ts +15 -0
- package/core/platform/platform.js +37 -0
- package/core/platform/platform.js.compressed +0 -0
- package/core/platform/platform.js.hash +1 -0
- package/core/platform/platform.js.map +7 -0
- package/core/platform/platform.prebundle.d.ts +15 -0
- package/core/platform/platform.prebundle.js +50 -0
- package/core/platform/platform.prebundle.js.map +1 -0
- package/core/platform/platform.prebundle.ts +64 -0
- package/core/platform/promise-utilities.js +10 -0
- package/core/platform/promise-utilities.js.map +7 -0
- package/core/platform/set-utilities.d.ts +2 -0
- package/core/platform/set-utilities.js +20 -0
- package/core/platform/set-utilities.js.map +7 -0
- package/core/platform/string-utilities.d.ts +40 -0
- package/core/platform/string-utilities.js +439 -0
- package/core/platform/string-utilities.js.map +7 -0
- package/core/platform/typescript-utilities.d.ts +56 -0
- package/core/platform/typescript-utilities.js +13 -0
- package/core/platform/typescript-utilities.js.map +7 -0
- package/generated/protocol.d.ts +16189 -0
- package/generated/protocol.js +2230 -0
- package/models/cpu_profile/CPUProfileDataModel.js +375 -0
- package/models/cpu_profile/CPUProfileDataModel.js.map +7 -0
- package/models/cpu_profile/ProfileTreeModel.js +90 -0
- package/models/cpu_profile/ProfileTreeModel.js.map +7 -0
- package/models/cpu_profile/bundle-tsconfig.json +1 -0
- package/models/cpu_profile/cpu_profile-tsconfig.json +51 -0
- package/models/cpu_profile/cpu_profile.js +7 -0
- package/models/cpu_profile/cpu_profile.js.map +7 -0
- package/models/cpu_profile/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/EntriesFilter.js +182 -0
- package/models/trace/EntriesFilter.js.map +7 -0
- package/models/trace/LegacyTracingModel.d.ts +1 -0
- package/models/trace/LegacyTracingModel.js +1 -0
- package/models/trace/LegacyTracingModel.js.map +7 -0
- package/models/trace/ModelImpl.js +116 -0
- package/models/trace/ModelImpl.js.map +7 -0
- package/models/trace/Processor.js +179 -0
- package/models/trace/Processor.js.map +7 -0
- package/models/trace/SDKServices.js +104 -0
- package/models/trace/SDKServices.js.map +7 -0
- package/models/trace/TraceProcessor.js +133 -0
- package/models/trace/TraceProcessor.js.map +7 -0
- package/models/trace/TracingManager.d.ts +1 -0
- package/models/trace/TracingManager.js +1 -0
- package/models/trace/TracingManager.js.map +7 -0
- package/models/trace/TreeManipulator.js +85 -0
- package/models/trace/TreeManipulator.js.map +7 -0
- package/models/trace/bundle-tsconfig.json +1 -0
- package/models/trace/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/devtools_entrypoint-legacy-typescript-tsconfig.json +43 -0
- package/models/trace/extras/FetchNodes.js +104 -0
- package/models/trace/extras/FetchNodes.js.map +7 -0
- package/models/trace/extras/FilmStrip.js +37 -0
- package/models/trace/extras/FilmStrip.js.map +7 -0
- package/models/trace/extras/MainThreadActivity.js +61 -0
- package/models/trace/extras/MainThreadActivity.js.map +7 -0
- package/models/trace/extras/Metadata.js +28 -0
- package/models/trace/extras/Metadata.js.map +7 -0
- package/models/trace/extras/bundle-tsconfig.json +1 -0
- package/models/trace/extras/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/extras/extras-tsconfig.json +59 -0
- package/models/trace/extras/extras.d.ts +1 -0
- package/models/trace/extras/extras.js +1 -0
- package/models/trace/extras/extras.js.map +7 -0
- package/models/trace/frames/TimelineFrameModel.js +392 -0
- package/models/trace/frames/TimelineFrameModel.js.map +7 -0
- package/models/trace/frames/bundle-tsconfig.json +1 -0
- package/models/trace/frames/devtools_entrypoint-bundle-typescript-tsconfig.json +43 -0
- package/models/trace/frames/frames-tsconfig.json +58 -0
- package/models/trace/frames/frames.js +5 -0
- package/models/trace/frames/frames.js.map +7 -0
- package/models/trace/handlers/AnimationHandler.js +30 -0
- package/models/trace/handlers/AnimationHandler.js.map +7 -0
- package/models/trace/handlers/AuctionWorkletsHandler.js +106 -0
- package/models/trace/handlers/AuctionWorkletsHandler.js.map +7 -0
- package/models/trace/handlers/FramesHandler.js +388 -0
- package/models/trace/handlers/FramesHandler.js.map +7 -0
- package/models/trace/handlers/GPUHandler.js +50 -0
- package/models/trace/handlers/GPUHandler.js.map +7 -0
- package/models/trace/handlers/InitiatorsHandler.js +133 -0
- package/models/trace/handlers/InitiatorsHandler.js.map +7 -0
- package/models/trace/handlers/InvalidationsHandler.js +98 -0
- package/models/trace/handlers/InvalidationsHandler.js.map +7 -0
- package/models/trace/handlers/LargestImagePaintHandler.js +18 -0
- package/models/trace/handlers/LargestImagePaintHandler.js.map +7 -0
- package/models/trace/handlers/LargestTextPaintHandler.js +18 -0
- package/models/trace/handlers/LargestTextPaintHandler.js.map +7 -0
- package/models/trace/handlers/LayerTreeHandler.js +90 -0
- package/models/trace/handlers/LayerTreeHandler.js.map +7 -0
- package/models/trace/handlers/LayoutShiftsHandler.js +270 -0
- package/models/trace/handlers/LayoutShiftsHandler.js.map +7 -0
- package/models/trace/handlers/MemoryHandler.js +17 -0
- package/models/trace/handlers/MemoryHandler.js.map +7 -0
- package/models/trace/handlers/MetaHandler.js +250 -0
- package/models/trace/handlers/MetaHandler.js.map +7 -0
- package/models/trace/handlers/Migration.js +27 -0
- package/models/trace/handlers/Migration.js.map +7 -0
- package/models/trace/handlers/ModelHandlers.js +22 -0
- package/models/trace/handlers/ModelHandlers.js.map +7 -0
- package/models/trace/handlers/NetworkRequestsHandler.js +237 -0
- package/models/trace/handlers/NetworkRequestsHandler.js.map +7 -0
- package/models/trace/handlers/PageLoadMetricsHandler.js +334 -0
- package/models/trace/handlers/PageLoadMetricsHandler.js.map +7 -0
- package/models/trace/handlers/RendererHandler.js +221 -0
- package/models/trace/handlers/RendererHandler.js.map +7 -0
- package/models/trace/handlers/SamplesHandler.js +178 -0
- package/models/trace/handlers/SamplesHandler.js.map +7 -0
- package/models/trace/handlers/ScreenshotsHandler.js +57 -0
- package/models/trace/handlers/ScreenshotsHandler.js.map +7 -0
- package/models/trace/handlers/Threads.js +77 -0
- package/models/trace/handlers/Threads.js.map +7 -0
- package/models/trace/handlers/UberFramesHandler.js +293 -0
- package/models/trace/handlers/UberFramesHandler.js.map +7 -0
- package/models/trace/handlers/UserInteractionsHandler.js +168 -0
- package/models/trace/handlers/UserInteractionsHandler.js.map +7 -0
- package/models/trace/handlers/UserTimingsHandler.js +97 -0
- package/models/trace/handlers/UserTimingsHandler.js.map +7 -0
- package/models/trace/handlers/WarningsHandler.js +87 -0
- package/models/trace/handlers/WarningsHandler.js.map +7 -0
- package/models/trace/handlers/WorkersHandler.js +50 -0
- package/models/trace/handlers/WorkersHandler.js.map +7 -0
- package/models/trace/handlers/bundle-tsconfig.json +1 -0
- package/models/trace/handlers/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/handlers/handlers-tsconfig.json +79 -0
- package/models/trace/handlers/handlers.js +4 -0
- package/models/trace/handlers/handlers.js.map +7 -0
- package/models/trace/handlers/types.js +18 -0
- package/models/trace/handlers/types.js.map +7 -0
- package/models/trace/helpers/SamplesIntegrator.js +220 -0
- package/models/trace/helpers/SamplesIntegrator.js.map +7 -0
- package/models/trace/helpers/Timing.js +141 -0
- package/models/trace/helpers/Timing.js.map +7 -0
- package/models/trace/helpers/Trace.js +196 -0
- package/models/trace/helpers/Trace.js.map +7 -0
- package/models/trace/helpers/TreeHelpers.js +119 -0
- package/models/trace/helpers/TreeHelpers.js.map +7 -0
- package/models/trace/helpers/bundle-tsconfig.json +1 -0
- package/models/trace/helpers/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/helpers/helpers-tsconfig.json +59 -0
- package/models/trace/helpers/helpers.js +5 -0
- package/models/trace/helpers/helpers.js.map +7 -0
- package/models/trace/legacy-tsconfig.json +1 -0
- package/models/trace/root-causes/LayoutShift.js +370 -0
- package/models/trace/root-causes/LayoutShift.js.map +7 -0
- package/models/trace/root-causes/RootCauses.js +8 -0
- package/models/trace/root-causes/RootCauses.js.map +7 -0
- package/models/trace/root-causes/bundle-tsconfig.json +1 -0
- package/models/trace/root-causes/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/root-causes/root-causes-tsconfig.json +57 -0
- package/models/trace/root-causes/root-causes.js +2 -0
- package/models/trace/root-causes/root-causes.js.map +7 -0
- package/models/trace/sdk_services/DOMNodeLookup.js +41 -0
- package/models/trace/sdk_services/DOMNodeLookup.js.map +7 -0
- package/models/trace/sdk_services/LayoutShifts.js +68 -0
- package/models/trace/sdk_services/LayoutShifts.js.map +7 -0
- package/models/trace/sdk_services/bundle-tsconfig.json +1 -0
- package/models/trace/sdk_services/devtools_entrypoint-bundle-typescript-tsconfig.json +41 -0
- package/models/trace/sdk_services/sdk_services-tsconfig.json +57 -0
- package/models/trace/sdk_services/sdk_services.js +7 -0
- package/models/trace/sdk_services/sdk_services.js.map +7 -0
- package/models/trace/trace-legacy.js +16 -0
- package/models/trace/trace-legacy.js.map +7 -0
- package/models/trace/trace-tsconfig.json +69 -0
- package/models/trace/trace.js +23 -0
- package/models/trace/trace.js.map +7 -0
- package/models/trace/types/Configuration.js +18 -0
- package/models/trace/types/Configuration.js.map +7 -0
- package/models/trace/types/File.js +6 -0
- package/models/trace/types/File.js.map +7 -0
- package/models/trace/types/Timing.js +17 -0
- package/models/trace/types/Timing.js.map +7 -0
- package/models/trace/types/TraceEvents.js +595 -0
- package/models/trace/types/TraceEvents.js.map +7 -0
- package/models/trace/types/bundle-tsconfig.json +1 -0
- package/models/trace/types/devtools_entrypoint-bundle-typescript-tsconfig.json +44 -0
- package/models/trace/types/types-tsconfig.json +47 -0
- package/models/trace/types/types.js +5 -0
- package/models/trace/types/types.js.map +7 -0
- package/models/trace/worker/Processor.js +143 -0
- package/models/trace/worker/Processor.js.map +7 -0
- package/models/trace/worker/Types.js +1 -0
- package/models/trace/worker/Types.js.map +7 -0
- package/models/trace/worker/bundle-tsconfig.json +1 -0
- package/models/trace/worker/devtools_entrypoint-bundle-typescript-tsconfig.json +41 -0
- package/models/trace/worker/devtools_entrypoint-worker_entrypoint-typescript-tsconfig.json +41 -0
- package/models/trace/worker/processor-tsconfig.json +45 -0
- package/models/trace/worker/worker.js +7 -0
- package/models/trace/worker/worker.js.map +7 -0
- package/models/trace/worker/worker_entrypoint-tsconfig.json +1 -0
- package/models/trace/worker/worker_entrypoint.js +36 -0
- package/models/trace/worker/worker_entrypoint.js.map +7 -0
- package/package.json +2 -2
- package/trace.mjs +15 -8
- package/trace.mjs.map +3 -2
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import * as Types from "../types/types.js";
|
|
2
|
+
const runningInProcessEvents = /* @__PURE__ */ new Map();
|
|
3
|
+
const doneWithProcessEvents = /* @__PURE__ */ new Map();
|
|
4
|
+
const createdSyntheticEvents = /* @__PURE__ */ new Map();
|
|
5
|
+
const utilityThreads = /* @__PURE__ */ new Map();
|
|
6
|
+
const v8HelperThreads = /* @__PURE__ */ new Map();
|
|
7
|
+
export function reset() {
|
|
8
|
+
runningInProcessEvents.clear();
|
|
9
|
+
doneWithProcessEvents.clear();
|
|
10
|
+
createdSyntheticEvents.clear();
|
|
11
|
+
utilityThreads.clear();
|
|
12
|
+
v8HelperThreads.clear();
|
|
13
|
+
}
|
|
14
|
+
export function handleEvent(event) {
|
|
15
|
+
if (Types.TraceEvents.isTraceEventAuctionWorkletRunningInProcess(event)) {
|
|
16
|
+
runningInProcessEvents.set(event.args.data.pid, event);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (Types.TraceEvents.isTraceEventAuctionWorkletDoneWithProcess(event)) {
|
|
20
|
+
doneWithProcessEvents.set(event.args.data.pid, event);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (Types.TraceEvents.isThreadName(event)) {
|
|
24
|
+
if (event.args.name === "auction_worklet.CrUtilityMain") {
|
|
25
|
+
utilityThreads.set(event.pid, event);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (event.args.name === "AuctionV8HelperThread") {
|
|
29
|
+
v8HelperThreads.set(event.pid, event);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function workletType(input) {
|
|
34
|
+
switch (input) {
|
|
35
|
+
case "seller":
|
|
36
|
+
return Types.TraceEvents.AuctionWorkletType.SELLER;
|
|
37
|
+
case "bidder":
|
|
38
|
+
return Types.TraceEvents.AuctionWorkletType.BIDDER;
|
|
39
|
+
default:
|
|
40
|
+
return Types.TraceEvents.AuctionWorkletType.UNKNOWN;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function makeSyntheticEventBase(event) {
|
|
44
|
+
return {
|
|
45
|
+
name: "SyntheticAuctionWorkletEvent",
|
|
46
|
+
s: Types.TraceEvents.TraceEventScope.THREAD,
|
|
47
|
+
cat: event.cat,
|
|
48
|
+
tid: event.tid,
|
|
49
|
+
ts: event.ts,
|
|
50
|
+
ph: Types.TraceEvents.Phase.INSTANT,
|
|
51
|
+
pid: event.args.data.pid,
|
|
52
|
+
host: event.args.data.host,
|
|
53
|
+
target: event.args.data.target,
|
|
54
|
+
type: workletType(event.args.data.type)
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export async function finalize() {
|
|
58
|
+
for (const [pid, utilityThreadNameEvent] of utilityThreads) {
|
|
59
|
+
const v8HelperEvent = v8HelperThreads.get(pid);
|
|
60
|
+
if (!v8HelperEvent) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const runningEvent = runningInProcessEvents.get(pid);
|
|
64
|
+
const doneWithEvent = doneWithProcessEvents.get(pid);
|
|
65
|
+
let syntheticEvent = null;
|
|
66
|
+
if (runningEvent) {
|
|
67
|
+
syntheticEvent = {
|
|
68
|
+
...makeSyntheticEventBase(runningEvent),
|
|
69
|
+
args: {
|
|
70
|
+
data: {
|
|
71
|
+
runningInProcessEvent: runningEvent,
|
|
72
|
+
utilityThread: utilityThreadNameEvent,
|
|
73
|
+
v8HelperThread: v8HelperEvent
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
if (doneWithEvent) {
|
|
78
|
+
syntheticEvent.args.data.doneWithProcessEvent = doneWithEvent;
|
|
79
|
+
}
|
|
80
|
+
} else if (doneWithEvent) {
|
|
81
|
+
syntheticEvent = {
|
|
82
|
+
...makeSyntheticEventBase(doneWithEvent),
|
|
83
|
+
args: {
|
|
84
|
+
data: {
|
|
85
|
+
doneWithProcessEvent: doneWithEvent,
|
|
86
|
+
utilityThread: utilityThreadNameEvent,
|
|
87
|
+
v8HelperThread: v8HelperEvent
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
if (runningEvent) {
|
|
92
|
+
syntheticEvent.args.data.runningInProcessEvent = runningEvent;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (syntheticEvent === null) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
createdSyntheticEvents.set(pid, syntheticEvent);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export function data() {
|
|
102
|
+
return {
|
|
103
|
+
worklets: new Map(createdSyntheticEvents)
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=AuctionWorkletsHandler.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../../front_end/models/trace/handlers/AuctionWorkletsHandler.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * as Types from '../types/types.js';\n\n/**\n * There are two metadata events that we care about.\n * => AuctionWorkletRunningInProcess tells us which process the Auction Worklet\n * has taken to run in.\n * => AuctionWorkletDoneWithProcess tells us when the worklet is done with that\n * process. This is less useful - but in the future we might want to surface\n * this information so we still parse and return the event.\n *\n * It is important to note that the top level PID on these events is NOT the\n * PID that the worklet is running on; instead we have to look at its\n * args.data.pid property, which is the PID of the process that it is running\n * on.\n *\n * For any given RunningInProcess event, we would typically expect to see a\n * DoneWithProcess event, however this is not guaranteed, especially as users\n * can record any chunk of time in DevTools.\n *\n * Similarly, it is also possible to see a DoneWithProcess event without a\n * RunningInProcess event, if the user started recording after the auction\n * worklets started. Therefore we are happy to create\n * SyntheticAuctionWorkletEvents as long as we see just one of these events.\n *\n * If we do get two events and need to pair them, we can use the\n * args.data.target property, which is a string ID shared by both\n * events.\n */\nconst runningInProcessEvents:\n Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventAuctionWorkletRunningInProcess> = new Map();\nconst doneWithProcessEvents:\n Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventAuctionWorkletDoneWithProcess> = new Map();\n\n// Keyed by the PID defined in `args.data.pid` on AuctionWorklet trace events..\nconst createdSyntheticEvents: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.SyntheticAuctionWorkletEvent> =\n new Map();\n\n// Each AuctonWorklet takes over a process and has 2 threads (that we care\n// about and want to show as tracks):\n// 1. A CrUtilityMain thread which is known as the \"control process\".\n// 2. A AuctionV8HelperThread which is the actual auction worklet and will be\n// either a \"Seller\" or a \"Bidder\"\n// To detect these we look for the metadata thread_name events. We key these by\n// PID so that we can easily look them up later without having to loop through.\nconst utilityThreads: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventThreadName> = new Map();\nconst v8HelperThreads: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.TraceEventThreadName> = new Map();\n\nexport function reset(): void {\n runningInProcessEvents.clear();\n doneWithProcessEvents.clear();\n createdSyntheticEvents.clear();\n utilityThreads.clear();\n v8HelperThreads.clear();\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (Types.TraceEvents.isTraceEventAuctionWorkletRunningInProcess(event)) {\n runningInProcessEvents.set(event.args.data.pid, event);\n return;\n }\n\n if (Types.TraceEvents.isTraceEventAuctionWorkletDoneWithProcess(event)) {\n doneWithProcessEvents.set(event.args.data.pid, event);\n return;\n }\n\n if (Types.TraceEvents.isThreadName(event)) {\n if (event.args.name === 'auction_worklet.CrUtilityMain') {\n utilityThreads.set(event.pid, event);\n return;\n }\n if (event.args.name === 'AuctionV8HelperThread') {\n v8HelperThreads.set(event.pid, event);\n }\n }\n}\n\nfunction workletType(input: string): Types.TraceEvents.AuctionWorkletType {\n switch (input) {\n case 'seller':\n return Types.TraceEvents.AuctionWorkletType.SELLER;\n case 'bidder':\n return Types.TraceEvents.AuctionWorkletType.BIDDER;\n default:\n return Types.TraceEvents.AuctionWorkletType.UNKNOWN;\n }\n}\n\n/**\n * We cannot make the full event without knowing the type of event, but we can\n * create everything other than the `args` field, as those are identical\n * regardless of the type of event.\n */\nfunction makeSyntheticEventBase(event: Types.TraceEvents.TraceEventAuctionWorkletDoneWithProcess|\n Types.TraceEvents.TraceEventAuctionWorkletRunningInProcess):\n Omit<Types.TraceEvents.SyntheticAuctionWorkletEvent, 'args'> {\n return {\n name: 'SyntheticAuctionWorkletEvent',\n s: Types.TraceEvents.TraceEventScope.THREAD,\n cat: event.cat,\n tid: event.tid,\n ts: event.ts,\n ph: Types.TraceEvents.Phase.INSTANT,\n pid: event.args.data.pid,\n host: event.args.data.host,\n target: event.args.data.target,\n type: workletType(event.args.data.type),\n };\n}\n\nexport async function finalize(): Promise<void> {\n // Loop through the utility threads we found to create the worklet events. We\n // expect each worklet to have a utility thread, so we can use them as the\n // root of our list of worklets.\n for (const [pid, utilityThreadNameEvent] of utilityThreads) {\n const v8HelperEvent = v8HelperThreads.get(pid);\n if (!v8HelperEvent) {\n // Bad trace data - AuctionWorklets are expected to always have both threads.\n continue;\n }\n\n const runningEvent = runningInProcessEvents.get(pid);\n const doneWithEvent = doneWithProcessEvents.get(pid);\n\n // We can create a worklet from either the runningEvent or doneWithEvent -\n // we do not need both. We cannot express that to TypeScript with an early\n // return here, so instead we set the event initially to null, and then\n // create it from either the running event or the doneWith event. If it is\n // still null after this, that means neither event was found, and we drop\n // the worklet as we do not have enough information to create the synthetic\n // event.\n\n let syntheticEvent: Types.TraceEvents.SyntheticAuctionWorkletEvent|null = null;\n\n if (runningEvent) {\n syntheticEvent = {\n ...makeSyntheticEventBase(runningEvent),\n args: {\n data: {\n runningInProcessEvent: runningEvent,\n utilityThread: utilityThreadNameEvent,\n v8HelperThread: v8HelperEvent,\n },\n },\n };\n if (doneWithEvent) {\n syntheticEvent.args.data.doneWithProcessEvent = doneWithEvent;\n }\n } else if (doneWithEvent) {\n syntheticEvent = {\n ...makeSyntheticEventBase(doneWithEvent),\n args: {\n data: {\n doneWithProcessEvent: doneWithEvent,\n utilityThread: utilityThreadNameEvent,\n v8HelperThread: v8HelperEvent,\n },\n },\n };\n if (runningEvent) {\n syntheticEvent.args.data.runningInProcessEvent = runningEvent;\n }\n }\n if (syntheticEvent === null) {\n continue;\n }\n createdSyntheticEvents.set(pid, syntheticEvent);\n }\n}\n\nexport interface AuctionWorkletsData {\n worklets: Map<Types.TraceEvents.ProcessID, Types.TraceEvents.SyntheticAuctionWorkletEvent>;\n}\n\nexport function data(): AuctionWorkletsData {\n return {\n worklets: new Map(createdSyntheticEvents),\n };\n}\n"],
|
|
5
|
+
"mappings": "AAIA;AA4BA,MAAM,yBAC6F,oBAAI;AACvG,MAAM,wBAC4F,oBAAI;AAGtG,MAAM,yBACF,oBAAI;AASR,MAAM,iBAA2F,oBAAI;AACrG,MAAM,kBAA4F,oBAAI;AAE/F,wBAAuB;AAC5B,yBAAuB;AACvB,wBAAsB;AACtB,yBAAuB;AACvB,iBAAe;AACf,kBAAgB;AAAA;AAGX,4BAAqB,OAA+C;AACzE,MAAI,MAAM,YAAY,2CAA2C,QAAQ;AACvE,2BAAuB,IAAI,MAAM,KAAK,KAAK,KAAK;AAChD;AAAA;AAGF,MAAI,MAAM,YAAY,0CAA0C,QAAQ;AACtE,0BAAsB,IAAI,MAAM,KAAK,KAAK,KAAK;AAC/C;AAAA;AAGF,MAAI,MAAM,YAAY,aAAa,QAAQ;AACzC,QAAI,MAAM,KAAK,SAAS,iCAAiC;AACvD,qBAAe,IAAI,MAAM,KAAK;AAC9B;AAAA;AAEF,QAAI,MAAM,KAAK,SAAS,yBAAyB;AAC/C,sBAAgB,IAAI,MAAM,KAAK;AAAA;AAAA;AAAA;AAKrC,qBAAqB,OAAqD;AACxE,UAAQ;AAAA,SACD;AACH,aAAO,MAAM,YAAY,mBAAmB;AAAA,SACzC;AACH,aAAO,MAAM,YAAY,mBAAmB;AAAA;AAE5C,aAAO,MAAM,YAAY,mBAAmB;AAAA;AAAA;AASlD,gCAAgC,OAEiC;AAC/D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,GAAG,MAAM,YAAY,gBAAgB;AAAA,IACrC,KAAK,MAAM;AAAA,IACX,KAAK,MAAM;AAAA,IACX,IAAI,MAAM;AAAA,IACV,IAAI,MAAM,YAAY,MAAM;AAAA,IAC5B,KAAK,MAAM,KAAK,KAAK;AAAA,IACrB,MAAM,MAAM,KAAK,KAAK;AAAA,IACtB,QAAQ,MAAM,KAAK,KAAK;AAAA,IACxB,MAAM,YAAY,MAAM,KAAK,KAAK;AAAA;AAAA;AAItC,iCAAgD;AAI9C,aAAW,CAAC,KAAK,2BAA2B,gBAAgB;AAC1D,UAAM,gBAAgB,gBAAgB,IAAI;AAC1C,QAAI,CAAC,eAAe;AAElB;AAAA;AAGF,UAAM,eAAe,uBAAuB,IAAI;AAChD,UAAM,gBAAgB,sBAAsB,IAAI;AAUhD,QAAI,iBAAsE;AAE1E,QAAI,cAAc;AAChB,uBAAiB;AAAA,WACZ,uBAAuB;AAAA,QAC1B,MAAM;AAAA,UACJ,MAAM;AAAA,YACJ,uBAAuB;AAAA,YACvB,eAAe;AAAA,YACf,gBAAgB;AAAA;AAAA;AAAA;AAItB,UAAI,eAAe;AACjB,uBAAe,KAAK,KAAK,uBAAuB;AAAA;AAAA,eAEzC,eAAe;AACxB,uBAAiB;AAAA,WACZ,uBAAuB;AAAA,QAC1B,MAAM;AAAA,UACJ,MAAM;AAAA,YACJ,sBAAsB;AAAA,YACtB,eAAe;AAAA,YACf,gBAAgB;AAAA;AAAA;AAAA;AAItB,UAAI,cAAc;AAChB,uBAAe,KAAK,KAAK,wBAAwB;AAAA;AAAA;AAGrD,QAAI,mBAAmB,MAAM;AAC3B;AAAA;AAEF,2BAAuB,IAAI,KAAK;AAAA;AAAA;AAQ7B,uBAAqC;AAC1C,SAAO;AAAA,IACL,UAAU,IAAI,IAAI;AAAA;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
import * as Platform from "../../../core/platform/platform.js";
|
|
2
|
+
import * as Helpers from "../helpers/helpers.js";
|
|
3
|
+
import * as Types from "../types/types.js";
|
|
4
|
+
import { data as auctionWorkletsData } from "./AuctionWorkletsHandler.js";
|
|
5
|
+
import { data as layerTreeHandlerData } from "./LayerTreeHandler.js";
|
|
6
|
+
import { data as metaHandlerData } from "./MetaHandler.js";
|
|
7
|
+
import { data as rendererHandlerData } from "./RendererHandler.js";
|
|
8
|
+
import * as Threads from "./Threads.js";
|
|
9
|
+
import { HandlerState } from "./types.js";
|
|
10
|
+
let handlerState = HandlerState.UNINITIALIZED;
|
|
11
|
+
const allEvents = [];
|
|
12
|
+
let model = null;
|
|
13
|
+
export function reset() {
|
|
14
|
+
handlerState = HandlerState.UNINITIALIZED;
|
|
15
|
+
allEvents.length = 0;
|
|
16
|
+
}
|
|
17
|
+
export function initialize() {
|
|
18
|
+
if (handlerState !== HandlerState.UNINITIALIZED) {
|
|
19
|
+
throw new Error("FramesHandler was not reset before being initialized");
|
|
20
|
+
}
|
|
21
|
+
handlerState = HandlerState.INITIALIZED;
|
|
22
|
+
}
|
|
23
|
+
export function handleEvent(event) {
|
|
24
|
+
allEvents.push(event);
|
|
25
|
+
}
|
|
26
|
+
export async function finalize() {
|
|
27
|
+
if (handlerState !== HandlerState.INITIALIZED) {
|
|
28
|
+
throw new Error("FramesHandler is not initialized");
|
|
29
|
+
}
|
|
30
|
+
Helpers.Trace.sortTraceEventsInPlace(allEvents);
|
|
31
|
+
const modelForTrace = new TimelineFrameModel(allEvents, rendererHandlerData(), auctionWorkletsData(), metaHandlerData(), layerTreeHandlerData());
|
|
32
|
+
model = modelForTrace;
|
|
33
|
+
}
|
|
34
|
+
export function data() {
|
|
35
|
+
return {
|
|
36
|
+
frames: model ? Array.from(model.frames()) : [],
|
|
37
|
+
framesById: model ? { ...model.framesById() } : {}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function deps() {
|
|
41
|
+
return ["Meta", "Renderer", "AuctionWorklets", "LayerTree"];
|
|
42
|
+
}
|
|
43
|
+
function isFrameEvent(event) {
|
|
44
|
+
return Types.TraceEvents.isTraceEventSetLayerId(event) || Types.TraceEvents.isTraceEventBeginFrame(event) || Types.TraceEvents.isTraceEventDroppedFrame(event) || Types.TraceEvents.isTraceEventRequestMainThreadFrame(event) || Types.TraceEvents.isTraceEventBeginMainThreadFrame(event) || Types.TraceEvents.isTraceEventNeedsBeginFrameChanged(event) || Types.TraceEvents.isTraceEventCommit(event) || Types.TraceEvents.isTraceEventCompositeLayers(event) || Types.TraceEvents.isTraceEventActivateLayerTree(event) || Types.TraceEvents.isTraceEventDrawFrame(event);
|
|
45
|
+
}
|
|
46
|
+
function entryIsTopLevel(entry) {
|
|
47
|
+
const devtoolsTimelineCategory = "disabled-by-default-devtools.timeline";
|
|
48
|
+
return entry.name === Types.TraceEvents.KnownEventName.RunTask && entry.cat.includes(devtoolsTimelineCategory);
|
|
49
|
+
}
|
|
50
|
+
export class TimelineFrameModel {
|
|
51
|
+
#frames = [];
|
|
52
|
+
#frameById = {};
|
|
53
|
+
#beginFrameQueue = new TimelineFrameBeginFrameQueue();
|
|
54
|
+
#lastFrame = null;
|
|
55
|
+
#mainFrameCommitted = false;
|
|
56
|
+
#mainFrameRequested = false;
|
|
57
|
+
#lastLayerTree = null;
|
|
58
|
+
#framePendingActivation = null;
|
|
59
|
+
#framePendingCommit = null;
|
|
60
|
+
#lastBeginFrame = null;
|
|
61
|
+
#lastNeedsBeginFrame = null;
|
|
62
|
+
#lastTaskBeginTime = null;
|
|
63
|
+
#layerTreeId = null;
|
|
64
|
+
#activeProcessId = null;
|
|
65
|
+
#activeThreadId = null;
|
|
66
|
+
#layerTreeData;
|
|
67
|
+
constructor(allEvents2, rendererData, auctionWorkletsData2, metaData, layerTreeData) {
|
|
68
|
+
const mainThreads = Threads.threadsInRenderer(rendererData, auctionWorkletsData2).filter((thread) => {
|
|
69
|
+
return thread.type === Threads.ThreadType.MAIN_THREAD && thread.processIsOnMainFrame;
|
|
70
|
+
});
|
|
71
|
+
const threadData = mainThreads.map((thread) => {
|
|
72
|
+
return {
|
|
73
|
+
tid: thread.tid,
|
|
74
|
+
pid: thread.pid,
|
|
75
|
+
startTime: thread.entries[0].ts
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
this.#layerTreeData = layerTreeData;
|
|
79
|
+
this.#addTraceEvents(allEvents2, threadData, metaData.mainFrameId);
|
|
80
|
+
}
|
|
81
|
+
framesById() {
|
|
82
|
+
return this.#frameById;
|
|
83
|
+
}
|
|
84
|
+
frames() {
|
|
85
|
+
return this.#frames;
|
|
86
|
+
}
|
|
87
|
+
#handleBeginFrame(startTime, seqId) {
|
|
88
|
+
if (!this.#lastFrame) {
|
|
89
|
+
this.#startFrame(startTime, seqId);
|
|
90
|
+
}
|
|
91
|
+
this.#lastBeginFrame = startTime;
|
|
92
|
+
this.#beginFrameQueue.addFrameIfNotExists(seqId, startTime, false, false);
|
|
93
|
+
}
|
|
94
|
+
#handleDroppedFrame(startTime, seqId, isPartial) {
|
|
95
|
+
if (!this.#lastFrame) {
|
|
96
|
+
this.#startFrame(startTime, seqId);
|
|
97
|
+
}
|
|
98
|
+
this.#beginFrameQueue.addFrameIfNotExists(seqId, startTime, true, isPartial);
|
|
99
|
+
this.#beginFrameQueue.setDropped(seqId, true);
|
|
100
|
+
this.#beginFrameQueue.setPartial(seqId, isPartial);
|
|
101
|
+
}
|
|
102
|
+
#handleDrawFrame(startTime, seqId) {
|
|
103
|
+
if (!this.#lastFrame) {
|
|
104
|
+
this.#startFrame(startTime, seqId);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (this.#mainFrameCommitted || !this.#mainFrameRequested) {
|
|
108
|
+
if (this.#lastNeedsBeginFrame) {
|
|
109
|
+
const idleTimeEnd = this.#framePendingActivation ? this.#framePendingActivation.triggerTime : this.#lastBeginFrame || this.#lastNeedsBeginFrame;
|
|
110
|
+
if (idleTimeEnd > this.#lastFrame.startTime) {
|
|
111
|
+
this.#lastFrame.idle = true;
|
|
112
|
+
this.#lastBeginFrame = null;
|
|
113
|
+
}
|
|
114
|
+
this.#lastNeedsBeginFrame = null;
|
|
115
|
+
}
|
|
116
|
+
const framesToVisualize = this.#beginFrameQueue.processPendingBeginFramesOnDrawFrame(seqId);
|
|
117
|
+
for (const frame of framesToVisualize) {
|
|
118
|
+
const isLastFrameIdle = this.#lastFrame.idle;
|
|
119
|
+
this.#startFrame(frame.startTime, seqId);
|
|
120
|
+
if (isLastFrameIdle && this.#framePendingActivation) {
|
|
121
|
+
this.#commitPendingFrame();
|
|
122
|
+
}
|
|
123
|
+
if (frame.isDropped) {
|
|
124
|
+
this.#lastFrame.dropped = true;
|
|
125
|
+
}
|
|
126
|
+
if (frame.isPartial) {
|
|
127
|
+
this.#lastFrame.isPartial = true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
this.#mainFrameCommitted = false;
|
|
132
|
+
}
|
|
133
|
+
#handleActivateLayerTree() {
|
|
134
|
+
if (!this.#lastFrame) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (this.#framePendingActivation && !this.#lastNeedsBeginFrame) {
|
|
138
|
+
this.#commitPendingFrame();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
#handleRequestMainThreadFrame() {
|
|
142
|
+
if (!this.#lastFrame) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
this.#mainFrameRequested = true;
|
|
146
|
+
}
|
|
147
|
+
#handleCommit() {
|
|
148
|
+
if (!this.#framePendingCommit) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
this.#framePendingActivation = this.#framePendingCommit;
|
|
152
|
+
this.#framePendingCommit = null;
|
|
153
|
+
this.#mainFrameRequested = false;
|
|
154
|
+
this.#mainFrameCommitted = true;
|
|
155
|
+
}
|
|
156
|
+
#handleLayerTreeSnapshot(layerTree) {
|
|
157
|
+
this.#lastLayerTree = layerTree;
|
|
158
|
+
}
|
|
159
|
+
#handleNeedFrameChanged(startTime, needsBeginFrame) {
|
|
160
|
+
if (needsBeginFrame) {
|
|
161
|
+
this.#lastNeedsBeginFrame = startTime;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
#startFrame(startTime, seqId) {
|
|
165
|
+
if (this.#lastFrame) {
|
|
166
|
+
this.#flushFrame(this.#lastFrame, startTime);
|
|
167
|
+
}
|
|
168
|
+
this.#lastFrame = new TimelineFrame(seqId, startTime, Types.Timing.MicroSeconds(startTime - metaHandlerData().traceBounds.min));
|
|
169
|
+
}
|
|
170
|
+
#flushFrame(frame, endTime) {
|
|
171
|
+
frame.setLayerTree(this.#lastLayerTree);
|
|
172
|
+
frame.setEndTime(endTime);
|
|
173
|
+
if (this.#lastLayerTree) {
|
|
174
|
+
this.#lastLayerTree.paints = frame.paints;
|
|
175
|
+
}
|
|
176
|
+
const lastFrame = this.#frames[this.#frames.length - 1];
|
|
177
|
+
if (this.#frames.length && lastFrame && (frame.startTime !== lastFrame.endTime || frame.startTime > frame.endTime)) {
|
|
178
|
+
console.assert(false, `Inconsistent frame time for frame ${this.#frames.length} (${frame.startTime} - ${frame.endTime})`);
|
|
179
|
+
}
|
|
180
|
+
this.#frames.push(frame);
|
|
181
|
+
if (typeof frame.mainFrameId === "number") {
|
|
182
|
+
this.#frameById[frame.mainFrameId] = frame;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
#commitPendingFrame() {
|
|
186
|
+
if (!this.#framePendingActivation || !this.#lastFrame) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
this.#lastFrame.paints = this.#framePendingActivation.paints;
|
|
190
|
+
this.#lastFrame.mainFrameId = this.#framePendingActivation.mainFrameId;
|
|
191
|
+
this.#framePendingActivation = null;
|
|
192
|
+
}
|
|
193
|
+
#addTraceEvents(events, threadData, mainFrameId) {
|
|
194
|
+
let j = 0;
|
|
195
|
+
this.#activeThreadId = threadData.length && threadData[0].tid || null;
|
|
196
|
+
this.#activeProcessId = threadData.length && threadData[0].pid || null;
|
|
197
|
+
for (let i = 0; i < events.length; ++i) {
|
|
198
|
+
while (j + 1 < threadData.length && threadData[j + 1].startTime <= events[i].ts) {
|
|
199
|
+
this.#activeThreadId = threadData[++j].tid;
|
|
200
|
+
this.#activeProcessId = threadData[j].pid;
|
|
201
|
+
}
|
|
202
|
+
this.#addTraceEvent(events[i], mainFrameId);
|
|
203
|
+
}
|
|
204
|
+
this.#activeThreadId = null;
|
|
205
|
+
this.#activeProcessId = null;
|
|
206
|
+
}
|
|
207
|
+
#addTraceEvent(event, mainFrameId) {
|
|
208
|
+
if (Types.TraceEvents.isTraceEventSetLayerId(event) && event.args.data.frame === mainFrameId) {
|
|
209
|
+
this.#layerTreeId = event.args.data.layerTreeId;
|
|
210
|
+
} else if (Types.TraceEvents.isTraceEventLayerTreeHostImplSnapshot(event) && Number(event.id) === this.#layerTreeId) {
|
|
211
|
+
this.#handleLayerTreeSnapshot({
|
|
212
|
+
entry: event,
|
|
213
|
+
paints: []
|
|
214
|
+
});
|
|
215
|
+
} else {
|
|
216
|
+
if (isFrameEvent(event)) {
|
|
217
|
+
this.#processCompositorEvents(event);
|
|
218
|
+
}
|
|
219
|
+
if (event.tid === this.#activeThreadId && event.pid === this.#activeProcessId) {
|
|
220
|
+
this.#addMainThreadTraceEvent(event);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
#processCompositorEvents(entry) {
|
|
225
|
+
if (entry.args["layerTreeId"] !== this.#layerTreeId) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (Types.TraceEvents.isTraceEventBeginFrame(entry)) {
|
|
229
|
+
this.#handleBeginFrame(entry.ts, entry.args["frameSeqId"]);
|
|
230
|
+
} else if (Types.TraceEvents.isTraceEventDrawFrame(entry)) {
|
|
231
|
+
this.#handleDrawFrame(entry.ts, entry.args["frameSeqId"]);
|
|
232
|
+
} else if (Types.TraceEvents.isTraceEventActivateLayerTree(entry)) {
|
|
233
|
+
this.#handleActivateLayerTree();
|
|
234
|
+
} else if (Types.TraceEvents.isTraceEventRequestMainThreadFrame(entry)) {
|
|
235
|
+
this.#handleRequestMainThreadFrame();
|
|
236
|
+
} else if (Types.TraceEvents.isTraceEventNeedsBeginFrameChanged(entry)) {
|
|
237
|
+
this.#handleNeedFrameChanged(entry.ts, entry.args["data"] && Boolean(entry.args["data"]["needsBeginFrame"]));
|
|
238
|
+
} else if (Types.TraceEvents.isTraceEventDroppedFrame(entry)) {
|
|
239
|
+
this.#handleDroppedFrame(entry.ts, entry.args["frameSeqId"], Boolean(entry.args["hasPartialUpdate"]));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
#addMainThreadTraceEvent(entry) {
|
|
243
|
+
if (entryIsTopLevel(entry)) {
|
|
244
|
+
this.#lastTaskBeginTime = entry.ts;
|
|
245
|
+
}
|
|
246
|
+
if (!this.#framePendingCommit && MAIN_FRAME_MARKERS.has(entry.name)) {
|
|
247
|
+
this.#framePendingCommit = new PendingFrame(this.#lastTaskBeginTime || entry.ts);
|
|
248
|
+
}
|
|
249
|
+
if (!this.#framePendingCommit) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (Types.TraceEvents.isTraceEventBeginMainThreadFrame(entry) && entry.args.data.frameId) {
|
|
253
|
+
this.#framePendingCommit.mainFrameId = entry.args.data.frameId;
|
|
254
|
+
}
|
|
255
|
+
if (Types.TraceEvents.isTraceEventPaint(entry)) {
|
|
256
|
+
const snapshot = this.#layerTreeData.paintsToSnapshots.get(entry);
|
|
257
|
+
if (snapshot) {
|
|
258
|
+
this.#framePendingCommit.paints.push(new LayerPaintEvent(entry, snapshot));
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if ((Types.TraceEvents.isTraceEventCompositeLayers(entry) || Types.TraceEvents.isTraceEventCommit(entry)) && entry.args["layerTreeId"] === this.#layerTreeId) {
|
|
262
|
+
this.#handleCommit();
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const MAIN_FRAME_MARKERS = /* @__PURE__ */ new Set([
|
|
267
|
+
Types.TraceEvents.KnownEventName.ScheduleStyleRecalculation,
|
|
268
|
+
Types.TraceEvents.KnownEventName.InvalidateLayout,
|
|
269
|
+
Types.TraceEvents.KnownEventName.BeginMainThreadFrame,
|
|
270
|
+
Types.TraceEvents.KnownEventName.ScrollLayer
|
|
271
|
+
]);
|
|
272
|
+
export class TimelineFrame {
|
|
273
|
+
startTime;
|
|
274
|
+
startTimeOffset;
|
|
275
|
+
endTime;
|
|
276
|
+
duration;
|
|
277
|
+
idle;
|
|
278
|
+
dropped;
|
|
279
|
+
isPartial;
|
|
280
|
+
layerTree;
|
|
281
|
+
paints;
|
|
282
|
+
mainFrameId;
|
|
283
|
+
seqId;
|
|
284
|
+
constructor(seqId, startTime, startTimeOffset) {
|
|
285
|
+
this.seqId = seqId;
|
|
286
|
+
this.startTime = startTime;
|
|
287
|
+
this.startTimeOffset = startTimeOffset;
|
|
288
|
+
this.endTime = this.startTime;
|
|
289
|
+
this.duration = Types.Timing.MicroSeconds(0);
|
|
290
|
+
this.idle = false;
|
|
291
|
+
this.dropped = false;
|
|
292
|
+
this.isPartial = false;
|
|
293
|
+
this.layerTree = null;
|
|
294
|
+
this.paints = [];
|
|
295
|
+
this.mainFrameId = void 0;
|
|
296
|
+
}
|
|
297
|
+
setEndTime(endTime) {
|
|
298
|
+
this.endTime = endTime;
|
|
299
|
+
this.duration = Types.Timing.MicroSeconds(this.endTime - this.startTime);
|
|
300
|
+
}
|
|
301
|
+
setLayerTree(layerTree) {
|
|
302
|
+
this.layerTree = layerTree;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
export class LayerPaintEvent {
|
|
306
|
+
#event;
|
|
307
|
+
#snapshot;
|
|
308
|
+
constructor(event, snapshot) {
|
|
309
|
+
this.#event = event;
|
|
310
|
+
this.#snapshot = snapshot;
|
|
311
|
+
}
|
|
312
|
+
layerId() {
|
|
313
|
+
return this.#event.args.data.layerId;
|
|
314
|
+
}
|
|
315
|
+
event() {
|
|
316
|
+
return this.#event;
|
|
317
|
+
}
|
|
318
|
+
picture() {
|
|
319
|
+
const rect = this.#snapshot.args.snapshot.params?.layer_rect;
|
|
320
|
+
const pictureData = this.#snapshot.args.snapshot.skp64;
|
|
321
|
+
return rect && pictureData ? { rect, serializedPicture: pictureData } : null;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
export class PendingFrame {
|
|
325
|
+
paints;
|
|
326
|
+
mainFrameId;
|
|
327
|
+
triggerTime;
|
|
328
|
+
constructor(triggerTime) {
|
|
329
|
+
this.paints = [];
|
|
330
|
+
this.mainFrameId = void 0;
|
|
331
|
+
this.triggerTime = triggerTime;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
class BeginFrameInfo {
|
|
335
|
+
seqId;
|
|
336
|
+
startTime;
|
|
337
|
+
isDropped;
|
|
338
|
+
isPartial;
|
|
339
|
+
constructor(seqId, startTime, isDropped, isPartial) {
|
|
340
|
+
this.seqId = seqId;
|
|
341
|
+
this.startTime = startTime;
|
|
342
|
+
this.isDropped = isDropped;
|
|
343
|
+
this.isPartial = isPartial;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
export class TimelineFrameBeginFrameQueue {
|
|
347
|
+
queueFrames = [];
|
|
348
|
+
mapFrames = {};
|
|
349
|
+
addFrameIfNotExists(seqId, startTime, isDropped, isPartial) {
|
|
350
|
+
if (!(seqId in this.mapFrames)) {
|
|
351
|
+
this.mapFrames[seqId] = new BeginFrameInfo(seqId, startTime, isDropped, isPartial);
|
|
352
|
+
this.queueFrames.push(seqId);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
setDropped(seqId, isDropped) {
|
|
356
|
+
if (seqId in this.mapFrames) {
|
|
357
|
+
this.mapFrames[seqId].isDropped = isDropped;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
setPartial(seqId, isPartial) {
|
|
361
|
+
if (seqId in this.mapFrames) {
|
|
362
|
+
this.mapFrames[seqId].isPartial = isPartial;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
processPendingBeginFramesOnDrawFrame(seqId) {
|
|
366
|
+
const framesToVisualize = [];
|
|
367
|
+
if (seqId in this.mapFrames) {
|
|
368
|
+
while (this.queueFrames[0] !== seqId) {
|
|
369
|
+
const currentSeqId = this.queueFrames[0];
|
|
370
|
+
if (this.mapFrames[currentSeqId].isDropped) {
|
|
371
|
+
framesToVisualize.push(this.mapFrames[currentSeqId]);
|
|
372
|
+
}
|
|
373
|
+
delete this.mapFrames[currentSeqId];
|
|
374
|
+
this.queueFrames.shift();
|
|
375
|
+
}
|
|
376
|
+
framesToVisualize.push(this.mapFrames[seqId]);
|
|
377
|
+
delete this.mapFrames[seqId];
|
|
378
|
+
this.queueFrames.shift();
|
|
379
|
+
}
|
|
380
|
+
return framesToVisualize;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
export function framesWithinWindow(frames, startTime, endTime) {
|
|
384
|
+
const firstFrame = Platform.ArrayUtilities.lowerBound(frames, startTime || 0, (time, frame) => time - frame.endTime);
|
|
385
|
+
const lastFrame = Platform.ArrayUtilities.lowerBound(frames, endTime || Infinity, (time, frame) => time - frame.startTime);
|
|
386
|
+
return frames.slice(firstFrame, lastFrame);
|
|
387
|
+
}
|
|
388
|
+
//# sourceMappingURL=FramesHandler.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../../front_end/models/trace/handlers/FramesHandler.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport * 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 {HandlerState, type TraceEventHandlerName} 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 */\nlet handlerState = HandlerState.UNINITIALIZED;\n\nconst allEvents: Types.TraceEvents.TraceEventData[] = [];\nlet model: TimelineFrameModel|null = null;\n\nexport function reset(): void {\n handlerState = HandlerState.UNINITIALIZED;\n allEvents.length = 0;\n}\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('FramesHandler was not reset before being initialized');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n allEvents.push(event);\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('FramesHandler is not initialized');\n }\n\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 TimelineFrame[];\n framesById: Readonly<Record<number, TimelineFrame|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(): TraceEventHandlerName[] {\n return ['Meta', 'Renderer', 'AuctionWorklets', 'LayerTree'];\n}\n\ntype FrameEvent = Types.TraceEvents.TraceEventBeginFrame|Types.TraceEvents.TraceEventDroppedFrame|\n Types.TraceEvents.TraceEventRequestMainThreadFrame|\n Types.TraceEvents.TraceEventBeginMainThreadFrame|Types.TraceEvents.TraceEventCommit|\n Types.TraceEvents.TraceEventCompositeLayers|Types.TraceEvents.TraceEventActivateLayerTree|\n Types.TraceEvents.TraceEventNeedsBeginFrameChanged|Types.TraceEvents.TraceEventDrawFrame;\n\nfunction isFrameEvent(event: Types.TraceEvents.TraceEventData): event is FrameEvent {\n return (\n Types.TraceEvents.isTraceEventSetLayerId(event) || Types.TraceEvents.isTraceEventBeginFrame(event) ||\n Types.TraceEvents.isTraceEventDroppedFrame(event) ||\n Types.TraceEvents.isTraceEventRequestMainThreadFrame(event) ||\n Types.TraceEvents.isTraceEventBeginMainThreadFrame(event) ||\n Types.TraceEvents.isTraceEventNeedsBeginFrameChanged(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.TraceEvents.isTraceEventCommit(event) || Types.TraceEvents.isTraceEventCompositeLayers(event) ||\n Types.TraceEvents.isTraceEventActivateLayerTree(event) || Types.TraceEvents.isTraceEventDrawFrame(event));\n}\n\nfunction entryIsTopLevel(entry: Types.TraceEvents.TraceEventData): boolean {\n const devtoolsTimelineCategory = 'disabled-by-default-devtools.timeline';\n return entry.name === Types.TraceEvents.KnownEventName.RunTask && 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: FrameLayerTreeData|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.MicroSeconds|null = null;\n #layerTreeId: number|null = null;\n #activeProcessId: Types.TraceEvents.ProcessID|null = null;\n #activeThreadId: Types.TraceEvents.ThreadID|null = null;\n #layerTreeData: LayerTreeData;\n\n constructor(\n allEvents: readonly Types.TraceEvents.TraceEventData[], 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.MicroSeconds, 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.MicroSeconds, 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.MicroSeconds, 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: FrameLayerTreeData): void {\n this.#lastLayerTree = layerTree;\n }\n\n #handleNeedFrameChanged(startTime: Types.Timing.MicroSeconds, needsBeginFrame: boolean): void {\n if (needsBeginFrame) {\n this.#lastNeedsBeginFrame = startTime;\n }\n }\n\n #startFrame(startTime: Types.Timing.MicroSeconds, seqId: number): void {\n if (this.#lastFrame) {\n this.#flushFrame(this.#lastFrame, startTime);\n }\n this.#lastFrame =\n new TimelineFrame(seqId, startTime, Types.Timing.MicroSeconds(startTime - metaHandlerData().traceBounds.min));\n }\n\n #flushFrame(frame: TimelineFrame, endTime: Types.Timing.MicroSeconds): 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 this.#frames.push(frame);\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.TraceEvents.TraceEventData[], threadData: {\n pid: Types.TraceEvents.ProcessID,\n tid: Types.TraceEvents.ThreadID,\n startTime: Types.Timing.MicroSeconds,\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.TraceEvents.TraceEventData, mainFrameId: string): void {\n if (Types.TraceEvents.isTraceEventSetLayerId(event) && event.args.data.frame === mainFrameId) {\n this.#layerTreeId = event.args.data.layerTreeId;\n } else if (\n Types.TraceEvents.isTraceEventLayerTreeHostImplSnapshot(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.TraceEvents.isTraceEventBeginFrame(entry)) {\n this.#handleBeginFrame(entry.ts, entry.args['frameSeqId']);\n } else if (Types.TraceEvents.isTraceEventDrawFrame(entry)) {\n this.#handleDrawFrame(entry.ts, entry.args['frameSeqId']);\n } else if (Types.TraceEvents.isTraceEventActivateLayerTree(entry)) {\n this.#handleActivateLayerTree();\n } else if (Types.TraceEvents.isTraceEventRequestMainThreadFrame(entry)) {\n this.#handleRequestMainThreadFrame();\n } else if (Types.TraceEvents.isTraceEventNeedsBeginFrameChanged(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.TraceEvents.isTraceEventDroppedFrame(entry)) {\n this.#handleDroppedFrame(entry.ts, entry.args['frameSeqId'], Boolean(entry.args['hasPartialUpdate']));\n }\n }\n\n #addMainThreadTraceEvent(entry: Types.TraceEvents.TraceEventData): void {\n if (entryIsTopLevel(entry)) {\n this.#lastTaskBeginTime = entry.ts;\n }\n if (!this.#framePendingCommit && MAIN_FRAME_MARKERS.has(entry.name as Types.TraceEvents.KnownEventName)) {\n this.#framePendingCommit = new PendingFrame(this.#lastTaskBeginTime || entry.ts);\n }\n if (!this.#framePendingCommit) {\n return;\n }\n\n if (Types.TraceEvents.isTraceEventBeginMainThreadFrame(entry) && entry.args.data.frameId) {\n this.#framePendingCommit.mainFrameId = entry.args.data.frameId;\n }\n if (Types.TraceEvents.isTraceEventPaint(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.TraceEvents.isTraceEventCompositeLayers(entry) || Types.TraceEvents.isTraceEventCommit(entry)) &&\n entry.args['layerTreeId'] === this.#layerTreeId) {\n this.#handleCommit();\n }\n }\n}\n\nconst MAIN_FRAME_MARKERS = new Set<Types.TraceEvents.KnownEventName>([\n Types.TraceEvents.KnownEventName.ScheduleStyleRecalculation,\n Types.TraceEvents.KnownEventName.InvalidateLayout,\n Types.TraceEvents.KnownEventName.BeginMainThreadFrame,\n Types.TraceEvents.KnownEventName.ScrollLayer,\n]);\n\nexport interface FrameLayerTreeData {\n entry: Types.TraceEvents.TraceEventLayerTreeHostImplSnapshot;\n paints: LayerPaintEvent[];\n}\n\nexport class TimelineFrame {\n startTime: Types.Timing.MicroSeconds;\n startTimeOffset: Types.Timing.MicroSeconds;\n endTime: Types.Timing.MicroSeconds;\n duration: Types.Timing.MicroSeconds;\n idle: boolean;\n dropped: boolean;\n isPartial: boolean;\n layerTree: FrameLayerTreeData|null;\n paints: LayerPaintEvent[];\n mainFrameId: number|undefined;\n readonly seqId: number;\n\n constructor(seqId: number, startTime: Types.Timing.MicroSeconds, startTimeOffset: Types.Timing.MicroSeconds) {\n this.seqId = seqId;\n this.startTime = startTime;\n this.startTimeOffset = startTimeOffset;\n this.endTime = this.startTime;\n this.duration = Types.Timing.MicroSeconds(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 setEndTime(endTime: Types.Timing.MicroSeconds): void {\n this.endTime = endTime;\n this.duration = Types.Timing.MicroSeconds(this.endTime - this.startTime);\n }\n\n setLayerTree(layerTree: FrameLayerTreeData|null): void {\n this.layerTree = layerTree;\n }\n}\n\nexport interface LayerPaintEventPicture {\n rect: Array<number>;\n serializedPicture: string;\n}\nexport class LayerPaintEvent {\n readonly #event: Types.TraceEvents.TraceEventPaint;\n #snapshot: Types.TraceEvents.TraceEventDisplayItemListSnapshot;\n\n constructor(event: Types.TraceEvents.TraceEventPaint, snapshot: Types.TraceEvents.TraceEventDisplayItemListSnapshot) {\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.TraceEvents.TraceEventPaint {\n return this.#event;\n }\n\n picture(): LayerPaintEventPicture|null {\n const rect = this.#snapshot.args.snapshot.params?.layer_rect;\n const pictureData = this.#snapshot.args.snapshot.skp64;\n return rect && pictureData ? {rect: 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.MicroSeconds;\n isDropped: boolean;\n isPartial: boolean;\n constructor(seqId: number, startTime: Types.Timing.MicroSeconds, 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.MicroSeconds, isDropped: boolean, isPartial: boolean):\n 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 TimelineFrame[], startTime: Types.Timing.MicroSeconds,\n endTime: Types.Timing.MicroSeconds): TimelineFrame[] {\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"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { data as metaHandlerData } from "./MetaHandler.js";
|
|
2
|
+
import { HandlerState } from "./types.js";
|
|
3
|
+
import * as Types from "../types/types.js";
|
|
4
|
+
import * as Helpers from "../helpers/helpers.js";
|
|
5
|
+
let handlerState = HandlerState.UNINITIALIZED;
|
|
6
|
+
const eventsInProcessThread = /* @__PURE__ */ new Map();
|
|
7
|
+
let mainGPUThreadTasks = [];
|
|
8
|
+
export function reset() {
|
|
9
|
+
eventsInProcessThread.clear();
|
|
10
|
+
mainGPUThreadTasks = [];
|
|
11
|
+
handlerState = HandlerState.UNINITIALIZED;
|
|
12
|
+
}
|
|
13
|
+
export function initialize() {
|
|
14
|
+
if (handlerState !== HandlerState.UNINITIALIZED) {
|
|
15
|
+
throw new Error("GPU Handler was not reset before being initialized");
|
|
16
|
+
}
|
|
17
|
+
handlerState = HandlerState.INITIALIZED;
|
|
18
|
+
}
|
|
19
|
+
export function handleEvent(event) {
|
|
20
|
+
if (handlerState !== HandlerState.INITIALIZED) {
|
|
21
|
+
throw new Error("GPU Handler is not initialized");
|
|
22
|
+
}
|
|
23
|
+
if (!Types.TraceEvents.isTraceEventGPUTask(event)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
Helpers.Trace.addEventToProcessThread(event, eventsInProcessThread);
|
|
27
|
+
}
|
|
28
|
+
export async function finalize() {
|
|
29
|
+
if (handlerState !== HandlerState.INITIALIZED) {
|
|
30
|
+
throw new Error("GPU Handler is not initialized");
|
|
31
|
+
}
|
|
32
|
+
const { gpuProcessId, gpuThreadId } = metaHandlerData();
|
|
33
|
+
const gpuThreadsForProcess = eventsInProcessThread.get(gpuProcessId);
|
|
34
|
+
if (gpuThreadsForProcess && gpuThreadId) {
|
|
35
|
+
mainGPUThreadTasks = gpuThreadsForProcess.get(gpuThreadId) || [];
|
|
36
|
+
}
|
|
37
|
+
handlerState = HandlerState.FINALIZED;
|
|
38
|
+
}
|
|
39
|
+
export function data() {
|
|
40
|
+
if (handlerState !== HandlerState.FINALIZED) {
|
|
41
|
+
throw new Error("GPU Handler is not finalized");
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
mainGPUThreadTasks: [...mainGPUThreadTasks]
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export function deps() {
|
|
48
|
+
return ["Meta"];
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=GPUHandler.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../../../front_end/models/trace/handlers/GPUHandler.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2022 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport {data as metaHandlerData} from './MetaHandler.js';\n\nimport {type TraceEventHandlerName, HandlerState} from './types.js';\n\nimport * as Types from '../types/types.js';\nimport * as Helpers from '../helpers/helpers.js';\n\nlet handlerState = HandlerState.UNINITIALIZED;\n\n// Each thread contains events. Events indicate the thread and process IDs, which are\n// used to store the event in the correct process thread entry below.\nconst eventsInProcessThread =\n new Map<Types.TraceEvents.ProcessID, Map<Types.TraceEvents.ThreadID, Types.TraceEvents.TraceEventGPUTask[]>>();\n\nlet mainGPUThreadTasks: Types.TraceEvents.TraceEventGPUTask[] = [];\n\nexport function reset(): void {\n eventsInProcessThread.clear();\n mainGPUThreadTasks = [];\n\n handlerState = HandlerState.UNINITIALIZED;\n}\n\nexport function initialize(): void {\n if (handlerState !== HandlerState.UNINITIALIZED) {\n throw new Error('GPU Handler was not reset before being initialized');\n }\n\n handlerState = HandlerState.INITIALIZED;\n}\n\nexport function handleEvent(event: Types.TraceEvents.TraceEventData): void {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('GPU Handler is not initialized');\n }\n\n if (!Types.TraceEvents.isTraceEventGPUTask(event)) {\n return;\n }\n\n Helpers.Trace.addEventToProcessThread(event, eventsInProcessThread);\n}\n\nexport async function finalize(): Promise<void> {\n if (handlerState !== HandlerState.INITIALIZED) {\n throw new Error('GPU Handler is not initialized');\n }\n\n const {gpuProcessId, gpuThreadId} = metaHandlerData();\n const gpuThreadsForProcess = eventsInProcessThread.get(gpuProcessId);\n if (gpuThreadsForProcess && gpuThreadId) {\n mainGPUThreadTasks = gpuThreadsForProcess.get(gpuThreadId) || [];\n }\n handlerState = HandlerState.FINALIZED;\n}\n\nexport interface GPUHandlerReturnData {\n mainGPUThreadTasks: readonly Types.TraceEvents.TraceEventGPUTask[];\n}\n\nexport function data(): GPUHandlerReturnData {\n if (handlerState !== HandlerState.FINALIZED) {\n throw new Error('GPU Handler is not finalized');\n }\n return {\n mainGPUThreadTasks: [...mainGPUThreadTasks],\n };\n}\n\nexport function deps(): TraceEventHandlerName[] {\n return ['Meta'];\n}\n"],
|
|
5
|
+
"mappings": "AAIA;AAEA;AAEA;AACA;AAEA,IAAI,eAAe,aAAa;AAIhC,MAAM,wBACF,oBAAI;AAER,IAAI,qBAA4D;AAEzD,wBAAuB;AAC5B,wBAAsB;AACtB,uBAAqB;AAErB,iBAAe,aAAa;AAAA;AAGvB,6BAA4B;AACjC,MAAI,iBAAiB,aAAa,eAAe;AAC/C,UAAM,IAAI,MAAM;AAAA;AAGlB,iBAAe,aAAa;AAAA;AAGvB,4BAAqB,OAA+C;AACzE,MAAI,iBAAiB,aAAa,aAAa;AAC7C,UAAM,IAAI,MAAM;AAAA;AAGlB,MAAI,CAAC,MAAM,YAAY,oBAAoB,QAAQ;AACjD;AAAA;AAGF,UAAQ,MAAM,wBAAwB,OAAO;AAAA;AAG/C,iCAAgD;AAC9C,MAAI,iBAAiB,aAAa,aAAa;AAC7C,UAAM,IAAI,MAAM;AAAA;AAGlB,QAAM,EAAC,cAAc,gBAAe;AACpC,QAAM,uBAAuB,sBAAsB,IAAI;AACvD,MAAI,wBAAwB,aAAa;AACvC,yBAAqB,qBAAqB,IAAI,gBAAgB;AAAA;AAEhE,iBAAe,aAAa;AAAA;AAOvB,uBAAsC;AAC3C,MAAI,iBAAiB,aAAa,WAAW;AAC3C,UAAM,IAAI,MAAM;AAAA;AAElB,SAAO;AAAA,IACL,oBAAoB,CAAC,GAAG;AAAA;AAAA;AAIrB,uBAAyC;AAC9C,SAAO,CAAC;AAAA;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|