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 16-- Needed for the scroll_jank table to tell which updates were janky. 17SELECT RUN_METRIC('chrome/scroll_jank.sql'); 18 19-------------------------------------------------------------------------------- 20-- Get all the track ids relevant to the critical path. 21-------------------------------------------------------------------------------- 22 23-- Grab the track of the browser. sendTouchEvent is a Java category event which 24-- only occurs on the browser. This saves us the trouble of dealing with all the 25-- different possible names of the browser (when including system tracing). 26DROP VIEW IF EXISTS browser_main_track_id; 27CREATE VIEW browser_main_track_id AS 28SELECT 29 track_id AS id 30FROM slice 31WHERE 32 name = "sendTouchEvent" 33LIMIT 1; 34 35DROP VIEW IF EXISTS viz_compositor_track_id; 36CREATE VIEW viz_compositor_track_id AS 37SELECT 38 id 39FROM thread_track 40WHERE 41 utid = ( 42 SELECT 43 utid 44 FROM thread 45 WHERE 46 name = "VizCompositorThread" 47 ) 48LIMIT 1; 49 50-- Grab the track of the GPU. gpu/command_buffer is a toplevel category event 51-- which only occurs on the gpu main. This saves us the trouble of dealing with 52-- all the different possible names of the GPU process (when including system 53-- tracing). 54DROP VIEW IF EXISTS gpu_main_track_id; 55CREATE VIEW gpu_main_track_id AS 56SELECT 57 track_id AS id 58FROM slice 59WHERE 60 EXTRACT_ARG(arg_set_id, "task.posted_from.file_name") LIKE 61 "%gpu/command_buffer/service/scheduler.cc" 62LIMIT 1; 63 64-- TODO(nuskos): Determine a good way to get all the renderer track_ids (each 65-- scroll will have a single renderer main and a single renderer 66-- compositor however different scroll updates could have 67-- DIFFERENT renderers so bit tricky). Ignore this complexity for 68-- now until we have a single task we want to blame jank on. 69 70-------------------------------------------------------------------------------- 71-- Grab the last LatencyInfo.Flow for each trace_id on the browser main. 72-------------------------------------------------------------------------------- 73DROP VIEW IF EXISTS browser_flows; 74CREATE VIEW browser_flows AS 75SELECT 76 EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id, 77 EXTRACT_ARG(arg_set_id, "chrome_latency_info.step") AS flow_step, 78 track_id, 79 max(ts) AS ts 80FROM slice 81WHERE 82 track_id = ( 83 SELECT id FROM browser_main_track_id 84 ) AND 85 name = "LatencyInfo.Flow" 86 GROUP BY trace_id; 87 88-- Grab the last LatencyInfo.Flow for each trace_id on the VizCompositor. 89DROP VIEW IF EXISTS viz_flows; 90CREATE VIEW viz_flows AS 91SELECT 92 EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id, 93 EXTRACT_ARG(arg_set_id, "chrome_latency_info.step") AS flow_step, 94 track_id, 95 max(ts) AS ts 96FROM slice 97WHERE 98 track_id = ( 99 SELECT id FROM viz_compositor_track_id 100 ) AND 101 name = "LatencyInfo.Flow" 102 GROUP BY trace_id; 103 104-- Grab the last LatencyInfo.Flow for each trace_id on the GPU main. 105DROP VIEW IF EXISTS gpu_flows; 106CREATE VIEW gpu_flows AS 107SELECT 108 EXTRACT_ARG(arg_set_id, "chrome_latency_info.trace_id") AS trace_id, 109 EXTRACT_ARG(arg_set_id, "chrome_latency_info.step") AS flow_step, 110 track_id, 111 max(ts) AS ts 112FROM slice 113WHERE 114 track_id = ( 115 SELECT id FROM gpu_main_track_id 116 ) AND 117 name = "LatencyInfo.Flow" 118 GROUP BY trace_id; 119 120-------------------------------------------------------------------------------- 121-- Finally join the relevant tracks/flows to the individual scrolls. 122-------------------------------------------------------------------------------- 123 124-- Keeping only the GestureScrollUpdates join the maximum flows with their 125-- associated scrolls. We only keep non-coalesced scrolls. 126DROP VIEW IF EXISTS scroll_with_browser_gpu_and_viz_flows; 127CREATE VIEW scroll_with_browser_gpu_and_viz_flows AS 128SELECT 129 scroll.trace_id, 130 scroll.scroll_id, 131 scroll.ts, 132 scroll.dur, 133 scroll.track_id, 134 browser_flows.ts AS browser_flow_ts, 135 browser_flows.flow_step AS browser_flow_step, 136 browser_flows.track_id AS browser_track_id, 137 viz_flows.ts AS viz_flow_ts, 138 viz_flows.flow_step AS viz_flow_step, 139 viz_flows.track_id AS viz_track_id, 140 gpu_flows.ts AS gpu_flow_ts, 141 gpu_flows.flow_step AS gpu_flow_step, 142 gpu_flows.track_id AS gpu_track_id 143FROM ( 144 SELECT 145 trace_id, 146 id AS scroll_id, 147 ts, 148 dur, 149 track_id 150 FROM scroll_jank 151) scroll JOIN browser_flows ON 152 scroll.trace_id = browser_flows.trace_id 153 JOIN viz_flows ON viz_flows.trace_id = scroll.trace_id 154 JOIN gpu_flows ON gpu_flows.trace_id = scroll.trace_id; 155 156-------------------------------------------------------------------------------- 157-- Below we determine individual causes of blocking tasks. 158-------------------------------------------------------------------------------- 159 160-------------------------------------------------------------------------------- 161-- Determine if a CopyOutputRequest blocked any important threads. 162-------------------------------------------------------------------------------- 163 164-- These are the events that block the Browser Main or the VizCompositor thread. 165DROP VIEW IF EXISTS blocking_browser_gpu_and_viz_copies; 166CREATE VIEW blocking_browser_gpu_and_viz_copies AS 167SELECT 168 id, 169 ts, 170 dur, 171 track_id 172FROM slice 173WHERE 174 ( 175 ( 176 name = "viz.mojom.CopyOutputResultSender" OR 177 name = "GLRenderer::CopyDrawnRenderPass" 178 ) AND 179 track_id = (SELECT id FROM browser_main_track_id) 180 ) OR ( 181 EXTRACT_ARG(arg_set_id, "task.posted_from.file_name") LIKE 182 "%components/viz/common/frame_sinks/copy_output_request.cc" AND 183 track_id = (SELECT id FROM viz_compositor_track_id) 184 ) OR ( 185 name = "SkiaOutputSurfaceImplOnGpu::CopyOutput" AND 186 track_id = (SELECT id FROM gpu_main_track_id) 187 ); 188 189-- Determine based on the LatencyInfo.Flow timestamp and the copy task overlap 190-- if this scroll might have been delayed because of the copy. 191DROP VIEW IF EXISTS blocking_copy_tasks; 192CREATE VIEW blocking_copy_tasks AS 193SELECT 194 scroll.scroll_id, 195 scroll.trace_id, 196 copy.id, 197 copy.ts, 198 copy.dur, 199 copy.track_id, 200 CASE WHEN copy.track_id = scroll.browser_track_id THEN 201 CASE WHEN copy.ts < scroll.browser_flow_ts THEN 202 TRUE 203 ELSE 204 FALSE 205 END 206 WHEN copy.track_id = scroll.viz_track_id THEN 207 CASE WHEN copy.ts < scroll.viz_flow_ts THEN 208 TRUE 209 ELSE 210 FALSE 211 END 212 WHEN copy.track_id = scroll.gpu_track_id THEN 213 CASE WHEN copy.ts < scroll.gpu_flow_ts THEN 214 TRUE 215 ELSE 216 FALSE 217 END 218 ELSE 219 FALSE 220 END AS blocked_by_copy 221FROM 222 scroll_with_browser_gpu_and_viz_flows scroll JOIN 223 blocking_browser_gpu_and_viz_copies copy ON 224 scroll.ts + scroll.dur >= copy.ts AND 225 copy.ts + copy.dur >= scroll.ts; 226 227-- Group by scroll so we can equally join one reply to the ScrollJankAndCauses 228-- view. 229DROP VIEW IF EXISTS screenshot_overlapping_scrolls; 230CREATE VIEW screenshot_overlapping_scrolls AS 231SELECT 232 scroll_id, trace_id, SUM(blocked_by_copy) > 0 AS blocked_by_copy_request 233FROM blocking_copy_tasks 234GROUP BY 1, 2; 235 236-------------------------------------------------------------------------------- 237-- Check for blocking language_detection on the browser thread 238-------------------------------------------------------------------------------- 239DROP VIEW IF EXISTS blocking_browser_language_detection; 240CREATE VIEW blocking_browser_language_detection AS 241SELECT 242 id, 243 ts, 244 dur, 245 track_id 246FROM slice 247WHERE 248 ( 249 name = "language_detection.mojom.LanguageDetectionService" AND 250 track_id = (SELECT id FROM browser_main_track_id) 251 ); 252 253DROP VIEW IF EXISTS blocking_language_detection_tasks; 254CREATE VIEW blocking_language_detection_tasks AS 255SELECT 256 scroll.scroll_id, 257 scroll.trace_id, 258 lang.id, 259 lang.ts, 260 lang.dur, 261 lang.track_id, 262 CASE WHEN lang.track_id = scroll.browser_track_id THEN 263 CASE WHEN lang.ts < scroll.browser_flow_ts THEN 264 TRUE 265 ELSE 266 FALSE 267 END 268 END AS blocked_by_language_detection 269FROM 270 scroll_with_browser_gpu_and_viz_flows scroll JOIN 271 blocking_browser_language_detection lang ON 272 scroll.ts + scroll.dur >= lang.ts AND 273 lang.ts + lang.dur >= scroll.ts; 274 275DROP VIEW IF EXISTS language_detection_overlapping_scrolls; 276CREATE VIEW language_detection_overlapping_scrolls AS 277SELECT 278 scroll_id, trace_id, 279 SUM(blocked_by_language_detection) > 0 AS blocked_by_language_detection 280FROM blocking_language_detection_tasks 281GROUP BY 1, 2; 282 283-------------------------------------------------------------------------------- 284-- Finally join the causes together for easy grouping. 285-------------------------------------------------------------------------------- 286DROP VIEW IF EXISTS scroll_jank_cause_blocking_task; 287CREATE VIEW scroll_jank_cause_blocking_task AS 288 SELECT 289 lang.scroll_id, 290 lang.blocked_by_language_detection, 291 copy.blocked_by_copy_request 292 FROM 293 language_detection_overlapping_scrolls lang JOIN 294 screenshot_overlapping_scrolls copy ON copy.scroll_id = lang.scroll_id; 295