xref: /aosp_15_r20/external/virglrenderer/perf-testing/Docker/merge_traces.py (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
1*bbecb9d1SAndroid Build Coastguard Worker#!/usr/bin/python3
2*bbecb9d1SAndroid Build Coastguard Worker#
3*bbecb9d1SAndroid Build Coastguard Worker# Copyright (C) 2020 Collabora Ltd
4*bbecb9d1SAndroid Build Coastguard Worker#
5*bbecb9d1SAndroid Build Coastguard Worker# Permission is hereby granted, free of charge, to any person obtaining a
6*bbecb9d1SAndroid Build Coastguard Worker# copy of this software and associated documentation files (the "Software"),
7*bbecb9d1SAndroid Build Coastguard Worker# to deal in the Software without restriction, including without limitation
8*bbecb9d1SAndroid Build Coastguard Worker# the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*bbecb9d1SAndroid Build Coastguard Worker# and/or sell copies of the Software, and to permit persons to whom the
10*bbecb9d1SAndroid Build Coastguard Worker# Software is furnished to do so, subject to the following conditions:
11*bbecb9d1SAndroid Build Coastguard Worker#
12*bbecb9d1SAndroid Build Coastguard Worker# The above copyright notice and this permission notice shall be included
13*bbecb9d1SAndroid Build Coastguard Worker# in all copies or substantial portions of the Software.
14*bbecb9d1SAndroid Build Coastguard Worker#
15*bbecb9d1SAndroid Build Coastguard Worker# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16*bbecb9d1SAndroid Build Coastguard Worker# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*bbecb9d1SAndroid Build Coastguard Worker# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*bbecb9d1SAndroid Build Coastguard Worker# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19*bbecb9d1SAndroid Build Coastguard Worker# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20*bbecb9d1SAndroid Build Coastguard Worker# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21*bbecb9d1SAndroid Build Coastguard Worker# OTHER DEALINGS IN THE SOFTWARE.
22*bbecb9d1SAndroid Build Coastguard Worker
23*bbecb9d1SAndroid Build Coastguard Workerfrom google import protobuf
24*bbecb9d1SAndroid Build Coastguard Workerimport protos.perfetto.trace.perfetto_trace_pb2
25*bbecb9d1SAndroid Build Coastguard Workerfrom protos.perfetto.trace.perfetto_trace_pb2 import BUILTIN_CLOCK_BOOTTIME
26*bbecb9d1SAndroid Build Coastguard Workerfrom protos.perfetto.trace.perfetto_trace_pb2 import BUILTIN_CLOCK_REALTIME
27*bbecb9d1SAndroid Build Coastguard Workerimport math
28*bbecb9d1SAndroid Build Coastguard Workerimport sys
29*bbecb9d1SAndroid Build Coastguard Workerimport operator
30*bbecb9d1SAndroid Build Coastguard Workerimport time
31*bbecb9d1SAndroid Build Coastguard Worker
32*bbecb9d1SAndroid Build Coastguard Workerdef add_ftrace_event(out_message, in_packet, in_event, max_host_sequence_id = 0):
33*bbecb9d1SAndroid Build Coastguard Worker    out_packet = out_message.packet.add()
34*bbecb9d1SAndroid Build Coastguard Worker    out_packet.ftrace_events.cpu = in_packet.ftrace_events.cpu
35*bbecb9d1SAndroid Build Coastguard Worker    out_packet.trusted_uid = in_packet.trusted_uid
36*bbecb9d1SAndroid Build Coastguard Worker    out_packet.trusted_packet_sequence_id += max_host_sequence_id
37*bbecb9d1SAndroid Build Coastguard Worker    out_packet.ftrace_events.event.add().CopyFrom(in_event)
38*bbecb9d1SAndroid Build Coastguard Worker
39*bbecb9d1SAndroid Build Coastguard Workervirtio_gpu_pids = set()
40*bbecb9d1SAndroid Build Coastguard Worker
41*bbecb9d1SAndroid Build Coastguard Workerprint('%d Loading host trace' % time.time())
42*bbecb9d1SAndroid Build Coastguard Worker
43*bbecb9d1SAndroid Build Coastguard Workerin_message = protos.perfetto.trace.perfetto_trace_pb2.Trace()
44*bbecb9d1SAndroid Build Coastguard Workerin_message.ParseFromString(open(sys.argv[1], 'rb').read())
45*bbecb9d1SAndroid Build Coastguard Worker
46*bbecb9d1SAndroid Build Coastguard Workerprint('%d Copying host trace' % time.time())
47*bbecb9d1SAndroid Build Coastguard Worker
48*bbecb9d1SAndroid Build Coastguard Workerout_message = protos.perfetto.trace.perfetto_trace_pb2.Trace()
49*bbecb9d1SAndroid Build Coastguard Workermax_host_sequence_id = 0
50*bbecb9d1SAndroid Build Coastguard Workerfirst_host_virtio_gpu_cmd = math.inf
51*bbecb9d1SAndroid Build Coastguard Workerhost_boot_ts = -1
52*bbecb9d1SAndroid Build Coastguard Workerfor in_packet in in_message.packet:
53*bbecb9d1SAndroid Build Coastguard Worker    max_host_sequence_id = max(max_host_sequence_id,
54*bbecb9d1SAndroid Build Coastguard Worker                               in_packet.trusted_packet_sequence_id)
55*bbecb9d1SAndroid Build Coastguard Worker
56*bbecb9d1SAndroid Build Coastguard Worker    if in_packet.HasField('ftrace_events'):
57*bbecb9d1SAndroid Build Coastguard Worker        for event in in_packet.ftrace_events.event:
58*bbecb9d1SAndroid Build Coastguard Worker            if event.HasField('sched_switch'):
59*bbecb9d1SAndroid Build Coastguard Worker                if 'virtio_gpu' == event.sched_switch.prev_comm:
60*bbecb9d1SAndroid Build Coastguard Worker                    virtio_gpu_pids.add(event.sched_switch.prev_pid)
61*bbecb9d1SAndroid Build Coastguard Worker                if 'virtio_gpu' == event.sched_switch.next_comm:
62*bbecb9d1SAndroid Build Coastguard Worker                    virtio_gpu_pids.add(event.sched_switch.next_pid)
63*bbecb9d1SAndroid Build Coastguard Worker
64*bbecb9d1SAndroid Build Coastguard Worker                if event.sched_switch.prev_pid in virtio_gpu_pids or \
65*bbecb9d1SAndroid Build Coastguard Worker                   event.sched_switch.next_pid in virtio_gpu_pids:
66*bbecb9d1SAndroid Build Coastguard Worker                    add_ftrace_event(out_message, in_packet, event)
67*bbecb9d1SAndroid Build Coastguard Worker            elif event.HasField('sched_wakeup'):
68*bbecb9d1SAndroid Build Coastguard Worker                if 'virtio_gpu' == event.sched_wakeup.comm:
69*bbecb9d1SAndroid Build Coastguard Worker                    virtio_gpu_pids.add(event.sched_wakeup.pid)
70*bbecb9d1SAndroid Build Coastguard Worker
71*bbecb9d1SAndroid Build Coastguard Worker                if event.sched_wakeup.pid in virtio_gpu_pids:
72*bbecb9d1SAndroid Build Coastguard Worker                    add_ftrace_event(out_message, in_packet, event)
73*bbecb9d1SAndroid Build Coastguard Worker            elif event.HasField('print'):
74*bbecb9d1SAndroid Build Coastguard Worker                 event_type, guest_pid, label, cookie = event.print.buf.split('|')
75*bbecb9d1SAndroid Build Coastguard Worker
76*bbecb9d1SAndroid Build Coastguard Worker                 # Replace host PID with the guest PID
77*bbecb9d1SAndroid Build Coastguard Worker                 event.pid = int(guest_pid)
78*bbecb9d1SAndroid Build Coastguard Worker                 add_ftrace_event(out_message, in_packet, event)
79*bbecb9d1SAndroid Build Coastguard Worker    else:
80*bbecb9d1SAndroid Build Coastguard Worker        if in_packet.HasField('track_descriptor'):
81*bbecb9d1SAndroid Build Coastguard Worker            if in_packet.track_descriptor.HasField('name'):
82*bbecb9d1SAndroid Build Coastguard Worker               in_packet.track_descriptor.name += ' (Host)'
83*bbecb9d1SAndroid Build Coastguard Worker        elif in_packet.HasField('track_event'):
84*bbecb9d1SAndroid Build Coastguard Worker            if in_packet.track_event.type == in_packet.track_event.TYPE_SLICE_BEGIN and \
85*bbecb9d1SAndroid Build Coastguard Worker               in_packet.track_event.name == 'GetCapset':
86*bbecb9d1SAndroid Build Coastguard Worker                first_host_virtio_gpu_cmd = min(first_host_virtio_gpu_cmd, in_packet.timestamp)
87*bbecb9d1SAndroid Build Coastguard Worker        elif host_boot_ts == -1 and in_packet.HasField('clock_snapshot'):
88*bbecb9d1SAndroid Build Coastguard Worker            for clock in in_packet.clock_snapshot.clocks:
89*bbecb9d1SAndroid Build Coastguard Worker                if clock.clock_id == BUILTIN_CLOCK_BOOTTIME:
90*bbecb9d1SAndroid Build Coastguard Worker                    host_boottime = clock.timestamp
91*bbecb9d1SAndroid Build Coastguard Worker                elif clock.clock_id == BUILTIN_CLOCK_REALTIME:
92*bbecb9d1SAndroid Build Coastguard Worker                    host_realtime = clock.timestamp
93*bbecb9d1SAndroid Build Coastguard Worker            host_boot_ts = host_realtime - host_boottime
94*bbecb9d1SAndroid Build Coastguard Worker        out_packet = out_message.packet.add()
95*bbecb9d1SAndroid Build Coastguard Worker        out_packet.CopyFrom(in_packet)
96*bbecb9d1SAndroid Build Coastguard Worker
97*bbecb9d1SAndroid Build Coastguard Workerprint('%d Loading guest trace' % time.time())
98*bbecb9d1SAndroid Build Coastguard Workerin_message.ParseFromString(open(sys.argv[2], 'rb').read())
99*bbecb9d1SAndroid Build Coastguard Worker
100*bbecb9d1SAndroid Build Coastguard Worker#print('%d Writing guest trace txt' % time.time())
101*bbecb9d1SAndroid Build Coastguard Worker#open('../traces-db/perfetto-guest.txt', 'w').write(str(in_message))
102*bbecb9d1SAndroid Build Coastguard Worker
103*bbecb9d1SAndroid Build Coastguard Workerfirst_guest_virtio_gpu_cmd = math.inf
104*bbecb9d1SAndroid Build Coastguard Workerguest_boot_ts = -1
105*bbecb9d1SAndroid Build Coastguard Workerfor in_packet in in_message.packet:
106*bbecb9d1SAndroid Build Coastguard Worker    if guest_boot_ts == -1 and in_packet.HasField('clock_snapshot'):
107*bbecb9d1SAndroid Build Coastguard Worker        for clock in in_packet.clock_snapshot.clocks:
108*bbecb9d1SAndroid Build Coastguard Worker            if clock.clock_id == BUILTIN_CLOCK_BOOTTIME:
109*bbecb9d1SAndroid Build Coastguard Worker                guest_boottime = clock.timestamp
110*bbecb9d1SAndroid Build Coastguard Worker            elif clock.clock_id == BUILTIN_CLOCK_REALTIME:
111*bbecb9d1SAndroid Build Coastguard Worker                guest_realtime = clock.timestamp
112*bbecb9d1SAndroid Build Coastguard Worker        guest_boot_ts = guest_realtime - guest_boottime
113*bbecb9d1SAndroid Build Coastguard Worker    elif in_packet.HasField('track_event'):
114*bbecb9d1SAndroid Build Coastguard Worker     if in_packet.track_event.type == in_packet.track_event.TYPE_SLICE_BEGIN and \
115*bbecb9d1SAndroid Build Coastguard Worker        in_packet.track_event.name == 'DRM_IOCTL_VIRTGPU_GET_CAPS':
116*bbecb9d1SAndroid Build Coastguard Worker         first_guest_virtio_gpu_cmd = min(first_guest_virtio_gpu_cmd, in_packet.timestamp)
117*bbecb9d1SAndroid Build Coastguard Worker
118*bbecb9d1SAndroid Build Coastguard Workerdelta = guest_boot_ts - host_boot_ts
119*bbecb9d1SAndroid Build Coastguard Workercmd_delta = first_host_virtio_gpu_cmd - first_guest_virtio_gpu_cmd - delta
120*bbecb9d1SAndroid Build Coastguard Workerprint("boottime delta %ds." % (delta / 1000 / 1000 / 1000))
121*bbecb9d1SAndroid Build Coastguard Workerprint("cmd delta %dus." % (cmd_delta / 1000))
122*bbecb9d1SAndroid Build Coastguard Worker
123*bbecb9d1SAndroid Build Coastguard Workerfor in_packet in in_message.packet:
124*bbecb9d1SAndroid Build Coastguard Worker    if in_packet.HasField('process_tree') or \
125*bbecb9d1SAndroid Build Coastguard Worker       in_packet.HasField('service_event') or \
126*bbecb9d1SAndroid Build Coastguard Worker       in_packet.HasField('track_event') or \
127*bbecb9d1SAndroid Build Coastguard Worker       in_packet.HasField('trace_packet_defaults') or \
128*bbecb9d1SAndroid Build Coastguard Worker       in_packet.HasField('track_descriptor'):
129*bbecb9d1SAndroid Build Coastguard Worker        out_packet = out_message.packet.add()
130*bbecb9d1SAndroid Build Coastguard Worker        out_packet.CopyFrom(in_packet)
131*bbecb9d1SAndroid Build Coastguard Worker        out_packet.trusted_packet_sequence_id += max_host_sequence_id
132*bbecb9d1SAndroid Build Coastguard Worker        out_packet.timestamp += delta
133*bbecb9d1SAndroid Build Coastguard Worker        if out_packet.HasField('track_descriptor'):
134*bbecb9d1SAndroid Build Coastguard Worker            if out_packet.track_descriptor.HasField('name'):
135*bbecb9d1SAndroid Build Coastguard Worker                out_packet.track_descriptor.name += ' (Guest)'
136*bbecb9d1SAndroid Build Coastguard Worker    elif in_packet.HasField('ftrace_events'):
137*bbecb9d1SAndroid Build Coastguard Worker         for event in in_packet.ftrace_events.event:
138*bbecb9d1SAndroid Build Coastguard Worker             event.timestamp += delta
139*bbecb9d1SAndroid Build Coastguard Worker             add_ftrace_event(out_message, in_packet, event, max_host_sequence_id)
140*bbecb9d1SAndroid Build Coastguard Worker
141*bbecb9d1SAndroid Build Coastguard Workerdef get_timestamp(packet):
142*bbecb9d1SAndroid Build Coastguard Worker    if packet.HasField('timestamp'):
143*bbecb9d1SAndroid Build Coastguard Worker        return packet.timestamp
144*bbecb9d1SAndroid Build Coastguard Worker    elif packet.HasField('ftrace_events') and \
145*bbecb9d1SAndroid Build Coastguard Worker         packet.ftrace_events.event:
146*bbecb9d1SAndroid Build Coastguard Worker        return packet.ftrace_events.event[0].timestamp
147*bbecb9d1SAndroid Build Coastguard Worker    return 0
148*bbecb9d1SAndroid Build Coastguard Worker
149*bbecb9d1SAndroid Build Coastguard Workerout_message.packet.sort(key=get_timestamp)
150*bbecb9d1SAndroid Build Coastguard Workerprint('%d Writing merged trace' % time.time())
151*bbecb9d1SAndroid Build Coastguard Workeropen(sys.argv[3], 'wb').write(out_message.SerializeToString())
152*bbecb9d1SAndroid Build Coastguard Worker
153*bbecb9d1SAndroid Build Coastguard Worker#print('%d Writing merged trace txt' % time.time())
154*bbecb9d1SAndroid Build Coastguard Worker#open('../traces-db/perfetto.txt', 'w').write(str(out_message))
155