     on_msg.dur,
     on_msg.expected_vsync_ts,
     lag(on_msg.ts_end) OVER (ORDER BY on_msg.ts_end ASC) AS ts_prev_frame_end,
-    lead(on_msg.ts) OVER (ORDER BY on_msg.ts ASC) AS ts_next_frame_start
+    lead(on_msg.ts) OVER (ORDER BY on_msg.ts ASC) AS ts_next_frame_start,
+    on_msg.gcs_idx
 FROM on_msg
 JOIN android_sysui_cuj_sf_vsync_boundaries cuj_boundaries
-WHERE on_msg.vsync >= cuj_boundaries.vsync_min AND on_msg.vsync <= cuj_boundaries.vsync_max;
+ON on_msg.vsync >= cuj_boundaries.vsync_min AND on_msg.vsync <= cuj_boundaries.vsync_max;
 
 -- Find just the composite slices
 DROP TABLE IF EXISTS android_sysui_cuj_surfaceflinger_composite_slices;

  JOIN android_sysui_cuj_sf_ts_boundaries cuj_boundaries
  ON slice.ts >= cuj_boundaries.ts AND slice.ts <= cuj_boundaries.ts_end
  WHERE slice.dur > 0;

DROP VIEW IF EXISTS android_sysui_cuj_gcs_to_mt_match;
CREATE VIEW android_sysui_cuj_gcs_to_mt_match AS
-- Match Mainthread slice with the first GPU Completion that begins during it
SELECT
gcs.ts AS gcs_ts,
gcs.ts_end AS gcs_ts_end,
gcs.dur AS gcs_dur,
gcs.idx AS idx,
mtf.ts AS mts_ts,
mtf.vsync AS vsync
FROM android_sysui_cuj_surfaceflinger_gpu_completion_slices_in_cuj gcs
-- join with all previous render frames but take latest start time
JOIN android_sysui_cuj_surfaceflinger_main_thread_frames mtf ON gcs.ts > mtf.ts AND gcs.ts < mtf.ts + mtf.dur
GROUP BY gcs.ts, gcs.ts_end, gcs.dur, gcs.idx;

-- Those SurfaceFlinger Frames where we missed the deadline
-- To avoid overlap - which could result in counting janky slices more than once - we limit the

    composite.ts_end - match.commit_ts AS dur,
    match.expected_vsync_ts,
    lag(composite.ts_end) OVER (ORDER BY composite.ts_end ASC) AS ts_prev_frame_end,
    lead(match.commit_ts) OVER (ORDER BY match.commit_ts ASC) AS ts_next_frame_start,
    composite.gcs_idx
  FROM commit_to_composite match
  JOIN android_sysui_cuj_surfaceflinger_composite_slices composite ON match.composite_ts = composite.ts;

