1 /*******************************************************************************
2 * Copyright (c) 2013, 2016 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.tracecompass
.tmf
.ui
.views
.callstack
;
15 import java
.util
.Optional
;
17 import org
.eclipse
.swt
.SWT
;
18 import org
.eclipse
.swt
.graphics
.GC
;
19 import org
.eclipse
.swt
.graphics
.RGB
;
20 import org
.eclipse
.swt
.graphics
.Rectangle
;
21 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
22 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Messages
;
23 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystem
;
24 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.StateSystemDisposedException
;
25 import org
.eclipse
.tracecompass
.statesystem
.core
.exceptions
.TimeRangeException
;
26 import org
.eclipse
.tracecompass
.statesystem
.core
.statevalue
.ITmfStateValue
;
27 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.StateItem
;
28 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.TimeGraphPresentationProvider
;
29 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeEvent
;
30 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.ITimeGraphEntry
;
31 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.model
.NullTimeEvent
;
32 import org
.eclipse
.tracecompass
.tmf
.ui
.widgets
.timegraph
.widgets
.Utils
;
34 import com
.google
.common
.cache
.CacheBuilder
;
35 import com
.google
.common
.cache
.CacheLoader
;
36 import com
.google
.common
.cache
.LoadingCache
;
39 * Presentation provider for the Call Stack view, based on the generic TMF
40 * presentation provider.
42 * @author Patrick Tasse
44 public class CallStackPresentationProvider
extends TimeGraphPresentationProvider
{
46 /** Number of colors used for call stack events */
47 public static final int NUM_COLORS
= 360;
49 private CallStackView fView
;
52 * Minimum width of a displayed state below which we will not print any text
53 * into it. It corresponds to the average width of 1 char, plus the width of
54 * the ellipsis characters.
56 private Integer fMinimumBarWidth
;
58 private final LoadingCache
<CallStackEvent
, Optional
<String
>> fTimeEventNames
= CacheBuilder
.newBuilder()
60 .build(new CacheLoader
<CallStackEvent
, Optional
<String
>>() {
62 public Optional
<String
> load(CallStackEvent event
) {
63 CallStackEntry entry
= event
.getEntry();
64 ITmfStateSystem ss
= entry
.getStateSystem();
66 ITmfStateValue value
= ss
.querySingleState(event
.getTime(), entry
.getQuark()).getStateValue();
67 if (!value
.isNull()) {
68 String name
= fView
.getFunctionName(entry
.getTrace(), entry
.getProcessId(), event
.getTime(), value
);
69 return Optional
.ofNullable(name
);
71 } catch (TimeRangeException e
) {
72 Activator
.getDefault().logError("Error querying state system", e
); //$NON-NLS-1$
73 } catch (StateSystemDisposedException e
) {
76 return Optional
.empty();
81 MULTIPLE (new RGB(100, 100, 100)),
82 EXEC (new RGB(0, 200, 0));
84 private final RGB rgb
;
86 private State (RGB rgb
) {
96 public CallStackPresentationProvider() {
100 * Sets the call stack view
103 * The call stack view that will contain the time events
106 public void setCallStackView(CallStackView view
) {
111 public String
getStateTypeName(ITimeGraphEntry entry
) {
112 return Messages
.CallStackPresentationProvider_Thread
;
116 public StateItem
[] getStateTable() {
117 final float saturation
= 0.6f
;
118 final float brightness
= 0.6f
;
119 StateItem
[] stateTable
= new StateItem
[NUM_COLORS
+ 1];
120 stateTable
[0] = new StateItem(State
.MULTIPLE
.rgb
, State
.MULTIPLE
.toString());
121 for (int i
= 0; i
< NUM_COLORS
; i
++) {
122 RGB rgb
= new RGB(i
, saturation
, brightness
);
123 stateTable
[i
+ 1] = new StateItem(rgb
, State
.EXEC
.toString());
129 public int getStateTableIndex(ITimeEvent event
) {
130 if (event
instanceof CallStackEvent
) {
131 CallStackEvent callStackEvent
= (CallStackEvent
) event
;
132 return callStackEvent
.getValue() + 1;
133 } else if (event
instanceof NullTimeEvent
) {
136 return State
.MULTIPLE
.ordinal();
140 public String
getEventName(ITimeEvent event
) {
141 if (event
instanceof CallStackEvent
) {
142 return fTimeEventNames
.getUnchecked((CallStackEvent
) event
).orElse(null);
144 return State
.MULTIPLE
.toString();
148 public void postDrawEvent(ITimeEvent event
, Rectangle bounds
, GC gc
) {
149 if (!(event
instanceof CallStackEvent
)) {
153 if (fMinimumBarWidth
== null) {
154 fMinimumBarWidth
= gc
.getFontMetrics().getAverageCharWidth() + gc
.stringExtent(Utils
.ELLIPSIS
).x
;
156 if (bounds
.width
<= fMinimumBarWidth
) {
158 * Don't print anything if we cannot at least show one character and
164 String name
= fTimeEventNames
.getUnchecked((CallStackEvent
) event
).orElse(""); //$NON-NLS-1$
165 if (name
.isEmpty()) {
166 /* No text to print */
170 gc
.setForeground(gc
.getDevice().getSystemColor(SWT
.COLOR_WHITE
));
171 Utils
.drawText(gc
, name
, bounds
.x
, bounds
.y
, bounds
.width
, bounds
.height
, true, true);
175 * Indicate that the provider of function names has changed, so any cached
176 * values must be reset.
178 void resetFunctionNames() {
179 fTimeEventNames
.invalidateAll();