1-- 2-- Copyright 2021 The Android Open Source Project 3-- 4-- Licensed under the Apache License, Version 2.0 (the "License"); 5-- you may not use this file except in compliance with the License. 6-- You may obtain a copy of the License at 7-- 8-- https://www.apache.org/licenses/LICENSE-2.0 9-- 10-- Unless required by applicable law or agreed to in writing, software 11-- distributed under the License is distributed on an "AS IS" BASIS, 12-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13-- See the License for the specific language governing permissions and 14-- limitations under the License. 15 16DROP VIEW IF EXISTS InteractionEvents; 17CREATE PERFETTO VIEW InteractionEvents AS 18SELECT 19 ts, dur, ts AS ts_ir, dur AS dur_ir 20FROM slice WHERE name GLOB 'Interaction.*'; 21 22DROP VIEW IF EXISTS GestureLegacyEvents; 23CREATE PERFETTO VIEW GestureLegacyEvents AS 24SELECT 25 ts, 26 EXTRACT_ARG(arg_set_id, 'legacy_event.phase') AS phase 27FROM __intrinsic_chrome_raw 28WHERE EXTRACT_ARG(arg_set_id, 'legacy_event.name') = 'SyntheticGestureController::running'; 29 30-- Convert pairs of 'S' and 'F' events into slices with ts and dur. 31DROP VIEW IF EXISTS GestureEvents; 32CREATE PERFETTO VIEW GestureEvents AS 33SELECT 34 ts, dur, ts AS ts_ge, dur AS dur_ge 35FROM ( 36 SELECT 37 ts, 38 phase, 39 LEAD(ts) OVER (ORDER BY ts) - ts AS dur 40 FROM GestureLegacyEvents 41) 42WHERE phase = 'S'; 43 44DROP TABLE IF EXISTS InteractionEventsJoinGestureEvents; 45CREATE VIRTUAL TABLE InteractionEventsJoinGestureEvents 46USING SPAN_LEFT_JOIN(InteractionEvents, GestureEvents); 47 48-------------------------------------------------------------------------------- 49-- Interesting segments are: 50-- 1) If there's a gesture overlapping with interaction, then gesture's range. 51-- 2) Else, interaction's range. 52 53DROP VIEW IF EXISTS InterestingSegments; 54CREATE PERFETTO VIEW InterestingSegments AS 55WITH pre_cast AS ( 56 SELECT -- 1) Gestures overlapping interactions. 57 ts_ge AS ts, 58 dur_ge AS dur 59 FROM InteractionEventsJoinGestureEvents 60 WHERE ts_ge IS NOT NULL 61 GROUP BY ts_ge 62 UNION ALL 63 SELECT -- 2) Interactions without gestures. 64 ts_ir AS ts, 65 dur_ir AS dur 66 FROM InteractionEventsJoinGestureEvents 67 WHERE ts_ge IS NULL 68 GROUP BY ts_ir 69 HAVING COUNT(*) = 1 70) 71SELECT 72 CAST(ts AS BIGINT) AS ts, 73 CAST(dur AS BIGINT) AS dur 74FROM pre_cast; 75 76-------------------------------------------------------------------------------- 77-- On ChromeOS, DRM events, if they exist, are the source of truth. Otherwise, 78-- look for display rendering stats. 79-- On Android, the TBMv2 version relied on Surface Flinger events that are 80-- currently unavailable in proto traces. So results may be different from 81-- the TBMv2 version on this platform. 82 83DROP TABLE IF EXISTS DisplayCompositorPresentationEvents; 84CREATE TABLE DisplayCompositorPresentationEvents AS 85SELECT ts, FALSE AS exp 86FROM slice 87WHERE name = 'DrmEventFlipComplete' 88GROUP BY ts; 89 90INSERT INTO DisplayCompositorPresentationEvents 91SELECT ts, FALSE AS exp 92FROM slice 93WHERE 94 name = 'vsync_before' 95 AND NOT EXISTS (SELECT * FROM DisplayCompositorPresentationEvents) 96GROUP BY ts; 97 98INSERT INTO DisplayCompositorPresentationEvents 99SELECT ts, FALSE AS exp 100FROM slice 101WHERE 102 name = 'BenchmarkInstrumentation::DisplayRenderingStats' 103 AND NOT EXISTS (SELECT * FROM DisplayCompositorPresentationEvents) 104GROUP BY ts; 105 106INSERT INTO DisplayCompositorPresentationEvents 107SELECT ts, TRUE AS exp 108FROM slice 109WHERE name = 'Display::FrameDisplayed' 110GROUP BY ts; 111 112DROP VIEW IF EXISTS FrameSegments; 113CREATE PERFETTO VIEW FrameSegments AS 114SELECT 115 ts, 116 LEAD(ts) OVER wnd - ts AS dur, 117 ts AS ts_fs, 118 LEAD(ts) OVER wnd - ts AS dur_fs, 119 exp 120FROM DisplayCompositorPresentationEvents 121WINDOW wnd AS (PARTITION BY exp ORDER BY ts); 122 123DROP TABLE IF EXISTS FrameSegmentsJoinInterestingSegments; 124CREATE VIRTUAL TABLE FrameSegmentsJoinInterestingSegments USING 125SPAN_JOIN(FrameSegments, InterestingSegments); 126 127DROP VIEW IF EXISTS FrameTimes; 128CREATE PERFETTO VIEW FrameTimes AS 129SELECT dur / 1e6 AS dur_ms, exp 130FROM FrameSegmentsJoinInterestingSegments 131WHERE ts = ts_fs AND dur = dur_fs; 132 133-------------------------------------------------------------------------------- 134-- Determine frame rate 135 136DROP VIEW IF EXISTS RefreshPeriodAndroid; 137CREATE PERFETTO VIEW RefreshPeriodAndroid AS 138-- Not implemented yet. 139SELECT NULL AS interval_ms; 140 141DROP VIEW IF EXISTS RefreshPeriodNonAndroid; 142CREATE PERFETTO VIEW RefreshPeriodNonAndroid AS 143SELECT EXTRACT_ARG(arg_set_id, 'debug.args.interval_us') / 1e3 AS interval_ms 144FROM slice 145JOIN thread_track ON (slice.track_id = thread_track.id) 146JOIN thread ON (thread_track.utid = thread.utid) 147WHERE thread.name = 'Compositor' AND slice.name = 'Scheduler::BeginFrame' 148LIMIT 1; 149 150DROP VIEW IF EXISTS RefreshPeriodDefault; 151CREATE PERFETTO VIEW RefreshPeriodDefault AS 152SELECT 1000.0 / 60 AS interval_ms; 153 154DROP TABLE IF EXISTS RefreshPeriod; 155CREATE PERFETTO TABLE RefreshPeriod AS 156SELECT COALESCE( 157 (SELECT interval_ms FROM RefreshPeriodAndroid), 158 (SELECT interval_ms FROM RefreshPeriodNonAndroid), 159 (SELECT interval_ms FROM RefreshPeriodDefault) 160) AS interval_ms; 161 162-------------------------------------------------------------------------------- 163-- Compute average FPS 164 165DROP VIEW IF EXISTS ValidFrameTimes; 166CREATE PERFETTO VIEW ValidFrameTimes AS 167SELECT 168 dur_ms / (SELECT interval_ms FROM RefreshPeriod) AS length, 169 exp 170FROM FrameTimes 171WHERE dur_ms / (SELECT interval_ms FROM RefreshPeriod) >= 0.5; 172 173DROP VIEW IF EXISTS AvgSurfaceFps; 174CREATE PERFETTO VIEW AvgSurfaceFps AS 175SELECT 176 exp, 177 1e3 * COUNT(*) / (SELECT SUM(dur_ms) FROM FrameTimes WHERE exp = valid.exp) AS fps 178FROM ValidFrameTimes valid 179GROUP BY exp; 180 181DROP VIEW IF EXISTS frame_times_output; 182CREATE PERFETTO VIEW frame_times_output AS 183SELECT FrameTimes( 184 'frame_time', (SELECT RepeatedField(dur_ms) FROM FrameTimes WHERE NOT exp), 185 'exp_frame_time', (SELECT RepeatedField(dur_ms) FROM FrameTimes WHERE exp), 186 'avg_surface_fps', (SELECT fps FROM AvgSurfaceFps WHERE NOT exp), 187 'exp_avg_surface_fps', (SELECT fps FROM AvgSurfaceFps WHERE exp) 188); 189