1-- 2-- Copyright 2020 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 16SELECT RUN_METRIC('chrome/scroll_jank.sql'); 17 18-- Below we want to collect TouchMoves and figure out if they blocked any 19-- GestureScrollUpdates. This table gets the TouchMove slice and joins it with 20-- the data from the first flow event for that TouchMove. 21DROP TABLE IF EXISTS touch_move_and_begin_flow; 22CREATE TABLE touch_move_and_begin_flow AS 23 SELECT 24 flow.begin_flow_id, 25 flow.begin_flow_ts, 26 flow.begin_flow_track_id, 27 move.* 28 FROM ( 29 SELECT 30 EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id, 31 * 32 FROM slice move 33 WHERE name = "InputLatency::TouchMove" 34 ) move JOIN ( 35 SELECT 36 MIN(id) AS begin_flow_id, 37 track_id AS begin_flow_track_id, 38 ts AS begin_flow_ts, 39 EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") 40 AS begin_flow_trace_id 41 FROM slice 42 WHERE 43 name = "LatencyInfo.Flow" AND 44 EXTRACT_ARG(arg_set_id, "chrome_latency_info.step") IS NULL 45 GROUP BY begin_flow_trace_id 46 ) flow ON flow.begin_flow_trace_id = move.trace_id; 47 48-- Now we take the TouchMove and beginning flow event and figure out if there 49-- is an end flow event on the same browser track_id. This will allow us to see 50-- if it was blocking because if they share the same parent stack then they 51-- weren't blocking. 52DROP TABLE IF EXISTS touch_move_begin_and_end_flow; 53CREATE TABLE touch_move_begin_and_end_flow AS 54 SELECT 55 flow.end_flow_id, 56 flow.end_flow_ts, 57 flow.end_flow_track_id, 58 move.* 59 FROM touch_move_and_begin_flow move LEFT JOIN ( 60 SELECT 61 MAX(id) AS end_flow_id, 62 ts AS end_flow_ts, 63 track_id AS end_flow_track_id, 64 EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") 65 AS end_flow_trace_id 66 FROM slice 67 WHERE 68 name = "LatencyInfo.Flow" AND 69 EXTRACT_ARG(arg_set_id, "chrome_latency_info.step") IS NULL 70 GROUP BY end_flow_trace_id 71 ) flow ON 72 flow.end_flow_trace_id = move.trace_id AND 73 move.begin_flow_track_id = flow.end_flow_track_id AND 74 flow.end_flow_id != move.begin_flow_id 75 WHERE flow.end_flow_id IS NOT NULL; 76 77-- Now that we have the begin and the end we need to find the parent stack of 78-- both. If the end didn't happen on the browser (end is NULL), then we can 79-- ignore it because it couldn't have generated a GestureScrollUpdate. 80DROP TABLE IF EXISTS touch_move_with_ancestor; 81CREATE TABLE touch_move_with_ancestor AS 82 SELECT 83 begin.id AS begin_ancestor_id, 84 end.id AS end_ancestor_id, 85 end.ts AS end_ancestor_ts, 86 end.dur AS end_ancestor_dur, 87 end.track_id AS end_ancestor_track_id, 88 move.* 89 FROM 90 touch_move_begin_and_end_flow move JOIN 91 ancestor_slice(begin_flow_id) begin ON begin.depth = 0 LEFT JOIN 92 ancestor_slice(end_flow_id) end ON end.depth = 0; 93 94-- Now take the parent stack for the end and find if a GestureScrollUpdate was 95-- launched that share the same parent as the end flow event for the TouchMove. 96-- This is the GestureScrollUpdate that the TouchMove blocked (or didn't block) 97-- depending on if the begin flow event is in the same stack. 98DROP TABLE IF EXISTS blocking_touch_move_with_scroll_update; 99CREATE TABLE blocking_touch_move_with_scroll_update AS 100 SELECT 101 move.begin_ancestor_id != move.end_ancestor_id AS blocking_touch_move, 102 scroll.scroll_begin_flow_id, 103 scroll.scroll_begin_flow_trace_id, 104 scroll.scroll_id, 105 move.* 106 FROM touch_move_with_ancestor move LEFT JOIN ( 107 SELECT in_flow.*, in_scroll.scroll_id FROM ( 108 SELECT 109 MIN(slice.id) AS scroll_begin_flow_id, 110 slice.ts AS scroll_begin_flow_ts, 111 slice.track_id AS scroll_begin_flow_track_id, 112 EXTRACT_ARG(slice.arg_set_id, "chrome_latency_info.trace_id") 113 AS scroll_begin_flow_trace_id, 114 ancestor.id AS scroll_begin_flow_ancestor_id 115 FROM 116 slice LEFT JOIN 117 ancestor_slice(slice.id) AS ancestor ON ancestor.depth = 0 118 WHERE 119 slice.name = "LatencyInfo.Flow" AND 120 EXTRACT_ARG(slice.arg_set_id, "chrome_latency_info.step") IS NULL 121 GROUP BY scroll_begin_flow_trace_id 122 ) in_flow JOIN ( 123 SELECT 124 id AS scroll_id, 125 EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") 126 AS scroll_trace_id 127 FROM slice in_scroll 128 WHERE 129 name = "InputLatency::GestureScrollUpdate" AND 130 dur != -1 AND 131 NOT EXTRACT_ARG(arg_set_id, "chrome_latency_info.is_coalesced") 132 ) in_scroll ON 133 in_scroll.scroll_trace_id = in_flow.scroll_begin_flow_trace_id 134 ) scroll ON 135 scroll.scroll_begin_flow_track_id = move.end_ancestor_track_id AND 136 scroll.scroll_begin_flow_ancestor_id = move.end_ancestor_id AND 137 scroll.scroll_begin_flow_ts > move.end_ancestor_ts AND 138 scroll.scroll_begin_flow_ts < move.end_ancestor_ts + move.end_ancestor_dur AND 139 scroll.scroll_begin_flow_id > move.end_ancestor_id 140 WHERE scroll.scroll_id IS NOT NULL; 141 142-- Now filter out any TouchMoves that weren't during a complete scroll. Most of 143-- the other ones will be null anyway since they won't have 144-- GestureScrollUpdates. 145DROP VIEW IF EXISTS scroll_jank_cause_blocking_touch_move; 146CREATE VIEW scroll_jank_cause_blocking_touch_move AS 147 SELECT 148 id, 149 ts, 150 dur, 151 track_id, 152 blocking_touch_move, 153 scroll_id 154 FROM joined_scroll_begin_and_end begin_and_end JOIN ( 155 SELECT 156 * 157 FROM blocking_touch_move_with_scroll_update 158 ) touch ON 159 touch.ts <= begin_and_end.end_ts AND 160 touch.ts > begin_and_end.begin_ts + begin_and_end.begin_dur AND 161 touch.trace_id > begin_and_end.begin_trace_id AND 162 touch.trace_id < begin_and_end.end_trace_id; 163