metrics: add g2d metrics
Add metrics to calculate g2d hw and sw execution time.
Bug: 178088675
Test: tools/diff_test_trace_processor.py <trace_processor_shell> \
--trace-filter='g2d_metrics'
Test: <trace_processor_shell> --run-metrics g2d \
<perfetto trace>
Change-Id: I0ae1f2d723d7342b1148b1362991340f385b76bd
diff --git a/Android.bp b/Android.bp
index 9c7df36..24dfc02 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3604,6 +3604,7 @@
"protos/perfetto/metrics/android/batt_metric.proto",
"protos/perfetto/metrics/android/cpu_metric.proto",
"protos/perfetto/metrics/android/display_metrics.proto",
+ "protos/perfetto/metrics/android/g2d_metric.proto",
"protos/perfetto/metrics/android/gpu_metric.proto",
"protos/perfetto/metrics/android/heap_profile_callsites.proto",
"protos/perfetto/metrics/android/hwcomposer.proto",
@@ -3648,6 +3649,7 @@
"protos/perfetto/metrics/android/batt_metric.proto",
"protos/perfetto/metrics/android/cpu_metric.proto",
"protos/perfetto/metrics/android/display_metrics.proto",
+ "protos/perfetto/metrics/android/g2d_metric.proto",
"protos/perfetto/metrics/android/gpu_metric.proto",
"protos/perfetto/metrics/android/heap_profile_callsites.proto",
"protos/perfetto/metrics/android/hwcomposer.proto",
@@ -7607,6 +7609,8 @@
"src/trace_processor/metrics/android/cpu_info.sql",
"src/trace_processor/metrics/android/display_metrics.sql",
"src/trace_processor/metrics/android/frame_missed.sql",
+ "src/trace_processor/metrics/android/g2d.sql",
+ "src/trace_processor/metrics/android/g2d_duration.sql",
"src/trace_processor/metrics/android/global_counter_span_view.sql",
"src/trace_processor/metrics/android/heap_profile_callsites.sql",
"src/trace_processor/metrics/android/hsc_startups.sql",
diff --git a/BUILD b/BUILD
index 35e71df..b1cf949 100644
--- a/BUILD
+++ b/BUILD
@@ -913,6 +913,8 @@
"src/trace_processor/metrics/android/cpu_info.sql",
"src/trace_processor/metrics/android/display_metrics.sql",
"src/trace_processor/metrics/android/frame_missed.sql",
+ "src/trace_processor/metrics/android/g2d.sql",
+ "src/trace_processor/metrics/android/g2d_duration.sql",
"src/trace_processor/metrics/android/global_counter_span_view.sql",
"src/trace_processor/metrics/android/heap_profile_callsites.sql",
"src/trace_processor/metrics/android/hsc_startups.sql",
@@ -2302,6 +2304,7 @@
"protos/perfetto/metrics/android/batt_metric.proto",
"protos/perfetto/metrics/android/cpu_metric.proto",
"protos/perfetto/metrics/android/display_metrics.proto",
+ "protos/perfetto/metrics/android/g2d_metric.proto",
"protos/perfetto/metrics/android/gpu_metric.proto",
"protos/perfetto/metrics/android/heap_profile_callsites.proto",
"protos/perfetto/metrics/android/hwcomposer.proto",
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index ce5a28a..14ed487 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -23,6 +23,7 @@
"batt_metric.proto",
"cpu_metric.proto",
"display_metrics.proto",
+ "g2d_metric.proto",
"gpu_metric.proto",
"heap_profile_callsites.proto",
"hwcomposer.proto",
diff --git a/protos/perfetto/metrics/android/g2d_metric.proto b/protos/perfetto/metrics/android/g2d_metric.proto
new file mode 100644
index 0000000..e7a2d6a
--- /dev/null
+++ b/protos/perfetto/metrics/android/g2d_metric.proto
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 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
+ *
+ * http://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.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+message G2dMetrics {
+ message G2dInstance {
+ // G2d name.
+ optional string name = 1;
+
+ optional int64 max_dur_ns = 2;
+ optional int64 min_dur_ns = 3;
+ optional int64 avg_dur_ns = 4;
+ optional uint32 frame_count = 5;
+ optional uint32 error_count = 6;
+ }
+ message G2dMetric {
+ // G2D Metric for each G2D Instance.
+ repeated G2dInstance instances = 1;
+
+ // max/min/avg G2d frame durations for all instances.
+ optional int64 max_dur_ns = 2;
+ optional int64 min_dur_ns = 3;
+ optional int64 avg_dur_ns = 4;
+
+ // the number of frames processed by G2D
+ optional uint32 frame_count = 5;
+ // the number of error events
+ optional uint32 error_count = 6;
+ }
+
+ optional G2dMetric g2d_hw = 1;
+ optional G2dMetric g2d_sw = 2;
+}
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index a1b6e19..ba6972e 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -21,6 +21,7 @@
import "protos/perfetto/metrics/android/batt_metric.proto";
import "protos/perfetto/metrics/android/cpu_metric.proto";
import "protos/perfetto/metrics/android/display_metrics.proto";
+import "protos/perfetto/metrics/android/g2d_metric.proto";
import "protos/perfetto/metrics/android/gpu_metric.proto";
import "protos/perfetto/metrics/android/heap_profile_callsites.proto";
import "protos/perfetto/metrics/android/hwcomposer.proto";
@@ -57,7 +58,7 @@
// Root message for all Perfetto-based metrics.
//
-// Next id: 29
+// Next id: 31
message TraceMetrics {
reserved 4, 10, 13, 14, 19;
@@ -132,6 +133,9 @@
// Detects common bad patterns that might lead to jank.
optional AndroidJankMetrics android_jank = 29;
+ // G2D metrics.
+ optional G2dMetrics g2d = 30;
+
// Demo extensions.
extensions 450 to 499;
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index 8c5f037..c6a3694 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -137,6 +137,40 @@
// End of protos/perfetto/metrics/android/display_metrics.proto
+// Begin of protos/perfetto/metrics/android/g2d_metric.proto
+
+message G2dMetrics {
+ message G2dInstance {
+ // G2d name.
+ optional string name = 1;
+
+ optional int64 max_dur_ns = 2;
+ optional int64 min_dur_ns = 3;
+ optional int64 avg_dur_ns = 4;
+ optional uint32 frame_count = 5;
+ optional uint32 error_count = 6;
+ }
+ message G2dMetric {
+ // G2D Metric for each G2D Instance.
+ repeated G2dInstance instances = 1;
+
+ // max/min/avg G2d frame durations for all instances.
+ optional int64 max_dur_ns = 2;
+ optional int64 min_dur_ns = 3;
+ optional int64 avg_dur_ns = 4;
+
+ // the number of frames processed by G2D
+ optional uint32 frame_count = 5;
+ // the number of error events
+ optional uint32 error_count = 6;
+ }
+
+ optional G2dMetric g2d_hw = 1;
+ optional G2dMetric g2d_sw = 2;
+}
+
+// End of protos/perfetto/metrics/android/g2d_metric.proto
+
// Begin of protos/perfetto/metrics/android/gpu_metric.proto
message AndroidGpuMetric {
@@ -856,7 +890,7 @@
// Root message for all Perfetto-based metrics.
//
-// Next id: 29
+// Next id: 31
message TraceMetrics {
reserved 4, 10, 13, 14, 19;
@@ -931,6 +965,9 @@
// Detects common bad patterns that might lead to jank.
optional AndroidJankMetrics android_jank = 29;
+ // G2D metrics.
+ optional G2dMetrics g2d = 30;
+
// Demo extensions.
extensions 450 to 499;
diff --git a/src/trace_processor/metrics/BUILD.gn b/src/trace_processor/metrics/BUILD.gn
index fcd4244..d4d68dc 100644
--- a/src/trace_processor/metrics/BUILD.gn
+++ b/src/trace_processor/metrics/BUILD.gn
@@ -42,6 +42,8 @@
"android/android_thread_time_in_state.sql",
"android/cpu_info.sql",
"android/display_metrics.sql",
+ "android/g2d.sql",
+ "android/g2d_duration.sql",
"android/heap_profile_callsites.sql",
"android/hsc_startups.sql",
"android/android_hwcomposer.sql",
diff --git a/src/trace_processor/metrics/android/g2d.sql b/src/trace_processor/metrics/android/g2d.sql
new file mode 100644
index 0000000..5e474b7
--- /dev/null
+++ b/src/trace_processor/metrics/android/g2d.sql
@@ -0,0 +1,34 @@
+--
+-- 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.
+
+
+SELECT RUN_METRIC(
+ 'android/g2d_duration.sql',
+ 'g2d_type', 'sw',
+ 'output_table', 'g2d_sw_duration_metric'
+);
+
+SELECT RUN_METRIC(
+ 'android/g2d_duration.sql',
+ 'g2d_type', 'hw',
+ 'output_table', 'g2d_hw_duration_metric'
+);
+
+DROP VIEW IF EXISTS g2d_output;
+CREATE VIEW g2d_output AS
+SELECT G2dMetrics(
+ 'g2d_hw', (SELECT metric FROM g2d_hw_duration_metric),
+ 'g2d_sw', (SELECT metric FROM g2d_sw_duration_metric)
+);
diff --git a/src/trace_processor/metrics/android/g2d_duration.sql b/src/trace_processor/metrics/android/g2d_duration.sql
new file mode 100644
index 0000000..7d96d06
--- /dev/null
+++ b/src/trace_processor/metrics/android/g2d_duration.sql
@@ -0,0 +1,68 @@
+--
+-- 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 raw_g2d_{{g2d_type}}_spans;
+CREATE VIEW raw_g2d_{{g2d_type}}_spans AS
+SELECT
+ ts,
+ t.name AS track_name,
+ LEAD(ts, 1, 0) OVER (PARTITION BY name ORDER BY ts) - ts AS dur,
+ LAG(value, 1, -1) OVER (PARTITION BY name ORDER BY ts) AS prev_g2d_value,
+ value AS g2d_value,
+ LEAD(value, 1, -1) OVER (PARTITION BY name ORDER BY ts) AS next_g2d_value
+FROM counter c JOIN thread_counter_track t ON t.id = c.track_id
+WHERE t.name LIKE 'g2d_frame_{{g2d_type}}%';
+
+
+DROP VIEW IF EXISTS g2d_{{g2d_type}}_spans;
+CREATE VIEW g2d_{{g2d_type}}_spans AS
+SELECT ts, track_name, dur
+FROM raw_g2d_{{g2d_type}}_spans
+WHERE g2d_value = 1 AND next_g2d_value = 0;
+
+
+DROP VIEW IF EXISTS g2d_{{g2d_type}}_errors;
+CREATE VIEW g2d_{{g2d_type}}_errors AS
+SELECT ts, track_name, g2d_value
+FROM raw_g2d_{{g2d_type}}_spans
+WHERE (g2d_value = 1 AND next_g2d_value = 1) OR (prev_g2d_value = 0 AND g2d_value = 0);
+
+
+DROP VIEW IF EXISTS g2d_{{g2d_type}}_instances;
+CREATE VIEW g2d_{{g2d_type}}_instances AS
+SELECT
+ G2dMetrics_G2dInstance(
+ 'name', g.track_name,
+ 'max_dur_ns', CAST(MAX(g.dur) AS INT64),
+ 'min_dur_ns', CAST(MIN(g.dur) AS INT64),
+ 'avg_dur_ns', CAST(AVG(g.dur) AS INT64),
+ 'frame_count', COUNT(*),
+ 'error_count', (SELECT COUNT(*) FROM g2d_{{g2d_type}}_errors e WHERE e.track_name = g.track_name)
+ ) AS instance
+FROM g2d_{{g2d_type}}_spans g GROUP BY g.track_name;
+
+
+DROP VIEW IF EXISTS {{output_table}};
+CREATE VIEW {{output_table}} AS
+SELECT
+ G2dMetrics_G2dMetric(
+ 'instances', (SELECT RepeatedField(instance) FROM g2d_{{g2d_type}}_instances),
+ 'max_dur_ns', CAST(MAX(dur) AS INT64),
+ 'min_dur_ns', CAST(MIN(dur) AS INT64),
+ 'avg_dur_ns', CAST(AVG(dur) AS INT64),
+ 'frame_count', COUNT(*),
+ 'error_count', (SELECT COUNT(*) FROM g2d_{{g2d_type}}_errors)
+ ) AS metric
+FROM g2d_{{g2d_type}}_spans;
diff --git a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
index 128dd8c..222cf60 100644
--- a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
+++ b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor
Binary files differ
diff --git a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor.sha1 b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor.sha1
index e87349c..d8d964c 100644
--- a/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor.sha1
+++ b/src/trace_processor/python/perfetto/trace_processor/metrics.descriptor.sha1
@@ -2,4 +2,4 @@
// SHA1(tools/gen_binary_descriptors)
// d50111afcc6af211b5bcd8a6935780af8fc96d9d
// SHA1(protos/perfetto/metrics/metrics.proto)
-// dc5f60a304848e44572924b88f4b1493c8e99588
+// b1c108f54258a70d1dc0d4a7499ad211d2021002
diff --git a/test/trace_processor/graphics/g2d_metrics.out b/test/trace_processor/graphics/g2d_metrics.out
new file mode 100644
index 0000000..a28e4fd
--- /dev/null
+++ b/test/trace_processor/graphics/g2d_metrics.out
@@ -0,0 +1,40 @@
+g2d {
+ g2d_hw {
+ instances {
+ name: "g2d_frame_hw#10"
+ max_dur_ns: 20
+ min_dur_ns: 20
+ avg_dur_ns: 20
+ frame_count: 1
+ error_count: 0
+ }
+ max_dur_ns: 20
+ min_dur_ns: 20
+ avg_dur_ns: 20
+ frame_count: 1
+ error_count: 0
+ }
+ g2d_sw {
+ instances {
+ name: "g2d_frame_sw#10"
+ max_dur_ns: 40
+ min_dur_ns: 20
+ avg_dur_ns: 30
+ frame_count: 2
+ error_count: 0
+ }
+ instances {
+ name: "g2d_frame_sw#11"
+ max_dur_ns: 40
+ min_dur_ns: 40
+ avg_dur_ns: 40
+ frame_count: 1
+ error_count: 2
+ }
+ max_dur_ns: 40
+ min_dur_ns: 20
+ avg_dur_ns: 33
+ frame_count: 3
+ error_count: 2
+ }
+}
diff --git a/test/trace_processor/graphics/g2d_metrics.textproto b/test/trace_processor/graphics/g2d_metrics.textproto
new file mode 100644
index 0000000..9ed87bf
--- /dev/null
+++ b/test/trace_processor/graphics/g2d_metrics.textproto
@@ -0,0 +1,127 @@
+packet {
+ ftrace_events {
+ cpu: 2
+ event {
+ timestamp: 1000
+ pid: 237
+ g2d_tracing_mark_write {
+ pid: 237
+ name: "g2d_frame_sw#11"
+ type: 67
+ value: 0
+ }
+ }
+ event {
+ timestamp: 1003
+ pid: 237
+ g2d_tracing_mark_write {
+ pid: 237
+ name: "g2d_frame_sw#11"
+ type: 67
+ value: 0
+ }
+ }
+ event {
+ timestamp: 1005
+ pid: 237
+ g2d_tracing_mark_write {
+ pid: 237
+ name: "g2d_frame_sw#11"
+ type: 67
+ value: 1
+ }
+ }
+ event {
+ timestamp: 1010
+ pid: 237
+ g2d_tracing_mark_write {
+ pid: 237
+ name: "g2d_frame_sw#10"
+ type: 67
+ value: 1
+ }
+ }
+ event {
+ timestamp: 1020
+ pid: 237
+ g2d_tracing_mark_write {
+ pid: 237
+ name: "g2d_frame_sw#11"
+ type: 67
+ value: 1
+ }
+ }
+ event {
+ timestamp: 1030
+ pid: 237
+ g2d_tracing_mark_write {
+ pid: 237
+ name: "g2d_frame_sw#10"
+ type: 67
+ value: 0
+ }
+ }
+ event {
+ timestamp: 1040
+ pid: 237
+ g2d_tracing_mark_write {
+ pid: 237
+ name: "g2d_frame_sw#10"
+ type: 67
+ value: 1
+ }
+ }
+ event {
+ timestamp: 1050
+ pid: 237
+ g2d_tracing_mark_write {
+ pid: 237
+ name: "g2d_frame_hw#10"
+ type: 67
+ value: 1
+ }
+ }
+ event {
+ timestamp: 1060
+ pid: 237
+ g2d_tracing_mark_write {
+ pid: 237
+ name: "g2d_frame_sw#11"
+ type: 67
+ value: 0
+ }
+ }
+ event {
+ timestamp: 1070
+ pid: 237
+ g2d_tracing_mark_write {
+ pid: 237
+ name: "g2d_frame_hw#10"
+ type: 67
+ value: 0
+ }
+ }
+ event {
+ timestamp: 1080
+ pid: 237
+ g2d_tracing_mark_write {
+ pid: 237
+ name: "g2d_frame_sw#10"
+ type: 67
+ value: 0
+ }
+ }
+ event {
+ timestamp: 1085
+ pid: 237
+ g2d_tracing_mark_write {
+ pid: 237
+ name: "g2d_frame_sw#11"
+ type: 67
+ value: 1
+ }
+ }
+ }
+ trusted_uid: 9999
+ trusted_packet_sequence_id: 3
+}
\ No newline at end of file
diff --git a/test/trace_processor/graphics/index b/test/trace_processor/graphics/index
index 01edbd3..6c6d8d4 100644
--- a/test/trace_processor/graphics/index
+++ b/test/trace_processor/graphics/index
@@ -36,3 +36,6 @@
# Android Jank metrics
android_jank.py android_jank android_jank.out
+
+# G2D metrics
+g2d_metrics.textproto g2d g2d_metrics.out