diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/TraceFileWriter.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/TraceFileWriter.java | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/TraceFileWriter.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/TraceFileWriter.java new file mode 100644 index 0000000..a6c02c4 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/TraceFileWriter.java @@ -0,0 +1,155 @@ +/* + * 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.ide.eclipse.gltrace.GLProtoBuf.GLMessage; +import com.android.ide.eclipse.gltrace.GLProtoBuf.GLMessage.Function; +import com.google.protobuf.InvalidProtocolBufferException; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/** A class that streams data received from a socket into the trace file. */ +public class TraceFileWriter { + private DataInputStream mInputStream; + private DataOutputStream mOutputStream; + private Thread mReceiverThread; + + private int mFileSize = 0; + private int mFrameCount = 0; + + /** + * Construct a trace file writer. + * @param fos output stream to write trace data to + * @param is input stream from which trace data is read + */ + public TraceFileWriter(FileOutputStream fos, DataInputStream is) { + mOutputStream = new DataOutputStream(fos); + mInputStream = is; + } + + public void start() { + // launch thread + mReceiverThread = new Thread(new GLTraceReceiverTask()); + mReceiverThread.setName("GL Trace Receiver"); + mReceiverThread.start(); + } + + public void stopTracing() { + // close socket to stop the receiver thread + try { + mInputStream.close(); + } catch (IOException e) { + // ignore exception while closing socket + } + + // wait for receiver to complete + try { + mReceiverThread.join(); + } catch (InterruptedException e1) { + // ignore, this cannot be interrupted + } + + // close stream + try { + mOutputStream.close(); + } catch (IOException e) { + // ignore error while closing stream + } + } + + /** + * The GLTraceReceiverTask collects trace data from the device and writes it + * into a file while collecting some stats on the way. + */ + private class GLTraceReceiverTask implements Runnable { + public void run() { + while (true) { + byte[] buffer = readTraceData(mInputStream); + if (buffer == null) { + break; + } + + try { + writeTraceData(buffer, mOutputStream); + } catch (IOException e) { + break; + } + + updateTraceStats(buffer); + } + } + } + + private byte[] readTraceData(DataInputStream dis) { + int len; + try { + len = dis.readInt(); + } catch (IOException e1) { + return null; + } + len = Integer.reverseBytes(len); // readInt is big endian, we want little endian + + byte[] buffer = new byte[len]; + int readLen = 0; + while (readLen < len) { + try { + int read = dis.read(buffer, readLen, len - readLen); + if (read < 0) { + return null; + } else { + readLen += read; + } + } catch (IOException e) { + return null; + } + } + + return buffer; + } + + + private void writeTraceData(byte[] buffer, DataOutputStream stream) throws IOException { + stream.writeInt(buffer.length); + stream.write(buffer); + } + + private void updateTraceStats(byte[] buffer) { + GLMessage msg = null; + try { + msg = GLMessage.parseFrom(buffer); + } catch (InvalidProtocolBufferException e) { + return; + } + + mFileSize += buffer.length; + + if (msg.getFunction() == Function.eglSwapBuffers) { + mFrameCount++; + } + } + + public int getCurrentFileSize() { + return mFileSize; + } + + public int getCurrentFrameCount() { + return mFrameCount; + } +} |