aboutsummaryrefslogtreecommitdiffstats
path: root/traceview/src/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'traceview/src/com/android')
-rw-r--r--traceview/src/com/android/traceview/Call.java177
-rw-r--r--traceview/src/com/android/traceview/ColorController.java113
-rw-r--r--traceview/src/com/android/traceview/DmTraceReader.java754
-rw-r--r--traceview/src/com/android/traceview/MainWindow.java300
-rw-r--r--traceview/src/com/android/traceview/MethodData.java513
-rw-r--r--traceview/src/com/android/traceview/ProfileData.java88
-rw-r--r--traceview/src/com/android/traceview/ProfileNode.java51
-rw-r--r--traceview/src/com/android/traceview/ProfileProvider.java467
-rw-r--r--traceview/src/com/android/traceview/ProfileSelf.java39
-rw-r--r--traceview/src/com/android/traceview/ProfileView.java332
-rw-r--r--traceview/src/com/android/traceview/PropertiesDialog.java104
-rw-r--r--traceview/src/com/android/traceview/Selection.java70
-rw-r--r--traceview/src/com/android/traceview/SelectionController.java35
-rw-r--r--traceview/src/com/android/traceview/ThreadData.java170
-rw-r--r--traceview/src/com/android/traceview/TickScaler.java148
-rw-r--r--traceview/src/com/android/traceview/TimeBase.java71
-rw-r--r--traceview/src/com/android/traceview/TimeLineView.java2154
-rw-r--r--traceview/src/com/android/traceview/TraceAction.java31
-rw-r--r--traceview/src/com/android/traceview/TraceReader.java79
-rw-r--r--traceview/src/com/android/traceview/TraceUnits.java93
20 files changed, 0 insertions, 5789 deletions
diff --git a/traceview/src/com/android/traceview/Call.java b/traceview/src/com/android/traceview/Call.java
deleted file mode 100644
index 0330b05..0000000
--- a/traceview/src/com/android/traceview/Call.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-import org.eclipse.swt.graphics.Color;
-
-class Call implements TimeLineView.Block {
- final private ThreadData mThreadData;
- final private MethodData mMethodData;
- final Call mCaller; // the caller, or null if this is the root
-
- private String mName;
- private boolean mIsRecursive;
-
- long mGlobalStartTime;
- long mGlobalEndTime;
-
- long mThreadStartTime;
- long mThreadEndTime;
-
- long mInclusiveRealTime; // real time spent in this call including its children
- long mExclusiveRealTime; // real time spent in this call including its children
-
- long mInclusiveCpuTime; // cpu time spent in this call including its children
- long mExclusiveCpuTime; // cpu time spent in this call excluding its children
-
- Call(ThreadData threadData, MethodData methodData, Call caller) {
- mThreadData = threadData;
- mMethodData = methodData;
- mName = methodData.getProfileName();
- mCaller = caller;
- }
-
- public void updateName() {
- mName = mMethodData.getProfileName();
- }
-
- @Override
- public double addWeight(int x, int y, double weight) {
- return mMethodData.addWeight(x, y, weight);
- }
-
- @Override
- public void clearWeight() {
- mMethodData.clearWeight();
- }
-
- @Override
- public long getStartTime() {
- return mGlobalStartTime;
- }
-
- @Override
- public long getEndTime() {
- return mGlobalEndTime;
- }
-
- @Override
- public long getExclusiveCpuTime() {
- return mExclusiveCpuTime;
- }
-
- @Override
- public long getInclusiveCpuTime() {
- return mInclusiveCpuTime;
- }
-
- @Override
- public long getExclusiveRealTime() {
- return mExclusiveRealTime;
- }
-
- @Override
- public long getInclusiveRealTime() {
- return mInclusiveRealTime;
- }
-
- @Override
- public Color getColor() {
- return mMethodData.getColor();
- }
-
- @Override
- public String getName() {
- return mName;
- }
-
- public void setName(String name) {
- mName = name;
- }
-
- public ThreadData getThreadData() {
- return mThreadData;
- }
-
- public int getThreadId() {
- return mThreadData.getId();
- }
-
- @Override
- public MethodData getMethodData() {
- return mMethodData;
- }
-
- @Override
- public boolean isContextSwitch() {
- return mMethodData.getId() == -1;
- }
-
- @Override
- public boolean isIgnoredBlock() {
- // Ignore the top-level call or context switches within the top-level call.
- return mCaller == null || isContextSwitch() && mCaller.mCaller == null;
- }
-
- @Override
- public TimeLineView.Block getParentBlock() {
- return mCaller;
- }
-
- public boolean isRecursive() {
- return mIsRecursive;
- }
-
- void setRecursive(boolean isRecursive) {
- mIsRecursive = isRecursive;
- }
-
- void addCpuTime(long elapsedCpuTime) {
- mExclusiveCpuTime += elapsedCpuTime;
- mInclusiveCpuTime += elapsedCpuTime;
- }
-
- /**
- * Record time spent in the method call.
- */
- void finish() {
- if (mCaller != null) {
- mCaller.mInclusiveCpuTime += mInclusiveCpuTime;
- mCaller.mInclusiveRealTime += mInclusiveRealTime;
- }
-
- mMethodData.addElapsedExclusive(mExclusiveCpuTime, mExclusiveRealTime);
- if (!mIsRecursive) {
- mMethodData.addTopExclusive(mExclusiveCpuTime, mExclusiveRealTime);
- }
- mMethodData.addElapsedInclusive(mInclusiveCpuTime, mInclusiveRealTime,
- mIsRecursive, mCaller);
- }
-
- public static final class TraceAction {
- public static final int ACTION_ENTER = 0;
- public static final int ACTION_EXIT = 1;
-
- public final int mAction;
- public final Call mCall;
-
- public TraceAction(int action, Call call) {
- mAction = action;
- mCall = call;
- }
- }
-}
diff --git a/traceview/src/com/android/traceview/ColorController.java b/traceview/src/com/android/traceview/ColorController.java
deleted file mode 100644
index f5e4c0d..0000000
--- a/traceview/src/com/android/traceview/ColorController.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-import java.util.HashMap;
-
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.RGB;
-import org.eclipse.swt.widgets.Display;
-
-public class ColorController {
- private static final int[] systemColors = { SWT.COLOR_BLUE, SWT.COLOR_RED,
- SWT.COLOR_GREEN, SWT.COLOR_CYAN, SWT.COLOR_MAGENTA, SWT.COLOR_DARK_BLUE,
- SWT.COLOR_DARK_RED, SWT.COLOR_DARK_GREEN, SWT.COLOR_DARK_YELLOW,
- SWT.COLOR_DARK_CYAN, SWT.COLOR_DARK_MAGENTA, SWT.COLOR_BLACK };
-
- private static RGB[] rgbColors = { new RGB(90, 90, 255), // blue
- new RGB(0, 240, 0), // green
- new RGB(255, 0, 0), // red
- new RGB(0, 255, 255), // cyan
- new RGB(255, 80, 255), // magenta
- new RGB(200, 200, 0), // yellow
- new RGB(40, 0, 200), // dark blue
- new RGB(150, 255, 150), // light green
- new RGB(150, 0, 0), // dark red
- new RGB(30, 150, 150), // dark cyan
- new RGB(200, 200, 255), // light blue
- new RGB(0, 120, 0), // dark green
- new RGB(255, 150, 150), // light red
- new RGB(140, 80, 140), // dark magenta
- new RGB(150, 100, 50), // brown
- new RGB(70, 70, 70), // dark grey
- };
-
- private static HashMap<Integer, Color> colorCache = new HashMap<Integer, Color>();
- private static HashMap<Integer, Image> imageCache = new HashMap<Integer, Image>();
-
- public ColorController() {
- }
-
- public static Color requestColor(Display display, RGB rgb) {
- return requestColor(display, rgb.red, rgb.green, rgb.blue);
- }
-
- public static Image requestColorSquare(Display display, RGB rgb) {
- return requestColorSquare(display, rgb.red, rgb.green, rgb.blue);
- }
-
- public static Color requestColor(Display display, int red, int green, int blue) {
- int key = (red << 16) | (green << 8) | blue;
- Color color = colorCache.get(key);
- if (color == null) {
- color = new Color(display, red, green, blue);
- colorCache.put(key, color);
- }
- return color;
- }
-
- public static Image requestColorSquare(Display display, int red, int green, int blue) {
- int key = (red << 16) | (green << 8) | blue;
- Image image = imageCache.get(key);
- if (image == null) {
- image = new Image(display, 8, 14);
- GC gc = new GC(image);
- Color color = requestColor(display, red, green, blue);
- gc.setBackground(color);
- gc.fillRectangle(image.getBounds());
- gc.dispose();
- imageCache.put(key, image);
- }
- return image;
- }
-
- public static void assignMethodColors(Display display, MethodData[] methods) {
- int nextColorIndex = 0;
- for (MethodData md : methods) {
- RGB rgb = rgbColors[nextColorIndex];
- if (++nextColorIndex == rgbColors.length)
- nextColorIndex = 0;
- Color color = requestColor(display, rgb);
- Image image = requestColorSquare(display, rgb);
- md.setColor(color);
- md.setImage(image);
-
- // Compute and set a faded color
- int fadedRed = 150 + rgb.red / 4;
- int fadedGreen = 150 + rgb.green / 4;
- int fadedBlue = 150 + rgb.blue / 4;
- RGB faded = new RGB(fadedRed, fadedGreen, fadedBlue);
- color = requestColor(display, faded);
- image = requestColorSquare(display, faded);
- md.setFadedColor(color);
- md.setFadedImage(image);
- }
- }
-}
diff --git a/traceview/src/com/android/traceview/DmTraceReader.java b/traceview/src/com/android/traceview/DmTraceReader.java
deleted file mode 100644
index 9bd6882..0000000
--- a/traceview/src/com/android/traceview/DmTraceReader.java
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteOrder;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class DmTraceReader extends TraceReader {
- private static final int TRACE_MAGIC = 0x574f4c53;
-
- private static final int METHOD_TRACE_ENTER = 0x00; // method entry
- private static final int METHOD_TRACE_EXIT = 0x01; // method exit
- private static final int METHOD_TRACE_UNROLL = 0x02; // method exited by exception unrolling
-
- // When in dual clock mode, we report that a context switch has occurred
- // when skew between the real time and thread cpu clocks is more than this
- // many microseconds.
- private static final long MIN_CONTEXT_SWITCH_TIME_USEC = 100;
-
- private enum ClockSource {
- THREAD_CPU, WALL, DUAL,
- };
-
- private int mVersionNumber;
- private boolean mRegression;
- private ProfileProvider mProfileProvider;
- private String mTraceFileName;
- private MethodData mTopLevel;
- private ArrayList<Call> mCallList;
- private HashMap<String, String> mPropertiesMap;
- private HashMap<Integer, MethodData> mMethodMap;
- private HashMap<Integer, ThreadData> mThreadMap;
- private ThreadData[] mSortedThreads;
- private MethodData[] mSortedMethods;
- private long mTotalCpuTime;
- private long mTotalRealTime;
- private MethodData mContextSwitch;
- private int mRecordSize;
- private ClockSource mClockSource;
-
- // A regex for matching the thread "id name" lines in the .key file
- private static final Pattern mIdNamePattern = Pattern.compile("(\\d+)\t(.*)"); //$NON-NLS-1$
-
- public DmTraceReader(String traceFileName, boolean regression) throws IOException {
- mTraceFileName = traceFileName;
- mRegression = regression;
- mPropertiesMap = new HashMap<String, String>();
- mMethodMap = new HashMap<Integer, MethodData>();
- mThreadMap = new HashMap<Integer, ThreadData>();
- mCallList = new ArrayList<Call>();
-
- // Create a single top-level MethodData object to hold the profile data
- // for time spent in the unknown caller.
- mTopLevel = new MethodData(0, "(toplevel)");
- mContextSwitch = new MethodData(-1, "(context switch)");
- mMethodMap.put(0, mTopLevel);
- mMethodMap.put(-1, mContextSwitch);
- generateTrees();
- }
-
- void generateTrees() throws IOException {
- long offset = parseKeys();
- parseData(offset);
- analyzeData();
- }
-
- @Override
- public ProfileProvider getProfileProvider() {
- if (mProfileProvider == null)
- mProfileProvider = new ProfileProvider(this);
- return mProfileProvider;
- }
-
- private MappedByteBuffer mapFile(String filename, long offset) throws IOException {
- MappedByteBuffer buffer = null;
- FileInputStream dataFile = new FileInputStream(filename);
- try {
- File file = new File(filename);
- FileChannel fc = dataFile.getChannel();
- buffer = fc.map(FileChannel.MapMode.READ_ONLY, offset, file.length() - offset);
- buffer.order(ByteOrder.LITTLE_ENDIAN);
-
- return buffer;
- } finally {
- dataFile.close(); // this *also* closes the associated channel, fc
- }
- }
-
- private void readDataFileHeader(MappedByteBuffer buffer) {
- int magic = buffer.getInt();
- if (magic != TRACE_MAGIC) {
- System.err.printf(
- "Error: magic number mismatch; got 0x%x, expected 0x%x\n",
- magic, TRACE_MAGIC);
- throw new RuntimeException();
- }
-
- // read version
- int version = buffer.getShort();
- if (version != mVersionNumber) {
- System.err.printf(
- "Error: version number mismatch; got %d in data header but %d in options\n",
- version, mVersionNumber);
- throw new RuntimeException();
- }
- if (version < 1 || version > 3) {
- System.err.printf(
- "Error: unsupported trace version number %d. "
- + "Please use a newer version of TraceView to read this file.", version);
- throw new RuntimeException();
- }
-
- // read offset
- int offsetToData = buffer.getShort() - 16;
-
- // read startWhen
- buffer.getLong();
-
- // read record size
- if (version == 1) {
- mRecordSize = 9;
- } else if (version == 2) {
- mRecordSize = 10;
- } else {
- mRecordSize = buffer.getShort();
- offsetToData -= 2;
- }
-
- // Skip over offsetToData bytes
- while (offsetToData-- > 0) {
- buffer.get();
- }
- }
-
- private void parseData(long offset) throws IOException {
- MappedByteBuffer buffer = mapFile(mTraceFileName, offset);
- readDataFileHeader(buffer);
-
- ArrayList<TraceAction> trace = null;
- if (mClockSource == ClockSource.THREAD_CPU) {
- trace = new ArrayList<TraceAction>();
- }
-
- final boolean haveThreadClock = mClockSource != ClockSource.WALL;
- final boolean haveGlobalClock = mClockSource != ClockSource.THREAD_CPU;
-
- // Parse all call records to obtain elapsed time information.
- ThreadData prevThreadData = null;
- for (;;) {
- int threadId;
- int methodId;
- long threadTime, globalTime;
- try {
- int recordSize = mRecordSize;
-
- if (mVersionNumber == 1) {
- threadId = buffer.get();
- recordSize -= 1;
- } else {
- threadId = buffer.getShort();
- recordSize -= 2;
- }
-
- methodId = buffer.getInt();
- recordSize -= 4;
-
- switch (mClockSource) {
- case WALL:
- threadTime = 0;
- globalTime = buffer.getInt();
- recordSize -= 4;
- break;
- case DUAL:
- threadTime = buffer.getInt();
- globalTime = buffer.getInt();
- recordSize -= 8;
- break;
- default:
- case THREAD_CPU:
- threadTime = buffer.getInt();
- globalTime = 0;
- recordSize -= 4;
- break;
- }
-
- while (recordSize-- > 0) {
- buffer.get();
- }
- } catch (BufferUnderflowException ex) {
- break;
- }
-
- int methodAction = methodId & 0x03;
- methodId = methodId & ~0x03;
- MethodData methodData = mMethodMap.get(methodId);
- if (methodData == null) {
- String name = String.format("(0x%1$x)", methodId); //$NON-NLS-1$
- methodData = new MethodData(methodId, name);
- mMethodMap.put(methodId, methodData);
- }
-
- ThreadData threadData = mThreadMap.get(threadId);
- if (threadData == null) {
- String name = String.format("[%1$d]", threadId); //$NON-NLS-1$
- threadData = new ThreadData(threadId, name, mTopLevel);
- mThreadMap.put(threadId, threadData);
- }
-
- long elapsedGlobalTime = 0;
- if (haveGlobalClock) {
- if (!threadData.mHaveGlobalTime) {
- threadData.mGlobalStartTime = globalTime;
- threadData.mHaveGlobalTime = true;
- } else {
- elapsedGlobalTime = globalTime - threadData.mGlobalEndTime;
- }
- threadData.mGlobalEndTime = globalTime;
- }
-
- if (haveThreadClock) {
- long elapsedThreadTime = 0;
- if (!threadData.mHaveThreadTime) {
- threadData.mThreadStartTime = threadTime;
- threadData.mThreadCurrentTime = threadTime;
- threadData.mHaveThreadTime = true;
- } else {
- elapsedThreadTime = threadTime - threadData.mThreadEndTime;
- }
- threadData.mThreadEndTime = threadTime;
-
- if (!haveGlobalClock) {
- // Detect context switches whenever execution appears to switch from one
- // thread to another. This assumption is only valid on uniprocessor
- // systems (which is why we now have a dual clock mode).
- // We represent context switches in the trace by pushing a call record
- // with MethodData mContextSwitch onto the stack of the previous
- // thread. We arbitrarily set the start and end time of the context
- // switch such that the context switch occurs in the middle of the thread
- // time and itself accounts for zero thread time.
- if (prevThreadData != null && prevThreadData != threadData) {
- // Begin context switch from previous thread.
- Call switchCall = prevThreadData.enter(mContextSwitch, trace);
- switchCall.mThreadStartTime = prevThreadData.mThreadEndTime;
- mCallList.add(switchCall);
-
- // Return from context switch to current thread.
- Call top = threadData.top();
- if (top.getMethodData() == mContextSwitch) {
- threadData.exit(mContextSwitch, trace);
- long beforeSwitch = elapsedThreadTime / 2;
- top.mThreadStartTime += beforeSwitch;
- top.mThreadEndTime = top.mThreadStartTime;
- }
- }
- prevThreadData = threadData;
- } else {
- // If we have a global clock, then we can detect context switches (or blocking
- // calls or cpu suspensions or clock anomalies) by comparing global time to
- // thread time for successive calls that occur on the same thread.
- // As above, we represent the context switch using a special method call.
- long sleepTime = elapsedGlobalTime - elapsedThreadTime;
- if (sleepTime > MIN_CONTEXT_SWITCH_TIME_USEC) {
- Call switchCall = threadData.enter(mContextSwitch, trace);
- long beforeSwitch = elapsedThreadTime / 2;
- long afterSwitch = elapsedThreadTime - beforeSwitch;
- switchCall.mGlobalStartTime = globalTime - elapsedGlobalTime + beforeSwitch;
- switchCall.mGlobalEndTime = globalTime - afterSwitch;
- switchCall.mThreadStartTime = threadTime - afterSwitch;
- switchCall.mThreadEndTime = switchCall.mThreadStartTime;
- threadData.exit(mContextSwitch, trace);
- mCallList.add(switchCall);
- }
- }
-
- // Add thread CPU time.
- Call top = threadData.top();
- top.addCpuTime(elapsedThreadTime);
- }
-
- switch (methodAction) {
- case METHOD_TRACE_ENTER: {
- Call call = threadData.enter(methodData, trace);
- if (haveGlobalClock) {
- call.mGlobalStartTime = globalTime;
- }
- if (haveThreadClock) {
- call.mThreadStartTime = threadTime;
- }
- mCallList.add(call);
- break;
- }
- case METHOD_TRACE_EXIT:
- case METHOD_TRACE_UNROLL: {
- Call call = threadData.exit(methodData, trace);
- if (call != null) {
- if (haveGlobalClock) {
- call.mGlobalEndTime = globalTime;
- }
- if (haveThreadClock) {
- call.mThreadEndTime = threadTime;
- }
- }
- break;
- }
- default:
- throw new RuntimeException("Unrecognized method action: " + methodAction);
- }
- }
-
- // Exit any pending open-ended calls.
- for (ThreadData threadData : mThreadMap.values()) {
- threadData.endTrace(trace);
- }
-
- // Recreate the global timeline from thread times, if needed.
- if (!haveGlobalClock) {
- long globalTime = 0;
- prevThreadData = null;
- for (TraceAction traceAction : trace) {
- Call call = traceAction.mCall;
- ThreadData threadData = call.getThreadData();
-
- if (traceAction.mAction == TraceAction.ACTION_ENTER) {
- long threadTime = call.mThreadStartTime;
- globalTime += call.mThreadStartTime - threadData.mThreadCurrentTime;
- call.mGlobalStartTime = globalTime;
- if (!threadData.mHaveGlobalTime) {
- threadData.mHaveGlobalTime = true;
- threadData.mGlobalStartTime = globalTime;
- }
- threadData.mThreadCurrentTime = threadTime;
- } else if (traceAction.mAction == TraceAction.ACTION_EXIT) {
- long threadTime = call.mThreadEndTime;
- globalTime += call.mThreadEndTime - threadData.mThreadCurrentTime;
- call.mGlobalEndTime = globalTime;
- threadData.mGlobalEndTime = globalTime;
- threadData.mThreadCurrentTime = threadTime;
- } // else, ignore ACTION_INCOMPLETE calls, nothing to do
- prevThreadData = threadData;
- }
- }
-
- // Finish updating all calls and calculate the total time spent.
- for (int i = mCallList.size() - 1; i >= 0; i--) {
- Call call = mCallList.get(i);
-
- // Calculate exclusive real-time by subtracting inclusive real time
- // accumulated by children from the total span.
- long realTime = call.mGlobalEndTime - call.mGlobalStartTime;
- call.mExclusiveRealTime = Math.max(realTime - call.mInclusiveRealTime, 0);
- call.mInclusiveRealTime = realTime;
-
- call.finish();
- }
- mTotalCpuTime = 0;
- mTotalRealTime = 0;
- for (ThreadData threadData : mThreadMap.values()) {
- Call rootCall = threadData.getRootCall();
- threadData.updateRootCallTimeBounds();
- rootCall.finish();
- mTotalCpuTime += rootCall.mInclusiveCpuTime;
- mTotalRealTime += rootCall.mInclusiveRealTime;
- }
-
- if (mRegression) {
- System.out.format("totalCpuTime %dus\n", mTotalCpuTime);
- System.out.format("totalRealTime %dus\n", mTotalRealTime);
-
- dumpThreadTimes();
- dumpCallTimes();
- }
- }
-
- static final int PARSE_VERSION = 0;
- static final int PARSE_THREADS = 1;
- static final int PARSE_METHODS = 2;
- static final int PARSE_OPTIONS = 4;
-
- long parseKeys() throws IOException {
- long offset = 0;
- BufferedReader in = null;
- try {
- in = new BufferedReader(new InputStreamReader(
- new FileInputStream(mTraceFileName), "US-ASCII"));
-
- int mode = PARSE_VERSION;
- String line = null;
- while (true) {
- line = in.readLine();
- if (line == null) {
- throw new IOException("Key section does not have an *end marker");
- }
-
- // Calculate how much we have read from the file so far. The
- // extra byte is for the line ending not included by readLine().
- offset += line.length() + 1;
- if (line.startsWith("*")) {
- if (line.equals("*version")) {
- mode = PARSE_VERSION;
- continue;
- }
- if (line.equals("*threads")) {
- mode = PARSE_THREADS;
- continue;
- }
- if (line.equals("*methods")) {
- mode = PARSE_METHODS;
- continue;
- }
- if (line.equals("*end")) {
- break;
- }
- }
- switch (mode) {
- case PARSE_VERSION:
- mVersionNumber = Integer.decode(line);
- mode = PARSE_OPTIONS;
- break;
- case PARSE_THREADS:
- parseThread(line);
- break;
- case PARSE_METHODS:
- parseMethod(line);
- break;
- case PARSE_OPTIONS:
- parseOption(line);
- break;
- }
- }
- } catch (FileNotFoundException ex) {
- System.err.println(ex.getMessage());
- } finally {
- if (in != null) {
- in.close();
- }
- }
-
- if (mClockSource == null) {
- mClockSource = ClockSource.THREAD_CPU;
- }
-
- return offset;
- }
-
- void parseOption(String line) {
- String[] tokens = line.split("=");
- if (tokens.length == 2) {
- String key = tokens[0];
- String value = tokens[1];
- mPropertiesMap.put(key, value);
-
- if (key.equals("clock")) {
- if (value.equals("thread-cpu")) {
- mClockSource = ClockSource.THREAD_CPU;
- } else if (value.equals("wall")) {
- mClockSource = ClockSource.WALL;
- } else if (value.equals("dual")) {
- mClockSource = ClockSource.DUAL;
- }
- }
- }
- }
-
- void parseThread(String line) {
- String idStr = null;
- String name = null;
- Matcher matcher = mIdNamePattern.matcher(line);
- if (matcher.find()) {
- idStr = matcher.group(1);
- name = matcher.group(2);
- }
- if (idStr == null) return;
- if (name == null) name = "(unknown)";
-
- int id = Integer.decode(idStr);
- mThreadMap.put(id, new ThreadData(id, name, mTopLevel));
- }
-
- void parseMethod(String line) {
- String[] tokens = line.split("\t");
- int id = Long.decode(tokens[0]).intValue();
- String className = tokens[1];
- String methodName = null;
- String signature = null;
- String pathname = null;
- int lineNumber = -1;
- if (tokens.length == 6) {
- methodName = tokens[2];
- signature = tokens[3];
- pathname = tokens[4];
- lineNumber = Integer.decode(tokens[5]);
- pathname = constructPathname(className, pathname);
- } else if (tokens.length > 2) {
- if (tokens[3].startsWith("(")) {
- methodName = tokens[2];
- signature = tokens[3];
- } else {
- pathname = tokens[2];
- lineNumber = Integer.decode(tokens[3]);
- }
- }
-
- mMethodMap.put(id, new MethodData(id, className, methodName, signature,
- pathname, lineNumber));
- }
-
- private String constructPathname(String className, String pathname) {
- int index = className.lastIndexOf('/');
- if (index > 0 && index < className.length() - 1
- && pathname.endsWith(".java"))
- pathname = className.substring(0, index + 1) + pathname;
- return pathname;
- }
-
- private void analyzeData() {
- final TimeBase timeBase = getPreferredTimeBase();
-
- // Sort the threads into decreasing cpu time
- Collection<ThreadData> tv = mThreadMap.values();
- mSortedThreads = tv.toArray(new ThreadData[tv.size()]);
- Arrays.sort(mSortedThreads, new Comparator<ThreadData>() {
- @Override
- public int compare(ThreadData td1, ThreadData td2) {
- if (timeBase.getTime(td2) > timeBase.getTime(td1))
- return 1;
- if (timeBase.getTime(td2) < timeBase.getTime(td1))
- return -1;
- return td2.getName().compareTo(td1.getName());
- }
- });
-
- // Sort the methods into decreasing inclusive time
- Collection<MethodData> mv = mMethodMap.values();
- MethodData[] methods;
- methods = mv.toArray(new MethodData[mv.size()]);
- Arrays.sort(methods, new Comparator<MethodData>() {
- @Override
- public int compare(MethodData md1, MethodData md2) {
- if (timeBase.getElapsedInclusiveTime(md2) > timeBase.getElapsedInclusiveTime(md1))
- return 1;
- if (timeBase.getElapsedInclusiveTime(md2) < timeBase.getElapsedInclusiveTime(md1))
- return -1;
- return md1.getName().compareTo(md2.getName());
- }
- });
-
- // Count the number of methods with non-zero inclusive time
- int nonZero = 0;
- for (MethodData md : methods) {
- if (timeBase.getElapsedInclusiveTime(md) == 0)
- break;
- nonZero += 1;
- }
-
- // Copy the methods with non-zero time
- mSortedMethods = new MethodData[nonZero];
- int ii = 0;
- for (MethodData md : methods) {
- if (timeBase.getElapsedInclusiveTime(md) == 0)
- break;
- md.setRank(ii);
- mSortedMethods[ii++] = md;
- }
-
- // Let each method analyze its profile data
- for (MethodData md : mSortedMethods) {
- md.analyzeData(timeBase);
- }
-
- // Update all the calls to include the method rank in
- // their name.
- for (Call call : mCallList) {
- call.updateName();
- }
-
- if (mRegression) {
- dumpMethodStats();
- }
- }
-
- /*
- * This method computes a list of records that describe the the execution
- * timeline for each thread. Each record is a pair: (row, block) where: row:
- * is the ThreadData object block: is the call (containing the start and end
- * times)
- */
- @Override
- public ArrayList<TimeLineView.Record> getThreadTimeRecords() {
- TimeLineView.Record record;
- ArrayList<TimeLineView.Record> timeRecs;
- timeRecs = new ArrayList<TimeLineView.Record>();
-
- // For each thread, push a "toplevel" call that encompasses the
- // entire execution of the thread.
- for (ThreadData threadData : mSortedThreads) {
- if (!threadData.isEmpty() && threadData.getId() != 0) {
- record = new TimeLineView.Record(threadData, threadData.getRootCall());
- timeRecs.add(record);
- }
- }
-
- for (Call call : mCallList) {
- record = new TimeLineView.Record(call.getThreadData(), call);
- timeRecs.add(record);
- }
-
- if (mRegression) {
- dumpTimeRecs(timeRecs);
- System.exit(0);
- }
- return timeRecs;
- }
-
- private void dumpThreadTimes() {
- System.out.print("\nThread Times\n");
- System.out.print("id t-start t-end g-start g-end name\n");
- for (ThreadData threadData : mThreadMap.values()) {
- System.out.format("%2d %8d %8d %8d %8d %s\n",
- threadData.getId(),
- threadData.mThreadStartTime, threadData.mThreadEndTime,
- threadData.mGlobalStartTime, threadData.mGlobalEndTime,
- threadData.getName());
- }
- }
-
- private void dumpCallTimes() {
- System.out.print("\nCall Times\n");
- System.out.print("id t-start t-end g-start g-end excl. incl. method\n");
- for (Call call : mCallList) {
- System.out.format("%2d %8d %8d %8d %8d %8d %8d %s\n",
- call.getThreadId(), call.mThreadStartTime, call.mThreadEndTime,
- call.mGlobalStartTime, call.mGlobalEndTime,
- call.mExclusiveCpuTime, call.mInclusiveCpuTime,
- call.getMethodData().getName());
- }
- }
-
- private void dumpMethodStats() {
- System.out.print("\nMethod Stats\n");
- System.out.print("Excl Cpu Incl Cpu Excl Real Incl Real Calls Method\n");
- for (MethodData md : mSortedMethods) {
- System.out.format("%9d %9d %9d %9d %9s %s\n",
- md.getElapsedExclusiveCpuTime(), md.getElapsedInclusiveCpuTime(),
- md.getElapsedExclusiveRealTime(), md.getElapsedInclusiveRealTime(),
- md.getCalls(), md.getProfileName());
- }
- }
-
- private void dumpTimeRecs(ArrayList<TimeLineView.Record> timeRecs) {
- System.out.print("\nTime Records\n");
- System.out.print("id t-start t-end g-start g-end method\n");
- for (TimeLineView.Record record : timeRecs) {
- Call call = (Call) record.block;
- System.out.format("%2d %8d %8d %8d %8d %s\n",
- call.getThreadId(), call.mThreadStartTime, call.mThreadEndTime,
- call.mGlobalStartTime, call.mGlobalEndTime,
- call.getMethodData().getName());
- }
- }
-
- @Override
- public HashMap<Integer, String> getThreadLabels() {
- HashMap<Integer, String> labels = new HashMap<Integer, String>();
- for (ThreadData t : mThreadMap.values()) {
- labels.put(t.getId(), t.getName());
- }
- return labels;
- }
-
- @Override
- public MethodData[] getMethods() {
- return mSortedMethods;
- }
-
- @Override
- public ThreadData[] getThreads() {
- return mSortedThreads;
- }
-
- @Override
- public long getTotalCpuTime() {
- return mTotalCpuTime;
- }
-
- @Override
- public long getTotalRealTime() {
- return mTotalRealTime;
- }
-
- @Override
- public boolean haveCpuTime() {
- return mClockSource != ClockSource.WALL;
- }
-
- @Override
- public boolean haveRealTime() {
- return mClockSource != ClockSource.THREAD_CPU;
- }
-
- @Override
- public HashMap<String, String> getProperties() {
- return mPropertiesMap;
- }
-
- @Override
- public TimeBase getPreferredTimeBase() {
- if (mClockSource == ClockSource.WALL) {
- return TimeBase.REAL_TIME;
- }
- return TimeBase.CPU_TIME;
- }
-
- @Override
- public String getClockSource() {
- switch (mClockSource) {
- case THREAD_CPU:
- return "cpu time";
- case WALL:
- return "real time";
- case DUAL:
- return "real time, dual clock";
- }
- return null;
- }
-}
diff --git a/traceview/src/com/android/traceview/MainWindow.java b/traceview/src/com/android/traceview/MainWindow.java
deleted file mode 100644
index ebab72b..0000000
--- a/traceview/src/com/android/traceview/MainWindow.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-import com.android.sdkstats.SdkStatsService;
-
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.window.ApplicationWindow;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Shell;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.channels.FileChannel;
-import java.util.HashMap;
-import java.util.Properties;
-
-public class MainWindow extends ApplicationWindow {
-
- private final static String PING_NAME = "Traceview";
-
- private TraceReader mReader;
- private String mTraceName;
-
- // A global cache of string names.
- public static HashMap<String, String> sStringCache = new HashMap<String, String>();
-
- public MainWindow(String traceName, TraceReader reader) {
- super(null);
- mReader = reader;
- mTraceName = traceName;
-
- addMenuBar();
- }
-
- public void run() {
- setBlockOnOpen(true);
- open();
- }
-
- @Override
- protected void configureShell(Shell shell) {
- super.configureShell(shell);
- shell.setText("Traceview: " + mTraceName);
-
- InputStream in = getClass().getClassLoader().getResourceAsStream(
- "icons/traceview-128.png");
- if (in != null) {
- shell.setImage(new Image(shell.getDisplay(), in));
- }
-
- shell.setBounds(100, 10, 1282, 900);
- }
-
- @Override
- protected Control createContents(Composite parent) {
- ColorController.assignMethodColors(parent.getDisplay(), mReader.getMethods());
- SelectionController selectionController = new SelectionController();
-
- GridLayout gridLayout = new GridLayout(1, false);
- gridLayout.marginWidth = 0;
- gridLayout.marginHeight = 0;
- gridLayout.horizontalSpacing = 0;
- gridLayout.verticalSpacing = 0;
- parent.setLayout(gridLayout);
-
- Display display = parent.getDisplay();
- Color darkGray = display.getSystemColor(SWT.COLOR_DARK_GRAY);
-
- // Create a sash form to separate the timeline view (on top)
- // and the profile view (on bottom)
- SashForm sashForm1 = new SashForm(parent, SWT.VERTICAL);
- sashForm1.setBackground(darkGray);
- sashForm1.SASH_WIDTH = 3;
- GridData data = new GridData(GridData.FILL_BOTH);
- sashForm1.setLayoutData(data);
-
- // Create the timeline view
- new TimeLineView(sashForm1, mReader, selectionController);
-
- // Create the profile view
- new ProfileView(sashForm1, mReader, selectionController);
- return sashForm1;
- }
-
- @Override
- protected MenuManager createMenuManager() {
- MenuManager manager = super.createMenuManager();
-
- MenuManager viewMenu = new MenuManager("View");
- manager.add(viewMenu);
-
- Action showPropertiesAction = new Action("Show Properties...") {
- @Override
- public void run() {
- showProperties();
- }
- };
- viewMenu.add(showPropertiesAction);
-
- return manager;
- }
-
- private void showProperties() {
- PropertiesDialog dialog = new PropertiesDialog(getShell());
- dialog.setProperties(mReader.getProperties());
- dialog.open();
- }
-
- /**
- * Convert the old two-file format into the current concatenated one.
- *
- * @param base Base path of the two files, i.e. base.key and base.data
- * @return Path to a temporary file that will be deleted on exit.
- * @throws IOException
- */
- private static String makeTempTraceFile(String base) throws IOException {
- // Make a temporary file that will go away on exit and prepare to
- // write into it.
- File temp = File.createTempFile(base, ".trace");
- temp.deleteOnExit();
-
- FileOutputStream dstStream = null;
- FileInputStream keyStream = null;
- FileInputStream dataStream = null;
-
- try {
- dstStream = new FileOutputStream(temp);
- FileChannel dstChannel = dstStream.getChannel();
-
- // First copy the contents of the key file into our temp file.
- keyStream = new FileInputStream(base + ".key");
- FileChannel srcChannel = keyStream.getChannel();
- long size = dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
- srcChannel.close();
-
- // Then concatenate the data file.
- dataStream = new FileInputStream(base + ".data");
- srcChannel = dataStream.getChannel();
- dstChannel.transferFrom(srcChannel, size, srcChannel.size());
- } finally {
- if (dstStream != null) {
- dstStream.close(); // also closes dstChannel
- }
- if (keyStream != null) {
- keyStream.close(); // also closes srcChannel
- }
- if (dataStream != null) {
- dataStream.close();
- }
- }
-
- // Return the path of the temp file.
- return temp.getPath();
- }
-
- /**
- * Returns the tools revision number.
- */
- private static String getRevision() {
- Properties p = new Properties();
- try{
- String toolsdir = System.getProperty("com.android.traceview.toolsdir"); //$NON-NLS-1$
- File sourceProp;
- if (toolsdir == null || toolsdir.length() == 0) {
- sourceProp = new File("source.properties"); //$NON-NLS-1$
- } else {
- sourceProp = new File(toolsdir, "source.properties"); //$NON-NLS-1$
- }
-
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(sourceProp);
- p.load(fis);
- } finally {
- if (fis != null) {
- try {
- fis.close();
- } catch (IOException ignore) {
- }
- }
- }
-
- String revision = p.getProperty("Pkg.Revision"); //$NON-NLS-1$
- if (revision != null && revision.length() > 0) {
- return revision;
- }
- } catch (FileNotFoundException e) {
- // couldn't find the file? don't ping.
- } catch (IOException e) {
- // couldn't find the file? don't ping.
- }
-
- return null;
- }
-
-
- public static void main(String[] args) {
- TraceReader reader = null;
- boolean regression = false;
-
- // ping the usage server
-
- String revision = getRevision();
- if (revision != null) {
- new SdkStatsService().ping(PING_NAME, revision);
- }
-
- // Process command line arguments
- int argc = 0;
- int len = args.length;
- while (argc < len) {
- String arg = args[argc];
- if (arg.charAt(0) != '-') {
- break;
- }
- if (arg.equals("-r")) {
- regression = true;
- } else {
- break;
- }
- argc++;
- }
- if (argc != len - 1) {
- System.out.printf("Usage: java %s [-r] trace%n", MainWindow.class.getName());
- System.out.printf(" -r regression only%n");
- return;
- }
-
- String traceName = args[len - 1];
- File file = new File(traceName);
- if (file.exists() && file.isDirectory()) {
- System.out.printf("Qemu trace files not supported yet.\n");
- System.exit(1);
- // reader = new QtraceReader(traceName);
- } else {
- // If the filename as given doesn't exist...
- if (!file.exists()) {
- // Try appending .trace.
- if (new File(traceName + ".trace").exists()) {
- traceName = traceName + ".trace";
- // Next, see if it is the old two-file trace.
- } else if (new File(traceName + ".data").exists()
- && new File(traceName + ".key").exists()) {
- try {
- traceName = makeTempTraceFile(traceName);
- } catch (IOException e) {
- System.err.printf("cannot convert old trace file '%s'\n", traceName);
- System.exit(1);
- }
- // Otherwise, give up.
- } else {
- System.err.printf("trace file '%s' not found\n", traceName);
- System.exit(1);
- }
- }
-
- try {
- reader = new DmTraceReader(traceName, regression);
- } catch (IOException e) {
- System.err.printf("Failed to read the trace file");
- e.printStackTrace();
- System.exit(1);
- return;
- }
- }
-
- reader.getTraceUnits().setTimeScale(TraceUnits.TimeScale.MilliSeconds);
-
- Display.setAppName("Traceview");
- new MainWindow(traceName, reader).run();
- }
-}
diff --git a/traceview/src/com/android/traceview/MethodData.java b/traceview/src/com/android/traceview/MethodData.java
deleted file mode 100644
index 69c5247..0000000
--- a/traceview/src/com/android/traceview/MethodData.java
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashMap;
-
-public class MethodData {
-
- private int mId;
- private int mRank = -1;
- private String mClassName;
- private String mMethodName;
- private String mSignature;
- private String mName;
- private String mProfileName;
- private String mPathname;
- private int mLineNumber;
- private long mElapsedExclusiveCpuTime;
- private long mElapsedInclusiveCpuTime;
- private long mTopExclusiveCpuTime;
- private long mElapsedExclusiveRealTime;
- private long mElapsedInclusiveRealTime;
- private long mTopExclusiveRealTime;
- private int[] mNumCalls = new int[2]; // index 0=normal, 1=recursive
- private Color mColor;
- private Color mFadedColor;
- private Image mImage;
- private Image mFadedImage;
- private HashMap<Integer, ProfileData> mParents;
- private HashMap<Integer, ProfileData> mChildren;
-
- // The parents of this method when this method was in a recursive call
- private HashMap<Integer, ProfileData> mRecursiveParents;
-
- // The children of this method when this method was in a recursive call
- private HashMap<Integer, ProfileData> mRecursiveChildren;
-
- private ProfileNode[] mProfileNodes;
- private int mX;
- private int mY;
- private double mWeight;
-
- public MethodData(int id, String className) {
- mId = id;
- mClassName = className;
- mMethodName = null;
- mSignature = null;
- mPathname = null;
- mLineNumber = -1;
- computeName();
- computeProfileName();
- }
-
- public MethodData(int id, String className, String methodName,
- String signature, String pathname, int lineNumber) {
- mId = id;
- mClassName = className;
- mMethodName = methodName;
- mSignature = signature;
- mPathname = pathname;
- mLineNumber = lineNumber;
- computeName();
- computeProfileName();
- }
-
- public double addWeight(int x, int y, double weight) {
- if (mX == x && mY == y)
- mWeight += weight;
- else {
- mX = x;
- mY = y;
- mWeight = weight;
- }
- return mWeight;
- }
-
- public void clearWeight() {
- mWeight = 0;
- }
-
- public int getRank() {
- return mRank;
- }
-
- public void setRank(int rank) {
- mRank = rank;
- computeProfileName();
- }
-
- public void addElapsedExclusive(long cpuTime, long realTime) {
- mElapsedExclusiveCpuTime += cpuTime;
- mElapsedExclusiveRealTime += realTime;
- }
-
- public void addElapsedInclusive(long cpuTime, long realTime,
- boolean isRecursive, Call parent) {
- if (isRecursive == false) {
- mElapsedInclusiveCpuTime += cpuTime;
- mElapsedInclusiveRealTime += realTime;
- mNumCalls[0] += 1;
- } else {
- mNumCalls[1] += 1;
- }
-
- if (parent == null)
- return;
-
- // Find the child method in the parent
- MethodData parentMethod = parent.getMethodData();
- if (parent.isRecursive()) {
- parentMethod.mRecursiveChildren = updateInclusive(cpuTime, realTime,
- parentMethod, this, false,
- parentMethod.mRecursiveChildren);
- } else {
- parentMethod.mChildren = updateInclusive(cpuTime, realTime,
- parentMethod, this, false, parentMethod.mChildren);
- }
-
- // Find the parent method in the child
- if (isRecursive) {
- mRecursiveParents = updateInclusive(cpuTime, realTime, this, parentMethod, true,
- mRecursiveParents);
- } else {
- mParents = updateInclusive(cpuTime, realTime, this, parentMethod, true,
- mParents);
- }
- }
-
- private HashMap<Integer, ProfileData> updateInclusive(long cpuTime, long realTime,
- MethodData contextMethod, MethodData elementMethod,
- boolean elementIsParent, HashMap<Integer, ProfileData> map) {
- if (map == null) {
- map = new HashMap<Integer, ProfileData>(4);
- } else {
- ProfileData profileData = map.get(elementMethod.mId);
- if (profileData != null) {
- profileData.addElapsedInclusive(cpuTime, realTime);
- return map;
- }
- }
-
- ProfileData elementData = new ProfileData(contextMethod,
- elementMethod, elementIsParent);
- elementData.setElapsedInclusive(cpuTime, realTime);
- elementData.setNumCalls(1);
- map.put(elementMethod.mId, elementData);
- return map;
- }
-
- public void analyzeData(TimeBase timeBase) {
- // Sort the parents and children into decreasing inclusive time
- ProfileData[] sortedParents;
- ProfileData[] sortedChildren;
- ProfileData[] sortedRecursiveParents;
- ProfileData[] sortedRecursiveChildren;
-
- sortedParents = sortProfileData(mParents, timeBase);
- sortedChildren = sortProfileData(mChildren, timeBase);
- sortedRecursiveParents = sortProfileData(mRecursiveParents, timeBase);
- sortedRecursiveChildren = sortProfileData(mRecursiveChildren, timeBase);
-
- // Add "self" time to the top of the sorted children
- sortedChildren = addSelf(sortedChildren);
-
- // Create the ProfileNode objects that we need
- ArrayList<ProfileNode> nodes = new ArrayList<ProfileNode>();
- ProfileNode profileNode;
- if (mParents != null) {
- profileNode = new ProfileNode("Parents", this, sortedParents,
- true, false);
- nodes.add(profileNode);
- }
- if (mChildren != null) {
- profileNode = new ProfileNode("Children", this, sortedChildren,
- false, false);
- nodes.add(profileNode);
- }
- if (mRecursiveParents!= null) {
- profileNode = new ProfileNode("Parents while recursive", this,
- sortedRecursiveParents, true, true);
- nodes.add(profileNode);
- }
- if (mRecursiveChildren != null) {
- profileNode = new ProfileNode("Children while recursive", this,
- sortedRecursiveChildren, false, true);
- nodes.add(profileNode);
- }
- mProfileNodes = nodes.toArray(new ProfileNode[nodes.size()]);
- }
-
- // Create and return a ProfileData[] array that is a sorted copy
- // of the given HashMap values.
- private ProfileData[] sortProfileData(HashMap<Integer, ProfileData> map,
- final TimeBase timeBase) {
- if (map == null)
- return null;
-
- // Convert the hash values to an array of ProfileData
- Collection<ProfileData> values = map.values();
- ProfileData[] sorted = values.toArray(new ProfileData[values.size()]);
-
- // Sort the array by elapsed inclusive time
- Arrays.sort(sorted, new Comparator<ProfileData>() {
- @Override
- public int compare(ProfileData pd1, ProfileData pd2) {
- if (timeBase.getElapsedInclusiveTime(pd2) > timeBase.getElapsedInclusiveTime(pd1))
- return 1;
- if (timeBase.getElapsedInclusiveTime(pd2) < timeBase.getElapsedInclusiveTime(pd1))
- return -1;
- return 0;
- }
- });
- return sorted;
- }
-
- private ProfileData[] addSelf(ProfileData[] children) {
- ProfileData[] pdata;
- if (children == null) {
- pdata = new ProfileData[1];
- } else {
- pdata = new ProfileData[children.length + 1];
- System.arraycopy(children, 0, pdata, 1, children.length);
- }
- pdata[0] = new ProfileSelf(this);
- return pdata;
- }
-
- public void addTopExclusive(long cpuTime, long realTime) {
- mTopExclusiveCpuTime += cpuTime;
- mTopExclusiveRealTime += realTime;
- }
-
- public long getTopExclusiveCpuTime() {
- return mTopExclusiveCpuTime;
- }
-
- public long getTopExclusiveRealTime() {
- return mTopExclusiveRealTime;
- }
-
- public int getId() {
- return mId;
- }
-
- private void computeName() {
- if (mMethodName == null) {
- mName = mClassName;
- return;
- }
-
- StringBuilder sb = new StringBuilder();
- sb.append(mClassName);
- sb.append("."); //$NON-NLS-1$
- sb.append(mMethodName);
- sb.append(" "); //$NON-NLS-1$
- sb.append(mSignature);
- mName = sb.toString();
- }
-
- public String getName() {
- return mName;
- }
-
- public String getClassName() {
- return mClassName;
- }
-
- public String getMethodName() {
- return mMethodName;
- }
-
- public String getProfileName() {
- return mProfileName;
- }
-
- public String getSignature() {
- return mSignature;
- }
-
- public void computeProfileName() {
- if (mRank == -1) {
- mProfileName = mName;
- return;
- }
-
- StringBuilder sb = new StringBuilder();
- sb.append(mRank);
- sb.append(" "); //$NON-NLS-1$
- sb.append(getName());
- mProfileName = sb.toString();
- }
-
- public String getCalls() {
- return String.format("%d+%d", mNumCalls[0], mNumCalls[1]);
- }
-
- public int getTotalCalls() {
- return mNumCalls[0] + mNumCalls[1];
- }
-
- public Color getColor() {
- return mColor;
- }
-
- public void setColor(Color color) {
- mColor = color;
- }
-
- public void setImage(Image image) {
- mImage = image;
- }
-
- public Image getImage() {
- return mImage;
- }
-
- @Override
- public String toString() {
- return getName();
- }
-
- public long getElapsedExclusiveCpuTime() {
- return mElapsedExclusiveCpuTime;
- }
-
- public long getElapsedExclusiveRealTime() {
- return mElapsedExclusiveRealTime;
- }
-
- public long getElapsedInclusiveCpuTime() {
- return mElapsedInclusiveCpuTime;
- }
-
- public long getElapsedInclusiveRealTime() {
- return mElapsedInclusiveRealTime;
- }
-
- public void setFadedColor(Color fadedColor) {
- mFadedColor = fadedColor;
- }
-
- public Color getFadedColor() {
- return mFadedColor;
- }
-
- public void setFadedImage(Image fadedImage) {
- mFadedImage = fadedImage;
- }
-
- public Image getFadedImage() {
- return mFadedImage;
- }
-
- public void setPathname(String pathname) {
- mPathname = pathname;
- }
-
- public String getPathname() {
- return mPathname;
- }
-
- public void setLineNumber(int lineNumber) {
- mLineNumber = lineNumber;
- }
-
- public int getLineNumber() {
- return mLineNumber;
- }
-
- public ProfileNode[] getProfileNodes() {
- return mProfileNodes;
- }
-
- public static class Sorter implements Comparator<MethodData> {
- @Override
- public int compare(MethodData md1, MethodData md2) {
- if (mColumn == Column.BY_NAME) {
- int result = md1.getName().compareTo(md2.getName());
- return (mDirection == Direction.INCREASING) ? result : -result;
- }
- if (mColumn == Column.BY_INCLUSIVE_CPU_TIME) {
- if (md2.getElapsedInclusiveCpuTime() > md1.getElapsedInclusiveCpuTime())
- return (mDirection == Direction.INCREASING) ? -1 : 1;
- if (md2.getElapsedInclusiveCpuTime() < md1.getElapsedInclusiveCpuTime())
- return (mDirection == Direction.INCREASING) ? 1 : -1;
- return md1.getName().compareTo(md2.getName());
- }
- if (mColumn == Column.BY_EXCLUSIVE_CPU_TIME) {
- if (md2.getElapsedExclusiveCpuTime() > md1.getElapsedExclusiveCpuTime())
- return (mDirection == Direction.INCREASING) ? -1 : 1;
- if (md2.getElapsedExclusiveCpuTime() < md1.getElapsedExclusiveCpuTime())
- return (mDirection == Direction.INCREASING) ? 1 : -1;
- return md1.getName().compareTo(md2.getName());
- }
- if (mColumn == Column.BY_INCLUSIVE_REAL_TIME) {
- if (md2.getElapsedInclusiveRealTime() > md1.getElapsedInclusiveRealTime())
- return (mDirection == Direction.INCREASING) ? -1 : 1;
- if (md2.getElapsedInclusiveRealTime() < md1.getElapsedInclusiveRealTime())
- return (mDirection == Direction.INCREASING) ? 1 : -1;
- return md1.getName().compareTo(md2.getName());
- }
- if (mColumn == Column.BY_EXCLUSIVE_REAL_TIME) {
- if (md2.getElapsedExclusiveRealTime() > md1.getElapsedExclusiveRealTime())
- return (mDirection == Direction.INCREASING) ? -1 : 1;
- if (md2.getElapsedExclusiveRealTime() < md1.getElapsedExclusiveRealTime())
- return (mDirection == Direction.INCREASING) ? 1 : -1;
- return md1.getName().compareTo(md2.getName());
- }
- if (mColumn == Column.BY_CALLS) {
- int result = md1.getTotalCalls() - md2.getTotalCalls();
- if (result == 0)
- return md1.getName().compareTo(md2.getName());
- return (mDirection == Direction.INCREASING) ? result : -result;
- }
- if (mColumn == Column.BY_CPU_TIME_PER_CALL) {
- double time1 = md1.getElapsedInclusiveCpuTime();
- time1 = time1 / md1.getTotalCalls();
- double time2 = md2.getElapsedInclusiveCpuTime();
- time2 = time2 / md2.getTotalCalls();
- double diff = time1 - time2;
- int result = 0;
- if (diff < 0)
- result = -1;
- else if (diff > 0)
- result = 1;
- if (result == 0)
- return md1.getName().compareTo(md2.getName());
- return (mDirection == Direction.INCREASING) ? result : -result;
- }
- if (mColumn == Column.BY_REAL_TIME_PER_CALL) {
- double time1 = md1.getElapsedInclusiveRealTime();
- time1 = time1 / md1.getTotalCalls();
- double time2 = md2.getElapsedInclusiveRealTime();
- time2 = time2 / md2.getTotalCalls();
- double diff = time1 - time2;
- int result = 0;
- if (diff < 0)
- result = -1;
- else if (diff > 0)
- result = 1;
- if (result == 0)
- return md1.getName().compareTo(md2.getName());
- return (mDirection == Direction.INCREASING) ? result : -result;
- }
- return 0;
- }
-
- public void setColumn(Column column) {
- // If the sort column specified is the same as last time,
- // then reverse the sort order.
- if (mColumn == column) {
- // Reverse the sort order
- if (mDirection == Direction.INCREASING)
- mDirection = Direction.DECREASING;
- else
- mDirection = Direction.INCREASING;
- } else {
- // Sort names into increasing order, data into decreasing order.
- if (column == Column.BY_NAME)
- mDirection = Direction.INCREASING;
- else
- mDirection = Direction.DECREASING;
- }
- mColumn = column;
- }
-
- public Column getColumn() {
- return mColumn;
- }
-
- public void setDirection(Direction direction) {
- mDirection = direction;
- }
-
- public Direction getDirection() {
- return mDirection;
- }
-
- public static enum Column {
- BY_NAME, BY_EXCLUSIVE_CPU_TIME, BY_EXCLUSIVE_REAL_TIME,
- BY_INCLUSIVE_CPU_TIME, BY_INCLUSIVE_REAL_TIME, BY_CALLS,
- BY_REAL_TIME_PER_CALL, BY_CPU_TIME_PER_CALL,
- };
-
- public static enum Direction {
- INCREASING, DECREASING
- };
-
- private Column mColumn;
- private Direction mDirection;
- }
-}
diff --git a/traceview/src/com/android/traceview/ProfileData.java b/traceview/src/com/android/traceview/ProfileData.java
deleted file mode 100644
index e3c47fb..0000000
--- a/traceview/src/com/android/traceview/ProfileData.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-
-public class ProfileData {
-
- protected MethodData mElement;
-
- /** mContext is either the parent or child of mElement */
- protected MethodData mContext;
- protected boolean mElementIsParent;
- protected long mElapsedInclusiveCpuTime;
- protected long mElapsedInclusiveRealTime;
- protected int mNumCalls;
-
- public ProfileData() {
- }
-
- public ProfileData(MethodData context, MethodData element,
- boolean elementIsParent) {
- mContext = context;
- mElement = element;
- mElementIsParent = elementIsParent;
- }
-
- public String getProfileName() {
- return mElement.getProfileName();
- }
-
- public MethodData getMethodData() {
- return mElement;
- }
-
- public void addElapsedInclusive(long cpuTime, long realTime) {
- mElapsedInclusiveCpuTime += cpuTime;
- mElapsedInclusiveRealTime += realTime;
- mNumCalls += 1;
- }
-
- public void setElapsedInclusive(long cpuTime, long realTime) {
- mElapsedInclusiveCpuTime = cpuTime;
- mElapsedInclusiveRealTime = realTime;
- }
-
- public long getElapsedInclusiveCpuTime() {
- return mElapsedInclusiveCpuTime;
- }
-
- public long getElapsedInclusiveRealTime() {
- return mElapsedInclusiveRealTime;
- }
-
- public void setNumCalls(int numCalls) {
- mNumCalls = numCalls;
- }
-
- public String getNumCalls() {
- int totalCalls;
- if (mElementIsParent)
- totalCalls = mContext.getTotalCalls();
- else
- totalCalls = mElement.getTotalCalls();
- return String.format("%d/%d", mNumCalls, totalCalls);
- }
-
- public boolean isParent() {
- return mElementIsParent;
- }
-
- public MethodData getContext() {
- return mContext;
- }
-}
diff --git a/traceview/src/com/android/traceview/ProfileNode.java b/traceview/src/com/android/traceview/ProfileNode.java
deleted file mode 100644
index 7cb0b5d..0000000
--- a/traceview/src/com/android/traceview/ProfileNode.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-public class ProfileNode {
-
- private String mLabel;
- private MethodData mMethodData;
- private ProfileData[] mChildren;
- private boolean mIsParent;
- private boolean mIsRecursive;
-
- public ProfileNode(String label, MethodData methodData,
- ProfileData[] children, boolean isParent, boolean isRecursive) {
- mLabel = label;
- mMethodData = methodData;
- mChildren = children;
- mIsParent = isParent;
- mIsRecursive = isRecursive;
- }
-
- public String getLabel() {
- return mLabel;
- }
-
- public ProfileData[] getChildren() {
- return mChildren;
- }
-
- public boolean isParent() {
- return mIsParent;
- }
-
- public boolean isRecursive() {
- return mIsRecursive;
- }
-}
diff --git a/traceview/src/com/android/traceview/ProfileProvider.java b/traceview/src/com/android/traceview/ProfileProvider.java
deleted file mode 100644
index 995e606..0000000
--- a/traceview/src/com/android/traceview/ProfileProvider.java
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-import com.android.utils.SdkUtils;
-
-import org.eclipse.jface.viewers.IColorProvider;
-import org.eclipse.jface.viewers.ITableLabelProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.LabelProvider;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-import org.eclipse.swt.widgets.TreeItem;
-
-import java.io.InputStream;
-import java.util.Arrays;
-
-class ProfileProvider implements ITreeContentProvider {
-
- private MethodData[] mRoots;
- private SelectionAdapter mListener;
- private TreeViewer mTreeViewer;
- private TraceReader mReader;
- private Image mSortUp;
- private Image mSortDown;
- private String mColumnNames[] = { "Name",
- "Incl Cpu Time %", "Incl Cpu Time", "Excl Cpu Time %", "Excl Cpu Time",
- "Incl Real Time %", "Incl Real Time", "Excl Real Time %", "Excl Real Time",
- "Calls+Recur\nCalls/Total", "Cpu Time/Call", "Real Time/Call" };
- private int mColumnWidths[] = { 370,
- 100, 100, 100, 100,
- 100, 100, 100, 100,
- 100, 100, 100 };
- private int mColumnAlignments[] = { SWT.LEFT,
- SWT.RIGHT, SWT.RIGHT, SWT.RIGHT, SWT.RIGHT,
- SWT.RIGHT, SWT.RIGHT, SWT.RIGHT, SWT.RIGHT,
- SWT.CENTER, SWT.RIGHT, SWT.RIGHT };
- private static final int COL_NAME = 0;
- private static final int COL_INCLUSIVE_CPU_TIME_PER = 1;
- private static final int COL_INCLUSIVE_CPU_TIME = 2;
- private static final int COL_EXCLUSIVE_CPU_TIME_PER = 3;
- private static final int COL_EXCLUSIVE_CPU_TIME = 4;
- private static final int COL_INCLUSIVE_REAL_TIME_PER = 5;
- private static final int COL_INCLUSIVE_REAL_TIME = 6;
- private static final int COL_EXCLUSIVE_REAL_TIME_PER = 7;
- private static final int COL_EXCLUSIVE_REAL_TIME = 8;
- private static final int COL_CALLS = 9;
- private static final int COL_CPU_TIME_PER_CALL = 10;
- private static final int COL_REAL_TIME_PER_CALL = 11;
- private long mTotalCpuTime;
- private long mTotalRealTime;
- private int mPrevMatchIndex = -1;
-
- public ProfileProvider(TraceReader reader) {
- mRoots = reader.getMethods();
- mReader = reader;
- mTotalCpuTime = reader.getTotalCpuTime();
- mTotalRealTime = reader.getTotalRealTime();
- Display display = Display.getCurrent();
- InputStream in = getClass().getClassLoader().getResourceAsStream(
- "icons/sort_up.png");
- mSortUp = new Image(display, in);
- in = getClass().getClassLoader().getResourceAsStream(
- "icons/sort_down.png");
- mSortDown = new Image(display, in);
- }
-
- private MethodData doMatchName(String name, int startIndex) {
- // Check if the given "name" has any uppercase letters
- boolean hasUpper = SdkUtils.hasUpperCaseCharacter(name);
- for (int ii = startIndex; ii < mRoots.length; ++ii) {
- MethodData md = mRoots[ii];
- String fullName = md.getName();
- // If there were no upper case letters in the given name,
- // then ignore case when matching.
- if (!hasUpper)
- fullName = fullName.toLowerCase();
- if (fullName.indexOf(name) != -1) {
- mPrevMatchIndex = ii;
- return md;
- }
- }
- mPrevMatchIndex = -1;
- return null;
- }
-
- public MethodData findMatchingName(String name) {
- return doMatchName(name, 0);
- }
-
- public MethodData findNextMatchingName(String name) {
- return doMatchName(name, mPrevMatchIndex + 1);
- }
-
- public MethodData findMatchingTreeItem(TreeItem item) {
- if (item == null)
- return null;
- String text = item.getText();
- if (Character.isDigit(text.charAt(0)) == false)
- return null;
- int spaceIndex = text.indexOf(' ');
- String numstr = text.substring(0, spaceIndex);
- int rank = Integer.valueOf(numstr);
- for (MethodData md : mRoots) {
- if (md.getRank() == rank)
- return md;
- }
- return null;
- }
-
- public void setTreeViewer(TreeViewer treeViewer) {
- mTreeViewer = treeViewer;
- }
-
- public String[] getColumnNames() {
- return mColumnNames;
- }
-
- public int[] getColumnWidths() {
- int[] widths = Arrays.copyOf(mColumnWidths, mColumnWidths.length);
- if (!mReader.haveCpuTime()) {
- widths[COL_EXCLUSIVE_CPU_TIME] = 0;
- widths[COL_EXCLUSIVE_CPU_TIME_PER] = 0;
- widths[COL_INCLUSIVE_CPU_TIME] = 0;
- widths[COL_INCLUSIVE_CPU_TIME_PER] = 0;
- widths[COL_CPU_TIME_PER_CALL] = 0;
- }
- if (!mReader.haveRealTime()) {
- widths[COL_EXCLUSIVE_REAL_TIME] = 0;
- widths[COL_EXCLUSIVE_REAL_TIME_PER] = 0;
- widths[COL_INCLUSIVE_REAL_TIME] = 0;
- widths[COL_INCLUSIVE_REAL_TIME_PER] = 0;
- widths[COL_REAL_TIME_PER_CALL] = 0;
- }
- return widths;
- }
-
- public int[] getColumnAlignments() {
- return mColumnAlignments;
- }
-
- @Override
- public Object[] getChildren(Object element) {
- if (element instanceof MethodData) {
- MethodData md = (MethodData) element;
- return md.getProfileNodes();
- }
- if (element instanceof ProfileNode) {
- ProfileNode pn = (ProfileNode) element;
- return pn.getChildren();
- }
- return new Object[0];
- }
-
- @Override
- public Object getParent(Object element) {
- return null;
- }
-
- @Override
- public boolean hasChildren(Object element) {
- if (element instanceof MethodData)
- return true;
- if (element instanceof ProfileNode)
- return true;
- return false;
- }
-
- @Override
- public Object[] getElements(Object element) {
- return mRoots;
- }
-
- @Override
- public void dispose() {
- }
-
- @Override
- public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
- }
-
- public Object getRoot() {
- return "root";
- }
-
- public SelectionAdapter getColumnListener() {
- if (mListener == null)
- mListener = new ColumnListener();
- return mListener;
- }
-
- public LabelProvider getLabelProvider() {
- return new ProfileLabelProvider();
- }
-
- class ProfileLabelProvider extends LabelProvider implements
- ITableLabelProvider, IColorProvider {
- Color colorRed;
- Color colorParentsBack;
- Color colorChildrenBack;
- TraceUnits traceUnits;
-
- public ProfileLabelProvider() {
- Display display = Display.getCurrent();
- colorRed = display.getSystemColor(SWT.COLOR_RED);
- colorParentsBack = new Color(display, 230, 230, 255); // blue
- colorChildrenBack = new Color(display, 255, 255, 210); // yellow
- traceUnits = mReader.getTraceUnits();
- }
-
- @Override
- public String getColumnText(Object element, int col) {
- if (element instanceof MethodData) {
- MethodData md = (MethodData) element;
- if (col == COL_NAME)
- return md.getProfileName();
- if (col == COL_EXCLUSIVE_CPU_TIME) {
- double val = md.getElapsedExclusiveCpuTime();
- val = traceUnits.getScaledValue(val);
- return String.format("%.3f", val);
- }
- if (col == COL_EXCLUSIVE_CPU_TIME_PER) {
- double val = md.getElapsedExclusiveCpuTime();
- double per = val * 100.0 / mTotalCpuTime;
- return String.format("%.1f%%", per);
- }
- if (col == COL_INCLUSIVE_CPU_TIME) {
- double val = md.getElapsedInclusiveCpuTime();
- val = traceUnits.getScaledValue(val);
- return String.format("%.3f", val);
- }
- if (col == COL_INCLUSIVE_CPU_TIME_PER) {
- double val = md.getElapsedInclusiveCpuTime();
- double per = val * 100.0 / mTotalCpuTime;
- return String.format("%.1f%%", per);
- }
- if (col == COL_EXCLUSIVE_REAL_TIME) {
- double val = md.getElapsedExclusiveRealTime();
- val = traceUnits.getScaledValue(val);
- return String.format("%.3f", val);
- }
- if (col == COL_EXCLUSIVE_REAL_TIME_PER) {
- double val = md.getElapsedExclusiveRealTime();
- double per = val * 100.0 / mTotalRealTime;
- return String.format("%.1f%%", per);
- }
- if (col == COL_INCLUSIVE_REAL_TIME) {
- double val = md.getElapsedInclusiveRealTime();
- val = traceUnits.getScaledValue(val);
- return String.format("%.3f", val);
- }
- if (col == COL_INCLUSIVE_REAL_TIME_PER) {
- double val = md.getElapsedInclusiveRealTime();
- double per = val * 100.0 / mTotalRealTime;
- return String.format("%.1f%%", per);
- }
- if (col == COL_CALLS)
- return md.getCalls();
- if (col == COL_CPU_TIME_PER_CALL) {
- int numCalls = md.getTotalCalls();
- double val = md.getElapsedInclusiveCpuTime();
- val = val / numCalls;
- val = traceUnits.getScaledValue(val);
- return String.format("%.3f", val);
- }
- if (col == COL_REAL_TIME_PER_CALL) {
- int numCalls = md.getTotalCalls();
- double val = md.getElapsedInclusiveRealTime();
- val = val / numCalls;
- val = traceUnits.getScaledValue(val);
- return String.format("%.3f", val);
- }
- } else if (element instanceof ProfileSelf) {
- ProfileSelf ps = (ProfileSelf) element;
- if (col == COL_NAME)
- return ps.getProfileName();
- if (col == COL_INCLUSIVE_CPU_TIME) {
- double val = ps.getElapsedInclusiveCpuTime();
- val = traceUnits.getScaledValue(val);
- return String.format("%.3f", val);
- }
- if (col == COL_INCLUSIVE_CPU_TIME_PER) {
- double total;
- double val = ps.getElapsedInclusiveCpuTime();
- MethodData context = ps.getContext();
- total = context.getElapsedInclusiveCpuTime();
- double per = val * 100.0 / total;
- return String.format("%.1f%%", per);
- }
- if (col == COL_INCLUSIVE_REAL_TIME) {
- double val = ps.getElapsedInclusiveRealTime();
- val = traceUnits.getScaledValue(val);
- return String.format("%.3f", val);
- }
- if (col == COL_INCLUSIVE_REAL_TIME_PER) {
- double total;
- double val = ps.getElapsedInclusiveRealTime();
- MethodData context = ps.getContext();
- total = context.getElapsedInclusiveRealTime();
- double per = val * 100.0 / total;
- return String.format("%.1f%%", per);
- }
- return "";
- } else if (element instanceof ProfileData) {
- ProfileData pd = (ProfileData) element;
- if (col == COL_NAME)
- return pd.getProfileName();
- if (col == COL_INCLUSIVE_CPU_TIME) {
- double val = pd.getElapsedInclusiveCpuTime();
- val = traceUnits.getScaledValue(val);
- return String.format("%.3f", val);
- }
- if (col == COL_INCLUSIVE_CPU_TIME_PER) {
- double total;
- double val = pd.getElapsedInclusiveCpuTime();
- MethodData context = pd.getContext();
- total = context.getElapsedInclusiveCpuTime();
- double per = val * 100.0 / total;
- return String.format("%.1f%%", per);
- }
- if (col == COL_INCLUSIVE_REAL_TIME) {
- double val = pd.getElapsedInclusiveRealTime();
- val = traceUnits.getScaledValue(val);
- return String.format("%.3f", val);
- }
- if (col == COL_INCLUSIVE_REAL_TIME_PER) {
- double total;
- double val = pd.getElapsedInclusiveRealTime();
- MethodData context = pd.getContext();
- total = context.getElapsedInclusiveRealTime();
- double per = val * 100.0 / total;
- return String.format("%.1f%%", per);
- }
- if (col == COL_CALLS)
- return pd.getNumCalls();
- return "";
- } else if (element instanceof ProfileNode) {
- ProfileNode pn = (ProfileNode) element;
- if (col == COL_NAME)
- return pn.getLabel();
- return "";
- }
- return "col" + col;
- }
-
- @Override
- public Image getColumnImage(Object element, int col) {
- if (col != COL_NAME)
- return null;
- if (element instanceof MethodData) {
- MethodData md = (MethodData) element;
- return md.getImage();
- }
- if (element instanceof ProfileData) {
- ProfileData pd = (ProfileData) element;
- MethodData md = pd.getMethodData();
- return md.getImage();
- }
- return null;
- }
-
- @Override
- public Color getForeground(Object element) {
- return null;
- }
-
- @Override
- public Color getBackground(Object element) {
- if (element instanceof ProfileData) {
- ProfileData pd = (ProfileData) element;
- if (pd.isParent())
- return colorParentsBack;
- return colorChildrenBack;
- }
- if (element instanceof ProfileNode) {
- ProfileNode pn = (ProfileNode) element;
- if (pn.isParent())
- return colorParentsBack;
- return colorChildrenBack;
- }
- return null;
- }
- }
-
- class ColumnListener extends SelectionAdapter {
- MethodData.Sorter sorter = new MethodData.Sorter();
-
- @Override
- public void widgetSelected(SelectionEvent event) {
- TreeColumn column = (TreeColumn) event.widget;
- String name = column.getText();
- Tree tree = column.getParent();
- tree.setRedraw(false);
- TreeColumn[] columns = tree.getColumns();
- for (TreeColumn col : columns) {
- col.setImage(null);
- }
- if (name == mColumnNames[COL_NAME]) {
- // Sort names alphabetically
- sorter.setColumn(MethodData.Sorter.Column.BY_NAME);
- Arrays.sort(mRoots, sorter);
- } else if (name == mColumnNames[COL_EXCLUSIVE_CPU_TIME]) {
- sorter.setColumn(MethodData.Sorter.Column.BY_EXCLUSIVE_CPU_TIME);
- Arrays.sort(mRoots, sorter);
- } else if (name == mColumnNames[COL_EXCLUSIVE_CPU_TIME_PER]) {
- sorter.setColumn(MethodData.Sorter.Column.BY_EXCLUSIVE_CPU_TIME);
- Arrays.sort(mRoots, sorter);
- } else if (name == mColumnNames[COL_INCLUSIVE_CPU_TIME]) {
- sorter.setColumn(MethodData.Sorter.Column.BY_INCLUSIVE_CPU_TIME);
- Arrays.sort(mRoots, sorter);
- } else if (name == mColumnNames[COL_INCLUSIVE_CPU_TIME_PER]) {
- sorter.setColumn(MethodData.Sorter.Column.BY_INCLUSIVE_CPU_TIME);
- Arrays.sort(mRoots, sorter);
- } else if (name == mColumnNames[COL_EXCLUSIVE_REAL_TIME]) {
- sorter.setColumn(MethodData.Sorter.Column.BY_EXCLUSIVE_REAL_TIME);
- Arrays.sort(mRoots, sorter);
- } else if (name == mColumnNames[COL_EXCLUSIVE_REAL_TIME_PER]) {
- sorter.setColumn(MethodData.Sorter.Column.BY_EXCLUSIVE_REAL_TIME);
- Arrays.sort(mRoots, sorter);
- } else if (name == mColumnNames[COL_INCLUSIVE_REAL_TIME]) {
- sorter.setColumn(MethodData.Sorter.Column.BY_INCLUSIVE_REAL_TIME);
- Arrays.sort(mRoots, sorter);
- } else if (name == mColumnNames[COL_INCLUSIVE_REAL_TIME_PER]) {
- sorter.setColumn(MethodData.Sorter.Column.BY_INCLUSIVE_REAL_TIME);
- Arrays.sort(mRoots, sorter);
- } else if (name == mColumnNames[COL_CALLS]) {
- sorter.setColumn(MethodData.Sorter.Column.BY_CALLS);
- Arrays.sort(mRoots, sorter);
- } else if (name == mColumnNames[COL_CPU_TIME_PER_CALL]) {
- sorter.setColumn(MethodData.Sorter.Column.BY_CPU_TIME_PER_CALL);
- Arrays.sort(mRoots, sorter);
- } else if (name == mColumnNames[COL_REAL_TIME_PER_CALL]) {
- sorter.setColumn(MethodData.Sorter.Column.BY_REAL_TIME_PER_CALL);
- Arrays.sort(mRoots, sorter);
- }
- MethodData.Sorter.Direction direction = sorter.getDirection();
- if (direction == MethodData.Sorter.Direction.INCREASING)
- column.setImage(mSortDown);
- else
- column.setImage(mSortUp);
- tree.setRedraw(true);
- mTreeViewer.refresh();
- }
- }
-}
diff --git a/traceview/src/com/android/traceview/ProfileSelf.java b/traceview/src/com/android/traceview/ProfileSelf.java
deleted file mode 100644
index 45543b2..0000000
--- a/traceview/src/com/android/traceview/ProfileSelf.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-public class ProfileSelf extends ProfileData {
- public ProfileSelf(MethodData methodData) {
- mElement = methodData;
- mContext = methodData;
- }
-
- @Override
- public String getProfileName() {
- return "self";
- }
-
- @Override
- public long getElapsedInclusiveCpuTime() {
- return mElement.getTopExclusiveCpuTime();
- }
-
- @Override
- public long getElapsedInclusiveRealTime() {
- return mElement.getTopExclusiveRealTime();
- }
-}
diff --git a/traceview/src/com/android/traceview/ProfileView.java b/traceview/src/com/android/traceview/ProfileView.java
deleted file mode 100644
index 683a2c7..0000000
--- a/traceview/src/com/android/traceview/ProfileView.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.ITreeViewerListener;
-import org.eclipse.jface.viewers.SelectionChangedEvent;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.viewers.TreeExpansionEvent;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.KeyAdapter;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-import org.eclipse.swt.widgets.TreeItem;
-
-import java.util.ArrayList;
-import java.util.Observable;
-import java.util.Observer;
-
-public class ProfileView extends Composite implements Observer {
-
- private TreeViewer mTreeViewer;
- private Text mSearchBox;
- private SelectionController mSelectionController;
- private ProfileProvider mProfileProvider;
- private Color mColorNoMatch;
- private Color mColorMatch;
- private MethodData mCurrentHighlightedMethod;
- private MethodHandler mMethodHandler;
-
- public interface MethodHandler {
- void handleMethod(MethodData method);
- }
-
- public ProfileView(Composite parent, TraceReader reader,
- SelectionController selectController) {
- super(parent, SWT.NONE);
- setLayout(new GridLayout(1, false));
- this.mSelectionController = selectController;
- mSelectionController.addObserver(this);
-
- // Add a tree viewer at the top
- mTreeViewer = new TreeViewer(this, SWT.MULTI | SWT.NONE);
- mTreeViewer.setUseHashlookup(true);
- mProfileProvider = reader.getProfileProvider();
- mProfileProvider.setTreeViewer(mTreeViewer);
- SelectionAdapter listener = mProfileProvider.getColumnListener();
- final Tree tree = mTreeViewer.getTree();
- tree.setHeaderVisible(true);
- tree.setLayoutData(new GridData(GridData.FILL_BOTH));
-
- // Get the column names from the ProfileProvider
- String[] columnNames = mProfileProvider.getColumnNames();
- int[] columnWidths = mProfileProvider.getColumnWidths();
- int[] columnAlignments = mProfileProvider.getColumnAlignments();
- for (int ii = 0; ii < columnWidths.length; ++ii) {
- TreeColumn column = new TreeColumn(tree, SWT.LEFT);
- column.setText(columnNames[ii]);
- column.setWidth(columnWidths[ii]);
- column.setMoveable(true);
- column.addSelectionListener(listener);
- column.setAlignment(columnAlignments[ii]);
- }
-
- // Add a listener to the tree so that we can make the row
- // height smaller.
- tree.addListener(SWT.MeasureItem, new Listener() {
- @Override
- public void handleEvent(Event event) {
- int fontHeight = event.gc.getFontMetrics().getHeight();
- event.height = fontHeight;
- }
- });
-
- mTreeViewer.setContentProvider(mProfileProvider);
- mTreeViewer.setLabelProvider(mProfileProvider.getLabelProvider());
- mTreeViewer.setInput(mProfileProvider.getRoot());
-
- // Create another composite to hold the label and text box
- Composite composite = new Composite(this, SWT.NONE);
- composite.setLayout(new GridLayout(2, false));
- composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
- // Add a label for the search box
- Label label = new Label(composite, SWT.NONE);
- label.setText("Find:");
-
- // Add a text box for searching for method names
- mSearchBox = new Text(composite, SWT.BORDER);
- mSearchBox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
- Display display = getDisplay();
- mColorNoMatch = new Color(display, 255, 200, 200);
- mColorMatch = mSearchBox.getBackground();
-
- mSearchBox.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent ev) {
- String query = mSearchBox.getText();
- if (query.length() == 0)
- return;
- findName(query);
- }
- });
-
- // Add a key listener to the text box so that we can clear
- // the text box if the user presses <ESC>.
- mSearchBox.addKeyListener(new KeyAdapter() {
- @Override
- public void keyPressed(KeyEvent event) {
- if (event.keyCode == SWT.ESC) {
- mSearchBox.setText("");
- } else if (event.keyCode == SWT.CR) {
- String query = mSearchBox.getText();
- if (query.length() == 0)
- return;
- findNextName(query);
- }
- }
- });
-
- // Also add a key listener to the tree viewer so that the
- // user can just start typing anywhere in the tree view.
- tree.addKeyListener(new KeyAdapter() {
- @Override
- public void keyPressed(KeyEvent event) {
- if (event.keyCode == SWT.ESC) {
- mSearchBox.setText("");
- } else if (event.keyCode == SWT.BS) {
- // Erase the last character from the search box
- String text = mSearchBox.getText();
- int len = text.length();
- String chopped;
- if (len <= 1)
- chopped = "";
- else
- chopped = text.substring(0, len - 1);
- mSearchBox.setText(chopped);
- } else if (event.keyCode == SWT.CR) {
- String query = mSearchBox.getText();
- if (query.length() == 0)
- return;
- findNextName(query);
- } else {
- // Append the given character to the search box
- String str = String.valueOf(event.character);
- mSearchBox.append(str);
- }
- event.doit = false;
- }
- });
-
- // Add a selection listener to the tree so that the user can click
- // on a method that is a child or parent and jump to that method.
- mTreeViewer
- .addSelectionChangedListener(new ISelectionChangedListener() {
- @Override
- public void selectionChanged(SelectionChangedEvent ev) {
- ISelection sel = ev.getSelection();
- if (sel.isEmpty())
- return;
- if (sel instanceof IStructuredSelection) {
- IStructuredSelection selection = (IStructuredSelection) sel;
- Object element = selection.getFirstElement();
- if (element == null)
- return;
- if (element instanceof MethodData) {
- MethodData md = (MethodData) element;
- highlightMethod(md, true);
- }
- if (element instanceof ProfileData) {
- MethodData md = ((ProfileData) element)
- .getMethodData();
- highlightMethod(md, true);
- }
- }
- }
- });
-
- // Add a tree listener so that we can expand the parents and children
- // of a method when a method is expanded.
- mTreeViewer.addTreeListener(new ITreeViewerListener() {
- @Override
- public void treeExpanded(TreeExpansionEvent event) {
- Object element = event.getElement();
- if (element instanceof MethodData) {
- MethodData md = (MethodData) element;
- expandNode(md);
- }
- }
- @Override
- public void treeCollapsed(TreeExpansionEvent event) {
- }
- });
-
- tree.addListener(SWT.MouseDown, new Listener() {
- @Override
- public void handleEvent(Event event) {
- Point point = new Point(event.x, event.y);
- TreeItem treeItem = tree.getItem(point);
- MethodData md = mProfileProvider.findMatchingTreeItem(treeItem);
- if (md == null)
- return;
- ArrayList<Selection> selections = new ArrayList<Selection>();
- selections.add(Selection.highlight("MethodData", md));
- mSelectionController.change(selections, "ProfileView");
-
- if (mMethodHandler != null && (event.stateMask & SWT.MOD1) != 0) {
- mMethodHandler.handleMethod(md);
- }
- }
- });
- }
-
- public void setMethodHandler(MethodHandler handler) {
- mMethodHandler = handler;
- }
-
- private void findName(String query) {
- MethodData md = mProfileProvider.findMatchingName(query);
- selectMethod(md);
- }
-
- private void findNextName(String query) {
- MethodData md = mProfileProvider.findNextMatchingName(query);
- selectMethod(md);
- }
-
- private void selectMethod(MethodData md) {
- if (md == null) {
- mSearchBox.setBackground(mColorNoMatch);
- return;
- }
- mSearchBox.setBackground(mColorMatch);
- highlightMethod(md, false);
- }
-
- @Override
- public void update(Observable objservable, Object arg) {
- // Ignore updates from myself
- if (arg == "ProfileView")
- return;
- // System.out.printf("profileview update from %s\n", arg);
- ArrayList<Selection> selections;
- selections = mSelectionController.getSelections();
- for (Selection selection : selections) {
- Selection.Action action = selection.getAction();
- if (action != Selection.Action.Highlight)
- continue;
- String name = selection.getName();
- if (name == "MethodData") {
- MethodData md = (MethodData) selection.getValue();
- highlightMethod(md, true);
- return;
- }
- if (name == "Call") {
- Call call = (Call) selection.getValue();
- MethodData md = call.getMethodData();
- highlightMethod(md, true);
- return;
- }
- }
- }
-
- private void highlightMethod(MethodData md, boolean clearSearch) {
- if (md == null)
- return;
- // Avoid an infinite recursion
- if (md == mCurrentHighlightedMethod)
- return;
- if (clearSearch) {
- mSearchBox.setText("");
- mSearchBox.setBackground(mColorMatch);
- }
- mCurrentHighlightedMethod = md;
- mTreeViewer.collapseAll();
- // Expand this node and its children
- expandNode(md);
- StructuredSelection sel = new StructuredSelection(md);
- mTreeViewer.setSelection(sel, true);
- Tree tree = mTreeViewer.getTree();
- TreeItem[] items = tree.getSelection();
- if (items.length != 0) {
- tree.setTopItem(items[0]);
- // workaround a Mac bug by adding showItem().
- tree.showItem(items[0]);
- }
- }
-
- private void expandNode(MethodData md) {
- ProfileNode[] nodes = md.getProfileNodes();
- mTreeViewer.setExpandedState(md, true);
- // Also expand the "Parents" and "Children" nodes.
- if (nodes != null) {
- for (ProfileNode node : nodes) {
- if (node.isRecursive() == false)
- mTreeViewer.setExpandedState(node, true);
- }
- }
- }
-}
diff --git a/traceview/src/com/android/traceview/PropertiesDialog.java b/traceview/src/com/android/traceview/PropertiesDialog.java
deleted file mode 100644
index 9f5eff9..0000000
--- a/traceview/src/com/android/traceview/PropertiesDialog.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.traceview;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.viewers.ArrayContentProvider;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.TableViewer;
-import org.eclipse.jface.viewers.TableViewerColumn;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Shell;
-
-import java.util.HashMap;
-import java.util.Map.Entry;
-
-public class PropertiesDialog extends Dialog {
- private HashMap<String, String> mProperties;
-
- public PropertiesDialog(Shell parent) {
- super(parent);
-
- setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE);
- }
-
- public void setProperties(HashMap<String, String> properties) {
- mProperties = properties;
- }
-
- @Override
- protected void createButtonsForButtonBar(Composite parent) {
- createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
- }
-
- @Override
- protected Control createDialogArea(Composite parent) {
- Composite container = (Composite) super.createDialogArea(parent);
- GridLayout gridLayout = new GridLayout(1, false);
- gridLayout.marginWidth = 0;
- gridLayout.marginHeight = 0;
- gridLayout.horizontalSpacing = 0;
- gridLayout.verticalSpacing = 0;
- container.setLayout(gridLayout);
-
- TableViewer tableViewer = new TableViewer(container, SWT.HIDE_SELECTION
- | SWT.V_SCROLL | SWT.BORDER);
- tableViewer.getTable().setLinesVisible(true);
- tableViewer.getTable().setHeaderVisible(true);
-
- TableViewerColumn propertyColumn = new TableViewerColumn(tableViewer, SWT.NONE);
- propertyColumn.getColumn().setText("Property");
- propertyColumn.setLabelProvider(new ColumnLabelProvider() {
- @Override
- @SuppressWarnings("unchecked")
- public String getText(Object element) {
- Entry<String, String> entry = (Entry<String, String>) element;
- return entry.getKey();
- }
- });
- propertyColumn.getColumn().setWidth(400);
-
- TableViewerColumn valueColumn = new TableViewerColumn(tableViewer, SWT.NONE);
- valueColumn.getColumn().setText("Value");
- valueColumn.setLabelProvider(new ColumnLabelProvider() {
- @Override
- @SuppressWarnings("unchecked")
- public String getText(Object element) {
- Entry<String, String> entry = (Entry<String, String>) element;
- return entry.getValue();
- }
- });
- valueColumn.getColumn().setWidth(200);
-
- tableViewer.setContentProvider(new ArrayContentProvider());
- tableViewer.setInput(mProperties.entrySet().toArray());
-
- GridData gridData = new GridData();
- gridData.verticalAlignment = GridData.FILL;
- gridData.horizontalAlignment = GridData.FILL;
- gridData.grabExcessHorizontalSpace = true;
- gridData.grabExcessVerticalSpace = true;
- tableViewer.getControl().setLayoutData(gridData);
-
- return container;
- }
-}
diff --git a/traceview/src/com/android/traceview/Selection.java b/traceview/src/com/android/traceview/Selection.java
deleted file mode 100644
index 3764619..0000000
--- a/traceview/src/com/android/traceview/Selection.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-public class Selection {
-
- private Action mAction;
- private String mName;
- private Object mValue;
-
- public Selection(Action action, String name, Object value) {
- mAction = action;
- mName = name;
- mValue = value;
- }
-
- public static Selection highlight(String name, Object value) {
- return new Selection(Action.Highlight, name, value);
- }
-
- public static Selection include(String name, Object value) {
- return new Selection(Action.Include, name, value);
- }
-
- public static Selection exclude(String name, Object value) {
- return new Selection(Action.Exclude, name, value);
- }
-
- public void setName(String name) {
- mName = name;
- }
-
- public String getName() {
- return mName;
- }
-
- public void setValue(Object value) {
- mValue = value;
- }
-
- public Object getValue() {
- return mValue;
- }
-
- public void setAction(Action action) {
- mAction = action;
- }
-
- public Action getAction() {
- return mAction;
- }
-
- public static enum Action {
- Highlight, Include, Exclude, Aggregate
- };
-}
diff --git a/traceview/src/com/android/traceview/SelectionController.java b/traceview/src/com/android/traceview/SelectionController.java
deleted file mode 100644
index 4c930ea..0000000
--- a/traceview/src/com/android/traceview/SelectionController.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-import java.util.ArrayList;
-import java.util.Observable;
-
-public class SelectionController extends Observable {
-
- private ArrayList<Selection> mSelections;
-
- public void change(ArrayList<Selection> selections, Object arg) {
- this.mSelections = selections;
- setChanged();
- notifyObservers(arg);
- }
-
- public ArrayList<Selection> getSelections() {
- return mSelections;
- }
-}
diff --git a/traceview/src/com/android/traceview/ThreadData.java b/traceview/src/com/android/traceview/ThreadData.java
deleted file mode 100644
index 05e54e8..0000000
--- a/traceview/src/com/android/traceview/ThreadData.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-class ThreadData implements TimeLineView.Row {
-
- private int mId;
- private String mName;
- private boolean mIsEmpty;
-
- private Call mRootCall;
- private ArrayList<Call> mStack = new ArrayList<Call>();
-
- // This is a hash of all the methods that are currently on the stack.
- private HashMap<MethodData, Integer> mStackMethods = new HashMap<MethodData, Integer>();
-
- boolean mHaveGlobalTime;
- long mGlobalStartTime;
- long mGlobalEndTime;
-
- boolean mHaveThreadTime;
- long mThreadStartTime;
- long mThreadEndTime;
-
- long mThreadCurrentTime; // only used while parsing thread-cpu clock
-
- ThreadData(int id, String name, MethodData topLevel) {
- mId = id;
- mName = String.format("[%d] %s", id, name);
- mIsEmpty = true;
- mRootCall = new Call(this, topLevel, null);
- mRootCall.setName(mName);
- mStack.add(mRootCall);
- }
-
- @Override
- public String getName() {
- return mName;
- }
-
- public Call getRootCall() {
- return mRootCall;
- }
-
- /**
- * Returns true if no calls have ever been recorded for this thread.
- */
- public boolean isEmpty() {
- return mIsEmpty;
- }
-
- Call enter(MethodData method, ArrayList<TraceAction> trace) {
- if (mIsEmpty) {
- mIsEmpty = false;
- if (trace != null) {
- trace.add(new TraceAction(TraceAction.ACTION_ENTER, mRootCall));
- }
- }
-
- Call caller = top();
- Call call = new Call(this, method, caller);
- mStack.add(call);
-
- if (trace != null) {
- trace.add(new TraceAction(TraceAction.ACTION_ENTER, call));
- }
-
- Integer num = mStackMethods.get(method);
- if (num == null) {
- num = 0;
- } else if (num > 0) {
- call.setRecursive(true);
- }
- mStackMethods.put(method, num + 1);
-
- return call;
- }
-
- Call exit(MethodData method, ArrayList<TraceAction> trace) {
- Call call = top();
- if (call.mCaller == null) {
- return null;
- }
-
- if (call.getMethodData() != method) {
- String error = "Method exit (" + method.getName()
- + ") does not match current method (" + call.getMethodData().getName()
- + ")";
- throw new RuntimeException(error);
- }
-
- mStack.remove(mStack.size() - 1);
-
- if (trace != null) {
- trace.add(new TraceAction(TraceAction.ACTION_EXIT, call));
- }
-
- Integer num = mStackMethods.get(method);
- if (num != null) {
- if (num == 1) {
- mStackMethods.remove(method);
- } else {
- mStackMethods.put(method, num - 1);
- }
- }
-
- return call;
- }
-
- Call top() {
- return mStack.get(mStack.size() - 1);
- }
-
- void endTrace(ArrayList<TraceAction> trace) {
- for (int i = mStack.size() - 1; i >= 1; i--) {
- Call call = mStack.get(i);
- call.mGlobalEndTime = mGlobalEndTime;
- call.mThreadEndTime = mThreadEndTime;
- if (trace != null) {
- trace.add(new TraceAction(TraceAction.ACTION_INCOMPLETE, call));
- }
- }
- mStack.clear();
- mStackMethods.clear();
- }
-
- void updateRootCallTimeBounds() {
- if (!mIsEmpty) {
- mRootCall.mGlobalStartTime = mGlobalStartTime;
- mRootCall.mGlobalEndTime = mGlobalEndTime;
- mRootCall.mThreadStartTime = mThreadStartTime;
- mRootCall.mThreadEndTime = mThreadEndTime;
- }
- }
-
- @Override
- public String toString() {
- return mName;
- }
-
- @Override
- public int getId() {
- return mId;
- }
-
- public long getCpuTime() {
- return mRootCall.mInclusiveCpuTime;
- }
-
- public long getRealTime() {
- return mRootCall.mInclusiveRealTime;
- }
-}
diff --git a/traceview/src/com/android/traceview/TickScaler.java b/traceview/src/com/android/traceview/TickScaler.java
deleted file mode 100644
index 79fa160..0000000
--- a/traceview/src/com/android/traceview/TickScaler.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-class TickScaler {
-
- private double mMinVal; // required input
- private double mMaxVal; // required input
- private double mRangeVal;
- private int mNumPixels; // required input
- private int mPixelsPerTick; // required input
- private double mPixelsPerRange;
- private double mTickIncrement;
- private double mMinMajorTick;
-
- TickScaler(double minVal, double maxVal, int numPixels, int pixelsPerTick) {
- mMinVal = minVal;
- mMaxVal = maxVal;
- mNumPixels = numPixels;
- mPixelsPerTick = pixelsPerTick;
- }
-
- public void setMinVal(double minVal) {
- mMinVal = minVal;
- }
-
- public double getMinVal() {
- return mMinVal;
- }
-
- public void setMaxVal(double maxVal) {
- mMaxVal = maxVal;
- }
-
- public double getMaxVal() {
- return mMaxVal;
- }
-
- public void setNumPixels(int numPixels) {
- mNumPixels = numPixels;
- }
-
- public int getNumPixels() {
- return mNumPixels;
- }
-
- public void setPixelsPerTick(int pixelsPerTick) {
- mPixelsPerTick = pixelsPerTick;
- }
-
- public int getPixelsPerTick() {
- return mPixelsPerTick;
- }
-
- public void setPixelsPerRange(double pixelsPerRange) {
- mPixelsPerRange = pixelsPerRange;
- }
-
- public double getPixelsPerRange() {
- return mPixelsPerRange;
- }
-
- public void setTickIncrement(double tickIncrement) {
- mTickIncrement = tickIncrement;
- }
-
- public double getTickIncrement() {
- return mTickIncrement;
- }
-
- public void setMinMajorTick(double minMajorTick) {
- mMinMajorTick = minMajorTick;
- }
-
- public double getMinMajorTick() {
- return mMinMajorTick;
- }
-
- // Convert a time value to a 0-based pixel value
- public int valueToPixel(double value) {
- return (int) Math.ceil(mPixelsPerRange * (value - mMinVal) - 0.5);
- }
-
- // Convert a time value to a 0-based fractional pixel
- public double valueToPixelFraction(double value) {
- return mPixelsPerRange * (value - mMinVal);
- }
-
- // Convert a 0-based pixel value to a time value
- public double pixelToValue(int pixel) {
- return mMinVal + (pixel / mPixelsPerRange);
- }
-
- public void computeTicks(boolean useGivenEndPoints) {
- int numTicks = mNumPixels / mPixelsPerTick;
- mRangeVal = mMaxVal - mMinVal;
- mTickIncrement = mRangeVal / numTicks;
- double dlogTickIncrement = Math.log10(mTickIncrement);
- int logTickIncrement = (int) Math.floor(dlogTickIncrement);
- double scale = Math.pow(10, logTickIncrement);
- double scaledTickIncr = mTickIncrement / scale;
- if (scaledTickIncr > 5.0)
- scaledTickIncr = 10;
- else if (scaledTickIncr > 2)
- scaledTickIncr = 5;
- else if (scaledTickIncr > 1)
- scaledTickIncr = 2;
- else
- scaledTickIncr = 1;
- mTickIncrement = scaledTickIncr * scale;
-
- if (!useGivenEndPoints) {
- // Round up the max val to the next minor tick
- double minorTickIncrement = mTickIncrement / 5;
- double dval = mMaxVal / minorTickIncrement;
- int ival = (int) dval;
- if (ival != dval)
- mMaxVal = (ival + 1) * minorTickIncrement;
-
- // Round down the min val to a multiple of tickIncrement
- ival = (int) (mMinVal / mTickIncrement);
- mMinVal = ival * mTickIncrement;
- mMinMajorTick = mMinVal;
- } else {
- int ival = (int) (mMinVal / mTickIncrement);
- mMinMajorTick = ival * mTickIncrement;
- if (mMinMajorTick < mMinVal)
- mMinMajorTick = mMinMajorTick + mTickIncrement;
- }
-
- mRangeVal = mMaxVal - mMinVal;
- mPixelsPerRange = (double) mNumPixels / mRangeVal;
- }
-}
diff --git a/traceview/src/com/android/traceview/TimeBase.java b/traceview/src/com/android/traceview/TimeBase.java
deleted file mode 100644
index b6b23cb..0000000
--- a/traceview/src/com/android/traceview/TimeBase.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-interface TimeBase {
- public static final TimeBase CPU_TIME = new CpuTimeBase();
- public static final TimeBase REAL_TIME = new RealTimeBase();
-
- public long getTime(ThreadData threadData);
- public long getElapsedInclusiveTime(MethodData methodData);
- public long getElapsedExclusiveTime(MethodData methodData);
- public long getElapsedInclusiveTime(ProfileData profileData);
-
- public static final class CpuTimeBase implements TimeBase {
- @Override
- public long getTime(ThreadData threadData) {
- return threadData.getCpuTime();
- }
-
- @Override
- public long getElapsedInclusiveTime(MethodData methodData) {
- return methodData.getElapsedInclusiveCpuTime();
- }
-
- @Override
- public long getElapsedExclusiveTime(MethodData methodData) {
- return methodData.getElapsedExclusiveCpuTime();
- }
-
- @Override
- public long getElapsedInclusiveTime(ProfileData profileData) {
- return profileData.getElapsedInclusiveCpuTime();
- }
- }
-
- public static final class RealTimeBase implements TimeBase {
- @Override
- public long getTime(ThreadData threadData) {
- return threadData.getRealTime();
- }
-
- @Override
- public long getElapsedInclusiveTime(MethodData methodData) {
- return methodData.getElapsedInclusiveRealTime();
- }
-
- @Override
- public long getElapsedExclusiveTime(MethodData methodData) {
- return methodData.getElapsedExclusiveRealTime();
- }
-
- @Override
- public long getElapsedInclusiveTime(ProfileData profileData) {
- return profileData.getElapsedInclusiveRealTime();
- }
- }
-}
diff --git a/traceview/src/com/android/traceview/TimeLineView.java b/traceview/src/com/android/traceview/TimeLineView.java
deleted file mode 100644
index cc9613a..0000000
--- a/traceview/src/com/android/traceview/TimeLineView.java
+++ /dev/null
@@ -1,2154 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-import org.eclipse.jface.resource.FontRegistry;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.custom.SashForm;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.events.MouseWheelListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.graphics.Cursor;
-import org.eclipse.swt.graphics.FontData;
-import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
-import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Canvas;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Listener;
-import org.eclipse.swt.widgets.ScrollBar;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Observable;
-import java.util.Observer;
-
-public class TimeLineView extends Composite implements Observer {
-
- private HashMap<String, RowData> mRowByName;
- private RowData[] mRows;
- private Segment[] mSegments;
- private HashMap<Integer, String> mThreadLabels;
- private Timescale mTimescale;
- private Surface mSurface;
- private RowLabels mLabels;
- private SashForm mSashForm;
- private int mScrollOffsetY;
-
- public static final int PixelsPerTick = 50;
- private TickScaler mScaleInfo = new TickScaler(0, 0, 0, PixelsPerTick);
- private static final int LeftMargin = 10; // blank space on left
- private static final int RightMargin = 60; // blank space on right
-
- private Color mColorBlack;
- private Color mColorGray;
- private Color mColorDarkGray;
- private Color mColorForeground;
- private Color mColorRowBack;
- private Color mColorZoomSelection;
- private FontRegistry mFontRegistry;
-
- /** vertical height of drawn blocks in each row */
- private static final int rowHeight = 20;
-
- /** the blank space between rows */
- private static final int rowYMargin = 12;
- private static final int rowYMarginHalf = rowYMargin / 2;
-
- /** total vertical space for row */
- private static final int rowYSpace = rowHeight + rowYMargin;
- private static final int majorTickLength = 8;
- private static final int minorTickLength = 4;
- private static final int timeLineOffsetY = 58;
- private static final int tickToFontSpacing = 2;
-
- /** start of first row */
- private static final int topMargin = 90;
- private int mMouseRow = -1;
- private int mNumRows;
- private int mStartRow;
- private int mEndRow;
- private TraceUnits mUnits;
- private String mClockSource;
- private boolean mHaveCpuTime;
- private boolean mHaveRealTime;
- private int mSmallFontWidth;
- private int mSmallFontHeight;
- private SelectionController mSelectionController;
- private MethodData mHighlightMethodData;
- private Call mHighlightCall;
- private static final int MinInclusiveRange = 3;
-
- /** Setting the fonts looks good on Linux but bad on Macs */
- private boolean mSetFonts = false;
-
- public static interface Block {
- public String getName();
- public MethodData getMethodData();
- public long getStartTime();
- public long getEndTime();
- public Color getColor();
- public double addWeight(int x, int y, double weight);
- public void clearWeight();
- public long getExclusiveCpuTime();
- public long getInclusiveCpuTime();
- public long getExclusiveRealTime();
- public long getInclusiveRealTime();
- public boolean isContextSwitch();
- public boolean isIgnoredBlock();
- public Block getParentBlock();
- }
-
- public static interface Row {
- public int getId();
- public String getName();
- }
-
- public static class Record {
- Row row;
- Block block;
-
- public Record(Row row, Block block) {
- this.row = row;
- this.block = block;
- }
- }
-
- public TimeLineView(Composite parent, TraceReader reader,
- SelectionController selectionController) {
- super(parent, SWT.NONE);
- mRowByName = new HashMap<String, RowData>();
- this.mSelectionController = selectionController;
- selectionController.addObserver(this);
- mUnits = reader.getTraceUnits();
- mClockSource = reader.getClockSource();
- mHaveCpuTime = reader.haveCpuTime();
- mHaveRealTime = reader.haveRealTime();
- mThreadLabels = reader.getThreadLabels();
-
- Display display = getDisplay();
- mColorGray = display.getSystemColor(SWT.COLOR_GRAY);
- mColorDarkGray = display.getSystemColor(SWT.COLOR_DARK_GRAY);
- mColorBlack = display.getSystemColor(SWT.COLOR_BLACK);
- // mColorBackground = display.getSystemColor(SWT.COLOR_WHITE);
- mColorForeground = display.getSystemColor(SWT.COLOR_BLACK);
- mColorRowBack = new Color(display, 240, 240, 255);
- mColorZoomSelection = new Color(display, 230, 230, 230);
-
- mFontRegistry = new FontRegistry(display);
- mFontRegistry.put("small", //$NON-NLS-1$
- new FontData[] { new FontData("Arial", 8, SWT.NORMAL) }); //$NON-NLS-1$
- mFontRegistry.put("courier8", //$NON-NLS-1$
- new FontData[] { new FontData("Courier New", 8, SWT.BOLD) }); //$NON-NLS-1$
- mFontRegistry.put("medium", //$NON-NLS-1$
- new FontData[] { new FontData("Courier New", 10, SWT.NORMAL) }); //$NON-NLS-1$
-
- Image image = new Image(display, new Rectangle(100, 100, 100, 100));
- GC gc = new GC(image);
- if (mSetFonts) {
- gc.setFont(mFontRegistry.get("small")); //$NON-NLS-1$
- }
- mSmallFontWidth = gc.getFontMetrics().getAverageCharWidth();
- mSmallFontHeight = gc.getFontMetrics().getHeight();
-
- image.dispose();
- gc.dispose();
-
- setLayout(new FillLayout());
-
- // Create a sash form for holding two canvas views, one for the
- // thread labels and one for the thread timeline.
- mSashForm = new SashForm(this, SWT.HORIZONTAL);
- mSashForm.setBackground(mColorGray);
- mSashForm.SASH_WIDTH = 3;
-
- // Create a composite for the left side of the sash
- Composite composite = new Composite(mSashForm, SWT.NONE);
- GridLayout layout = new GridLayout(1, true /* make columns equal width */);
- layout.marginHeight = 0;
- layout.marginWidth = 0;
- layout.verticalSpacing = 1;
- composite.setLayout(layout);
-
- // Create a blank corner space in the upper left corner
- BlankCorner corner = new BlankCorner(composite);
- GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
- gridData.heightHint = topMargin;
- corner.setLayoutData(gridData);
-
- // Add the thread labels below the blank corner.
- mLabels = new RowLabels(composite);
- gridData = new GridData(GridData.FILL_BOTH);
- mLabels.setLayoutData(gridData);
-
- // Create another composite for the right side of the sash
- composite = new Composite(mSashForm, SWT.NONE);
- layout = new GridLayout(1, true /* make columns equal width */);
- layout.marginHeight = 0;
- layout.marginWidth = 0;
- layout.verticalSpacing = 1;
- composite.setLayout(layout);
-
- mTimescale = new Timescale(composite);
- gridData = new GridData(GridData.FILL_HORIZONTAL);
- gridData.heightHint = topMargin;
- mTimescale.setLayoutData(gridData);
-
- mSurface = new Surface(composite);
- gridData = new GridData(GridData.FILL_BOTH);
- mSurface.setLayoutData(gridData);
- mSashForm.setWeights(new int[] { 1, 5 });
-
- final ScrollBar vBar = mSurface.getVerticalBar();
- vBar.addListener(SWT.Selection, new Listener() {
- @Override
- public void handleEvent(Event e) {
- mScrollOffsetY = vBar.getSelection();
- Point dim = mSurface.getSize();
- int newScrollOffsetY = computeVisibleRows(dim.y);
- if (newScrollOffsetY != mScrollOffsetY) {
- mScrollOffsetY = newScrollOffsetY;
- vBar.setSelection(newScrollOffsetY);
- }
- mLabels.redraw();
- mSurface.redraw();
- }
- });
-
- final ScrollBar hBar = mSurface.getHorizontalBar();
- hBar.addListener(SWT.Selection, new Listener() {
- @Override
- public void handleEvent(Event e) {
- mSurface.setScaleFromHorizontalScrollBar(hBar.getSelection());
- mSurface.redraw();
- }
- });
-
- mSurface.addListener(SWT.Resize, new Listener() {
- @Override
- public void handleEvent(Event e) {
- Point dim = mSurface.getSize();
-
- // If we don't need the scroll bar then don't display it.
- if (dim.y >= mNumRows * rowYSpace) {
- vBar.setVisible(false);
- } else {
- vBar.setVisible(true);
- }
- int newScrollOffsetY = computeVisibleRows(dim.y);
- if (newScrollOffsetY != mScrollOffsetY) {
- mScrollOffsetY = newScrollOffsetY;
- vBar.setSelection(newScrollOffsetY);
- }
-
- int spaceNeeded = mNumRows * rowYSpace;
- vBar.setMaximum(spaceNeeded);
- vBar.setThumb(dim.y);
-
- mLabels.redraw();
- mSurface.redraw();
- }
- });
-
- mSurface.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseUp(MouseEvent me) {
- mSurface.mouseUp(me);
- }
-
- @Override
- public void mouseDown(MouseEvent me) {
- mSurface.mouseDown(me);
- }
-
- @Override
- public void mouseDoubleClick(MouseEvent me) {
- mSurface.mouseDoubleClick(me);
- }
- });
-
- mSurface.addMouseMoveListener(new MouseMoveListener() {
- @Override
- public void mouseMove(MouseEvent me) {
- mSurface.mouseMove(me);
- }
- });
-
- mSurface.addMouseWheelListener(new MouseWheelListener() {
- @Override
- public void mouseScrolled(MouseEvent me) {
- mSurface.mouseScrolled(me);
- }
- });
-
- mTimescale.addMouseListener(new MouseAdapter() {
- @Override
- public void mouseUp(MouseEvent me) {
- mTimescale.mouseUp(me);
- }
-
- @Override
- public void mouseDown(MouseEvent me) {
- mTimescale.mouseDown(me);
- }
-
- @Override
- public void mouseDoubleClick(MouseEvent me) {
- mTimescale.mouseDoubleClick(me);
- }
- });
-
- mTimescale.addMouseMoveListener(new MouseMoveListener() {
- @Override
- public void mouseMove(MouseEvent me) {
- mTimescale.mouseMove(me);
- }
- });
-
- mLabels.addMouseMoveListener(new MouseMoveListener() {
- @Override
- public void mouseMove(MouseEvent me) {
- mLabels.mouseMove(me);
- }
- });
-
- setData(reader.getThreadTimeRecords());
- }
-
- @Override
- public void update(Observable objservable, Object arg) {
- // Ignore updates from myself
- if (arg == "TimeLineView") //$NON-NLS-1$
- return;
- // System.out.printf("timeline update from %s\n", arg);
- boolean foundHighlight = false;
- ArrayList<Selection> selections;
- selections = mSelectionController.getSelections();
- for (Selection selection : selections) {
- Selection.Action action = selection.getAction();
- if (action != Selection.Action.Highlight)
- continue;
- String name = selection.getName();
- // System.out.printf(" timeline highlight %s from %s\n", name, arg);
- if (name == "MethodData") { //$NON-NLS-1$
- foundHighlight = true;
- mHighlightMethodData = (MethodData) selection.getValue();
- // System.out.printf(" method %s\n",
- // highlightMethodData.getName());
- mHighlightCall = null;
- startHighlighting();
- } else if (name == "Call") { //$NON-NLS-1$
- foundHighlight = true;
- mHighlightCall = (Call) selection.getValue();
- // System.out.printf(" call %s\n", highlightCall.getName());
- mHighlightMethodData = null;
- startHighlighting();
- }
- }
- if (foundHighlight == false)
- mSurface.clearHighlights();
- }
-
- public void setData(ArrayList<Record> records) {
- if (records == null)
- records = new ArrayList<Record>();
-
- if (false) {
- System.out.println("TimelineView() list of records:"); //$NON-NLS-1$
- for (Record r : records) {
- System.out.printf("row '%s' block '%s' [%d, %d]\n", r.row //$NON-NLS-1$
- .getName(), r.block.getName(), r.block.getStartTime(),
- r.block.getEndTime());
- if (r.block.getStartTime() > r.block.getEndTime()) {
- System.err.printf("Error: block startTime > endTime\n"); //$NON-NLS-1$
- System.exit(1);
- }
- }
- }
-
- // Sort the records into increasing start time, and decreasing end time
- Collections.sort(records, new Comparator<Record>() {
- @Override
- public int compare(Record r1, Record r2) {
- long start1 = r1.block.getStartTime();
- long start2 = r2.block.getStartTime();
- if (start1 > start2)
- return 1;
- if (start1 < start2)
- return -1;
-
- // The start times are the same, so compare the end times
- long end1 = r1.block.getEndTime();
- long end2 = r2.block.getEndTime();
- if (end1 > end2)
- return -1;
- if (end1 < end2)
- return 1;
-
- return 0;
- }
- });
-
- ArrayList<Segment> segmentList = new ArrayList<Segment>();
-
- // The records are sorted into increasing start time,
- // so the minimum start time is the start time of the first record.
- double minVal = 0;
- if (records.size() > 0)
- minVal = records.get(0).block.getStartTime();
-
- // Sum the time spent in each row and block, and
- // keep track of the maximum end time.
- double maxVal = 0;
- for (Record rec : records) {
- Row row = rec.row;
- Block block = rec.block;
- if (block.isIgnoredBlock()) {
- continue;
- }
-
- String rowName = row.getName();
- RowData rd = mRowByName.get(rowName);
- if (rd == null) {
- rd = new RowData(row);
- mRowByName.put(rowName, rd);
- }
- long blockStartTime = block.getStartTime();
- long blockEndTime = block.getEndTime();
- if (blockEndTime > rd.mEndTime) {
- long start = Math.max(blockStartTime, rd.mEndTime);
- rd.mElapsed += blockEndTime - start;
- rd.mEndTime = blockEndTime;
- }
- if (blockEndTime > maxVal)
- maxVal = blockEndTime;
-
- // Keep track of nested blocks by using a stack (for each row).
- // Create a Segment object for each visible part of a block.
- Block top = rd.top();
- if (top == null) {
- rd.push(block);
- continue;
- }
-
- long topStartTime = top.getStartTime();
- long topEndTime = top.getEndTime();
- if (topEndTime >= blockStartTime) {
- // Add this segment if it has a non-zero elapsed time.
- if (topStartTime < blockStartTime) {
- Segment segment = new Segment(rd, top, topStartTime,
- blockStartTime);
- segmentList.add(segment);
- }
-
- // If this block starts where the previous (top) block ends,
- // then pop off the top block.
- if (topEndTime == blockStartTime)
- rd.pop();
- rd.push(block);
- } else {
- // We may have to pop several frames here.
- popFrames(rd, top, blockStartTime, segmentList);
- rd.push(block);
- }
- }
-
- // Clean up the stack of each row
- for (RowData rd : mRowByName.values()) {
- Block top = rd.top();
- popFrames(rd, top, Integer.MAX_VALUE, segmentList);
- }
-
- mSurface.setRange(minVal, maxVal);
- mSurface.setLimitRange(minVal, maxVal);
-
- // Sort the rows into decreasing elapsed time
- Collection<RowData> rv = mRowByName.values();
- mRows = rv.toArray(new RowData[rv.size()]);
- Arrays.sort(mRows, new Comparator<RowData>() {
- @Override
- public int compare(RowData rd1, RowData rd2) {
- return (int) (rd2.mElapsed - rd1.mElapsed);
- }
- });
-
- // Assign ranks to the sorted rows
- for (int ii = 0; ii < mRows.length; ++ii) {
- mRows[ii].mRank = ii;
- }
-
- // Compute the number of rows with data
- mNumRows = 0;
- for (int ii = 0; ii < mRows.length; ++ii) {
- if (mRows[ii].mElapsed == 0)
- break;
- mNumRows += 1;
- }
-
- // Sort the blocks into increasing rows, and within rows into
- // increasing start values.
- mSegments = segmentList.toArray(new Segment[segmentList.size()]);
- Arrays.sort(mSegments, new Comparator<Segment>() {
- @Override
- public int compare(Segment bd1, Segment bd2) {
- RowData rd1 = bd1.mRowData;
- RowData rd2 = bd2.mRowData;
- int diff = rd1.mRank - rd2.mRank;
- if (diff == 0) {
- long timeDiff = bd1.mStartTime - bd2.mStartTime;
- if (timeDiff == 0)
- timeDiff = bd1.mEndTime - bd2.mEndTime;
- return (int) timeDiff;
- }
- return diff;
- }
- });
-
- if (false) {
- for (Segment segment : mSegments) {
- System.out.printf("seg '%s' [%6d, %6d] %s\n",
- segment.mRowData.mName, segment.mStartTime,
- segment.mEndTime, segment.mBlock.getName());
- if (segment.mStartTime > segment.mEndTime) {
- System.err.printf("Error: segment startTime > endTime\n");
- System.exit(1);
- }
- }
- }
- }
-
- private static void popFrames(RowData rd, Block top, long startTime,
- ArrayList<Segment> segmentList) {
- long topEndTime = top.getEndTime();
- long lastEndTime = top.getStartTime();
- while (topEndTime <= startTime) {
- if (topEndTime > lastEndTime) {
- Segment segment = new Segment(rd, top, lastEndTime, topEndTime);
- segmentList.add(segment);
- lastEndTime = topEndTime;
- }
- rd.pop();
- top = rd.top();
- if (top == null)
- return;
- topEndTime = top.getEndTime();
- }
-
- // If we get here, then topEndTime > startTime
- if (lastEndTime < startTime) {
- Segment bd = new Segment(rd, top, lastEndTime, startTime);
- segmentList.add(bd);
- }
- }
-
- private class RowLabels extends Canvas {
-
- /** The space between the row label and the sash line */
- private static final int labelMarginX = 2;
-
- public RowLabels(Composite parent) {
- super(parent, SWT.NO_BACKGROUND);
- addPaintListener(new PaintListener() {
- @Override
- public void paintControl(PaintEvent pe) {
- draw(pe.display, pe.gc);
- }
- });
- }
-
- private void mouseMove(MouseEvent me) {
- int rownum = (me.y + mScrollOffsetY) / rowYSpace;
- if (mMouseRow != rownum) {
- mMouseRow = rownum;
- redraw();
- mSurface.redraw();
- }
- }
-
- private void draw(Display display, GC gc) {
- if (mSegments.length == 0) {
- // gc.setBackground(colorBackground);
- // gc.fillRectangle(getBounds());
- return;
- }
- Point dim = getSize();
-
- // Create an image for double-buffering
- Image image = new Image(display, getBounds());
-
- // Set up the off-screen gc
- GC gcImage = new GC(image);
- if (mSetFonts)
- gcImage.setFont(mFontRegistry.get("medium")); //$NON-NLS-1$
-
- if (mNumRows > 2) {
- // Draw the row background stripes
- gcImage.setBackground(mColorRowBack);
- for (int ii = 1; ii < mNumRows; ii += 2) {
- RowData rd = mRows[ii];
- int y1 = rd.mRank * rowYSpace - mScrollOffsetY;
- gcImage.fillRectangle(0, y1, dim.x, rowYSpace);
- }
- }
-
- // Draw the row labels
- int offsetY = rowYMarginHalf - mScrollOffsetY;
- for (int ii = mStartRow; ii <= mEndRow; ++ii) {
- RowData rd = mRows[ii];
- int y1 = rd.mRank * rowYSpace + offsetY;
- Point extent = gcImage.stringExtent(rd.mName);
- int x1 = dim.x - extent.x - labelMarginX;
- gcImage.drawString(rd.mName, x1, y1, true);
- }
-
- // Draw a highlight box on the row where the mouse is.
- if (mMouseRow >= mStartRow && mMouseRow <= mEndRow) {
- gcImage.setForeground(mColorGray);
- int y1 = mMouseRow * rowYSpace - mScrollOffsetY;
- gcImage.drawRectangle(0, y1, dim.x, rowYSpace);
- }
-
- // Draw the off-screen buffer to the screen
- gc.drawImage(image, 0, 0);
-
- // Clean up
- image.dispose();
- gcImage.dispose();
- }
- }
-
- private class BlankCorner extends Canvas {
- public BlankCorner(Composite parent) {
- //super(parent, SWT.NO_BACKGROUND);
- super(parent, SWT.NONE);
- addPaintListener(new PaintListener() {
- @Override
- public void paintControl(PaintEvent pe) {
- draw(pe.display, pe.gc);
- }
- });
- }
-
- private void draw(Display display, GC gc) {
- // Create a blank image and draw it to the canvas
- Image image = new Image(display, getBounds());
- gc.drawImage(image, 0, 0);
-
- // Clean up
- image.dispose();
- }
- }
-
- private class Timescale extends Canvas {
- private Point mMouse = new Point(LeftMargin, 0);
- private Cursor mZoomCursor;
- private String mMethodName = null;
- private Color mMethodColor = null;
- private String mDetails;
- private int mMethodStartY;
- private int mDetailsStartY;
- private int mMarkStartX;
- private int mMarkEndX;
-
- /** The space between the colored block and the method name */
- private static final int METHOD_BLOCK_MARGIN = 10;
-
- public Timescale(Composite parent) {
- //super(parent, SWT.NO_BACKGROUND);
- super(parent, SWT.NONE);
- Display display = getDisplay();
- mZoomCursor = new Cursor(display, SWT.CURSOR_SIZEWE);
- setCursor(mZoomCursor);
- mMethodStartY = mSmallFontHeight + 1;
- mDetailsStartY = mMethodStartY + mSmallFontHeight + 1;
- addPaintListener(new PaintListener() {
- @Override
- public void paintControl(PaintEvent pe) {
- draw(pe.display, pe.gc);
- }
- });
- }
-
- public void setVbarPosition(int x) {
- mMouse.x = x;
- }
-
- public void setMarkStart(int x) {
- mMarkStartX = x;
- }
-
- public void setMarkEnd(int x) {
- mMarkEndX = x;
- }
-
- public void setMethodName(String name) {
- mMethodName = name;
- }
-
- public void setMethodColor(Color color) {
- mMethodColor = color;
- }
-
- public void setDetails(String details) {
- mDetails = details;
- }
-
- private void mouseMove(MouseEvent me) {
- me.y = -1;
- mSurface.mouseMove(me);
- }
-
- private void mouseDown(MouseEvent me) {
- mSurface.startScaling(me.x);
- mSurface.redraw();
- }
-
- private void mouseUp(MouseEvent me) {
- mSurface.stopScaling(me.x);
- }
-
- private void mouseDoubleClick(MouseEvent me) {
- mSurface.resetScale();
- mSurface.redraw();
- }
-
- private void draw(Display display, GC gc) {
- Point dim = getSize();
-
- // Create an image for double-buffering
- Image image = new Image(display, getBounds());
-
- // Set up the off-screen gc
- GC gcImage = new GC(image);
- if (mSetFonts)
- gcImage.setFont(mFontRegistry.get("medium")); //$NON-NLS-1$
-
- if (mSurface.drawingSelection()) {
- drawSelection(display, gcImage);
- }
-
- drawTicks(display, gcImage);
-
- // Draw the vertical bar where the mouse is
- gcImage.setForeground(mColorDarkGray);
- gcImage.drawLine(mMouse.x, timeLineOffsetY, mMouse.x, dim.y);
-
- // Draw the current millseconds
- drawTickLegend(display, gcImage);
-
- // Draw the method name and color, if needed
- drawMethod(display, gcImage);
-
- // Draw the details, if needed
- drawDetails(display, gcImage);
-
- // Draw the off-screen buffer to the screen
- gc.drawImage(image, 0, 0);
-
- // Clean up
- image.dispose();
- gcImage.dispose();
- }
-
- private void drawSelection(Display display, GC gc) {
- Point dim = getSize();
- gc.setForeground(mColorGray);
- gc.drawLine(mMarkStartX, timeLineOffsetY, mMarkStartX, dim.y);
- gc.setBackground(mColorZoomSelection);
- int x, width;
- if (mMarkStartX < mMarkEndX) {
- x = mMarkStartX;
- width = mMarkEndX - mMarkStartX;
- } else {
- x = mMarkEndX;
- width = mMarkStartX - mMarkEndX;
- }
- if (width > 1) {
- gc.fillRectangle(x, timeLineOffsetY, width, dim.y);
- }
- }
-
- private void drawTickLegend(Display display, GC gc) {
- int mouseX = mMouse.x - LeftMargin;
- double mouseXval = mScaleInfo.pixelToValue(mouseX);
- String info = mUnits.labelledString(mouseXval);
- gc.setForeground(mColorForeground);
- gc.drawString(info, LeftMargin + 2, 1, true);
-
- // Display the maximum data value
- double maxVal = mScaleInfo.getMaxVal();
- info = mUnits.labelledString(maxVal);
- if (mClockSource != null) {
- info = String.format(" max %s (%s)", info, mClockSource); //$NON-NLS-1$
- } else {
- info = String.format(" max %s ", info); //$NON-NLS-1$
- }
- Point extent = gc.stringExtent(info);
- Point dim = getSize();
- int x1 = dim.x - RightMargin - extent.x;
- gc.drawString(info, x1, 1, true);
- }
-
- private void drawMethod(Display display, GC gc) {
- if (mMethodName == null) {
- return;
- }
-
- int x1 = LeftMargin;
- int y1 = mMethodStartY;
- gc.setBackground(mMethodColor);
- int width = 2 * mSmallFontWidth;
- gc.fillRectangle(x1, y1, width, mSmallFontHeight);
- x1 += width + METHOD_BLOCK_MARGIN;
- gc.drawString(mMethodName, x1, y1, true);
- }
-
- private void drawDetails(Display display, GC gc) {
- if (mDetails == null) {
- return;
- }
-
- int x1 = LeftMargin + 2 * mSmallFontWidth + METHOD_BLOCK_MARGIN;
- int y1 = mDetailsStartY;
- gc.drawString(mDetails, x1, y1, true);
- }
-
- private void drawTicks(Display display, GC gc) {
- Point dim = getSize();
- int y2 = majorTickLength + timeLineOffsetY;
- int y3 = minorTickLength + timeLineOffsetY;
- int y4 = y2 + tickToFontSpacing;
- gc.setForeground(mColorForeground);
- gc.drawLine(LeftMargin, timeLineOffsetY, dim.x - RightMargin,
- timeLineOffsetY);
- double minVal = mScaleInfo.getMinVal();
- double maxVal = mScaleInfo.getMaxVal();
- double minMajorTick = mScaleInfo.getMinMajorTick();
- double tickIncrement = mScaleInfo.getTickIncrement();
- double minorTickIncrement = tickIncrement / 5;
- double pixelsPerRange = mScaleInfo.getPixelsPerRange();
-
- // Draw the initial minor ticks, if any
- if (minVal < minMajorTick) {
- gc.setForeground(mColorGray);
- double xMinor = minMajorTick;
- for (int ii = 1; ii <= 4; ++ii) {
- xMinor -= minorTickIncrement;
- if (xMinor < minVal)
- break;
- int x1 = LeftMargin
- + (int) (0.5 + (xMinor - minVal) * pixelsPerRange);
- gc.drawLine(x1, timeLineOffsetY, x1, y3);
- }
- }
-
- if (tickIncrement <= 10) {
- // TODO avoid rendering the loop when tickIncrement is invalid. It can be zero
- // or too small.
- // System.out.println(String.format("Timescale.drawTicks error: tickIncrement=%1f", tickIncrement));
- return;
- }
- for (double x = minMajorTick; x <= maxVal; x += tickIncrement) {
- int x1 = LeftMargin
- + (int) (0.5 + (x - minVal) * pixelsPerRange);
-
- // Draw a major tick
- gc.setForeground(mColorForeground);
- gc.drawLine(x1, timeLineOffsetY, x1, y2);
- if (x > maxVal)
- break;
-
- // Draw the tick text
- String tickString = mUnits.valueOf(x);
- gc.drawString(tickString, x1, y4, true);
-
- // Draw 4 minor ticks between major ticks
- gc.setForeground(mColorGray);
- double xMinor = x;
- for (int ii = 1; ii <= 4; ii++) {
- xMinor += minorTickIncrement;
- if (xMinor > maxVal)
- break;
- x1 = LeftMargin
- + (int) (0.5 + (xMinor - minVal) * pixelsPerRange);
- gc.drawLine(x1, timeLineOffsetY, x1, y3);
- }
- }
- }
- }
-
- private static enum GraphicsState {
- Normal, Marking, Scaling, Animating, Scrolling
- };
-
- private class Surface extends Canvas {
-
- public Surface(Composite parent) {
- super(parent, SWT.NO_BACKGROUND | SWT.V_SCROLL | SWT.H_SCROLL);
- Display display = getDisplay();
- mNormalCursor = new Cursor(display, SWT.CURSOR_CROSS);
- mIncreasingCursor = new Cursor(display, SWT.CURSOR_SIZEE);
- mDecreasingCursor = new Cursor(display, SWT.CURSOR_SIZEW);
-
- initZoomFractionsWithExp();
-
- addPaintListener(new PaintListener() {
- @Override
- public void paintControl(PaintEvent pe) {
- draw(pe.display, pe.gc);
- }
- });
-
- mZoomAnimator = new Runnable() {
- @Override
- public void run() {
- animateZoom();
- }
- };
-
- mHighlightAnimator = new Runnable() {
- @Override
- public void run() {
- animateHighlight();
- }
- };
- }
-
- private void initZoomFractionsWithExp() {
- mZoomFractions = new double[ZOOM_STEPS];
- int next = 0;
- for (int ii = 0; ii < ZOOM_STEPS / 2; ++ii, ++next) {
- mZoomFractions[next] = (double) (1 << ii)
- / (double) (1 << (ZOOM_STEPS / 2));
- // System.out.printf("%d %f\n", next, zoomFractions[next]);
- }
- for (int ii = 2; ii < 2 + ZOOM_STEPS / 2; ++ii, ++next) {
- mZoomFractions[next] = (double) ((1 << ii) - 1)
- / (double) (1 << ii);
- // System.out.printf("%d %f\n", next, zoomFractions[next]);
- }
- }
-
- @SuppressWarnings("unused")
- private void initZoomFractionsWithSinWave() {
- mZoomFractions = new double[ZOOM_STEPS];
- for (int ii = 0; ii < ZOOM_STEPS; ++ii) {
- double offset = Math.PI * ii / ZOOM_STEPS;
- mZoomFractions[ii] = (Math.sin((1.5 * Math.PI + offset)) + 1.0) / 2.0;
- // System.out.printf("%d %f\n", ii, zoomFractions[ii]);
- }
- }
-
- public void setRange(double minVal, double maxVal) {
- mMinDataVal = minVal;
- mMaxDataVal = maxVal;
- mScaleInfo.setMinVal(minVal);
- mScaleInfo.setMaxVal(maxVal);
- }
-
- public void setLimitRange(double minVal, double maxVal) {
- mLimitMinVal = minVal;
- mLimitMaxVal = maxVal;
- }
-
- public void resetScale() {
- mScaleInfo.setMinVal(mLimitMinVal);
- mScaleInfo.setMaxVal(mLimitMaxVal);
- }
-
- public void setScaleFromHorizontalScrollBar(int selection) {
- double minVal = mScaleInfo.getMinVal();
- double maxVal = mScaleInfo.getMaxVal();
- double visibleRange = maxVal - minVal;
-
- minVal = mLimitMinVal + selection;
- maxVal = minVal + visibleRange;
- if (maxVal > mLimitMaxVal) {
- maxVal = mLimitMaxVal;
- minVal = maxVal - visibleRange;
- }
- mScaleInfo.setMinVal(minVal);
- mScaleInfo.setMaxVal(maxVal);
-
- mGraphicsState = GraphicsState.Scrolling;
- }
-
- private void updateHorizontalScrollBar() {
- double minVal = mScaleInfo.getMinVal();
- double maxVal = mScaleInfo.getMaxVal();
- double visibleRange = maxVal - minVal;
- double fullRange = mLimitMaxVal - mLimitMinVal;
-
- ScrollBar hBar = getHorizontalBar();
- if (fullRange > visibleRange) {
- hBar.setVisible(true);
- hBar.setMinimum(0);
- hBar.setMaximum((int)Math.ceil(fullRange));
- hBar.setThumb((int)Math.ceil(visibleRange));
- hBar.setSelection((int)Math.floor(minVal - mLimitMinVal));
- } else {
- hBar.setVisible(false);
- }
- }
-
- private void draw(Display display, GC gc) {
- if (mSegments.length == 0) {
- // gc.setBackground(colorBackground);
- // gc.fillRectangle(getBounds());
- return;
- }
-
- // Create an image for double-buffering
- Image image = new Image(display, getBounds());
-
- // Set up the off-screen gc
- GC gcImage = new GC(image);
- if (mSetFonts)
- gcImage.setFont(mFontRegistry.get("small")); //$NON-NLS-1$
-
- // Draw the background
- // gcImage.setBackground(colorBackground);
- // gcImage.fillRectangle(image.getBounds());
-
- if (mGraphicsState == GraphicsState.Scaling) {
- double diff = mMouse.x - mMouseMarkStartX;
- if (diff > 0) {
- double newMinVal = mScaleMinVal - diff / mScalePixelsPerRange;
- if (newMinVal < mLimitMinVal)
- newMinVal = mLimitMinVal;
- mScaleInfo.setMinVal(newMinVal);
- // System.out.printf("diff %f scaleMin %f newMin %f\n",
- // diff, scaleMinVal, newMinVal);
- } else if (diff < 0) {
- double newMaxVal = mScaleMaxVal - diff / mScalePixelsPerRange;
- if (newMaxVal > mLimitMaxVal)
- newMaxVal = mLimitMaxVal;
- mScaleInfo.setMaxVal(newMaxVal);
- // System.out.printf("diff %f scaleMax %f newMax %f\n",
- // diff, scaleMaxVal, newMaxVal);
- }
- }
-
- // Recompute the ticks and strips only if the size has changed,
- // or we scrolled so that a new row is visible.
- Point dim = getSize();
- if (mStartRow != mCachedStartRow || mEndRow != mCachedEndRow
- || mScaleInfo.getMinVal() != mCachedMinVal
- || mScaleInfo.getMaxVal() != mCachedMaxVal) {
- mCachedStartRow = mStartRow;
- mCachedEndRow = mEndRow;
- int xdim = dim.x - TotalXMargin;
- mScaleInfo.setNumPixels(xdim);
- boolean forceEndPoints = (mGraphicsState == GraphicsState.Scaling
- || mGraphicsState == GraphicsState.Animating
- || mGraphicsState == GraphicsState.Scrolling);
- mScaleInfo.computeTicks(forceEndPoints);
- mCachedMinVal = mScaleInfo.getMinVal();
- mCachedMaxVal = mScaleInfo.getMaxVal();
- if (mLimitMinVal > mScaleInfo.getMinVal())
- mLimitMinVal = mScaleInfo.getMinVal();
- if (mLimitMaxVal < mScaleInfo.getMaxVal())
- mLimitMaxVal = mScaleInfo.getMaxVal();
-
- // Compute the strips
- computeStrips();
-
- // Update the horizontal scrollbar.
- updateHorizontalScrollBar();
- }
-
- if (mNumRows > 2) {
- // Draw the row background stripes
- gcImage.setBackground(mColorRowBack);
- for (int ii = 1; ii < mNumRows; ii += 2) {
- RowData rd = mRows[ii];
- int y1 = rd.mRank * rowYSpace - mScrollOffsetY;
- gcImage.fillRectangle(0, y1, dim.x, rowYSpace);
- }
- }
-
- if (drawingSelection()) {
- drawSelection(display, gcImage);
- }
-
- String blockName = null;
- Color blockColor = null;
- String blockDetails = null;
-
- if (mDebug) {
- double pixelsPerRange = mScaleInfo.getPixelsPerRange();
- System.out
- .printf(
- "dim.x %d pixels %d minVal %f, maxVal %f ppr %f rpp %f\n",
- dim.x, dim.x - TotalXMargin, mScaleInfo
- .getMinVal(), mScaleInfo.getMaxVal(),
- pixelsPerRange, 1.0 / pixelsPerRange);
- }
-
- // Draw the strips
- Block selectBlock = null;
- for (Strip strip : mStripList) {
- if (strip.mColor == null) {
- // System.out.printf("strip.color is null\n");
- continue;
- }
- gcImage.setBackground(strip.mColor);
- gcImage.fillRectangle(strip.mX, strip.mY - mScrollOffsetY, strip.mWidth,
- strip.mHeight);
- if (mMouseRow == strip.mRowData.mRank) {
- if (mMouse.x >= strip.mX
- && mMouse.x < strip.mX + strip.mWidth) {
- Block block = strip.mSegment.mBlock;
- blockName = block.getName();
- blockColor = strip.mColor;
- if (mHaveCpuTime) {
- if (mHaveRealTime) {
- blockDetails = String.format(
- "excl cpu %s, incl cpu %s, "
- + "excl real %s, incl real %s",
- mUnits.labelledString(block.getExclusiveCpuTime()),
- mUnits.labelledString(block.getInclusiveCpuTime()),
- mUnits.labelledString(block.getExclusiveRealTime()),
- mUnits.labelledString(block.getInclusiveRealTime()));
- } else {
- blockDetails = String.format(
- "excl cpu %s, incl cpu %s",
- mUnits.labelledString(block.getExclusiveCpuTime()),
- mUnits.labelledString(block.getInclusiveCpuTime()));
- }
- } else {
- blockDetails = String.format(
- "excl real %s, incl real %s",
- mUnits.labelledString(block.getExclusiveRealTime()),
- mUnits.labelledString(block.getInclusiveRealTime()));
- }
- }
- if (mMouseSelect.x >= strip.mX
- && mMouseSelect.x < strip.mX + strip.mWidth) {
- selectBlock = strip.mSegment.mBlock;
- }
- }
- }
- mMouseSelect.x = 0;
- mMouseSelect.y = 0;
-
- if (selectBlock != null) {
- ArrayList<Selection> selections = new ArrayList<Selection>();
- // Get the row label
- RowData rd = mRows[mMouseRow];
- selections.add(Selection.highlight("Thread", rd.mName)); //$NON-NLS-1$
- selections.add(Selection.highlight("Call", selectBlock)); //$NON-NLS-1$
-
- int mouseX = mMouse.x - LeftMargin;
- double mouseXval = mScaleInfo.pixelToValue(mouseX);
- selections.add(Selection.highlight("Time", mouseXval)); //$NON-NLS-1$
-
- mSelectionController.change(selections, "TimeLineView"); //$NON-NLS-1$
- mHighlightMethodData = null;
- mHighlightCall = (Call) selectBlock;
- startHighlighting();
- }
-
- // Draw a highlight box on the row where the mouse is.
- // Except don't draw the box if we are animating the
- // highlighing of a call or method because the inclusive
- // highlight bar passes through the highlight box and
- // causes an annoying flashing artifact.
- if (mMouseRow >= 0 && mMouseRow < mNumRows && mHighlightStep == 0) {
- gcImage.setForeground(mColorGray);
- int y1 = mMouseRow * rowYSpace - mScrollOffsetY;
- gcImage.drawLine(0, y1, dim.x, y1);
- gcImage.drawLine(0, y1 + rowYSpace, dim.x, y1 + rowYSpace);
- }
-
- // Highlight a selected method, if any
- drawHighlights(gcImage, dim);
-
- // Draw a vertical line where the mouse is.
- gcImage.setForeground(mColorDarkGray);
- int lineEnd = Math.min(dim.y, mNumRows * rowYSpace);
- gcImage.drawLine(mMouse.x, 0, mMouse.x, lineEnd);
-
- if (blockName != null) {
- mTimescale.setMethodName(blockName);
- mTimescale.setMethodColor(blockColor);
- mTimescale.setDetails(blockDetails);
- mShowHighlightName = false;
- } else if (mShowHighlightName) {
- // Draw the highlighted method name
- MethodData md = mHighlightMethodData;
- if (md == null && mHighlightCall != null)
- md = mHighlightCall.getMethodData();
- if (md == null)
- System.out.printf("null highlight?\n"); //$NON-NLS-1$
- if (md != null) {
- mTimescale.setMethodName(md.getProfileName());
- mTimescale.setMethodColor(md.getColor());
- mTimescale.setDetails(null);
- }
- } else {
- mTimescale.setMethodName(null);
- mTimescale.setMethodColor(null);
- mTimescale.setDetails(null);
- }
- mTimescale.redraw();
-
- // Draw the off-screen buffer to the screen
- gc.drawImage(image, 0, 0);
-
- // Clean up
- image.dispose();
- gcImage.dispose();
- }
-
- private void drawHighlights(GC gc, Point dim) {
- int height = mHighlightHeight;
- if (height <= 0)
- return;
- for (Range range : mHighlightExclusive) {
- gc.setBackground(range.mColor);
- int xStart = range.mXdim.x;
- int width = range.mXdim.y;
- gc.fillRectangle(xStart, range.mY - height - mScrollOffsetY, width, height);
- }
-
- // Draw the inclusive lines a bit shorter
- height -= 1;
- if (height <= 0)
- height = 1;
-
- // Highlight the inclusive ranges
- gc.setForeground(mColorDarkGray);
- gc.setBackground(mColorDarkGray);
- for (Range range : mHighlightInclusive) {
- int x1 = range.mXdim.x;
- int x2 = range.mXdim.y;
- boolean drawLeftEnd = false;
- boolean drawRightEnd = false;
- if (x1 >= LeftMargin)
- drawLeftEnd = true;
- else
- x1 = LeftMargin;
- if (x2 >= LeftMargin)
- drawRightEnd = true;
- else
- x2 = dim.x - RightMargin;
- int y1 = range.mY + rowHeight + 2 - mScrollOffsetY;
-
- // If the range is very narrow, then just draw a small
- // rectangle.
- if (x2 - x1 < MinInclusiveRange) {
- int width = x2 - x1;
- if (width < 2)
- width = 2;
- gc.fillRectangle(x1, y1, width, height);
- continue;
- }
- if (drawLeftEnd) {
- if (drawRightEnd) {
- // Draw both ends
- int[] points = { x1, y1, x1, y1 + height, x2,
- y1 + height, x2, y1 };
- gc.drawPolyline(points);
- } else {
- // Draw the left end
- int[] points = { x1, y1, x1, y1 + height, x2,
- y1 + height };
- gc.drawPolyline(points);
- }
- } else {
- if (drawRightEnd) {
- // Draw the right end
- int[] points = { x1, y1 + height, x2, y1 + height, x2,
- y1 };
- gc.drawPolyline(points);
- } else {
- // Draw neither end, just the line
- int[] points = { x1, y1 + height, x2, y1 + height };
- gc.drawPolyline(points);
- }
- }
-
- // Draw the arrowheads, if necessary
- if (drawLeftEnd == false) {
- int[] points = { x1 + 7, y1 + height - 4, x1, y1 + height,
- x1 + 7, y1 + height + 4 };
- gc.fillPolygon(points);
- }
- if (drawRightEnd == false) {
- int[] points = { x2 - 7, y1 + height - 4, x2, y1 + height,
- x2 - 7, y1 + height + 4 };
- gc.fillPolygon(points);
- }
- }
- }
-
- private boolean drawingSelection() {
- return mGraphicsState == GraphicsState.Marking
- || mGraphicsState == GraphicsState.Animating;
- }
-
- private void drawSelection(Display display, GC gc) {
- Point dim = getSize();
- gc.setForeground(mColorGray);
- gc.drawLine(mMouseMarkStartX, 0, mMouseMarkStartX, dim.y);
- gc.setBackground(mColorZoomSelection);
- int width;
- int mouseX = (mGraphicsState == GraphicsState.Animating) ? mMouseMarkEndX : mMouse.x;
- int x;
- if (mMouseMarkStartX < mouseX) {
- x = mMouseMarkStartX;
- width = mouseX - mMouseMarkStartX;
- } else {
- x = mouseX;
- width = mMouseMarkStartX - mouseX;
- }
- gc.fillRectangle(x, 0, width, dim.y);
- }
-
- private void computeStrips() {
- double minVal = mScaleInfo.getMinVal();
- double maxVal = mScaleInfo.getMaxVal();
-
- // Allocate space for the pixel data
- Pixel[] pixels = new Pixel[mNumRows];
- for (int ii = 0; ii < mNumRows; ++ii)
- pixels[ii] = new Pixel();
-
- // Clear the per-block pixel data
- for (int ii = 0; ii < mSegments.length; ++ii) {
- mSegments[ii].mBlock.clearWeight();
- }
-
- mStripList.clear();
- mHighlightExclusive.clear();
- mHighlightInclusive.clear();
- MethodData callMethod = null;
- long callStart = 0;
- long callEnd = -1;
- RowData callRowData = null;
- int prevMethodStart = -1;
- int prevMethodEnd = -1;
- int prevCallStart = -1;
- int prevCallEnd = -1;
- if (mHighlightCall != null) {
- int callPixelStart = -1;
- int callPixelEnd = -1;
- callStart = mHighlightCall.getStartTime();
- callEnd = mHighlightCall.getEndTime();
- callMethod = mHighlightCall.getMethodData();
- if (callStart >= minVal)
- callPixelStart = mScaleInfo.valueToPixel(callStart);
- if (callEnd <= maxVal)
- callPixelEnd = mScaleInfo.valueToPixel(callEnd);
- // System.out.printf("callStart,End %d,%d minVal,maxVal %f,%f
- // callPixelStart,End %d,%d\n",
- // callStart, callEnd, minVal, maxVal, callPixelStart,
- // callPixelEnd);
- int threadId = mHighlightCall.getThreadId();
- String threadName = mThreadLabels.get(threadId);
- callRowData = mRowByName.get(threadName);
- int y1 = callRowData.mRank * rowYSpace + rowYMarginHalf;
- Color color = callMethod.getColor();
- mHighlightInclusive.add(new Range(callPixelStart + LeftMargin,
- callPixelEnd + LeftMargin, y1, color));
- }
- for (Segment segment : mSegments) {
- if (segment.mEndTime <= minVal)
- continue;
- if (segment.mStartTime >= maxVal)
- continue;
-
- Block block = segment.mBlock;
-
- // Skip over blocks that were not assigned a color, including the
- // top level block and others that have zero inclusive time.
- Color color = block.getColor();
- if (color == null)
- continue;
-
- double recordStart = Math.max(segment.mStartTime, minVal);
- double recordEnd = Math.min(segment.mEndTime, maxVal);
- if (recordStart == recordEnd)
- continue;
- int pixelStart = mScaleInfo.valueToPixel(recordStart);
- int pixelEnd = mScaleInfo.valueToPixel(recordEnd);
- int width = pixelEnd - pixelStart;
- boolean isContextSwitch = segment.mIsContextSwitch;
-
- RowData rd = segment.mRowData;
- MethodData md = block.getMethodData();
-
- // We will add the scroll offset later when we draw the strips
- int y1 = rd.mRank * rowYSpace + rowYMarginHalf;
-
- // If we can't display any more rows, then quit
- if (rd.mRank > mEndRow)
- break;
-
- // System.out.printf("segment %s val: [%.1f, %.1f] frac [%f, %f]
- // pixel: [%d, %d] pix.start %d weight %.2f %s\n",
- // block.getName(), recordStart, recordEnd,
- // scaleInfo.valueToPixelFraction(recordStart),
- // scaleInfo.valueToPixelFraction(recordEnd),
- // pixelStart, pixelEnd, pixels[rd.rank].start,
- // pixels[rd.rank].maxWeight,
- // pixels[rd.rank].segment != null
- // ? pixels[rd.rank].segment.block.getName()
- // : "null");
-
- if (mHighlightMethodData != null) {
- if (mHighlightMethodData == md) {
- if (prevMethodStart != pixelStart || prevMethodEnd != pixelEnd) {
- prevMethodStart = pixelStart;
- prevMethodEnd = pixelEnd;
- int rangeWidth = width;
- if (rangeWidth == 0)
- rangeWidth = 1;
- mHighlightExclusive.add(new Range(pixelStart
- + LeftMargin, rangeWidth, y1, color));
- callStart = block.getStartTime();
- int callPixelStart = -1;
- if (callStart >= minVal)
- callPixelStart = mScaleInfo.valueToPixel(callStart);
- int callPixelEnd = -1;
- callEnd = block.getEndTime();
- if (callEnd <= maxVal)
- callPixelEnd = mScaleInfo.valueToPixel(callEnd);
- if (prevCallStart != callPixelStart || prevCallEnd != callPixelEnd) {
- prevCallStart = callPixelStart;
- prevCallEnd = callPixelEnd;
- mHighlightInclusive.add(new Range(
- callPixelStart + LeftMargin,
- callPixelEnd + LeftMargin, y1, color));
- }
- }
- } else if (mFadeColors) {
- color = md.getFadedColor();
- }
- } else if (mHighlightCall != null) {
- if (segment.mStartTime >= callStart
- && segment.mEndTime <= callEnd && callMethod == md
- && callRowData == rd) {
- if (prevMethodStart != pixelStart || prevMethodEnd != pixelEnd) {
- prevMethodStart = pixelStart;
- prevMethodEnd = pixelEnd;
- int rangeWidth = width;
- if (rangeWidth == 0)
- rangeWidth = 1;
- mHighlightExclusive.add(new Range(pixelStart
- + LeftMargin, rangeWidth, y1, color));
- }
- } else if (mFadeColors) {
- color = md.getFadedColor();
- }
- }
-
- // Cases:
- // 1. This segment starts on a different pixel than the
- // previous segment started on. In this case, emit
- // the pixel strip, if any, and:
- // A. If the width is 0, then add this segment's
- // weight to the Pixel.
- // B. If the width > 0, then emit a strip for this
- // segment (no partial Pixel data).
- //
- // 2. Otherwise (the new segment starts on the same
- // pixel as the previous segment): add its "weight"
- // to the current pixel, and:
- // A. If the new segment has width 1,
- // then emit the pixel strip and then
- // add the segment's weight to the pixel.
- // B. If the new segment has width > 1,
- // then emit the pixel strip, and emit the rest
- // of the strip for this segment (no partial Pixel
- // data).
-
- Pixel pix = pixels[rd.mRank];
- if (pix.mStart != pixelStart) {
- if (pix.mSegment != null) {
- // Emit the pixel strip. This also clears the pixel.
- emitPixelStrip(rd, y1, pix);
- }
-
- if (width == 0) {
- // Compute the "weight" of this segment for the first
- // pixel. For a pixel N, the "weight" of a segment is
- // how much of the region [N - 0.5, N + 0.5] is covered
- // by the segment.
- double weight = computeWeight(recordStart, recordEnd,
- isContextSwitch, pixelStart);
- weight = block.addWeight(pixelStart, rd.mRank, weight);
- if (weight > pix.mMaxWeight) {
- pix.setFields(pixelStart, weight, segment, color,
- rd);
- }
- } else {
- int x1 = pixelStart + LeftMargin;
- Strip strip = new Strip(
- x1, isContextSwitch ? y1 + rowHeight - 1 : y1,
- width, isContextSwitch ? 1 : rowHeight,
- rd, segment, color);
- mStripList.add(strip);
- }
- } else {
- double weight = computeWeight(recordStart, recordEnd,
- isContextSwitch, pixelStart);
- weight = block.addWeight(pixelStart, rd.mRank, weight);
- if (weight > pix.mMaxWeight) {
- pix.setFields(pixelStart, weight, segment, color, rd);
- }
- if (width == 1) {
- // Emit the pixel strip. This also clears the pixel.
- emitPixelStrip(rd, y1, pix);
-
- // Compute the weight for the next pixel
- pixelStart += 1;
- weight = computeWeight(recordStart, recordEnd,
- isContextSwitch, pixelStart);
- weight = block.addWeight(pixelStart, rd.mRank, weight);
- pix.setFields(pixelStart, weight, segment, color, rd);
- } else if (width > 1) {
- // Emit the pixel strip. This also clears the pixel.
- emitPixelStrip(rd, y1, pix);
-
- // Emit a strip for the rest of the segment.
- pixelStart += 1;
- width -= 1;
- int x1 = pixelStart + LeftMargin;
- Strip strip = new Strip(
- x1, isContextSwitch ? y1 + rowHeight - 1 : y1,
- width, isContextSwitch ? 1 : rowHeight,
- rd,segment, color);
- mStripList.add(strip);
- }
- }
- }
-
- // Emit the last pixels of each row, if any
- for (int ii = 0; ii < mNumRows; ++ii) {
- Pixel pix = pixels[ii];
- if (pix.mSegment != null) {
- RowData rd = pix.mRowData;
- int y1 = rd.mRank * rowYSpace + rowYMarginHalf;
- // Emit the pixel strip. This also clears the pixel.
- emitPixelStrip(rd, y1, pix);
- }
- }
-
- if (false) {
- System.out.printf("computeStrips()\n");
- for (Strip strip : mStripList) {
- System.out.printf("%3d, %3d width %3d height %d %s\n",
- strip.mX, strip.mY, strip.mWidth, strip.mHeight,
- strip.mSegment.mBlock.getName());
- }
- }
- }
-
- private double computeWeight(double start, double end,
- boolean isContextSwitch, int pixel) {
- if (isContextSwitch) {
- return 0;
- }
- double pixelStartFraction = mScaleInfo.valueToPixelFraction(start);
- double pixelEndFraction = mScaleInfo.valueToPixelFraction(end);
- double leftEndPoint = Math.max(pixelStartFraction, pixel - 0.5);
- double rightEndPoint = Math.min(pixelEndFraction, pixel + 0.5);
- double weight = rightEndPoint - leftEndPoint;
- return weight;
- }
-
- private void emitPixelStrip(RowData rd, int y, Pixel pixel) {
- Strip strip;
-
- if (pixel.mSegment == null)
- return;
-
- int x = pixel.mStart + LeftMargin;
- // Compute the percentage of the row height proportional to
- // the weight of this pixel. But don't let the proportion
- // exceed 3/4 of the row height so that we can easily see
- // if a given time range includes more than one method.
- int height = (int) (pixel.mMaxWeight * rowHeight * 0.75);
- if (height < mMinStripHeight)
- height = mMinStripHeight;
- int remainder = rowHeight - height;
- if (remainder > 0) {
- strip = new Strip(x, y, 1, remainder, rd, pixel.mSegment,
- mFadeColors ? mColorGray : mColorBlack);
- mStripList.add(strip);
- // System.out.printf("emitPixel (%d, %d) height %d black\n",
- // x, y, remainder);
- }
- strip = new Strip(x, y + remainder, 1, height, rd, pixel.mSegment,
- pixel.mColor);
- mStripList.add(strip);
- // System.out.printf("emitPixel (%d, %d) height %d %s\n",
- // x, y + remainder, height, pixel.segment.block.getName());
- pixel.mSegment = null;
- pixel.mMaxWeight = 0.0;
- }
-
- private void mouseMove(MouseEvent me) {
- if (false) {
- if (mHighlightMethodData != null) {
- mHighlightMethodData = null;
- // Force a recomputation of the strip colors
- mCachedEndRow = -1;
- }
- }
- Point dim = mSurface.getSize();
- int x = me.x;
- if (x < LeftMargin)
- x = LeftMargin;
- if (x > dim.x - RightMargin)
- x = dim.x - RightMargin;
- mMouse.x = x;
- mMouse.y = me.y;
- mTimescale.setVbarPosition(x);
- if (mGraphicsState == GraphicsState.Marking) {
- mTimescale.setMarkEnd(x);
- }
-
- if (mGraphicsState == GraphicsState.Normal) {
- // Set the cursor to the normal state.
- mSurface.setCursor(mNormalCursor);
- } else if (mGraphicsState == GraphicsState.Marking) {
- // Make the cursor point in the direction of the sweep
- if (mMouse.x >= mMouseMarkStartX)
- mSurface.setCursor(mIncreasingCursor);
- else
- mSurface.setCursor(mDecreasingCursor);
- }
- int rownum = (mMouse.y + mScrollOffsetY) / rowYSpace;
- if (me.y < 0 || me.y >= dim.y) {
- rownum = -1;
- }
- if (mMouseRow != rownum) {
- mMouseRow = rownum;
- mLabels.redraw();
- }
- redraw();
- }
-
- private void mouseDown(MouseEvent me) {
- Point dim = mSurface.getSize();
- int x = me.x;
- if (x < LeftMargin)
- x = LeftMargin;
- if (x > dim.x - RightMargin)
- x = dim.x - RightMargin;
- mMouseMarkStartX = x;
- mGraphicsState = GraphicsState.Marking;
- mSurface.setCursor(mIncreasingCursor);
- mTimescale.setMarkStart(mMouseMarkStartX);
- mTimescale.setMarkEnd(mMouseMarkStartX);
- redraw();
- }
-
- private void mouseUp(MouseEvent me) {
- mSurface.setCursor(mNormalCursor);
- if (mGraphicsState != GraphicsState.Marking) {
- mGraphicsState = GraphicsState.Normal;
- return;
- }
- mGraphicsState = GraphicsState.Animating;
- Point dim = mSurface.getSize();
-
- // If the user released the mouse outside the drawing area then
- // cancel the zoom.
- if (me.y <= 0 || me.y >= dim.y) {
- mGraphicsState = GraphicsState.Normal;
- redraw();
- return;
- }
-
- int x = me.x;
- if (x < LeftMargin)
- x = LeftMargin;
- if (x > dim.x - RightMargin)
- x = dim.x - RightMargin;
- mMouseMarkEndX = x;
-
- // If the user clicked and released the mouse at the same point
- // (+/- a pixel or two) then cancel the zoom (but select the
- // method).
- int dist = mMouseMarkEndX - mMouseMarkStartX;
- if (dist < 0)
- dist = -dist;
- if (dist <= 2) {
- mGraphicsState = GraphicsState.Normal;
-
- // Select the method underneath the mouse
- mMouseSelect.x = mMouseMarkStartX;
- mMouseSelect.y = me.y;
- redraw();
- return;
- }
-
- // Make mouseEndX be the higher end point
- if (mMouseMarkEndX < mMouseMarkStartX) {
- int temp = mMouseMarkEndX;
- mMouseMarkEndX = mMouseMarkStartX;
- mMouseMarkStartX = temp;
- }
-
- // If the zoom area is the whole window (or nearly the whole
- // window) then cancel the zoom.
- if (mMouseMarkStartX <= LeftMargin + MinZoomPixelMargin
- && mMouseMarkEndX >= dim.x - RightMargin - MinZoomPixelMargin) {
- mGraphicsState = GraphicsState.Normal;
- redraw();
- return;
- }
-
- // Compute some variables needed for zooming.
- // It's probably easiest to explain by an example. There
- // are two scales (or dimensions) involved: one for the pixels
- // and one for the values (microseconds). To keep the example
- // simple, suppose we have pixels in the range [0,16] and
- // values in the range [100, 260], and suppose the user
- // selects a zoom window from pixel 4 to pixel 8.
- //
- // usec: 100 140 180 260
- // |-------|ZZZZZZZ|---------------|
- // pixel: 0 4 8 16
- //
- // I've drawn the pixels starting at zero for simplicity, but
- // in fact the drawable area is offset from the left margin
- // by the value of "LeftMargin".
- //
- // The "pixels-per-range" (ppr) in this case is 0.1 (a tenth of
- // a pixel per usec). What we want is to redraw the screen in
- // several steps, each time increasing the zoom window until the
- // zoom window fills the screen. For simplicity, assume that
- // we want to zoom in four equal steps. Then the snapshots
- // of the screen at each step would look something like this:
- //
- // usec: 100 140 180 260
- // |-------|ZZZZZZZ|---------------|
- // pixel: 0 4 8 16
- //
- // usec: ? 140 180 ?
- // |-----|ZZZZZZZZZZZZZ|-----------|
- // pixel: 0 3 10 16
- //
- // usec: ? 140 180 ?
- // |---|ZZZZZZZZZZZZZZZZZZZ|-------|
- // pixel: 0 2 12 16
- //
- // usec: ?140 180 ?
- // |-|ZZZZZZZZZZZZZZZZZZZZZZZZZ|---|
- // pixel: 0 1 14 16
- //
- // usec: 140 180
- // |ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ|
- // pixel: 0 16
- //
- // The problem is how to compute the endpoints (denoted by ?)
- // for each step. This is a little tricky. We first need to
- // compute the "fixed point": this is the point in the selection
- // that doesn't move left or right. Then we can recompute the
- // "ppr" (pixels per range) at each step and then find the
- // endpoints. The computation of the end points is done
- // in animateZoom(). This method computes the fixed point
- // and some other variables needed in animateZoom().
-
- double minVal = mScaleInfo.getMinVal();
- double maxVal = mScaleInfo.getMaxVal();
- double ppr = mScaleInfo.getPixelsPerRange();
- mZoomMin = minVal + ((mMouseMarkStartX - LeftMargin) / ppr);
- mZoomMax = minVal + ((mMouseMarkEndX - LeftMargin) / ppr);
-
- // Clamp the min and max values to the actual data min and max
- if (mZoomMin < mMinDataVal)
- mZoomMin = mMinDataVal;
- if (mZoomMax > mMaxDataVal)
- mZoomMax = mMaxDataVal;
-
- // Snap the min and max points to the grid determined by the
- // TickScaler
- // before we zoom.
- int xdim = dim.x - TotalXMargin;
- TickScaler scaler = new TickScaler(mZoomMin, mZoomMax, xdim,
- PixelsPerTick);
- scaler.computeTicks(false);
- mZoomMin = scaler.getMinVal();
- mZoomMax = scaler.getMaxVal();
-
- // Also snap the mouse points (in pixel space) to be consistent with
- // zoomMin and zoomMax (in value space).
- mMouseMarkStartX = (int) ((mZoomMin - minVal) * ppr + LeftMargin);
- mMouseMarkEndX = (int) ((mZoomMax - minVal) * ppr + LeftMargin);
- mTimescale.setMarkStart(mMouseMarkStartX);
- mTimescale.setMarkEnd(mMouseMarkEndX);
-
- // Compute the mouse selection end point distances
- mMouseEndDistance = dim.x - RightMargin - mMouseMarkEndX;
- mMouseStartDistance = mMouseMarkStartX - LeftMargin;
- mZoomMouseStart = mMouseMarkStartX;
- mZoomMouseEnd = mMouseMarkEndX;
- mZoomStep = 0;
-
- // Compute the fixed point in both value space and pixel space.
- mMin2ZoomMin = mZoomMin - minVal;
- mZoomMax2Max = maxVal - mZoomMax;
- mZoomFixed = mZoomMin + (mZoomMax - mZoomMin) * mMin2ZoomMin
- / (mMin2ZoomMin + mZoomMax2Max);
- mZoomFixedPixel = (mZoomFixed - minVal) * ppr + LeftMargin;
- mFixedPixelStartDistance = mZoomFixedPixel - LeftMargin;
- mFixedPixelEndDistance = dim.x - RightMargin - mZoomFixedPixel;
-
- mZoomMin2Fixed = mZoomFixed - mZoomMin;
- mFixed2ZoomMax = mZoomMax - mZoomFixed;
-
- getDisplay().timerExec(ZOOM_TIMER_INTERVAL, mZoomAnimator);
- redraw();
- update();
- }
-
- private void mouseScrolled(MouseEvent me) {
- mGraphicsState = GraphicsState.Scrolling;
- double tMin = mScaleInfo.getMinVal();
- double tMax = mScaleInfo.getMaxVal();
- double zoomFactor = 2;
- double tMinRef = mLimitMinVal;
- double tMaxRef = mLimitMaxVal;
- double t; // the fixed point
- double tMinNew;
- double tMaxNew;
- if (me.count > 0) {
- // we zoom in
- Point dim = mSurface.getSize();
- int x = me.x;
- if (x < LeftMargin)
- x = LeftMargin;
- if (x > dim.x - RightMargin)
- x = dim.x - RightMargin;
- double ppr = mScaleInfo.getPixelsPerRange();
- t = tMin + ((x - LeftMargin) / ppr);
- tMinNew = Math.max(tMinRef, t - (t - tMin) / zoomFactor);
- tMaxNew = Math.min(tMaxRef, t + (tMax - t) / zoomFactor);
- } else {
- // we zoom out
- double factor = (tMax - tMin) / (tMaxRef - tMinRef);
- if (factor < 1) {
- t = (factor * tMinRef - tMin) / (factor - 1);
- tMinNew = Math.max(tMinRef, t - zoomFactor * (t - tMin));
- tMaxNew = Math.min(tMaxRef, t + zoomFactor * (tMax - t));
- } else {
- return;
- }
- }
- mScaleInfo.setMinVal(tMinNew);
- mScaleInfo.setMaxVal(tMaxNew);
- mSurface.redraw();
- }
-
- // No defined behavior yet for double-click.
- private void mouseDoubleClick(MouseEvent me) {
- }
-
- public void startScaling(int mouseX) {
- Point dim = mSurface.getSize();
- int x = mouseX;
- if (x < LeftMargin)
- x = LeftMargin;
- if (x > dim.x - RightMargin)
- x = dim.x - RightMargin;
- mMouseMarkStartX = x;
- mGraphicsState = GraphicsState.Scaling;
- mScalePixelsPerRange = mScaleInfo.getPixelsPerRange();
- mScaleMinVal = mScaleInfo.getMinVal();
- mScaleMaxVal = mScaleInfo.getMaxVal();
- }
-
- public void stopScaling(int mouseX) {
- mGraphicsState = GraphicsState.Normal;
- }
-
- private void animateHighlight() {
- mHighlightStep += 1;
- if (mHighlightStep >= HIGHLIGHT_STEPS) {
- mFadeColors = false;
- mHighlightStep = 0;
- // Force a recomputation of the strip colors
- mCachedEndRow = -1;
- } else {
- mFadeColors = true;
- mShowHighlightName = true;
- mHighlightHeight = highlightHeights[mHighlightStep];
- getDisplay().timerExec(HIGHLIGHT_TIMER_INTERVAL, mHighlightAnimator);
- }
- redraw();
- }
-
- private void clearHighlights() {
- // System.out.printf("clearHighlights()\n");
- mShowHighlightName = false;
- mHighlightHeight = 0;
- mHighlightMethodData = null;
- mHighlightCall = null;
- mFadeColors = false;
- mHighlightStep = 0;
- // Force a recomputation of the strip colors
- mCachedEndRow = -1;
- redraw();
- }
-
- private void animateZoom() {
- mZoomStep += 1;
- if (mZoomStep > ZOOM_STEPS) {
- mGraphicsState = GraphicsState.Normal;
- // Force a normal recomputation
- mCachedMinVal = mScaleInfo.getMinVal() + 1;
- } else if (mZoomStep == ZOOM_STEPS) {
- mScaleInfo.setMinVal(mZoomMin);
- mScaleInfo.setMaxVal(mZoomMax);
- mMouseMarkStartX = LeftMargin;
- Point dim = getSize();
- mMouseMarkEndX = dim.x - RightMargin;
- mTimescale.setMarkStart(mMouseMarkStartX);
- mTimescale.setMarkEnd(mMouseMarkEndX);
- getDisplay().timerExec(ZOOM_TIMER_INTERVAL, mZoomAnimator);
- } else {
- // Zoom in slowly at first, then speed up, then slow down.
- // The zoom fractions are precomputed to save time.
- double fraction = mZoomFractions[mZoomStep];
- mMouseMarkStartX = (int) (mZoomMouseStart - fraction * mMouseStartDistance);
- mMouseMarkEndX = (int) (mZoomMouseEnd + fraction * mMouseEndDistance);
- mTimescale.setMarkStart(mMouseMarkStartX);
- mTimescale.setMarkEnd(mMouseMarkEndX);
-
- // Compute the new pixels-per-range. Avoid division by zero.
- double ppr;
- if (mZoomMin2Fixed >= mFixed2ZoomMax)
- ppr = (mZoomFixedPixel - mMouseMarkStartX) / mZoomMin2Fixed;
- else
- ppr = (mMouseMarkEndX - mZoomFixedPixel) / mFixed2ZoomMax;
- double newMin = mZoomFixed - mFixedPixelStartDistance / ppr;
- double newMax = mZoomFixed + mFixedPixelEndDistance / ppr;
- mScaleInfo.setMinVal(newMin);
- mScaleInfo.setMaxVal(newMax);
-
- getDisplay().timerExec(ZOOM_TIMER_INTERVAL, mZoomAnimator);
- }
- redraw();
- }
-
- private static final int TotalXMargin = LeftMargin + RightMargin;
- private static final int yMargin = 1; // blank space on top
- // The minimum margin on each side of the zoom window, in pixels.
- private static final int MinZoomPixelMargin = 10;
- private GraphicsState mGraphicsState = GraphicsState.Normal;
- private Point mMouse = new Point(LeftMargin, 0);
- private int mMouseMarkStartX;
- private int mMouseMarkEndX;
- private boolean mDebug = false;
- private ArrayList<Strip> mStripList = new ArrayList<Strip>();
- private ArrayList<Range> mHighlightExclusive = new ArrayList<Range>();
- private ArrayList<Range> mHighlightInclusive = new ArrayList<Range>();
- private int mMinStripHeight = 2;
- private double mCachedMinVal;
- private double mCachedMaxVal;
- private int mCachedStartRow;
- private int mCachedEndRow;
- private double mScalePixelsPerRange;
- private double mScaleMinVal;
- private double mScaleMaxVal;
- private double mLimitMinVal;
- private double mLimitMaxVal;
- private double mMinDataVal;
- private double mMaxDataVal;
- private Cursor mNormalCursor;
- private Cursor mIncreasingCursor;
- private Cursor mDecreasingCursor;
- private static final int ZOOM_TIMER_INTERVAL = 10;
- private static final int HIGHLIGHT_TIMER_INTERVAL = 50;
- private static final int ZOOM_STEPS = 8; // must be even
- private int mHighlightHeight = 4;
- private final int[] highlightHeights = { 0, 2, 4, 5, 6, 5, 4, 2, 4, 5,
- 6 };
- private final int HIGHLIGHT_STEPS = highlightHeights.length;
- private boolean mFadeColors;
- private boolean mShowHighlightName;
- private double[] mZoomFractions;
- private int mZoomStep;
- private int mZoomMouseStart;
- private int mZoomMouseEnd;
- private int mMouseStartDistance;
- private int mMouseEndDistance;
- private Point mMouseSelect = new Point(0, 0);
- private double mZoomFixed;
- private double mZoomFixedPixel;
- private double mFixedPixelStartDistance;
- private double mFixedPixelEndDistance;
- private double mZoomMin2Fixed;
- private double mMin2ZoomMin;
- private double mFixed2ZoomMax;
- private double mZoomMax2Max;
- private double mZoomMin;
- private double mZoomMax;
- private Runnable mZoomAnimator;
- private Runnable mHighlightAnimator;
- private int mHighlightStep;
- }
-
- private int computeVisibleRows(int ydim) {
- // If we resize, then move the bottom row down. Don't allow the scroll
- // to waste space at the bottom.
- int offsetY = mScrollOffsetY;
- int spaceNeeded = mNumRows * rowYSpace;
- if (offsetY + ydim > spaceNeeded) {
- offsetY = spaceNeeded - ydim;
- if (offsetY < 0) {
- offsetY = 0;
- }
- }
- mStartRow = offsetY / rowYSpace;
- mEndRow = (offsetY + ydim) / rowYSpace;
- if (mEndRow >= mNumRows) {
- mEndRow = mNumRows - 1;
- }
-
- return offsetY;
- }
-
- private void startHighlighting() {
- // System.out.printf("startHighlighting()\n");
- mSurface.mHighlightStep = 0;
- mSurface.mFadeColors = true;
- // Force a recomputation of the color strips
- mSurface.mCachedEndRow = -1;
- getDisplay().timerExec(0, mSurface.mHighlightAnimator);
- }
-
- private static class RowData {
- RowData(Row row) {
- mName = row.getName();
- mStack = new ArrayList<Block>();
- }
-
- public void push(Block block) {
- mStack.add(block);
- }
-
- public Block top() {
- if (mStack.size() == 0)
- return null;
- return mStack.get(mStack.size() - 1);
- }
-
- public void pop() {
- if (mStack.size() == 0)
- return;
- mStack.remove(mStack.size() - 1);
- }
-
- private String mName;
- private int mRank;
- private long mElapsed;
- private long mEndTime;
- private ArrayList<Block> mStack;
- }
-
- private static class Segment {
- Segment(RowData rowData, Block block, long startTime, long endTime) {
- mRowData = rowData;
- if (block.isContextSwitch()) {
- mBlock = block.getParentBlock();
- mIsContextSwitch = true;
- } else {
- mBlock = block;
- }
- mStartTime = startTime;
- mEndTime = endTime;
- }
-
- private RowData mRowData;
- private Block mBlock;
- private long mStartTime;
- private long mEndTime;
- private boolean mIsContextSwitch;
- }
-
- private static class Strip {
- Strip(int x, int y, int width, int height, RowData rowData,
- Segment segment, Color color) {
- mX = x;
- mY = y;
- mWidth = width;
- mHeight = height;
- mRowData = rowData;
- mSegment = segment;
- mColor = color;
- }
-
- int mX;
- int mY;
- int mWidth;
- int mHeight;
- RowData mRowData;
- Segment mSegment;
- Color mColor;
- }
-
- private static class Pixel {
- public void setFields(int start, double weight, Segment segment,
- Color color, RowData rowData) {
- mStart = start;
- mMaxWeight = weight;
- mSegment = segment;
- mColor = color;
- mRowData = rowData;
- }
-
- int mStart = -2; // some value that won't match another pixel
- double mMaxWeight;
- Segment mSegment;
- Color mColor; // we need the color here because it may be faded
- RowData mRowData;
- }
-
- private static class Range {
- Range(int xStart, int width, int y, Color color) {
- mXdim.x = xStart;
- mXdim.y = width;
- mY = y;
- mColor = color;
- }
-
- Point mXdim = new Point(0, 0);
- int mY;
- Color mColor;
- }
-}
diff --git a/traceview/src/com/android/traceview/TraceAction.java b/traceview/src/com/android/traceview/TraceAction.java
deleted file mode 100644
index 6717300..0000000
--- a/traceview/src/com/android/traceview/TraceAction.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.traceview;
-
-final class TraceAction {
- public static final int ACTION_ENTER = 0;
- public static final int ACTION_EXIT = 1;
- public static final int ACTION_INCOMPLETE = 2;
-
- public final int mAction;
- public final Call mCall;
-
- public TraceAction(int action, Call call) {
- mAction = action;
- mCall = call;
- }
-}
diff --git a/traceview/src/com/android/traceview/TraceReader.java b/traceview/src/com/android/traceview/TraceReader.java
deleted file mode 100644
index fa76d27..0000000
--- a/traceview/src/com/android/traceview/TraceReader.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public abstract class TraceReader {
-
- private TraceUnits mTraceUnits;
-
- public TraceUnits getTraceUnits() {
- if (mTraceUnits == null)
- mTraceUnits = new TraceUnits();
- return mTraceUnits;
- }
-
- public ArrayList<TimeLineView.Record> getThreadTimeRecords() {
- return null;
- }
-
- public HashMap<Integer, String> getThreadLabels() {
- return null;
- }
-
- public MethodData[] getMethods() {
- return null;
- }
-
- public ThreadData[] getThreads() {
- return null;
- }
-
- public long getTotalCpuTime() {
- return 0;
- }
-
- public long getTotalRealTime() {
- return 0;
- }
-
- public boolean haveCpuTime() {
- return false;
- }
-
- public boolean haveRealTime() {
- return false;
- }
-
- public HashMap<String, String> getProperties() {
- return null;
- }
-
- public ProfileProvider getProfileProvider() {
- return null;
- }
-
- public TimeBase getPreferredTimeBase() {
- return TimeBase.CPU_TIME;
- }
-
- public String getClockSource() {
- return null;
- }
-}
diff --git a/traceview/src/com/android/traceview/TraceUnits.java b/traceview/src/com/android/traceview/TraceUnits.java
deleted file mode 100644
index 20938f5..0000000
--- a/traceview/src/com/android/traceview/TraceUnits.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2006 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.traceview;
-
-import java.text.DecimalFormat;
-
-// This should be a singleton.
-public class TraceUnits {
-
- private TimeScale mTimeScale = TimeScale.MicroSeconds;
- private double mScale = 1.0;
- DecimalFormat mFormatter = new DecimalFormat();
-
- public double getScaledValue(long value) {
- return value * mScale;
- }
-
- public double getScaledValue(double value) {
- return value * mScale;
- }
-
- public String valueOf(long value) {
- return valueOf((double) value);
- }
-
- public String valueOf(double value) {
- String pattern;
- double scaled = value * mScale;
- if ((int) scaled == scaled)
- pattern = "###,###";
- else
- pattern = "###,###.###";
- mFormatter.applyPattern(pattern);
- return mFormatter.format(scaled);
- }
-
- public String labelledString(double value) {
- String units = label();
- String num = valueOf(value);
- return String.format("%s: %s", units, num);
- }
-
- public String labelledString(long value) {
- return labelledString((double) value);
- }
-
- public String label() {
- if (mScale == 1.0)
- return "usec";
- if (mScale == 0.001)
- return "msec";
- if (mScale == 0.000001)
- return "sec";
- return null;
- }
-
- public void setTimeScale(TimeScale val) {
- mTimeScale = val;
- switch (val) {
- case Seconds:
- mScale = 0.000001;
- break;
- case MilliSeconds:
- mScale = 0.001;
- break;
- case MicroSeconds:
- mScale = 1.0;
- break;
- }
- }
-
- public TimeScale getTimeScale() {
- return mTimeScale;
- }
-
- public enum TimeScale {
- Seconds, MilliSeconds, MicroSeconds
- };
-}