From 4367d9fc2ffff7651f048419734a11a8cd9134b8 Mon Sep 17 00:00:00 2001 From: Pascal Muetschard Date: Fri, 5 Apr 2019 16:47:50 -0700 Subject: [PATCH] Report whether a device supports taking a Perfetto trace. And allow the UI (hidden via a flag) to take a Perfetto trace. --- gapic/src/main/BUILD.bazel | 1 + gapic/src/main/com/google/gapid/Main.java | 2 + .../com/google/gapid/models/Settings.java | 3 ++ .../com/google/gapid/views/TracerDialog.java | 52 +++++++++++++++---- gapis/trace/android/trace.go | 5 +- .../trace/tracer/default_api_trace_options.go | 10 ++++ 6 files changed, 63 insertions(+), 10 deletions(-) diff --git a/gapic/src/main/BUILD.bazel b/gapic/src/main/BUILD.bazel index 4b36f750c4..88063225b9 100644 --- a/gapic/src/main/BUILD.bazel +++ b/gapic/src/main/BUILD.bazel @@ -65,5 +65,6 @@ java_library( "//gapis/service/path:path_java_proto", "//gapis/stringtable:stringtable_java_proto", "//gapis/vertex:vertex_java_proto", + "@perfetto//:config_java_proto", ], ) diff --git a/gapic/src/main/com/google/gapid/Main.java b/gapic/src/main/com/google/gapid/Main.java index b48c0f6bfe..6feb35ba37 100644 --- a/gapic/src/main/com/google/gapid/Main.java +++ b/gapic/src/main/com/google/gapid/Main.java @@ -36,6 +36,7 @@ import com.google.gapid.util.Logging; import com.google.gapid.util.Messages; import com.google.gapid.util.Scheduler; +import com.google.gapid.views.TracerDialog; import com.google.gapid.widgets.Theme; import com.google.gapid.widgets.Widgets; @@ -206,5 +207,6 @@ private static interface ShellRunnable { Logging.logDir, Follower.logFollowRequests, Server.useCache, + TracerDialog.perfettoConfig, }; } diff --git a/gapic/src/main/com/google/gapid/models/Settings.java b/gapic/src/main/com/google/gapid/models/Settings.java index b88cfce53a..7bda50b5a1 100644 --- a/gapic/src/main/com/google/gapid/models/Settings.java +++ b/gapic/src/main/com/google/gapid/models/Settings.java @@ -67,6 +67,7 @@ public class Settings { public int[] shaderSplitterWeights = new int[] { 70, 30 }; public int[] texturesSplitterWeights = new int[] { 20, 80 }; public String traceDevice = ""; + public String traceType = "Graphics"; public String traceApi = ""; public String traceUri = ""; public String traceArguments = ""; @@ -217,6 +218,7 @@ private void updateFrom(Properties properties) { texturesSplitterWeights = getIntList(properties, "texture.splitter.weights", texturesSplitterWeights); traceDevice = properties.getProperty("trace.device", traceDevice); + traceType = properties.getProperty("trace.type", traceType); traceApi = properties.getProperty("trace.api", traceApi); traceUri = properties.getProperty("trace.uri", traceUri); traceArguments = properties.getProperty("trace.arguments", traceArguments); @@ -260,6 +262,7 @@ private void updateTo(Properties properties) { setIntList(properties, "shader.splitter.weights", shaderSplitterWeights); setIntList(properties, "texture.splitter.weights", texturesSplitterWeights); properties.setProperty("trace.device", traceDevice); + properties.setProperty("trace.type", traceType); properties.setProperty("trace.api", traceApi); properties.setProperty("trace.uri", traceUri); properties.setProperty("trace.arguments", traceArguments); diff --git a/gapic/src/main/com/google/gapid/views/TracerDialog.java b/gapic/src/main/com/google/gapid/views/TracerDialog.java index 31c90071c9..c8baa56aba 100644 --- a/gapic/src/main/com/google/gapid/views/TracerDialog.java +++ b/gapic/src/main/com/google/gapid/views/TracerDialog.java @@ -28,6 +28,7 @@ import static com.google.gapid.widgets.Widgets.withLayoutData; import static com.google.gapid.widgets.Widgets.withMargin; import static com.google.gapid.widgets.Widgets.withSpans; +import static java.util.stream.Collectors.toList; import com.google.common.collect.Lists; import com.google.gapid.models.Analytics; @@ -41,10 +42,13 @@ import com.google.gapid.proto.service.Service.ClientAction; import com.google.gapid.proto.service.Service.DeviceTraceConfiguration; import com.google.gapid.proto.service.Service.StatusResponse; +import com.google.gapid.proto.service.Service.TraceType; import com.google.gapid.proto.service.Service.TraceTypeCapabilities; import com.google.gapid.server.Client; import com.google.gapid.server.Tracer; import com.google.gapid.server.Tracer.TraceRequest; +import com.google.gapid.util.Flags; +import com.google.gapid.util.Flags.Flag; import com.google.gapid.util.Messages; import com.google.gapid.util.OS; import com.google.gapid.util.Scheduler; @@ -54,6 +58,7 @@ import com.google.gapid.widgets.LoadingIndicator; import com.google.gapid.widgets.Theme; import com.google.gapid.widgets.Widgets; +import com.google.protobuf.TextFormat; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.viewers.ArrayContentProvider; @@ -80,6 +85,10 @@ import org.eclipse.swt.widgets.Text; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Collections; @@ -95,6 +104,10 @@ public class TracerDialog { protected static final Logger LOG = Logger.getLogger(TracerDialog.class.getName()); + public static final Flag perfettoConfig = Flags.value("perfetto", "", + "Path to a file containing a perfetto trace config proto in text format. " + + "Specifying this flag will enable the Perfetto tracing UI features"); + private TracerDialog() { } @@ -153,6 +166,16 @@ public void onCaptureDevicesLoaded() { } } + protected static void readPerfettoConfig(Service.TraceOptions.Builder options) { + try (Reader in = new InputStreamReader(new FileInputStream(perfettoConfig.get()))) { + TextFormat.merge(in, options.getPerfettoConfigBuilder()); + } catch (IOException e) { + // This is temporary, experimental code, so just sort of crash. + throw new RuntimeException("Failed to read perfetto config from " + perfettoConfig.get(), e); + } + } + + /** * Dialog to request the information from the user to start a trace (which app, filename, etc.). */ @@ -277,7 +300,7 @@ public TraceInput(Composite parent, Models models, Widgets widgets, Runnable ref deviceComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); - createLabel(this, "API:"); + createLabel(this, "Type:"); api = createApiDropDown(this); api.getCombo().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); @@ -490,16 +513,22 @@ private void updateDevicesDropDown(Settings settings) { private void updateApiDropdown(DeviceTraceConfiguration config, Settings settings) { if (api != null && config != null) { - api.setInput(config.getApisList()); - TraceTypeCapabilities deflt = config.getApis(0); - for (TraceTypeCapabilities c : config.getApisList()) { - if (c.getApi().equals(settings.traceApi)) { - deflt = c; - break; + List caps = config.getApisList().stream() + .filter(t -> t.getType() != TraceType.Perfetto || !perfettoConfig.get().isEmpty()) + .collect(toList()); + api.setInput(caps); + if (!caps.isEmpty()) { + TraceTypeCapabilities deflt = caps.get(0); + for (TraceTypeCapabilities c : caps) { + if (c.getType().name().equals(settings.traceType) && + (c.getApi().isEmpty() || c.getApi().equals(settings.traceApi))) { + deflt = c; + break; + } } + api.setSelection(new StructuredSelection(deflt)); + api.getCombo().notifyListeners(SWT.Selection, new Event()); } - api.setSelection(new StructuredSelection(deflt)); - api.getCombo().notifyListeners(SWT.Selection, new Event()); } } @@ -577,6 +606,7 @@ public TraceRequest getTraceRequest(Settings settings) { File output = getOutputFile(); settings.traceDevice = dev.device.getSerial(); + settings.traceType = config.getType().name(); settings.traceApi = config.getApi(); settings.traceUri = traceTarget.getText(); settings.traceArguments = arguments.getText(); @@ -618,6 +648,10 @@ public TraceRequest getTraceRequest(Settings settings) { options.setDisablePcs(disablePcs.getSelection()); } + if (config.getType() == TraceType.Perfetto) { + readPerfettoConfig(options); + } + return new TraceRequest(output, options.build()); } diff --git a/gapis/trace/android/trace.go b/gapis/trace/android/trace.go index 67fc8218d5..b9b220616d 100644 --- a/gapis/trace/android/trace.go +++ b/gapis/trace/android/trace.go @@ -97,13 +97,16 @@ func NewTracer(dev bind.Device) tracer.Tracer { // TraceConfiguration returns the device's supported trace configuration. func (t *androidTracer) TraceConfiguration(ctx context.Context) (*service.DeviceTraceConfiguration, error) { - apis := make([]*service.TraceTypeCapabilities, 0, 2) + apis := make([]*service.TraceTypeCapabilities, 0, 3) if t.b.Instance().GetConfiguration().GetDrivers().GetOpengl().GetVersion() != "" { apis = append(apis, tracer.GLESTraceOptions()) } if len(t.b.Instance().GetConfiguration().GetDrivers().GetVulkan().GetPhysicalDevices()) > 0 { apis = append(apis, tracer.VulkanTraceOptions()) } + if t.b.Instance().GetConfiguration().GetOS().GetAPIVersion() >= 28 { + apis = append(apis, tracer.PerfettoTraceOptions()) + } return &service.DeviceTraceConfiguration{ Apis: apis, diff --git a/gapis/trace/tracer/default_api_trace_options.go b/gapis/trace/tracer/default_api_trace_options.go index 2028144e65..578a797048 100644 --- a/gapis/trace/tracer/default_api_trace_options.go +++ b/gapis/trace/tracer/default_api_trace_options.go @@ -39,3 +39,13 @@ func GLESTraceOptions() *service.TraceTypeCapabilities { CanEnableUnsupportedExtensions: false, } } + +// PerfettoTraceOptions returns the default trace options for Perfetto. +func PerfettoTraceOptions() *service.TraceTypeCapabilities { + return &service.TraceTypeCapabilities{ + Type: service.TraceType_Perfetto, + CanDisablePcs: false, + MidExecutionCaptureSupport: service.FeatureStatus_Supported, + CanEnableUnsupportedExtensions: false, + } +}