Home | History | Annotate | Download | only in gltrace
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.ide.eclipse.gltrace;
     18 
     19 import org.eclipse.jface.dialogs.IDialogConstants;
     20 import org.eclipse.jface.dialogs.MessageDialog;
     21 import org.eclipse.jface.dialogs.TitleAreaDialog;
     22 import org.eclipse.swt.SWT;
     23 import org.eclipse.swt.events.SelectionAdapter;
     24 import org.eclipse.swt.events.SelectionEvent;
     25 import org.eclipse.swt.events.SelectionListener;
     26 import org.eclipse.swt.layout.GridData;
     27 import org.eclipse.swt.layout.GridLayout;
     28 import org.eclipse.swt.widgets.Button;
     29 import org.eclipse.swt.widgets.Composite;
     30 import org.eclipse.swt.widgets.Control;
     31 import org.eclipse.swt.widgets.Display;
     32 import org.eclipse.swt.widgets.Group;
     33 import org.eclipse.swt.widgets.Label;
     34 import org.eclipse.swt.widgets.ProgressBar;
     35 import org.eclipse.swt.widgets.Shell;
     36 
     37 import java.io.IOException;
     38 import java.text.DecimalFormat;
     39 
     40 /** Dialog displayed while the trace is being streamed from device to host. */
     41 public class GLTraceCollectorDialog extends TitleAreaDialog {
     42     private static final String TITLE = "OpenGL ES Trace";
     43     private static final String DEFAULT_MESSAGE = "Trace collection in progress.";
     44     private static final DecimalFormat SIZE_FORMATTER = new DecimalFormat("#.##"); //$NON-NLS-1$
     45 
     46     private TraceOptions mTraceOptions;
     47     private final TraceFileWriter mTraceFileWriter;
     48     private final TraceCommandWriter mTraceCommandWriter;
     49 
     50     private Label mFramesCollectedLabel;
     51     private Label mTraceFileSizeLabel;
     52     private StatusRefreshTask mRefreshTask;
     53 
     54     protected GLTraceCollectorDialog(Shell parentShell, TraceFileWriter traceFileWriter,
     55             TraceCommandWriter traceCommandWriter, TraceOptions traceOptions) {
     56         super(parentShell);
     57         mTraceFileWriter = traceFileWriter;
     58         mTraceCommandWriter = traceCommandWriter;
     59         mTraceOptions = traceOptions;
     60     }
     61 
     62     @Override
     63     protected Control createButtonBar(Composite parent) {
     64         Composite c = new Composite(parent, SWT.NONE);
     65         c.setLayout(new GridLayout(0, false));
     66         GridData gd = new GridData(GridData.FILL_HORIZONTAL);
     67         gd.horizontalAlignment = GridData.CENTER;
     68         c.setLayoutData(gd);
     69 
     70         createButton(c, IDialogConstants.OK_ID, "Stop Tracing", true);
     71         return c;
     72     }
     73 
     74     @Override
     75     protected Control createDialogArea(Composite parent) {
     76         parent.setLayout(new GridLayout());
     77 
     78         setTitle(TITLE);
     79         setMessage(DEFAULT_MESSAGE);
     80 
     81         Group controlGroup = new Group(parent, SWT.BORDER);
     82         controlGroup.setLayout(new GridLayout(2, false));
     83         controlGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
     84         controlGroup.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE));
     85         controlGroup.setText("Trace Options");
     86 
     87         createLabel(controlGroup, "Collect Framebuffer contents on eglSwapBuffers()");
     88         final Button eglSwapCheckBox = createButton(controlGroup,
     89                 mTraceOptions.collectFbOnEglSwap);
     90 
     91         createLabel(controlGroup, "Collect Framebuffer contents on glDraw*()");
     92         final Button glDrawCheckBox = createButton(controlGroup, mTraceOptions.collectFbOnGlDraw);
     93 
     94         createLabel(controlGroup, "Collect texture data for glTexImage*()");
     95         final Button glTexImageCheckBox = createButton(controlGroup,
     96                 mTraceOptions.collectTextureData);
     97 
     98         SelectionListener l = new SelectionAdapter() {
     99             @Override
    100             public void widgetSelected(SelectionEvent event) {
    101                 boolean eglSwap = eglSwapCheckBox.getSelection();
    102                 boolean glDraw = glDrawCheckBox.getSelection();
    103                 boolean glTexImage = glTexImageCheckBox.getSelection();
    104 
    105                 try {
    106                     mTraceCommandWriter.setTraceOptions(eglSwap, glDraw, glTexImage);
    107                 } catch (IOException e) {
    108                     eglSwapCheckBox.setEnabled(false);
    109                     glDrawCheckBox.setEnabled(false);
    110                     glTexImageCheckBox.setEnabled(false);
    111 
    112                     MessageDialog.openError(Display.getDefault().getActiveShell(),
    113                             "OpenGL ES Trace",
    114                             "Error while setting trace options: " + e.getMessage());
    115                 }
    116 
    117                 // update the text on the button
    118                 if (!(event.getSource() instanceof Button)) {
    119                     return;
    120                 }
    121                 Button sourceButton = (Button) event.getSource();
    122                 sourceButton.setText(getToggleActionText(sourceButton.getSelection()));
    123                 sourceButton.pack();
    124             }
    125         };
    126 
    127         eglSwapCheckBox.addSelectionListener(l);
    128         glDrawCheckBox.addSelectionListener(l);
    129         glTexImageCheckBox.addSelectionListener(l);
    130 
    131         Group statusGroup = new Group(parent, SWT.NONE);
    132         statusGroup.setLayout(new GridLayout(2, false));
    133         statusGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
    134         statusGroup.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE));
    135         statusGroup.setText("Trace Status");
    136 
    137         createLabel(statusGroup, "Frames Collected:");
    138         mFramesCollectedLabel = createLabel(statusGroup, "");
    139 
    140         createLabel(statusGroup, "Trace File Size:");
    141         mTraceFileSizeLabel = createLabel(statusGroup, "");
    142 
    143         ProgressBar pb = new ProgressBar(statusGroup, SWT.INDETERMINATE);
    144         GridData gd = new GridData(GridData.FILL_HORIZONTAL);
    145         gd.horizontalSpan = 2;
    146         pb.setLayoutData(gd);
    147 
    148         mRefreshTask = new StatusRefreshTask();
    149         new Thread(mRefreshTask, "Trace Status Refresh Thread").start();
    150 
    151         return super.createDialogArea(parent);
    152     }
    153 
    154     private Button createButton(Composite controlComposite, boolean selection) {
    155         Button b = new Button(controlComposite, SWT.TOGGLE);
    156         b.setText(getToggleActionText(selection));
    157         b.setSelection(selection);
    158         return b;
    159     }
    160 
    161     /** Get text to show on toggle box given its current selection. */
    162     private String getToggleActionText(boolean en) {
    163         return en ? "Disable" : "Enable";
    164     }
    165 
    166     private Label createLabel(Composite parent, String text) {
    167         Label l = new Label(parent, SWT.NONE);
    168         l.setText(text);
    169         GridData gd = new GridData(GridData.FILL_HORIZONTAL);
    170         gd.horizontalAlignment = SWT.LEFT;
    171         gd.verticalAlignment = SWT.CENTER;
    172         l.setLayoutData(gd);
    173 
    174         return l;
    175     }
    176 
    177     @Override
    178     protected void okPressed() {
    179         mRefreshTask.cancel();
    180         super.okPressed();
    181     }
    182 
    183     /** Periodically refresh the trace status. */
    184     private class StatusRefreshTask implements Runnable {
    185         private static final int REFRESH_INTERVAL = 1000;
    186         private volatile boolean mIsCancelled = false;
    187 
    188         @Override
    189         public void run() {
    190             if (mTraceFileWriter == null) {
    191                 return;
    192             }
    193 
    194             while (!mIsCancelled) {
    195                 final String frameCount = Integer.toString(mTraceFileWriter.getCurrentFrameCount());
    196 
    197                 double fileSize = mTraceFileWriter.getCurrentFileSize();
    198                 fileSize /= (1024 * 1024); // convert to size in MB
    199                 final String frameSize = SIZE_FORMATTER.format(fileSize) + " MB";
    200 
    201                 Display.getDefault().syncExec(new Runnable() {
    202                     @Override
    203                     public void run() {
    204                         if (mFramesCollectedLabel.isDisposed()) {
    205                             return;
    206                         }
    207 
    208                         mFramesCollectedLabel.setText(frameCount);
    209                         mTraceFileSizeLabel.setText(frameSize);
    210 
    211                         mFramesCollectedLabel.pack();
    212                         mTraceFileSizeLabel.pack();
    213                     }
    214                 });
    215 
    216                 try {
    217                     Thread.sleep(REFRESH_INTERVAL);
    218                 } catch (InterruptedException e) {
    219                     return;
    220                 }
    221             }
    222         }
    223 
    224         public void cancel() {
    225             mIsCancelled = true;
    226         }
    227     }
    228 }
    229