blob: 1fbbe52bc09ada64d6d1c0feca224f915a4d6ecc [file] [log] [blame]
--
-- Copyright 2021 The Android Open Source Project
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- https://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
DROP VIEW IF EXISTS InteractionEvents;
CREATE VIEW InteractionEvents AS
SELECT
ts, dur, ts AS ts_ir, dur AS dur_ir
FROM slice WHERE name GLOB 'Interaction.*';
DROP VIEW IF EXISTS GestureLegacyEvents;
CREATE VIEW GestureLegacyEvents AS
SELECT
ts,
EXTRACT_ARG(arg_set_id, 'legacy_event.phase') AS phase
FROM raw
WHERE EXTRACT_ARG(arg_set_id, 'legacy_event.name') = 'SyntheticGestureController::running';
-- Convert pairs of 'S' and 'F' events into slices with ts and dur.
DROP VIEW IF EXISTS GestureEvents;
CREATE VIEW GestureEvents AS
SELECT
ts, dur, ts AS ts_ge, dur AS dur_ge
FROM (
SELECT
ts,
phase,
LEAD(ts) OVER (ORDER BY ts) - ts AS dur
FROM GestureLegacyEvents
)
WHERE phase = 'S';
DROP TABLE IF EXISTS InteractionEventsJoinGestureEvents;
CREATE VIRTUAL TABLE InteractionEventsJoinGestureEvents
USING SPAN_LEFT_JOIN(InteractionEvents, GestureEvents);
--------------------------------------------------------------------------------
-- Interesting segments are:
-- 1) If there's a gesture overlapping with interaction, then gesture's range.
-- 2) Else, interaction's range.
DROP VIEW IF EXISTS InterestingSegments;
CREATE VIEW InterestingSegments AS
SELECT -- 1) Gestures overlapping interactions.
ts_ge AS ts,
dur_ge AS dur
FROM InteractionEventsJoinGestureEvents
WHERE ts_ge IS NOT NULL
GROUP BY ts_ge
UNION ALL
SELECT -- 2) Interactions without gestures.
ts_ir AS ts,
dur_ir AS dur
FROM InteractionEventsJoinGestureEvents
WHERE ts_ge IS NULL
GROUP BY ts_ir
HAVING COUNT(*) = 1;
--------------------------------------------------------------------------------
-- On ChromeOS, DRM events, if they exist, are the source of truth. Otherwise,
-- look for display rendering stats.
-- On Android, the TBMv2 version relied on Surface Flinger events that are
-- currently unavailable in proto traces. So results may be different from
-- the TBMv2 version on this platform.
DROP TABLE IF EXISTS DisplayCompositorPresentationEvents;
CREATE TABLE DisplayCompositorPresentationEvents AS
SELECT ts, FALSE AS exp
FROM slice
WHERE name = 'DrmEventFlipComplete'
GROUP BY ts;
INSERT INTO DisplayCompositorPresentationEvents
SELECT ts, FALSE AS exp
FROM slice
WHERE
name = 'vsync_before'
AND NOT EXISTS (SELECT * FROM DisplayCompositorPresentationEvents)
GROUP BY ts;
INSERT INTO DisplayCompositorPresentationEvents
SELECT ts, FALSE AS exp
FROM slice
WHERE
name = 'BenchmarkInstrumentation::DisplayRenderingStats'
AND NOT EXISTS (SELECT * FROM DisplayCompositorPresentationEvents)
GROUP BY ts;
INSERT INTO DisplayCompositorPresentationEvents
SELECT ts, TRUE AS exp
FROM slice
WHERE name = 'Display::FrameDisplayed'
GROUP BY ts;
DROP VIEW IF EXISTS FrameSegments;
CREATE VIEW FrameSegments AS
SELECT
ts,
LEAD(ts) OVER wnd - ts AS dur,
ts AS ts_fs,
LEAD(ts) OVER wnd - ts AS dur_fs,
exp
FROM DisplayCompositorPresentationEvents
WINDOW wnd AS (PARTITION BY exp ORDER BY ts);
DROP TABLE IF EXISTS FrameSegmentsJoinInterestingSegments;
CREATE VIRTUAL TABLE FrameSegmentsJoinInterestingSegments USING
SPAN_JOIN(FrameSegments, InterestingSegments);
DROP VIEW IF EXISTS FrameTimes;
CREATE VIEW FrameTimes AS
SELECT dur / 1e6 AS dur_ms, exp
FROM FrameSegmentsJoinInterestingSegments
WHERE ts = ts_fs AND dur = dur_fs;
--------------------------------------------------------------------------------
-- Determine frame rate
DROP VIEW IF EXISTS RefreshPeriodAndroid;
CREATE VIEW RefreshPeriodAndroid AS
-- Not implemented yet.
SELECT NULL AS interval_ms;
DROP VIEW IF EXISTS RefreshPeriodNonAndroid;
CREATE VIEW RefreshPeriodNonAndroid AS
SELECT EXTRACT_ARG(arg_set_id, 'debug.args.interval_us') / 1e3 AS interval_ms
FROM slice
JOIN thread_track ON (slice.track_id = thread_track.id)
JOIN thread ON (thread_track.utid = thread.utid)
WHERE thread.name = 'Compositor' AND slice.name = 'Scheduler::BeginFrame'
LIMIT 1;
DROP VIEW IF EXISTS RefreshPeriodDefault;
CREATE VIEW RefreshPeriodDefault AS
SELECT 1000.0 / 60 AS interval_ms;
DROP TABLE IF EXISTS RefreshPeriod;
CREATE TABLE RefreshPeriod AS
SELECT COALESCE(
(SELECT interval_ms FROM RefreshPeriodAndroid),
(SELECT interval_ms FROM RefreshPeriodNonAndroid),
(SELECT interval_ms FROM RefreshPeriodDefault)
) AS interval_ms;
--------------------------------------------------------------------------------
-- Compute average FPS
DROP VIEW IF EXISTS ValidFrameTimes;
CREATE VIEW ValidFrameTimes AS
SELECT
dur_ms / (SELECT interval_ms FROM RefreshPeriod) AS length,
exp
FROM FrameTimes
WHERE dur_ms / (SELECT interval_ms FROM RefreshPeriod) >= 0.5;
DROP VIEW IF EXISTS AvgSurfaceFps;
CREATE VIEW AvgSurfaceFps AS
SELECT
exp,
1e3 * COUNT(*) / (SELECT SUM(dur_ms) FROM FrameTimes WHERE exp = valid.exp) AS fps
FROM ValidFrameTimes valid
GROUP BY exp;
DROP VIEW IF EXISTS frame_times_output;
CREATE VIEW frame_times_output AS
SELECT FrameTimes(
'frame_time', (SELECT RepeatedField(dur_ms) FROM FrameTimes WHERE NOT exp),
'exp_frame_time', (SELECT RepeatedField(dur_ms) FROM FrameTimes WHERE exp),
'avg_surface_fps', (SELECT fps FROM AvgSurfaceFps WHERE NOT exp),
'exp_avg_surface_fps', (SELECT fps FROM AvgSurfaceFps WHERE exp)
);