aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/GLTraceOptionsDialog.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/GLTraceOptionsDialog.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/GLTraceOptionsDialog.java403
1 files changed, 403 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/GLTraceOptionsDialog.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/GLTraceOptionsDialog.java
new file mode 100644
index 000000000..b4de3d151
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/GLTraceOptionsDialog.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+package com.android.ide.eclipse.gltrace;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.IDevice;
+
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.osgi.service.prefs.BackingStoreException;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/** Dialog displaying all the trace options before the user initiates tracing. */
+public class GLTraceOptionsDialog extends TitleAreaDialog {
+ private static final String TITLE = "OpenGL ES Trace Options";
+ private static final String DEFAULT_MESSAGE = "Provide the application and activity to be traced.";
+
+ private static final String PREF_APP_PACKAGE = "gl.trace.apppackage"; //$NON-NLS-1$
+ private static final String PREF_ACTIVITY = "gl.trace.activity"; //$NON-NLS-1$
+ private static final String PREF_TRACEFILE = "gl.trace.destfile"; //$NON-NLS-1$
+ private static final String PREF_DEVICE = "gl.trace.device"; //$NON-NLS-1$
+ private String mLastUsedDevice;
+
+ private static String sSaveToFolder = System.getProperty("user.home"); //$NON-NLS-1$
+
+ private Button mOkButton;
+
+ private Combo mDeviceCombo;
+ private Text mAppPackageToTraceText;
+ private Text mActivityToTraceText;
+ private Button mIsActivityFullyQualifiedButton;
+ private Text mTraceFilePathText;
+
+ private String mSelectedDevice = "";
+ private String mAppPackageToTrace = "";
+ private String mActivityToTrace = "";
+ private String mTraceFilePath = "";
+ private boolean mAllowAppSelection;
+
+ private static boolean sCollectFbOnEglSwap = true;
+ private static boolean sCollectFbOnGlDraw = false;
+ private static boolean sCollectTextureData = false;
+ private static boolean sIsActivityFullyQualified = false;
+ private IDevice[] mDevices;
+
+ public GLTraceOptionsDialog(Shell parentShell) {
+ this(parentShell, true, null);
+ }
+
+ /**
+ * Constructs a dialog displaying options for the tracer.
+ * @param allowAppSelection true if user can change the application to trace
+ * @param appToTrace default application package to trace
+ */
+ public GLTraceOptionsDialog(Shell parentShell, boolean allowAppSelection,
+ String appToTrace) {
+ super(parentShell);
+ loadPreferences();
+
+ mAllowAppSelection = allowAppSelection;
+ if (appToTrace != null) {
+ mAppPackageToTrace = appToTrace;
+ }
+ }
+
+ @Override
+ protected Control createDialogArea(Composite shell) {
+ setTitle(TITLE);
+ setMessage(DEFAULT_MESSAGE);
+
+ Composite parent = (Composite) super.createDialogArea(shell);
+ Composite c = new Composite(parent, SWT.BORDER);
+ c.setLayout(new GridLayout(2, false));
+ c.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ createLabel(c, "Device:");
+ mDevices = AndroidDebugBridge.getBridge().getDevices();
+ createDeviceDropdown(c, mDevices);
+
+ createSeparator(c);
+
+ createLabel(c, "Application Package:");
+ createAppToTraceText(c, "e.g. com.example.package");
+
+ createLabel(c, "Activity to launch:");
+ createActivityToTraceText(c, "Leave blank to launch default activity");
+
+ createLabel(c, "");
+ createIsFullyQualifedActivityButton(c,
+ "Activity name is fully qualified, do not prefix with package name");
+
+ if (!mAllowAppSelection) {
+ mAppPackageToTraceText.setEnabled(false);
+ mActivityToTraceText.setEnabled(false);
+ mIsActivityFullyQualifiedButton.setEnabled(false);
+ }
+
+ createSeparator(c);
+
+ createLabel(c, "Data Collection Options:");
+ createCaptureImageOptions(c);
+
+ createSeparator(c);
+
+ createLabel(c, "Destination File: ");
+ createSaveToField(c);
+
+ return c;
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ super.createButtonsForButtonBar(parent);
+
+ mOkButton = getButton(IDialogConstants.OK_ID);
+ mOkButton.setText("Trace");
+
+ DialogStatus status = validateDialog();
+ mOkButton.setEnabled(status.valid);
+ }
+
+ private void createSeparator(Composite c) {
+ Label l = new Label(c, SWT.SEPARATOR | SWT.HORIZONTAL);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = 2;
+ l.setLayoutData(gd);
+ }
+
+ private void createSaveToField(Composite parent) {
+ Composite c = new Composite(parent, SWT.NONE);
+ c.setLayout(new GridLayout(2, false));
+ c.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ mTraceFilePathText = new Text(c, SWT.BORDER);
+ mTraceFilePathText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ mTraceFilePathText.setText(mTraceFilePath);
+ mTraceFilePathText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ validateAndSetMessage();
+ }
+ });
+
+ Button browse = new Button(c, SWT.PUSH);
+ browse.setText("Browse...");
+ browse.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ String fName = openBrowseDialog();
+ if (fName == null) {
+ return;
+ }
+
+ mTraceFilePathText.setText(fName);
+ validateAndSetMessage();
+ }
+ });
+ }
+
+ private String openBrowseDialog() {
+ FileDialog fd = new FileDialog(Display.getDefault().getActiveShell(), SWT.SAVE);
+
+ fd.setText("Save To");
+ fd.setFileName("trace1.gltrace");
+
+ fd.setFilterPath(sSaveToFolder);
+ fd.setFilterExtensions(new String[] { "*.gltrace" });
+
+ String fname = fd.open();
+ if (fname == null || fname.trim().length() == 0) {
+ return null;
+ }
+
+ sSaveToFolder = fd.getFilterPath();
+ return fname;
+ }
+
+ /** Options controlling when the FB should be captured. */
+ private void createCaptureImageOptions(Composite parent) {
+ Composite c = new Composite(parent, SWT.NONE);
+ c.setLayout(new GridLayout(1, false));
+ c.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ final Button readFbOnEglSwapCheckBox = new Button(c, SWT.CHECK);
+ readFbOnEglSwapCheckBox.setText("Read back framebuffer 0 on eglSwapBuffers()");
+ readFbOnEglSwapCheckBox.setSelection(sCollectFbOnEglSwap);
+
+ final Button readFbOnGlDrawCheckBox = new Button(c, SWT.CHECK);
+ readFbOnGlDrawCheckBox.setText("Read back currently bound framebuffer On glDraw*()");
+ readFbOnGlDrawCheckBox.setSelection(sCollectFbOnGlDraw);
+
+ final Button readTextureDataCheckBox = new Button(c, SWT.CHECK);
+ readTextureDataCheckBox.setText("Collect texture data submitted using glTexImage*()");
+ readTextureDataCheckBox.setSelection(sCollectTextureData);
+
+ SelectionListener l = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ sCollectFbOnEglSwap = readFbOnEglSwapCheckBox.getSelection();
+ sCollectFbOnGlDraw = readFbOnGlDrawCheckBox.getSelection();
+ sCollectTextureData = readTextureDataCheckBox.getSelection();
+ }
+ };
+
+ readFbOnEglSwapCheckBox.addSelectionListener(l);
+ readFbOnGlDrawCheckBox.addSelectionListener(l);
+ readTextureDataCheckBox.addSelectionListener(l);
+ }
+
+ private Text createAppToTraceText(Composite parent, String defaultMessage) {
+ mAppPackageToTraceText = new Text(parent, SWT.BORDER);
+ mAppPackageToTraceText.setMessage(defaultMessage);
+ mAppPackageToTraceText.setText(mAppPackageToTrace);
+
+ mAppPackageToTraceText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ mAppPackageToTraceText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ validateAndSetMessage();
+ }
+ });
+
+ return mActivityToTraceText;
+ }
+
+ private Text createActivityToTraceText(Composite parent, String defaultMessage) {
+ mActivityToTraceText = new Text(parent, SWT.BORDER);
+ mActivityToTraceText.setMessage(defaultMessage);
+ mActivityToTraceText.setText(mActivityToTrace);
+
+ mActivityToTraceText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ mActivityToTraceText.addModifyListener(new ModifyListener() {
+ @Override
+ public void modifyText(ModifyEvent e) {
+ validateAndSetMessage();
+ }
+ });
+
+ return mActivityToTraceText;
+ }
+
+ private Button createIsFullyQualifedActivityButton(Composite parent, String message) {
+ mIsActivityFullyQualifiedButton = new Button(parent, SWT.CHECK);
+ mIsActivityFullyQualifiedButton.setText(message);
+ mIsActivityFullyQualifiedButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ mIsActivityFullyQualifiedButton.setSelection(sIsActivityFullyQualified);
+
+ return mIsActivityFullyQualifiedButton;
+ }
+
+ private void validateAndSetMessage() {
+ DialogStatus status = validateDialog();
+ mOkButton.setEnabled(status.valid);
+ setErrorMessage(status.message);
+ }
+
+ private Combo createDeviceDropdown(Composite parent, IDevice[] devices) {
+ mDeviceCombo = new Combo(parent, SWT.READ_ONLY | SWT.BORDER);
+
+ List<String> items = new ArrayList<String>(devices.length);
+ for (IDevice d : devices) {
+ items.add(d.getName());
+ }
+ mDeviceCombo.setItems(items.toArray(new String[items.size()]));
+
+ int index = 0;
+ if (items.contains(mLastUsedDevice)) {
+ index = items.indexOf(mLastUsedDevice);
+ }
+ if (index >= 0 && index < items.size()) {
+ mDeviceCombo.select(index);
+ }
+ return mDeviceCombo;
+ }
+
+ private void createLabel(Composite parent, String text) {
+ Label l = new Label(parent, SWT.NONE);
+ l.setText(text);
+ GridData gd = new GridData();
+ gd.horizontalAlignment = SWT.RIGHT;
+ gd.verticalAlignment = SWT.CENTER;
+ l.setLayoutData(gd);
+ }
+
+ /**
+ * A tuple that specifies whether the current state of the inputs
+ * on the dialog is valid or not. If it is not valid, the message
+ * field stores the reason why it isn't.
+ */
+ private final class DialogStatus {
+ final boolean valid;
+ final String message;
+
+ private DialogStatus(boolean isValid, String errMessage) {
+ valid = isValid;
+ message = errMessage;
+ }
+ }
+
+ private DialogStatus validateDialog() {
+ if (mDevices.length == 0) {
+ return new DialogStatus(false, "No connected devices.");
+ }
+
+ if (mAppPackageToTraceText.getText().trim().isEmpty()) {
+ return new DialogStatus(false, "Provide an application name");
+ }
+
+ String traceFile = mTraceFilePathText.getText().trim();
+ if (traceFile.isEmpty()) {
+ return new DialogStatus(false, "Specify the location where the trace will be saved.");
+ }
+
+ File f = new File(traceFile).getParentFile();
+ if (f != null && !f.exists()) {
+ return new DialogStatus(false,
+ String.format("Folder %s does not exist", f.getAbsolutePath()));
+ }
+
+ return new DialogStatus(true, null);
+ }
+
+ @Override
+ protected void okPressed() {
+ mAppPackageToTrace = mAppPackageToTraceText.getText().trim();
+ mActivityToTrace = mActivityToTraceText.getText().trim();
+ if (mActivityToTrace.startsWith(".")) { //$NON-NLS-1$
+ mActivityToTrace = mActivityToTrace.substring(1);
+ }
+ sIsActivityFullyQualified = mIsActivityFullyQualifiedButton.getSelection();
+ mTraceFilePath = mTraceFilePathText.getText().trim();
+ mSelectedDevice = mDeviceCombo.getText();
+
+ savePreferences();
+
+ super.okPressed();
+ }
+
+ private void savePreferences() {
+ IEclipsePreferences prefs = new InstanceScope().getNode(GlTracePlugin.PLUGIN_ID);
+ prefs.put(PREF_APP_PACKAGE, mAppPackageToTrace);
+ prefs.put(PREF_ACTIVITY, mActivityToTrace);
+ prefs.put(PREF_TRACEFILE, mTraceFilePath);
+ prefs.put(PREF_DEVICE, mSelectedDevice);
+ try {
+ prefs.flush();
+ } catch (BackingStoreException e) {
+ // ignore issues while persisting preferences
+ }
+ }
+
+ private void loadPreferences() {
+ IEclipsePreferences prefs = new InstanceScope().getNode(GlTracePlugin.PLUGIN_ID);
+ mAppPackageToTrace = prefs.get(PREF_APP_PACKAGE, "");
+ mActivityToTrace = prefs.get(PREF_ACTIVITY, "");
+ mTraceFilePath = prefs.get(PREF_TRACEFILE, "");
+ mLastUsedDevice = prefs.get(PREF_DEVICE, "");
+ }
+
+ public TraceOptions getTraceOptions() {
+ return new TraceOptions(mSelectedDevice, mAppPackageToTrace, mActivityToTrace,
+ sIsActivityFullyQualified, mTraceFilePath, sCollectFbOnEglSwap,
+ sCollectFbOnGlDraw, sCollectTextureData);
+ }
+}