aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/DurationMinimap.java541
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/GLCallGroups.java202
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/GLFunctionTraceViewer.java984
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/StateContentProvider.java75
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/StateLabelProvider.java103
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/StateViewPage.java372
6 files changed, 0 insertions, 2277 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/DurationMinimap.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/DurationMinimap.java
deleted file mode 100644
index 9b4c57cad..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/DurationMinimap.java
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.gltrace.editors;
-
-import com.android.ide.eclipse.gltrace.GLProtoBuf.GLMessage.Function;
-import com.android.ide.eclipse.gltrace.model.GLCall;
-import com.android.ide.eclipse.gltrace.model.GLTrace;
-
-import org.eclipse.jface.resource.FontRegistry;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
-import org.eclipse.swt.events.MouseMoveListener;
-import org.eclipse.swt.events.MouseTrackListener;
-import org.eclipse.swt.events.PaintEvent;
-import org.eclipse.swt.events.PaintListener;
-import org.eclipse.swt.graphics.Color;
-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.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 java.util.ArrayList;
-import java.util.List;
-
-public class DurationMinimap extends Canvas {
- /** Default alpha value. */
- private static final int DEFAULT_ALPHA = 255;
-
- /** Alpha value for highlighting visible calls. */
- private static final int VISIBLE_CALLS_HIGHLIGHT_ALPHA = 50;
-
- /** Clamp call durations at this value. */
- private static final long CALL_DURATION_CLAMP = 20000;
-
- private static final String FONT_KEY = "default.font"; //$NON-NLS-1$
-
- /** Scale font size by this amount to get the max display length of call duration. */
- private static final int MAX_DURATION_LENGTH_SCALE = 6;
-
- /** List of GL Calls in the trace. */
- private List<GLCall> mCalls;
-
- /** Number of GL contexts in the trace. */
- private int mContextCount;
-
- /** Starting call index of currently displayed frame. */
- private int mStartCallIndex;
-
- /** Ending call index of currently displayed frame. */
- private int mEndCallIndex;
-
- /** The top index that is currently visible in the table. */
- private int mVisibleCallTopIndex;
-
- /** The bottom index that is currently visible in the table. */
- private int mVisibleCallBottomIndex;
-
- private Color mBackgroundColor;
- private Color mDurationLineColor;
- private Color mGlDrawColor;
- private Color mGlErrorColor;
- private Color mContextHeaderColor;
- private Color mVisibleCallsHighlightColor;
- private Color mMouseMarkerColor;
-
- private FontRegistry mFontRegistry;
- private int mFontWidth;
- private int mFontHeight;
-
- // back buffers used for double buffering
- private Image mBackBufferImage;
- private GC mBackBufferGC;
-
- // mouse state
- private boolean mMouseInSelf;
- private int mMouseY;
-
- // helper object used to position various items on screen
- private final PositionHelper mPositionHelper;
-
- public DurationMinimap(Composite parent, GLTrace trace) {
- super(parent, SWT.NO_BACKGROUND);
-
- setInput(trace);
-
- initializeColors();
- initializeFonts();
-
- mPositionHelper = new PositionHelper(
- mFontHeight,
- mContextCount,
- mFontWidth * MAX_DURATION_LENGTH_SCALE, /* max display length for call. */
- CALL_DURATION_CLAMP /* max duration */);
-
- addPaintListener(new PaintListener() {
- @Override
- public void paintControl(PaintEvent e) {
- draw(e.display, e.gc);
- }
- });
-
- addListener(SWT.Resize, new Listener() {
- @Override
- public void handleEvent(Event event) {
- controlResized();
- }
- });
-
- addMouseMoveListener(new MouseMoveListener() {
- @Override
- public void mouseMove(MouseEvent e) {
- mouseMoved(e);
- }
- });
-
- addMouseListener(new MouseAdapter() {
- @Override
- public void mouseUp(MouseEvent e) {
- mouseClicked(e);
- }
- });
-
- addMouseTrackListener(new MouseTrackListener() {
- @Override
- public void mouseHover(MouseEvent e) {
- }
-
- @Override
- public void mouseExit(MouseEvent e) {
- mMouseInSelf = false;
- redraw();
- }
-
- @Override
- public void mouseEnter(MouseEvent e) {
- mMouseInSelf = true;
- redraw();
- }
- });
- }
-
- public void setInput(GLTrace trace) {
- if (trace != null) {
- mCalls = trace.getGLCalls();
- mContextCount = trace.getContexts().size();
- } else {
- mCalls = null;
- mContextCount = 1;
- }
- }
-
- @Override
- public void dispose() {
- disposeColors();
- disposeBackBuffer();
- super.dispose();
- }
-
- private void initializeColors() {
- mBackgroundColor = new Color(getDisplay(), 0x33, 0x33, 0x33);
- mDurationLineColor = new Color(getDisplay(), 0x08, 0x51, 0x9c);
- mGlDrawColor = new Color(getDisplay(), 0x6b, 0xae, 0xd6);
- mContextHeaderColor = new Color(getDisplay(), 0xd1, 0xe5, 0xf0);
- mVisibleCallsHighlightColor = new Color(getDisplay(), 0xcc, 0xcc, 0xcc);
- mMouseMarkerColor = new Color(getDisplay(), 0xaa, 0xaa, 0xaa);
-
- mGlErrorColor = getDisplay().getSystemColor(SWT.COLOR_RED);
- }
-
- private void disposeColors() {
- mBackgroundColor.dispose();
- mDurationLineColor.dispose();
- mGlDrawColor.dispose();
- mContextHeaderColor.dispose();
- mVisibleCallsHighlightColor.dispose();
- mMouseMarkerColor.dispose();
- }
-
- private void initializeFonts() {
- mFontRegistry = new FontRegistry(getDisplay());
- mFontRegistry.put(FONT_KEY,
- new FontData[] { new FontData("Arial", 8, SWT.NORMAL) }); //$NON-NLS-1$
-
- GC gc = new GC(getDisplay());
- gc.setFont(mFontRegistry.get(FONT_KEY));
- mFontWidth = gc.getFontMetrics().getAverageCharWidth();
- mFontHeight = gc.getFontMetrics().getHeight();
- gc.dispose();
- }
-
- private void initializeBackBuffer() {
- Rectangle clientArea = getClientArea();
-
- if (clientArea.width == 0 || clientArea.height == 0) {
- mBackBufferImage = null;
- mBackBufferGC = null;
- return;
- }
-
- mBackBufferImage = new Image(getDisplay(),
- clientArea.width,
- clientArea.height);
- mBackBufferGC = new GC(mBackBufferImage);
- }
-
- private void disposeBackBuffer() {
- if (mBackBufferImage != null) {
- mBackBufferImage.dispose();
- mBackBufferImage = null;
- }
-
- if (mBackBufferGC != null) {
- mBackBufferGC.dispose();
- mBackBufferGC = null;
- }
- }
-
- private void mouseMoved(MouseEvent e) {
- mMouseY = e.y;
- redraw();
- }
-
- private void mouseClicked(MouseEvent e) {
- if (mMouseInSelf) {
- int selIndex = mPositionHelper.getCallAt(mMouseY);
- sendCallSelectedEvent(selIndex);
- redraw();
- }
- }
-
- private void draw(Display display, GC gc) {
- if (mBackBufferImage == null) {
- initializeBackBuffer();
- }
-
- if (mBackBufferImage == null) {
- return;
- }
-
- // draw contents onto the back buffer
- drawBackground(mBackBufferGC, mBackBufferImage.getBounds());
- drawContextHeaders(mBackBufferGC);
- drawCallDurations(mBackBufferGC);
- drawVisibleCallHighlights(mBackBufferGC);
- drawMouseMarkers(mBackBufferGC);
-
- // finally copy over the rendered back buffer onto screen
- int width = getClientArea().width;
- int height = getClientArea().height;
- gc.drawImage(mBackBufferImage,
- 0, 0, width, height,
- 0, 0, width, height);
- }
-
- private void drawBackground(GC gc, Rectangle bounds) {
- gc.setBackground(mBackgroundColor);
- gc.fillRectangle(bounds);
- }
-
- private void drawContextHeaders(GC gc) {
- if (mContextCount <= 1) {
- return;
- }
-
- gc.setForeground(mContextHeaderColor);
- gc.setFont(mFontRegistry.get(FONT_KEY));
- for (int i = 0; i < mContextCount; i++) {
- Point p = mPositionHelper.getHeaderLocation(i);
- gc.drawText("CTX" + Integer.toString(i), p.x, p.y);
- }
- }
-
- /** Draw the call durations as a sequence of lines.
- *
- * Calls are arranged on the y-axis based on the sequence in which they were originally
- * called by the application. If the display height is lesser than the number of calls, then
- * not every call is shown - the calls are underscanned based the height of the display.
- *
- * The x-axis shows two pieces of information: the duration of the call, and the context
- * in which the call was made. The duration controls how long the displayed line is, and
- * the context controls the starting offset of the line.
- */
- private void drawCallDurations(GC gc) {
- if (mCalls == null || mCalls.size() < mEndCallIndex) {
- return;
- }
-
- gc.setBackground(mDurationLineColor);
-
- int callUnderScan = mPositionHelper.getCallUnderScanValue();
- for (int i = mStartCallIndex; i < mEndCallIndex; i += callUnderScan) {
- boolean resetColor = false;
- GLCall c = mCalls.get(i);
-
- long duration = c.getWallDuration();
-
- if (c.hasErrors()) {
- gc.setBackground(mGlErrorColor);
- resetColor = true;
-
- // If the call has any errors, we want it to be visible in the minimap
- // regardless of how long it took.
- duration = mPositionHelper.getMaxDuration();
- } else if (c.getFunction() == Function.glDrawArrays
- || c.getFunction() == Function.glDrawElements
- || c.getFunction() == Function.eglSwapBuffers) {
- gc.setBackground(mGlDrawColor);
- resetColor = true;
-
- // render all draw calls & swap buffer at max length
- duration = mPositionHelper.getMaxDuration();
- }
-
- Rectangle bounds = mPositionHelper.getDurationBounds(
- i - mStartCallIndex,
- c.getContextId(),
- duration);
- gc.fillRectangle(bounds);
-
- if (resetColor) {
- gc.setBackground(mDurationLineColor);
- }
- }
- }
-
- /**
- * Draw a bounding box that highlights the currently visible range of calls in the
- * {@link GLFunctionTraceViewer} table.
- */
- private void drawVisibleCallHighlights(GC gc) {
- gc.setAlpha(VISIBLE_CALLS_HIGHLIGHT_ALPHA);
- gc.setBackground(mVisibleCallsHighlightColor);
- gc.fillRectangle(mPositionHelper.getBoundsFramingCalls(
- mVisibleCallTopIndex - mStartCallIndex,
- mVisibleCallBottomIndex - mStartCallIndex));
- gc.setAlpha(DEFAULT_ALPHA);
- }
-
- private void drawMouseMarkers(GC gc) {
- if (!mMouseInSelf) {
- return;
- }
-
- if (mPositionHelper.getCallAt(mMouseY) < 0) {
- return;
- }
-
- gc.setForeground(mMouseMarkerColor);
- gc.drawLine(0, mMouseY, getClientArea().width, mMouseY);
- }
-
- private void controlResized() {
- // regenerate back buffer on size changes
- disposeBackBuffer();
- initializeBackBuffer();
-
- redraw();
- }
-
- public int getMinimumWidth() {
- return mPositionHelper.getMinimumWidth();
- }
-
- /** Set the GL Call start and end indices for currently displayed frame. */
- public void setCallRangeForCurrentFrame(int startCallIndex, int endCallIndex) {
- mStartCallIndex = startCallIndex;
- mEndCallIndex = endCallIndex;
- mPositionHelper.updateCallDensity(mEndCallIndex - mStartCallIndex, getClientArea().height);
- redraw();
- }
-
- /**
- * Set the call range that is currently visible in the {@link GLFunctionTraceViewer} table.
- * @param visibleTopIndex index of call currently visible at the top of the table.
- * @param visibleBottomIndex index of call currently visible at the bottom of the table.
- */
- public void setVisibleCallRange(int visibleTopIndex, int visibleBottomIndex) {
- mVisibleCallTopIndex = visibleTopIndex;
- mVisibleCallBottomIndex = visibleBottomIndex;
- redraw();
- }
-
- public interface ICallSelectionListener {
- void callSelected(int selectedCallIndex);
- }
-
- private List<ICallSelectionListener> mListeners = new ArrayList<ICallSelectionListener>();
-
- public void addCallSelectionListener(ICallSelectionListener l) {
- mListeners.add(l);
- }
-
- private void sendCallSelectedEvent(int selectedCall) {
- for (ICallSelectionListener l : mListeners) {
- l.callSelected(selectedCall);
- }
- }
-
- /** Utility class to help with the positioning and sizes of elements in the canvas. */
- private static class PositionHelper {
- /** Left Margin after which duration lines are drawn. */
- private static final int LEFT_MARGIN = 5;
-
- /** Top margin after which header is drawn. */
- private static final int TOP_MARGIN = 5;
-
- /** # of pixels of padding between duration markers for different contexts. */
- private static final int CONTEXT_PADDING = 10;
-
- private final int mHeaderMargin;
- private final int mContextCount;
- private final int mMaxDurationLength;
- private final long mMaxDuration;
- private final double mScale;
-
- private int mCallCount;
- private int mNumCallsPerPixel = 1;
-
- public PositionHelper(int fontHeight, int contextCount,
- int maxDurationLength, long maxDuration) {
- mContextCount = contextCount;
- mMaxDurationLength = maxDurationLength;
- mMaxDuration = maxDuration;
- mScale = (double) maxDurationLength / maxDuration;
-
- // header region is present only there are multiple contexts
- if (mContextCount > 1) {
- mHeaderMargin = fontHeight * 3;
- } else {
- mHeaderMargin = 0;
- }
- }
-
- /** Get the minimum width of the canvas. */
- public int getMinimumWidth() {
- return LEFT_MARGIN + (mMaxDurationLength + CONTEXT_PADDING) * mContextCount;
- }
-
- /** Get the bounds for a call duration line. */
- public Rectangle getDurationBounds(int callIndex, int context, long duration) {
- if (duration <= 0) {
- duration = 1;
- } else if (duration > mMaxDuration) {
- duration = mMaxDuration;
- }
-
- int x = LEFT_MARGIN + ((mMaxDurationLength + CONTEXT_PADDING) * context);
- int y = (callIndex/mNumCallsPerPixel) + TOP_MARGIN + mHeaderMargin;
- int w = (int) (duration * mScale);
- int h = 1;
-
- return new Rectangle(x, y, w, h);
- }
-
- public long getMaxDuration() {
- return mMaxDuration;
- }
-
- /** Get the bounds for calls spanning given range. */
- public Rectangle getBoundsFramingCalls(int startCallIndex, int endCallIndex) {
- if (startCallIndex >= 0 && endCallIndex >= startCallIndex
- && endCallIndex <= mCallCount) {
- int x = LEFT_MARGIN;
- int y = (startCallIndex/mNumCallsPerPixel) + TOP_MARGIN + mHeaderMargin;
- int w = ((mMaxDurationLength + CONTEXT_PADDING) * mContextCount);
- int h = (endCallIndex - startCallIndex)/mNumCallsPerPixel;
- return new Rectangle(x, y, w, h);
- } else {
- return new Rectangle(0, 0, 0, 0);
- }
- }
-
- public Point getHeaderLocation(int context) {
- int x = LEFT_MARGIN + ((mMaxDurationLength + CONTEXT_PADDING) * context);
- return new Point(x, TOP_MARGIN);
- }
-
- /** Update the call density based on the number of calls to be displayed and
- * the available height to display them in. */
- public void updateCallDensity(int callCount, int displayHeight) {
- mCallCount = callCount;
-
- if (displayHeight <= 0) {
- displayHeight = callCount + 1;
- }
-
- mNumCallsPerPixel = (callCount / displayHeight) + 1;
- }
-
- /** Get the underscan value. In cases where there are more calls to be displayed
- * than there are availble pixels, we only display 1 out of every underscan calls. */
- public int getCallUnderScanValue() {
- return mNumCallsPerPixel;
- }
-
- /** Get the index of the call at given y offset. */
- public int getCallAt(int y) {
- if (!isWithinBounds(y)) {
- return -1;
- }
-
- Rectangle displayBounds = getBoundsFramingCalls(0, mCallCount);
- return (y - displayBounds.y) * mNumCallsPerPixel;
- }
-
- /** Does the provided y offset map to a valid call? */
- private boolean isWithinBounds(int y) {
- Rectangle displayBounds = getBoundsFramingCalls(0, mCallCount);
- if (y < displayBounds.y) {
- return false;
- }
-
- if (y > (displayBounds.y + displayBounds.height)) {
- return false;
- }
-
- return true;
- }
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/GLCallGroups.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/GLCallGroups.java
deleted file mode 100644
index 226d4831a..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/GLCallGroups.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.gltrace.editors;
-
-import com.android.ide.eclipse.gltrace.GLProtoBuf.GLMessage.Function;
-import com.android.ide.eclipse.gltrace.model.GLCall;
-import com.android.ide.eclipse.gltrace.model.GLTrace;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Stack;
-
-public class GLCallGroups {
- /**
- * A {@link GLCallNode} is a simple wrapper around a {@link GLCall} that
- * adds the notion of hierarchy.
- */
- public interface GLCallNode {
- /** Does this call have child nodes? */
- boolean hasChildren();
-
- /** Returns a list of child nodes of this call. */
- List<GLCallNode> getChildren();
-
- /** Returns the {@link GLCall} that is wrapped by this node. */
- GLCall getCall();
-
- /** Returns the parent of this node, the parent is null if this is a top level node */
- GLCallNode getParent();
-
- /** Set the parent node. */
- void setParent(GLCallNode parent);
- }
-
- private static class GLTreeNode implements GLCallNode {
- private final GLCall mCall;
- private GLCallNode mParent;
- private List<GLCallNode> mGLCallNodes;
-
- public GLTreeNode(GLCall call) {
- mCall = call;
- mGLCallNodes = new ArrayList<GLCallNode>();
- }
-
- @Override
- public boolean hasChildren() {
- return true;
- }
-
- @Override
- public GLCallNode getParent() {
- return mParent;
- }
-
- @Override
- public void setParent(GLCallNode parent) {
- mParent = parent;
- }
-
- @Override
- public List<GLCallNode> getChildren() {
- return mGLCallNodes;
- }
-
- public void addChild(GLCallNode n) {
- mGLCallNodes.add(n);
- n.setParent(this);
- }
-
- @Override
- public GLCall getCall() {
- return mCall;
- }
- }
-
- private static class GLLeafNode implements GLCallNode {
- private final GLCall mCall;
- private GLCallNode mParent;
-
- public GLLeafNode(GLCall call) {
- mCall = call;
- }
-
- @Override
- public boolean hasChildren() {
- return false;
- }
-
- @Override
- public List<GLCallNode> getChildren() {
- return null;
- }
-
- @Override
- public GLCallNode getParent() {
- return mParent;
- }
-
- @Override
- public void setParent(GLCallNode parent) {
- mParent = parent;
- }
-
- @Override
- public GLCall getCall() {
- return mCall;
- }
- }
-
- /**
- * Impose a hierarchy on a list of {@link GLCall}'s based on the presence of
- * {@link Function#glPushGroupMarkerEXT} and {@link Function#glPopGroupMarkerEXT} calls.
- * Such a hierarchy is possible only if calls from a single context are considered.
- * @param trace trace to look at
- * @param start starting call index
- * @param end ending call index
- * @param contextToGroup context from which calls should be grouped. If no such context
- * is present, then all calls in the given range will be returned back as a flat
- * list.
- * @return a tree structured list of {@link GLCallNode} objects
- */
- public static List<GLCallNode> constructCallHierarchy(GLTrace trace, int start, int end,
- int contextToGroup) {
- if (trace == null) {
- return Collections.emptyList();
- }
-
- if (contextToGroup < 0 || contextToGroup > trace.getContexts().size()) {
- return flatHierarchy(trace, start, end);
- }
-
- List<GLCall> calls = trace.getGLCalls();
-
- Stack<GLTreeNode> hierarchyStack = new Stack<GLTreeNode>();
- List<GLCallNode> items = new ArrayList<GLCallNode>();
-
- for (int i = start; i < end; i++) {
- GLCall c = calls.get(i);
- if (c.getContextId() != contextToGroup) {
- // skip this call if it is not part of the context we need to display
- continue;
- }
-
- if (c.getFunction() == Function.glPushGroupMarkerEXT) {
- GLTreeNode group = new GLTreeNode(c);
- if (hierarchyStack.size() > 0) {
- hierarchyStack.peek().addChild(group);
- } else {
- items.add(group);
- }
- hierarchyStack.push(group);
- } else if (c.getFunction() == Function.glPopGroupMarkerEXT) {
- if (hierarchyStack.size() > 0) {
- hierarchyStack.pop();
- } else {
- // FIXME: If we are attempting to pop from an empty stack,
- // that implies that a push marker was seen in a prior frame
- // (in a call before @start). In such a case, we simply continue
- // adding further calls to the root of the hierarchy rather than
- // searching backwards in the call list for the corresponding
- // push markers.
- items.add(new GLLeafNode(c));
- }
- } else {
- GLLeafNode leaf = new GLLeafNode(c);
- if (hierarchyStack.size() > 0) {
- hierarchyStack.peek().addChild(leaf);
- } else {
- items.add(leaf);
- }
- }
- }
-
- return items;
- }
-
- private static List<GLCallNode> flatHierarchy(GLTrace trace, int start, int end) {
- List<GLCallNode> items = new ArrayList<GLCallNode>();
-
- List<GLCall> calls = trace.getGLCalls();
- for (int i = start; i < end; i++) {
- items.add(new GLLeafNode(calls.get(i)));
- }
-
- return items;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/GLFunctionTraceViewer.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/GLFunctionTraceViewer.java
deleted file mode 100644
index b809ddddf..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/GLFunctionTraceViewer.java
+++ /dev/null
@@ -1,984 +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.ide.eclipse.gltrace.editors;
-
-import com.android.ddmuilib.AbstractBufferFindTarget;
-import com.android.ddmuilib.FindDialog;
-import com.android.ide.eclipse.gltrace.GLProtoBuf.GLMessage.Function;
-import com.android.ide.eclipse.gltrace.GlTracePlugin;
-import com.android.ide.eclipse.gltrace.SwtUtils;
-import com.android.ide.eclipse.gltrace.TraceFileParserTask;
-import com.android.ide.eclipse.gltrace.editors.DurationMinimap.ICallSelectionListener;
-import com.android.ide.eclipse.gltrace.editors.GLCallGroups.GLCallNode;
-import com.android.ide.eclipse.gltrace.model.GLCall;
-import com.android.ide.eclipse.gltrace.model.GLFrame;
-import com.android.ide.eclipse.gltrace.model.GLTrace;
-import com.android.ide.eclipse.gltrace.views.FrameSummaryViewPage;
-import com.android.ide.eclipse.gltrace.views.detail.DetailsPage;
-import com.google.common.base.Charsets;
-import com.google.common.io.Files;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.CellLabelProvider;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.ISelectionProvider;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.jface.viewers.TreeViewerColumn;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jface.viewers.ViewerCell;
-import org.eclipse.jface.viewers.ViewerFilter;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.swt.dnd.TextTransfer;
-import org.eclipse.swt.dnd.Transfer;
-import org.eclipse.swt.events.ControlAdapter;
-import org.eclipse.swt.events.ControlEvent;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.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.Combo;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Scale;
-import org.eclipse.swt.widgets.ScrollBar;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Spinner;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.widgets.ToolBar;
-import org.eclipse.swt.widgets.ToolItem;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-import org.eclipse.swt.widgets.TreeItem;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.IEditorInput;
-import org.eclipse.ui.IEditorSite;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.IURIEditorInput;
-import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.actions.ActionFactory;
-import org.eclipse.ui.part.EditorPart;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/** Display OpenGL function trace in a tabular view. */
-public class GLFunctionTraceViewer extends EditorPart implements ISelectionProvider {
- public static final String ID = "com.android.ide.eclipse.gltrace.GLFunctionTrace"; //$NON-NLS-1$
-
- private static final String DEFAULT_FILTER_MESSAGE = "Filter list of OpenGL calls. Accepts Java regexes.";
- private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$
-
- private static Image sExpandAllIcon;
-
- private static String sLastExportedToFolder;
-
- private String mFilePath;
- private Scale mFrameSelectionScale;
- private Spinner mFrameSelectionSpinner;
-
- private GLTrace mTrace;
-
- private TreeViewer mFrameTreeViewer;
- private List<GLCallNode> mTreeViewerNodes;
-
- private Text mFilterText;
- private GLCallFilter mGLCallFilter;
-
- private Color mGldrawTextColor;
- private Color mGlCallErrorColor;
-
- /**
- * Job to refresh the tree view & frame summary view.
- *
- * When the currently displayed frame is changed, either via the {@link #mFrameSelectionScale}
- * or via {@link #mFrameSelectionSpinner}, we need to update the displayed tree of calls for
- * that frame, and the frame summary view. Both these operations need to happen on the UI
- * thread, but are time consuming. This works out ok if the frame selection is not changing
- * rapidly (i.e., when the spinner or scale is moved to the target frame in a single action).
- * However, if the spinner is constantly pressed, then the user is scrolling through a sequence
- * of frames, and rather than refreshing the details for each of the intermediate frames,
- * we create a job to refresh the details and schedule the job after a short interval
- * {@link #TREE_REFRESH_INTERVAL}. This allows us to stay responsive to the spinner/scale,
- * and not do the costly refresh for each of the intermediate frames.
- */
- private Job mTreeRefresherJob;
- private final Object mTreeRefresherLock = new Object();
- private static final int TREE_REFRESH_INTERVAL_MS = 250;
-
- private int mCurrentFrame;
-
- // Currently displayed frame's start and end call indices.
- private int mCallStartIndex;
- private int mCallEndIndex;
-
- private DurationMinimap mDurationMinimap;
- private ScrollBar mVerticalScrollBar;
-
- private Combo mContextSwitchCombo;
- private boolean mShowContextSwitcher;
- private int mCurrentlyDisplayedContext = -1;
-
- private StateViewPage mStateViewPage;
- private FrameSummaryViewPage mFrameSummaryViewPage;
- private DetailsPage mDetailsPage;
-
- private ToolItem mExpandAllToolItem;
- private ToolItem mCollapseAllToolItem;
- private ToolItem mSaveAsToolItem;
-
- public GLFunctionTraceViewer() {
- mGldrawTextColor = Display.getDefault().getSystemColor(SWT.COLOR_BLUE);
- mGlCallErrorColor = Display.getDefault().getSystemColor(SWT.COLOR_RED);
- }
-
- @Override
- public void doSave(IProgressMonitor monitor) {
- }
-
- @Override
- public void doSaveAs() {
- }
-
- @Override
- public void init(IEditorSite site, IEditorInput input) throws PartInitException {
- // we use a IURIEditorInput to allow opening files not within the workspace
- if (!(input instanceof IURIEditorInput)) {
- throw new PartInitException("GL Function Trace View: unsupported input type.");
- }
-
- setSite(site);
- setInput(input);
- mFilePath = ((IURIEditorInput) input).getURI().getPath();
-
- // set the editor part name to be the name of the file.
- File f = new File(mFilePath);
- setPartName(f.getName());
- }
-
- @Override
- public boolean isDirty() {
- return false;
- }
-
- @Override
- public boolean isSaveAsAllowed() {
- return false;
- }
-
- @Override
- public void createPartControl(Composite parent) {
- Composite c = new Composite(parent, SWT.NONE);
- c.setLayout(new GridLayout(1, false));
- GridData gd = new GridData(GridData.FILL_BOTH);
- c.setLayoutData(gd);
-
- setInput(parent.getShell(), mFilePath);
-
- createFrameSelectionControls(c);
- createOptionsBar(c);
- createFrameTraceView(c);
-
- getSite().setSelectionProvider(mFrameTreeViewer);
-
- IActionBars actionBars = getEditorSite().getActionBars();
- actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(),
- new Action("Copy") {
- @Override
- public void run() {
- copySelectionToClipboard();
- }
- });
-
- actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
- new Action("Select All") {
- @Override
- public void run() {
- selectAll();
- }
- });
-
- actionBars.setGlobalActionHandler(ActionFactory.FIND.getId(),
- new Action("Find") {
- @Override
- public void run() {
- showFindDialog();
- }
- });
- }
-
- public void setInput(Shell shell, String tracePath) {
- ProgressMonitorDialog dlg = new ProgressMonitorDialog(shell);
- TraceFileParserTask parser = new TraceFileParserTask(mFilePath);
- try {
- dlg.run(true, true, parser);
- } catch (InvocationTargetException e) {
- // exception while parsing, display error to user
- MessageDialog.openError(shell,
- "Error parsing OpenGL Trace File",
- e.getCause().getMessage());
- return;
- } catch (InterruptedException e) {
- // operation canceled by user, just return
- return;
- }
-
- mTrace = parser.getTrace();
- mShowContextSwitcher = (mTrace == null) ? false : mTrace.getContexts().size() > 1;
- if (mStateViewPage != null) {
- mStateViewPage.setInput(mTrace);
- }
- if (mFrameSummaryViewPage != null) {
- mFrameSummaryViewPage.setInput(mTrace);
- }
- if (mDetailsPage != null) {
- mDetailsPage.setInput(mTrace);
- }
- if (mDurationMinimap != null) {
- mDurationMinimap.setInput(mTrace);
- }
-
- Display.getDefault().asyncExec(new Runnable() {
- @Override
- public void run() {
- refreshUI();
- }
- });
- }
-
- private void refreshUI() {
- if (mTrace == null || mTrace.getGLCalls().size() == 0) {
- setFrameCount(0);
- return;
- }
-
- setFrameCount(mTrace.getFrames().size());
- selectFrame(1);
- }
-
- private void createFrameSelectionControls(Composite parent) {
- Composite c = new Composite(parent, SWT.NONE);
- c.setLayout(new GridLayout(3, false));
- GridData gd = new GridData(GridData.FILL_HORIZONTAL);
- c.setLayoutData(gd);
-
- Label l = new Label(c, SWT.NONE);
- l.setText("Select Frame:");
-
- mFrameSelectionScale = new Scale(c, SWT.HORIZONTAL);
- mFrameSelectionScale.setMinimum(1);
- mFrameSelectionScale.setMaximum(1);
- mFrameSelectionScale.setSelection(0);
- gd = new GridData(GridData.FILL_HORIZONTAL);
- mFrameSelectionScale.setLayoutData(gd);
-
- mFrameSelectionScale.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- int selectedFrame = mFrameSelectionScale.getSelection();
- mFrameSelectionSpinner.setSelection(selectedFrame);
- selectFrame(selectedFrame);
- }
- });
-
- mFrameSelectionSpinner = new Spinner(c, SWT.BORDER);
- gd = new GridData();
- // width to hold atleast 6 digits
- gd.widthHint = SwtUtils.getApproximateFontWidth(mFrameSelectionSpinner) * 6;
- mFrameSelectionSpinner.setLayoutData(gd);
-
- mFrameSelectionSpinner.setMinimum(1);
- mFrameSelectionSpinner.setMaximum(1);
- mFrameSelectionSpinner.setSelection(0);
- mFrameSelectionSpinner.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- int selectedFrame = mFrameSelectionSpinner.getSelection();
- mFrameSelectionScale.setSelection(selectedFrame);
- selectFrame(selectedFrame);
- }
- });
- }
-
- private void setFrameCount(int nFrames) {
- boolean en = nFrames > 0;
- mFrameSelectionScale.setEnabled(en);
- mFrameSelectionSpinner.setEnabled(en);
-
- mFrameSelectionScale.setMaximum(nFrames);
- mFrameSelectionSpinner.setMaximum(nFrames);
- }
-
- private void selectFrame(int selectedFrame) {
- mFrameSelectionScale.setSelection(selectedFrame);
- mFrameSelectionSpinner.setSelection(selectedFrame);
-
- synchronized (mTreeRefresherLock) {
- if (mTrace != null) {
- GLFrame f = mTrace.getFrame(selectedFrame - 1);
- mCallStartIndex = f.getStartIndex();
- mCallEndIndex = f.getEndIndex();
- } else {
- mCallStartIndex = mCallEndIndex = 0;
- }
-
- mCurrentFrame = selectedFrame - 1;
-
- scheduleNewRefreshJob();
- }
-
- // update minimap view
- mDurationMinimap.setCallRangeForCurrentFrame(mCallStartIndex, mCallEndIndex);
- }
-
- /**
- * Show only calls from the given context
- * @param context context id whose calls should be displayed. Illegal values will result in
- * calls from all contexts being displayed.
- */
- private void selectContext(int context) {
- if (mCurrentlyDisplayedContext == context) {
- return;
- }
-
- synchronized (mTreeRefresherLock) {
- mCurrentlyDisplayedContext = context;
- scheduleNewRefreshJob();
- }
- }
-
- private void scheduleNewRefreshJob() {
- if (mTreeRefresherJob != null) {
- return;
- }
-
- mTreeRefresherJob = new Job("Refresh GL Trace View Tree") {
- @Override
- protected IStatus run(IProgressMonitor monitor) {
- final int start, end, context;
-
- synchronized (mTreeRefresherLock) {
- start = mCallStartIndex;
- end = mCallEndIndex;
- context = mCurrentlyDisplayedContext;
-
- mTreeRefresherJob = null;
- }
-
- // update tree view in the editor
- Display.getDefault().syncExec(new Runnable() {
- @Override
- public void run() {
- refreshTree(start, end, context);
-
- // update the frame summary view
- if (mFrameSummaryViewPage != null) {
- mFrameSummaryViewPage.setSelectedFrame(mCurrentFrame);
- }
- }
- });
- return Status.OK_STATUS;
- }
- };
- mTreeRefresherJob.setPriority(Job.SHORT);
- mTreeRefresherJob.schedule(TREE_REFRESH_INTERVAL_MS);
- }
-
- private void refreshTree(int startCallIndex, int endCallIndex, int contextToDisplay) {
- mTreeViewerNodes = GLCallGroups.constructCallHierarchy(mTrace,
- startCallIndex, endCallIndex,
- contextToDisplay);
- mFrameTreeViewer.setInput(mTreeViewerNodes);
- mFrameTreeViewer.refresh();
- mFrameTreeViewer.expandAll();
- }
-
- private void createOptionsBar(Composite parent) {
- int numColumns = mShowContextSwitcher ? 4 : 3;
-
- Composite c = new Composite(parent, SWT.NONE);
- c.setLayout(new GridLayout(numColumns, false));
- GridData gd = new GridData(GridData.FILL_HORIZONTAL);
- c.setLayoutData(gd);
-
- Label l = new Label(c, SWT.NONE);
- l.setText("Filter:");
-
- mFilterText = new Text(c, SWT.BORDER | SWT.ICON_SEARCH | SWT.SEARCH | SWT.ICON_CANCEL);
- mFilterText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
- mFilterText.setMessage(DEFAULT_FILTER_MESSAGE);
- mFilterText.addModifyListener(new ModifyListener() {
- @Override
- public void modifyText(ModifyEvent e) {
- updateAppliedFilters();
- }
- });
-
- if (mShowContextSwitcher) {
- mContextSwitchCombo = new Combo(c, SWT.BORDER | SWT.READ_ONLY);
-
- // Setup the combo such that "All Contexts" is the first item,
- // and then we have an item for each context.
- mContextSwitchCombo.add("All Contexts");
- mContextSwitchCombo.select(0);
- mCurrentlyDisplayedContext = -1; // showing all contexts
- for (int i = 0; i < mTrace.getContexts().size(); i++) {
- mContextSwitchCombo.add("Context " + i);
- }
-
- mContextSwitchCombo.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- selectContext(mContextSwitchCombo.getSelectionIndex() - 1);
- }
- });
- } else {
- mCurrentlyDisplayedContext = 0;
- }
-
- ToolBar toolBar = new ToolBar(c, SWT.FLAT | SWT.BORDER);
-
- mExpandAllToolItem = new ToolItem(toolBar, SWT.PUSH);
- mExpandAllToolItem.setToolTipText("Expand All");
- if (sExpandAllIcon == null) {
- ImageDescriptor id = GlTracePlugin.getImageDescriptor("/icons/expandall.png");
- sExpandAllIcon = id.createImage();
- }
- if (sExpandAllIcon != null) {
- mExpandAllToolItem.setImage(sExpandAllIcon);
- }
-
- mCollapseAllToolItem = new ToolItem(toolBar, SWT.PUSH);
- mCollapseAllToolItem.setToolTipText("Collapse All");
- mCollapseAllToolItem.setImage(
- PlatformUI.getWorkbench().getSharedImages().getImage(
- ISharedImages.IMG_ELCL_COLLAPSEALL));
-
- mSaveAsToolItem = new ToolItem(toolBar, SWT.PUSH);
- mSaveAsToolItem.setToolTipText("Export Trace");
- mSaveAsToolItem.setImage(
- PlatformUI.getWorkbench().getSharedImages().getImage(
- ISharedImages.IMG_ETOOL_SAVEAS_EDIT));
-
- SelectionListener toolbarSelectionListener = new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- if (e.getSource() == mCollapseAllToolItem) {
- setTreeItemsExpanded(false);
- } else if (e.getSource() == mExpandAllToolItem) {
- setTreeItemsExpanded(true);
- } else if (e.getSource() == mSaveAsToolItem) {
- exportTrace();
- }
- }
- };
- mExpandAllToolItem.addSelectionListener(toolbarSelectionListener);
- mCollapseAllToolItem.addSelectionListener(toolbarSelectionListener);
- mSaveAsToolItem.addSelectionListener(toolbarSelectionListener);
- }
-
- private void updateAppliedFilters() {
- mGLCallFilter.setFilters(mFilterText.getText().trim());
- mFrameTreeViewer.refresh();
- }
-
- private void createFrameTraceView(Composite parent) {
- Composite c = new Composite(parent, SWT.NONE);
- c.setLayout(new GridLayout(2, false));
- GridData gd = new GridData(GridData.FILL_BOTH);
- c.setLayoutData(gd);
-
- final Tree tree = new Tree(c, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI);
- gd = new GridData(GridData.FILL_BOTH);
- tree.setLayoutData(gd);
- tree.setLinesVisible(true);
- tree.setHeaderVisible(true);
-
- mFrameTreeViewer = new TreeViewer(tree);
- CellLabelProvider labelProvider = new GLFrameLabelProvider();
-
- // column showing the GL context id
- TreeViewerColumn tvc = new TreeViewerColumn(mFrameTreeViewer, SWT.NONE);
- tvc.setLabelProvider(labelProvider);
- TreeColumn column = tvc.getColumn();
- column.setText("Function");
- column.setWidth(500);
-
- // column showing the GL function duration (wall clock time)
- tvc = new TreeViewerColumn(mFrameTreeViewer, SWT.NONE);
- tvc.setLabelProvider(labelProvider);
- column = tvc.getColumn();
- column.setText("Wall Time (ns)");
- column.setWidth(150);
- column.setAlignment(SWT.RIGHT);
-
- // column showing the GL function duration (thread time)
- tvc = new TreeViewerColumn(mFrameTreeViewer, SWT.NONE);
- tvc.setLabelProvider(labelProvider);
- column = tvc.getColumn();
- column.setText("Thread Time (ns)");
- column.setWidth(150);
- column.setAlignment(SWT.RIGHT);
-
- mFrameTreeViewer.setContentProvider(new GLFrameContentProvider());
-
- mGLCallFilter = new GLCallFilter();
- mFrameTreeViewer.addFilter(mGLCallFilter);
-
- // when the control is resized, give all the additional space
- // to the function name column.
- tree.addControlListener(new ControlAdapter() {
- @Override
- public void controlResized(ControlEvent e) {
- int w = mFrameTreeViewer.getTree().getClientArea().width;
- if (w > 200) {
- mFrameTreeViewer.getTree().getColumn(2).setWidth(100);
- mFrameTreeViewer.getTree().getColumn(1).setWidth(100);
- mFrameTreeViewer.getTree().getColumn(0).setWidth(w - 200);
- }
- }
- });
-
- mDurationMinimap = new DurationMinimap(c, mTrace);
- gd = new GridData(GridData.FILL_VERTICAL);
- gd.widthHint = gd.minimumWidth = mDurationMinimap.getMinimumWidth();
- mDurationMinimap.setLayoutData(gd);
- mDurationMinimap.addCallSelectionListener(new ICallSelectionListener() {
- @Override
- public void callSelected(int selectedCallIndex) {
- if (selectedCallIndex > 0 && selectedCallIndex < mTreeViewerNodes.size()) {
- TreeItem item = tree.getItem(selectedCallIndex);
- tree.select(item);
- tree.setTopItem(item);
- }
- }
- });
-
- mVerticalScrollBar = tree.getVerticalBar();
- mVerticalScrollBar.addSelectionListener(new SelectionAdapter() {
- @Override
- public void widgetSelected(SelectionEvent e) {
- updateVisibleRange();
- }
- });
- }
-
- private void updateVisibleRange() {
- int visibleCallTopIndex = mCallStartIndex;
- int visibleCallBottomIndex = mCallEndIndex;
-
- if (mVerticalScrollBar.isEnabled()) {
- int selection = mVerticalScrollBar.getSelection();
- int thumb = mVerticalScrollBar.getThumb();
- int max = mVerticalScrollBar.getMaximum();
-
- // from the scrollbar values, compute the visible fraction
- double top = (double) selection / max;
- double bottom = (double) (selection + thumb) / max;
-
- // map the fraction to the call indices
- int range = mCallEndIndex - mCallStartIndex;
- visibleCallTopIndex = mCallStartIndex + (int) Math.floor(range * top);
- visibleCallBottomIndex = mCallStartIndex + (int) Math.ceil(range * bottom);
- }
-
- mDurationMinimap.setVisibleCallRange(visibleCallTopIndex, visibleCallBottomIndex);
- }
-
- @Override
- public void setFocus() {
- mFrameTreeViewer.getTree().setFocus();
- }
-
- private static class GLFrameContentProvider implements ITreeContentProvider {
- @Override
- public void dispose() {
- }
-
- @Override
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- @Override
- public Object[] getElements(Object inputElement) {
- return getChildren(inputElement);
- }
-
- @Override
- public Object[] getChildren(Object parentElement) {
- if (parentElement instanceof List<?>) {
- return ((List<?>) parentElement).toArray();
- }
-
- if (!(parentElement instanceof GLCallNode)) {
- return null;
- }
-
- GLCallNode parent = (GLCallNode) parentElement;
- if (parent.hasChildren()) {
- return parent.getChildren().toArray();
- } else {
- return new Object[0];
- }
- }
-
- @Override
- public Object getParent(Object element) {
- if (!(element instanceof GLCallNode)) {
- return null;
- }
-
- return ((GLCallNode) element).getParent();
- }
-
- @Override
- public boolean hasChildren(Object element) {
- if (!(element instanceof GLCallNode)) {
- return false;
- }
-
- return ((GLCallNode) element).hasChildren();
- }
- }
-
- private class GLFrameLabelProvider extends ColumnLabelProvider {
- @Override
- public void update(ViewerCell cell) {
- Object element = cell.getElement();
- if (!(element instanceof GLCallNode)) {
- return;
- }
-
- GLCall c = ((GLCallNode) element).getCall();
-
- if (c.getFunction() == Function.glDrawArrays
- || c.getFunction() == Function.glDrawElements) {
- cell.setForeground(mGldrawTextColor);
- }
-
- if (c.hasErrors()) {
- cell.setForeground(mGlCallErrorColor);
- }
-
- cell.setText(getColumnText(c, cell.getColumnIndex()));
- }
-
- private String getColumnText(GLCall c, int columnIndex) {
- switch (columnIndex) {
- case 0:
- if (c.getFunction() == Function.glPushGroupMarkerEXT) {
- Object marker = c.getProperty(GLCall.PROPERTY_MARKERNAME);
- if (marker instanceof String) {
- return ((String) marker);
- }
- }
- return c.toString();
- case 1:
- return formatDuration(c.getWallDuration());
- case 2:
- return formatDuration(c.getThreadDuration());
- default:
- return Integer.toString(c.getContextId());
- }
- }
-
- private String formatDuration(int time) {
- // Max duration is in the 10s of milliseconds, so xx,xxx,xxx ns
- // So we require a format specifier that is 10 characters wide
- return String.format("%,10d", time); //$NON-NLS-1$
- }
- }
-
- private static class GLCallFilter extends ViewerFilter {
- private final List<Pattern> mPatterns = new ArrayList<Pattern>();
-
- public void setFilters(String filter) {
- mPatterns.clear();
-
- // split the user input into multiple regexes
- // we assume that the regexes are OR'ed together i.e., all text that matches
- // any one of the regexes will be displayed
- for (String regex : filter.split(" ")) {
- mPatterns.add(Pattern.compile(regex, Pattern.CASE_INSENSITIVE));
- }
- }
-
- @Override
- public boolean select(Viewer viewer, Object parentElement, Object element) {
- if (!(element instanceof GLCallNode)) {
- return true;
- }
-
- String text = getTextUnderNode((GLCallNode) element);
-
- if (mPatterns.size() == 0) {
- // match if there are no regex filters
- return true;
- }
-
- for (Pattern p : mPatterns) {
- Matcher matcher = p.matcher(text);
- if (matcher.find()) {
- // match if atleast one of the regexes matches this text
- return true;
- }
- }
-
- return false;
- }
-
- /** Obtain a string representation of all functions under a given tree node. */
- private String getTextUnderNode(GLCallNode element) {
- String func = element.getCall().getFunction().toString();
- if (!element.hasChildren()) {
- return func;
- }
-
- StringBuilder sb = new StringBuilder(100);
- sb.append(func);
-
- for (GLCallNode child : element.getChildren()) {
- sb.append(getTextUnderNode(child));
- }
-
- return sb.toString();
- }
- }
-
- @Override
- public void addSelectionChangedListener(ISelectionChangedListener listener) {
- if (mFrameTreeViewer != null) {
- mFrameTreeViewer.addSelectionChangedListener(listener);
- }
- }
-
- @Override
- public ISelection getSelection() {
- if (mFrameTreeViewer != null) {
- return mFrameTreeViewer.getSelection();
- } else {
- return null;
- }
- }
-
- @Override
- public void removeSelectionChangedListener(ISelectionChangedListener listener) {
- if (mFrameTreeViewer != null) {
- mFrameTreeViewer.removeSelectionChangedListener(listener);
- }
- }
-
- @Override
- public void setSelection(ISelection selection) {
- if (mFrameTreeViewer != null) {
- mFrameTreeViewer.setSelection(selection);
- }
- }
-
- public GLTrace getTrace() {
- return mTrace;
- }
-
- public StateViewPage getStateViewPage() {
- if (mStateViewPage == null) {
- mStateViewPage = new StateViewPage(mTrace);
- }
-
- return mStateViewPage;
- }
-
- public FrameSummaryViewPage getFrameSummaryViewPage() {
- if (mFrameSummaryViewPage == null) {
- mFrameSummaryViewPage = new FrameSummaryViewPage(mTrace);
- }
-
- return mFrameSummaryViewPage;
- }
-
- public DetailsPage getDetailsPage() {
- if (mDetailsPage == null) {
- mDetailsPage = new DetailsPage(mTrace);
- }
-
- return mDetailsPage;
- }
-
- private void copySelectionToClipboard() {
- if (mFrameTreeViewer == null || mFrameTreeViewer.getTree().isDisposed()) {
- return;
- }
-
- StringBuilder sb = new StringBuilder();
-
- for (TreeItem it: mFrameTreeViewer.getTree().getSelection()) {
- Object data = it.getData();
- if (data instanceof GLCallNode) {
- sb.append(((GLCallNode) data).getCall());
- sb.append(NEWLINE);
- }
- }
-
- if (sb.length() > 0) {
- Clipboard cb = new Clipboard(Display.getDefault());
- cb.setContents(
- new Object[] { sb.toString() },
- new Transfer[] { TextTransfer.getInstance() });
- cb.dispose();
- }
- }
-
- private void selectAll() {
- if (mFrameTreeViewer == null || mFrameTreeViewer.getTree().isDisposed()) {
- return;
- }
-
- mFrameTreeViewer.getTree().selectAll();
- }
-
- private void exportTrace() {
- if (mFrameTreeViewer == null || mFrameTreeViewer.getTree().isDisposed()) {
- return;
- }
-
- if (mCallEndIndex == 0) {
- return;
- }
-
- FileDialog fd = new FileDialog(mFrameTreeViewer.getTree().getShell(), SWT.SAVE);
- fd.setFilterExtensions(new String[] { "*.txt" });
- if (sLastExportedToFolder != null) {
- fd.setFilterPath(sLastExportedToFolder);
- }
-
- String path = fd.open();
- if (path == null) {
- return;
- }
-
- File f = new File(path);
- sLastExportedToFolder = f.getParent();
- try {
- exportFrameTo(f);
- } catch (IOException e) {
- ErrorDialog.openError(mFrameTreeViewer.getTree().getShell(),
- "Export trace file.",
- "Unexpected error exporting trace file.",
- new Status(Status.ERROR, GlTracePlugin.PLUGIN_ID, e.toString()));
- }
- }
-
- private void exportFrameTo(File f) throws IOException {
- String glCalls = serializeGlCalls(mTrace.getGLCalls(), mCallStartIndex, mCallEndIndex);
- Files.write(glCalls, f, Charsets.UTF_8);
- }
-
- private String serializeGlCalls(List<GLCall> glCalls, int start, int end) {
- StringBuilder sb = new StringBuilder();
- while (start < end) {
- sb.append(glCalls.get(start).toString());
- sb.append("\n"); //$NON-NLS-1$
- start++;
- }
-
- return sb.toString();
- }
-
- private void setTreeItemsExpanded(boolean expand) {
- if (mFrameTreeViewer == null || mFrameTreeViewer.getTree().isDisposed()) {
- return;
- }
-
- if (expand) {
- mFrameTreeViewer.expandAll();
- } else {
- mFrameTreeViewer.collapseAll();
- }
- }
-
- private class TraceViewerFindTarget extends AbstractBufferFindTarget {
- @Override
- public int getItemCount() {
- return mFrameTreeViewer.getTree().getItemCount();
- }
-
- @Override
- public String getItem(int index) {
- Object data = mFrameTreeViewer.getTree().getItem(index).getData();
- if (data instanceof GLCallNode) {
- return ((GLCallNode) data).getCall().toString();
- }
- return null;
- }
-
- @Override
- public void selectAndReveal(int index) {
- Tree t = mFrameTreeViewer.getTree();
- t.deselectAll();
- t.select(t.getItem(index));
- t.showSelection();
- }
-
- @Override
- public int getStartingIndex() {
- return 0;
- }
- };
-
- private FindDialog mFindDialog;
- private TraceViewerFindTarget mFindTarget = new TraceViewerFindTarget();
-
- private void showFindDialog() {
- if (mFindDialog != null) {
- // the dialog is already displayed
- return;
- }
-
- mFindDialog = new FindDialog(Display.getDefault().getActiveShell(),
- mFindTarget,
- FindDialog.FIND_NEXT_ID);
- mFindDialog.open(); // blocks until find dialog is closed
- mFindDialog = null;
- }
-
- public String getInputPath() {
- return mFilePath;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/StateContentProvider.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/StateContentProvider.java
deleted file mode 100644
index 7bff168fc..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/StateContentProvider.java
+++ /dev/null
@@ -1,75 +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.ide.eclipse.gltrace.editors;
-
-import com.android.ide.eclipse.gltrace.state.GLCompositeProperty;
-import com.android.ide.eclipse.gltrace.state.GLListProperty;
-import com.android.ide.eclipse.gltrace.state.GLSparseArrayProperty;
-import com.android.ide.eclipse.gltrace.state.IGLProperty;
-
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-
-public class StateContentProvider implements ITreeContentProvider {
- @Override
- public void dispose() {
- }
-
- @Override
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
- }
-
- @Override
- public Object[] getElements(Object inputElement) {
- return getChildren(inputElement);
- }
-
- @Override
- public Object[] getChildren(Object parentElement) {
- if (parentElement instanceof GLListProperty) {
- return ((GLListProperty) parentElement).getList().toArray();
- }
-
- if (parentElement instanceof GLCompositeProperty) {
- return ((GLCompositeProperty) parentElement).getProperties().toArray();
- }
-
- if (parentElement instanceof GLSparseArrayProperty) {
- return ((GLSparseArrayProperty) parentElement).getValues().toArray();
- }
-
- return null;
- }
-
- @Override
- public Object getParent(Object element) {
- if (element instanceof IGLProperty) {
- return ((IGLProperty) element).getParent();
- }
-
- return null;
- }
-
- @Override
- public boolean hasChildren(Object element) {
- if (element instanceof IGLProperty) {
- return ((IGLProperty) element).isComposite();
- }
-
- return false;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/StateLabelProvider.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/StateLabelProvider.java
deleted file mode 100644
index e37ea77fd..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/StateLabelProvider.java
+++ /dev/null
@@ -1,103 +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.ide.eclipse.gltrace.editors;
-
-import com.android.ide.eclipse.gltrace.state.GLListProperty;
-import com.android.ide.eclipse.gltrace.state.GLSparseArrayProperty;
-import com.android.ide.eclipse.gltrace.state.GLStateType;
-import com.android.ide.eclipse.gltrace.state.IGLProperty;
-
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.ViewerCell;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.widgets.Display;
-
-import java.util.Set;
-
-public class StateLabelProvider extends ColumnLabelProvider {
- private Set<IGLProperty> mChangedProperties;
-
- private Color mHighlightForegroundColor;
- private Color mNormalForegroundColor;
-
- public StateLabelProvider() {
- mHighlightForegroundColor = Display.getDefault().getSystemColor(SWT.COLOR_BLUE);
- mNormalForegroundColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK);
- }
-
- public String getColumnText(IGLProperty property, int columnIndex) {
- switch (columnIndex) {
- case 0:
- return getName(property);
- case 1:
- return getValue(property);
- default:
- return "";
- }
- }
-
- private String getValue(IGLProperty element) {
- return element.getStringValue();
- }
-
- private String getName(IGLProperty element) {
- IGLProperty parent = element.getParent();
- if (parent instanceof GLListProperty) {
- // For members of list, use the index in the list as the name as opposed to
- // the property type
- int index = ((GLListProperty) parent).indexOf(element);
- if (element.getType() == GLStateType.GL_STATE_ES1) {
- return String.format("Context %d (ES1)", index);
- } else if (element.getType() == GLStateType.GL_STATE_ES2) {
- return String.format("Context %d (ES2)", index);
- } else {
- return Integer.toString(index);
- }
- } else if (parent instanceof GLSparseArrayProperty) {
- // For members of sparse array, use the key as the name as opposed to
- // the property type
- int index = ((GLSparseArrayProperty) parent).keyFor(element);
- return Integer.toString(index);
- }
-
- return element.getType().getDescription();
- }
-
- @Override
- public void update(ViewerCell cell) {
- Object element = cell.getElement();
- if (!(element instanceof IGLProperty)) {
- return;
- }
-
- IGLProperty prop = (IGLProperty) element;
-
- String text = getColumnText(prop, cell.getColumnIndex());
- cell.setText(text);
-
- if (mChangedProperties != null && mChangedProperties.contains(prop)) {
- cell.setForeground(mHighlightForegroundColor);
- } else {
- cell.setForeground(mNormalForegroundColor);
- }
- }
-
- public void setChangedProperties(Set<IGLProperty> changedProperties) {
- mChangedProperties = changedProperties;
- }
-}
diff --git a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/StateViewPage.java b/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/StateViewPage.java
deleted file mode 100644
index faa9561cb..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.gldebugger/src/com/android/ide/eclipse/gltrace/editors/StateViewPage.java
+++ /dev/null
@@ -1,372 +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.ide.eclipse.gltrace.editors;
-
-import com.android.ide.eclipse.gltrace.GlTracePlugin;
-import com.android.ide.eclipse.gltrace.editors.GLCallGroups.GLCallNode;
-import com.android.ide.eclipse.gltrace.model.GLCall;
-import com.android.ide.eclipse.gltrace.model.GLTrace;
-import com.android.ide.eclipse.gltrace.state.GLState;
-import com.android.ide.eclipse.gltrace.state.IGLProperty;
-import com.android.ide.eclipse.gltrace.state.StatePrettyPrinter;
-import com.android.ide.eclipse.gltrace.state.transforms.IStateTransform;
-import com.google.common.base.Charsets;
-import com.google.common.io.Files;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.ILock;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IToolBarManager;
-import org.eclipse.jface.dialogs.ErrorDialog;
-import org.eclipse.jface.layout.GridDataFactory;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.ISelectionChangedListener;
-import org.eclipse.jface.viewers.ISelectionProvider;
-import org.eclipse.jface.viewers.TreeSelection;
-import org.eclipse.jface.viewers.TreeViewer;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.swt.widgets.FileDialog;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Tree;
-import org.eclipse.swt.widgets.TreeColumn;
-import org.eclipse.ui.ISelectionListener;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.IWorkbenchPart;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.part.IPageSite;
-import org.eclipse.ui.part.Page;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A tree view of the OpenGL state. It listens to the current GLCall that is selected
- * in the Function Trace view, and updates its view to reflect the state as of the selected call.
- */
-public class StateViewPage extends Page implements ISelectionListener, ISelectionProvider {
- public static final String ID = "com.android.ide.eclipse.gltrace.views.GLState"; //$NON-NLS-1$
- private static String sLastUsedPath;
- private static final ILock sGlStateLock = Job.getJobManager().newLock();
-
- private GLTrace mTrace;
- private List<GLCall> mGLCalls;
-
- /** OpenGL State as of call {@link #mCurrentStateIndex}. */
- private IGLProperty mState;
- private int mCurrentStateIndex;
-
- private String[] TREE_PROPERTIES = { "Name", "Value" };
- private TreeViewer mTreeViewer;
- private StateLabelProvider mLabelProvider;
-
- public StateViewPage(GLTrace trace) {
- setInput(trace);
- }
-
- public void setInput(GLTrace trace) {
- mTrace = trace;
- if (trace != null) {
- mGLCalls = trace.getGLCalls();
- } else {
- mGLCalls = null;
- }
-
- mState = GLState.createDefaultState();
- mCurrentStateIndex = -1;
-
- if (mTreeViewer != null) {
- mTreeViewer.setInput(mState);
- mTreeViewer.refresh();
- }
- }
-
- @Override
- public void createControl(Composite parent) {
- final Tree tree = new Tree(parent, SWT.VIRTUAL | SWT.H_SCROLL | SWT.V_SCROLL);
- GridDataFactory.fillDefaults().grab(true, true).applyTo(tree);
-
- tree.setHeaderVisible(true);
- tree.setLinesVisible(true);
- tree.setLayoutData(new GridData(GridData.FILL_BOTH));
-
- TreeColumn col1 = new TreeColumn(tree, SWT.LEFT);
- col1.setText(TREE_PROPERTIES[0]);
- col1.setWidth(200);
-
- TreeColumn col2 = new TreeColumn(tree, SWT.LEFT);
- col2.setText(TREE_PROPERTIES[1]);
- col2.setWidth(200);
-
- mTreeViewer = new TreeViewer(tree);
- mTreeViewer.setContentProvider(new StateContentProvider());
- mLabelProvider = new StateLabelProvider();
- mTreeViewer.setLabelProvider(mLabelProvider);
- mTreeViewer.setInput(mState);
- mTreeViewer.refresh();
-
- final IToolBarManager manager = getSite().getActionBars().getToolBarManager();
- manager.add(new Action("Save to File",
- PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(
- ISharedImages.IMG_ETOOL_SAVEAS_EDIT)) {
- @Override
- public void run() {
- saveCurrentState();
- }
- });
- }
-
- private void saveCurrentState() {
- final Shell shell = mTreeViewer.getTree().getShell();
- FileDialog fd = new FileDialog(shell, SWT.SAVE);
- fd.setFilterExtensions(new String[] { "*.txt" });
- if (sLastUsedPath != null) {
- fd.setFilterPath(sLastUsedPath);
- }
-
- String path = fd.open();
- if (path == null) {
- return;
- }
-
- File f = new File(path);
- sLastUsedPath = f.getParent();
-
- // export state to f
- StatePrettyPrinter pp = new StatePrettyPrinter();
- synchronized (sGlStateLock) {
- mState.prettyPrint(pp);
- }
-
- try {
- Files.write(pp.toString(), f, Charsets.UTF_8);
- } catch (IOException e) {
- ErrorDialog.openError(shell,
- "Export GL State",
- "Unexpected error while writing GL state to file.",
- new Status(Status.ERROR, GlTracePlugin.PLUGIN_ID, e.toString()));
- }
- }
-
- @Override
- public void init(IPageSite pageSite) {
- super.init(pageSite);
- pageSite.getPage().addSelectionListener(this);
- }
-
- @Override
- public void dispose() {
- getSite().getPage().removeSelectionListener(this);
- super.dispose();
- }
-
- @Override
- public void selectionChanged(IWorkbenchPart part, ISelection selection) {
- if (!(part instanceof GLFunctionTraceViewer)) {
- return;
- }
-
- if (((GLFunctionTraceViewer) part).getTrace() != mTrace) {
- return;
- }
-
- if (!(selection instanceof TreeSelection)) {
- return;
- }
-
- GLCall selectedCall = null;
-
- Object data = ((TreeSelection) selection).getFirstElement();
- if (data instanceof GLCallNode) {
- selectedCall = ((GLCallNode) data).getCall();
- }
-
- if (selectedCall == null) {
- return;
- }
-
- final int selectedCallIndex = selectedCall.getIndex();
-
- // Creation of texture images takes a few seconds on the first run. So run
- // the update task as an Eclipse job.
- Job job = new Job("Updating GL State") {
- @Override
- protected IStatus run(IProgressMonitor monitor) {
- Set<IGLProperty> changedProperties = null;
-
- try {
- sGlStateLock.acquire();
- changedProperties = updateState(mCurrentStateIndex,
- selectedCallIndex);
- mCurrentStateIndex = selectedCallIndex;
- } catch (Exception e) {
- GlTracePlugin.getDefault().logMessage(
- "Unexpected error while updating GL State.");
- GlTracePlugin.getDefault().logMessage(e.getMessage());
- return new Status(Status.ERROR,
- GlTracePlugin.PLUGIN_ID,
- "Unexpected error while updating GL State.",
- e);
- } finally {
- sGlStateLock.release();
- }
-
- mLabelProvider.setChangedProperties(changedProperties);
- Display.getDefault().syncExec(new Runnable() {
- @Override
- public void run() {
- if (!mTreeViewer.getTree().isDisposed()) {
- mTreeViewer.refresh();
- }
- }
- });
-
- return Status.OK_STATUS;
- }
- };
- job.setPriority(Job.SHORT);
- job.schedule();
- }
-
- @Override
- public Control getControl() {
- if (mTreeViewer == null) {
- return null;
- }
-
- return mTreeViewer.getControl();
- }
-
- @Override
- public void setFocus() {
- }
-
- /**
- * Update GL state from GL call at fromIndex to the call at toIndex.
- * If fromIndex < toIndex, the GL state will be updated by applying all the transformations
- * corresponding to calls from (fromIndex + 1) to toIndex (inclusive).
- * If fromIndex > toIndex, the GL state will be updated by reverting all the calls from
- * fromIndex (inclusive) to (toIndex + 1).
- * @return GL state properties that changed as a result of this update.
- */
- private Set<IGLProperty> updateState(int fromIndex, int toIndex) {
- assert fromIndex >= -1 && fromIndex < mGLCalls.size();
- assert toIndex >= 0 && toIndex < mGLCalls.size();
-
- if (fromIndex < toIndex) {
- return applyTransformations(fromIndex, toIndex);
- } else if (fromIndex > toIndex) {
- return revertTransformations(fromIndex, toIndex);
- } else {
- return Collections.emptySet();
- }
- }
-
- private Set<IGLProperty> applyTransformations(int fromIndex, int toIndex) {
- int setSizeHint = 3 * (toIndex - fromIndex) + 10;
- Set<IGLProperty> changedProperties = new HashSet<IGLProperty>(setSizeHint);
-
- for (int i = fromIndex + 1; i <= toIndex; i++) {
- GLCall call = mGLCalls.get(i);
- for (IStateTransform f : call.getStateTransformations()) {
- try {
- f.apply(mState);
- IGLProperty changedProperty = f.getChangedProperty(mState);
- if (changedProperty != null) {
- changedProperties.addAll(getHierarchy(changedProperty));
- }
- } catch (Exception e) {
- GlTracePlugin.getDefault().logMessage("Error applying transformations for "
- + call);
- GlTracePlugin.getDefault().logMessage(e.toString());
- }
- }
- }
-
- return changedProperties;
- }
-
- private Set<IGLProperty> revertTransformations(int fromIndex, int toIndex) {
- int setSizeHint = 3 * (fromIndex - toIndex) + 10;
- Set<IGLProperty> changedProperties = new HashSet<IGLProperty>(setSizeHint);
-
- for (int i = fromIndex; i > toIndex; i--) {
- List<IStateTransform> transforms = mGLCalls.get(i).getStateTransformations();
- // When reverting transformations, iterate from the last to first so that the reversals
- // are performed in the correct sequence.
- for (int j = transforms.size() - 1; j >= 0; j--) {
- IStateTransform f = transforms.get(j);
- f.revert(mState);
-
- IGLProperty changedProperty = f.getChangedProperty(mState);
- if (changedProperty != null) {
- changedProperties.addAll(getHierarchy(changedProperty));
- }
- }
- }
-
- return changedProperties;
- }
-
- /**
- * Obtain the list of properties starting from the provided property up to
- * the root of GL state.
- */
- private List<IGLProperty> getHierarchy(IGLProperty changedProperty) {
- List<IGLProperty> changedProperties = new ArrayList<IGLProperty>(5);
- changedProperties.add(changedProperty);
-
- // add the entire parent chain until we reach the root
- IGLProperty prop = changedProperty;
- while ((prop = prop.getParent()) != null) {
- changedProperties.add(prop);
- }
-
- return changedProperties;
- }
-
- @Override
- public void addSelectionChangedListener(ISelectionChangedListener listener) {
- mTreeViewer.addSelectionChangedListener(listener);
- }
-
- @Override
- public ISelection getSelection() {
- return mTreeViewer.getSelection();
- }
-
- @Override
- public void removeSelectionChangedListener(ISelectionChangedListener listener) {
- mTreeViewer.removeSelectionChangedListener(listener);
- }
-
- @Override
- public void setSelection(ISelection selection) {
- mTreeViewer.setSelection(selection);
- }
-}