blob: 56dc8e9ac38d537610c85ea0a9ae363f9d48b344 [file] [log] [blame]
/*
* 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 org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.SWT;
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.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
import java.io.IOException;
import java.text.DecimalFormat;
/** Dialog displayed while the trace is being streamed from device to host. */
public class GLTraceCollectorDialog extends TitleAreaDialog {
private static final String TITLE = "OpenGL ES Trace";
private static final String DEFAULT_MESSAGE = "Trace collection in progress.";
private static final DecimalFormat SIZE_FORMATTER = new DecimalFormat("#.##"); //$NON-NLS-1$
private TraceOptions mTraceOptions;
private final TraceFileWriter mTraceFileWriter;
private final TraceCommandWriter mTraceCommandWriter;
private Label mFramesCollectedLabel;
private Label mTraceFileSizeLabel;
private StatusRefreshTask mRefreshTask;
protected GLTraceCollectorDialog(Shell parentShell, TraceFileWriter traceFileWriter,
TraceCommandWriter traceCommandWriter, TraceOptions traceOptions) {
super(parentShell);
mTraceFileWriter = traceFileWriter;
mTraceCommandWriter = traceCommandWriter;
mTraceOptions = traceOptions;
}
@Override
protected Control createButtonBar(Composite parent) {
Composite c = new Composite(parent, SWT.NONE);
c.setLayout(new GridLayout(0, false));
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalAlignment = GridData.CENTER;
c.setLayoutData(gd);
createButton(c, IDialogConstants.OK_ID, "Stop Tracing", true);
return c;
}
@Override
protected Control createDialogArea(Composite parent) {
parent.setLayout(new GridLayout());
setTitle(TITLE);
setMessage(DEFAULT_MESSAGE);
Group controlGroup = new Group(parent, SWT.BORDER);
controlGroup.setLayout(new GridLayout(2, false));
controlGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
controlGroup.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE));
controlGroup.setText("Trace Options");
createLabel(controlGroup, "Collect Framebuffer contents on eglSwapBuffers()");
final Button eglSwapCheckBox = createButton(controlGroup,
mTraceOptions.collectFbOnEglSwap);
createLabel(controlGroup, "Collect Framebuffer contents on glDraw*()");
final Button glDrawCheckBox = createButton(controlGroup, mTraceOptions.collectFbOnGlDraw);
createLabel(controlGroup, "Collect texture data for glTexImage*()");
final Button glTexImageCheckBox = createButton(controlGroup,
mTraceOptions.collectTextureData);
SelectionListener l = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
boolean eglSwap = eglSwapCheckBox.getSelection();
boolean glDraw = glDrawCheckBox.getSelection();
boolean glTexImage = glTexImageCheckBox.getSelection();
try {
mTraceCommandWriter.setTraceOptions(eglSwap, glDraw, glTexImage);
} catch (IOException e) {
eglSwapCheckBox.setEnabled(false);
glDrawCheckBox.setEnabled(false);
glTexImageCheckBox.setEnabled(false);
MessageDialog.openError(Display.getDefault().getActiveShell(),
"OpenGL ES Trace",
"Error while setting trace options: " + e.getMessage());
}
// update the text on the button
if (!(event.getSource() instanceof Button)) {
return;
}
Button sourceButton = (Button) event.getSource();
sourceButton.setText(getToggleActionText(sourceButton.getSelection()));
sourceButton.pack();
}
};
eglSwapCheckBox.addSelectionListener(l);
glDrawCheckBox.addSelectionListener(l);
glTexImageCheckBox.addSelectionListener(l);
Group statusGroup = new Group(parent, SWT.NONE);
statusGroup.setLayout(new GridLayout(2, false));
statusGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
statusGroup.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE));
statusGroup.setText("Trace Status");
createLabel(statusGroup, "Frames Collected:");
mFramesCollectedLabel = createLabel(statusGroup, "");
createLabel(statusGroup, "Trace File Size:");
mTraceFileSizeLabel = createLabel(statusGroup, "");
ProgressBar pb = new ProgressBar(statusGroup, SWT.INDETERMINATE);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 2;
pb.setLayoutData(gd);
mRefreshTask = new StatusRefreshTask();
new Thread(mRefreshTask, "Trace Status Refresh Thread").start();
return super.createDialogArea(parent);
}
private Button createButton(Composite controlComposite, boolean selection) {
Button b = new Button(controlComposite, SWT.TOGGLE);
b.setText(getToggleActionText(selection));
b.setSelection(selection);
return b;
}
/** Get text to show on toggle box given its current selection. */
private String getToggleActionText(boolean en) {
return en ? "Disable" : "Enable";
}
private Label createLabel(Composite parent, String text) {
Label l = new Label(parent, SWT.NONE);
l.setText(text);
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalAlignment = SWT.LEFT;
gd.verticalAlignment = SWT.CENTER;
l.setLayoutData(gd);
return l;
}
@Override
protected void okPressed() {
mRefreshTask.cancel();
super.okPressed();
}
/** Periodically refresh the trace status. */
private class StatusRefreshTask implements Runnable {
private static final int REFRESH_INTERVAL = 1000;
private volatile boolean mIsCancelled = false;
@Override
public void run() {
if (mTraceFileWriter == null) {
return;
}
while (!mIsCancelled) {
final String frameCount = Integer.toString(mTraceFileWriter.getCurrentFrameCount());
double fileSize = mTraceFileWriter.getCurrentFileSize();
fileSize /= (1024 * 1024); // convert to size in MB
final String frameSize = SIZE_FORMATTER.format(fileSize) + " MB";
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
if (mFramesCollectedLabel.isDisposed()) {
return;
}
mFramesCollectedLabel.setText(frameCount);
mTraceFileSizeLabel.setText(frameSize);
mFramesCollectedLabel.pack();
mTraceFileSizeLabel.pack();
}
});
try {
Thread.sleep(REFRESH_INTERVAL);
} catch (InterruptedException e) {
return;
}
}
}
public void cancel() {
mIsCancelled = true;
}
}
}