Update surfaceflinger worklload proto to include skia pipelines

Skia pipelines correspond to shaders used as part of a compositing
workload.

Also, update the corresponding SQL tables. Because many pipelines can be
used in a single workload, use a flattened SQL table
diff --git a/protos/perfetto/trace/android/android_track_event.proto b/protos/perfetto/trace/android/android_track_event.proto
index e6d34cf..e833b75 100644
--- a/protos/perfetto/trace/android/android_track_event.proto
+++ b/protos/perfetto/trace/android/android_track_event.proto
@@ -210,10 +210,29 @@
       optional int32 gpu_composited_layers = 1;
       // Number of layers that needed to be composited via the DPU.
       optional int32 dpu_composited_layers = 2;
+      // List of skia pipelines that were used in this workload.
+      message Pipeline {
+        // Key that identifies the shader
+        optional string shader_key = 1;
+        // Operation that the caching pipeline used
+        enum CachingOp {
+          // Unknown operation
+          UNKNOWN = 0;
+          // Cache miss
+          ADDED = 1;
+          // Cache hit
+          FOUND = 2;
+        }
+        optional CachingOp caching_op = 2;
+      }
+      repeated Pipeline skia_pipelines = 3;
     }
     optional Stats stats = 2;
   }
   optional Summary summary = 4;
+
+  // Unique identifier for the workload, for joining with other events.
+  optional int64 workload_id = 5;
 }
 
 enum ReceiverType {
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/surfaceflinger.sql b/src/trace_processor/perfetto_sql/stdlib/android/surfaceflinger.sql
index b1aea6f..77fa686 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/surfaceflinger.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/surfaceflinger.sql
@@ -222,6 +222,8 @@
 
 -- Workloads that are submitted to SurfaceFlinger to do compositing work
 CREATE PERFETTO TABLE android_surfaceflinger_workloads (
+  -- Identifier for the workload, for joining with other tables
+  workload_id LONG,
   -- Timestamp of the workload
   ts TIMESTAMP,
   -- Source of the workload
@@ -256,6 +258,7 @@
   dpu_composited_layers LONG
 ) AS
 SELECT
+  extract_arg(arg_set_id, 'surfaceflinger_workload.workload_id') AS workload_id,
   ts,
   extract_arg(arg_set_id, 'surfaceflinger_workload.source') AS source,
   extract_arg(arg_set_id, 'surfaceflinger_workload.output_name') AS output_name,
@@ -278,3 +281,36 @@
 FROM slice
 WHERE
   category = 'rendering' AND name = 'WorkloadSummary';
+
+-- Skia pipelines used in SurfaceFlinger workloads.
+-- As there can be many skia pipelines used in a workload, this table is flattened.
+CREATE PERFETTO TABLE android_surfaceflinger_workload_pipelines (
+  -- Identifier for the workload, matches android_surfaceflinger_workloads.workload_id
+  workload_id JOINID(android_surfaceflinger_workloads.workload_id),
+  -- Key that identifies the shader
+  shader_key STRING,
+  -- Operation that the caching pipeline used
+  caching_op STRING
+) AS
+SELECT
+  extract_arg(s.arg_set_id, 'surfaceflinger_workload.workload_id') AS workload_id,
+  extract_arg(
+    s.arg_set_id,
+    'surfaceflinger_workload.summary.stats.skia_pipelines[' || i.value || '].shader_key'
+  ) AS shader_key,
+  extract_arg(
+    s.arg_set_id,
+    'surfaceflinger_workload.summary.stats.skia_pipelines[' || i.value || '].caching_op'
+  ) AS caching_op
+FROM slice AS s
+JOIN (
+  SELECT
+    arg_set_id,
+    cast_int!(str_split(str_split(key, '[', 1), ']', 0)) AS value
+  FROM args
+  WHERE
+    key GLOB 'surfaceflinger_workload.summary.stats.skia_pipelines[[]*[]].shader_key'
+) AS i
+  ON s.arg_set_id = i.arg_set_id
+WHERE
+  s.category = 'rendering' AND s.name = 'WorkloadSummary';