• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2023 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
17SELECT RUN_METRIC('android/android_cpu.sql');
18
19-- Attaching thread proto with media thread name
20DROP VIEW IF EXISTS core_type_proto_per_thread_name;
21CREATE PERFETTO VIEW core_type_proto_per_thread_name AS
22SELECT
23thread.name as thread_name,
24core_type_proto_per_thread.proto AS proto
25FROM core_type_proto_per_thread
26JOIN thread using(utid)
27WHERE thread.name = 'MediaCodec_loop' OR
28      thread.name = 'CodecLooper'
29GROUP BY thread.name;
30
31-- aggregate all cpu the codec threads
32DROP VIEW IF EXISTS codec_per_thread_cpu_use;
33CREATE PERFETTO VIEW codec_per_thread_cpu_use AS
34SELECT
35  upid,
36  process.name AS process_name,
37  thread.name AS thread_name,
38  CAST(SUM(sched.dur) as INT64) AS cpu_time_ns,
39  COUNT(DISTINCT utid) AS num_threads
40FROM sched
41JOIN thread USING(utid)
42JOIN process USING(upid)
43WHERE thread.name = 'MediaCodec_loop' OR
44      thread.name = 'CodecLooper'
45GROUP BY process.name, thread.name;
46
47-- All process that has codec thread
48DROP VIEW IF EXISTS android_codec_process;
49CREATE PERFETTO VIEW android_codec_process AS
50SELECT
51  upid,
52  process.name as process_name
53FROM sched
54JOIN thread using(utid)
55JOIN process using(upid)
56WHERE thread.name = 'MediaCodec_loop' OR
57      thread.name = 'CodecLooper'
58GROUP BY process_name;
59
60-- Total cpu for a process
61DROP VIEW IF EXISTS codec_total_per_process_cpu_use;
62CREATE PERFETTO VIEW codec_total_per_process_cpu_use AS
63SELECT
64  upid,
65  process_name,
66  CAST(SUM(sched.dur) as INT64) AS media_process_cpu_time_ns
67FROM sched
68JOIN thread using(utid)
69JOIN android_codec_process using(upid)
70GROUP BY process_name;
71
72-- Joining total process with media thread table
73DROP VIEW IF EXISTS codec_per_process_thread_cpu_use;
74CREATE PERFETTO VIEW codec_per_process_thread_cpu_use AS
75SELECT
76  *
77FROM codec_total_per_process_cpu_use
78JOIN codec_per_thread_cpu_use using(process_name);
79
80-- Traces are collected using specific traits in codec framework. These traits
81-- are mapped to actual names of slices and then combined with other tables to
82-- give out the total_cpu and cpu_running time.
83
84-- Utility function to trim codec trace string: extract the string demilited
85-- by the limiter.
86CREATE OR REPLACE PERFETTO FUNCTION extract_codec_string(slice_name STRING, limiter STRING)
87RETURNS STRING AS
88SELECT CASE
89  -- Delimit with the first occurrence
90  WHEN instr($slice_name, $limiter) > 0
91  THEN substr($slice_name, 1, instr($slice_name, $limiter) - 1)
92  ELSE $slice_name
93END;
94
95-- traits strings from codec framework
96DROP TABLE IF EXISTS trace_trait_table;
97CREATE TABLE trace_trait_table(
98  trace_trait  varchar(100));
99insert into trace_trait_table (trace_trait) values
100  ('MediaCodec'),
101  ('CCodec'),
102  ('C2PooledBlockPool'),
103  ('C2BufferQueueBlockPool'),
104  ('Codec2'),
105  ('ACodec'),
106  ('FrameDecoder');
107
108-- Maps traits to slice strings. Any string with '@' is considered to indicate
109-- the same trace with different information.Hence those strings are delimited
110-- using '@' and considered as part of single trace.
111DROP VIEW IF EXISTS codec_slices;
112CREATE PERFETTO VIEW codec_slices AS
113SELECT
114  DISTINCT extract_codec_string(slice.name, '@') as codec_slice_string
115FROM slice
116JOIN trace_trait_table ON slice.name glob  '*' || trace_trait || '*';
117
118-- combine slice and thread info
119DROP VIEW IF EXISTS slice_with_utid;
120CREATE PERFETTO VIEW slice_with_utid AS
121SELECT
122  extract_codec_string(slice.name, '@') as codec_string,
123  ts,
124  dur,
125  upid,
126  slice.name as slice_name,
127  slice.id as slice_id, utid,
128  thread.name as thread_name
129FROM slice
130JOIN thread_track ON thread_track.id = slice.track_id
131JOIN thread USING (utid);
132
133-- Combine with thread_state info
134DROP TABLE IF EXISTS slice_thread_state_breakdown;
135CREATE VIRTUAL TABLE slice_thread_state_breakdown
136USING SPAN_LEFT_JOIN(
137  slice_with_utid PARTITIONED utid,
138  thread_state PARTITIONED utid
139);
140
141-- Get cpu_running_time for all the slices of interest
142DROP VIEW IF EXISTS slice_cpu_running;
143CREATE PERFETTO VIEW slice_cpu_running AS
144SELECT
145  codec_string,
146  sum(dur) as cpu_time,
147  sum(case when state = 'Running' then dur else 0 end) as cpu_run_ns,
148  thread_name,
149  process.name as process_name,
150  slice_id,
151  slice_name
152FROM slice_thread_state_breakdown
153LEFT JOIN process using(upid)
154where codec_string in (select codec_slice_string from codec_slices)
155GROUP BY codec_string, thread_name, process_name;
156
157
158-- Generate proto for the trace
159DROP VIEW IF EXISTS metrics_per_slice_type;
160CREATE PERFETTO VIEW metrics_per_slice_type AS
161SELECT
162  process_name,
163  codec_string,
164  AndroidCodecMetrics_Detail(
165    'thread_name', thread_name,
166    'total_cpu_ns', CAST(cpu_time as INT64),
167    'running_cpu_ns', CAST(cpu_run_ns as INT64)
168  ) AS proto
169FROM slice_cpu_running;
170
171-- Generating codec framework cpu metric
172DROP VIEW IF EXISTS codec_metrics_output;
173CREATE PERFETTO VIEW codec_metrics_output AS
174SELECT AndroidCodecMetrics(
175  'cpu_usage', (
176    SELECT RepeatedField(
177      AndroidCodecMetrics_CpuUsage(
178        'process_name', process_name,
179        'thread_name', thread_name,
180        'thread_cpu_ns', CAST((cpu_time_ns) as INT64),
181        'num_threads', num_threads,
182        'core_data', core_type_proto_per_thread_name.proto
183      )
184    ) FROM codec_per_process_thread_cpu_use
185      JOIN core_type_proto_per_thread_name using(thread_name)
186  ),
187  'codec_function', (
188    SELECT RepeatedField (
189      AndroidCodecMetrics_CodecFunction(
190        'codec_string', codec_string,
191        'process_name', process_name,
192        'detail', metrics_per_slice_type.proto
193      )
194    ) FROM metrics_per_slice_type
195  )
196);
197