]> git.cworth.org Git - vogl/blob - src/vogleditor/vogleditor_apicalltreeitem.cpp
UI: Add 'GL Context' column to API call tree to help with multi-context debugging.
[vogl] / src / vogleditor / vogleditor_apicalltreeitem.cpp
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 #include "vogleditor_qapicalltreemodel.h"
27
28 #include "vogl_common.h"
29 #include "vogl_trace_file_reader.h"
30 #include "vogl_trace_packet.h"
31 #include "vogl_trace_stream_types.h"
32 #include "vogleditor_gl_state_snapshot.h"
33
34 vogleditor_apiCallTreeItem::vogleditor_apiCallTreeItem(vogleditor_QApiCallTreeModel* pModel)
35  : m_parentItem(NULL),
36    m_pApiCallItem(NULL),
37    m_pFrameItem(NULL),
38    m_pModel(pModel)
39 {
40     m_columnData[VOGL_ACTC_APICALL] = "API Call";
41     m_columnData[VOGL_ACTC_INDEX] = "Index";
42     m_columnData[VOGL_ACTC_FLAGS] = "";
43     m_columnData[VOGL_ACTC_GLCONTEXT] = "GL Context";
44     //m_ColumnTitles[VOGL_ACTC_BEGINTIME] = "Begin Time";
45     //m_ColumnTitles[VOGL_ACTC_ENDTIME] = "End Time";
46     m_columnData[VOGL_ACTC_DURATION] = "Duration (ns)";
47 }
48
49 // Constructor for frame nodes
50 vogleditor_apiCallTreeItem::vogleditor_apiCallTreeItem(vogleditor_frameItem* frameItem, vogleditor_apiCallTreeItem* parent)
51  : m_parentItem(parent),
52    m_pApiCallItem(NULL),
53    m_pFrameItem(frameItem),
54    m_pModel(NULL)
55 {
56    if (frameItem != NULL)
57    {
58       QString tmp;
59       tmp.sprintf("Frame %" PRIu64, frameItem->frameNumber());
60       m_columnData[VOGL_ACTC_APICALL] = tmp;
61    }
62
63    if (m_parentItem != NULL)
64    {
65       m_pModel = m_parentItem->m_pModel;
66    }
67 }
68
69 // Constructor for apiCall nodes
70 vogleditor_apiCallTreeItem::vogleditor_apiCallTreeItem(QString nodeText, vogleditor_apiCallItem* apiCallItem, vogleditor_apiCallTreeItem* parent)
71  : m_parentItem(parent),
72    m_pApiCallItem(apiCallItem),
73    m_pFrameItem(NULL),
74    m_pModel(NULL)
75 {
76    m_columnData[VOGL_ACTC_APICALL] = nodeText;
77
78    if (apiCallItem != NULL)
79    {
80       m_columnData[VOGL_ACTC_INDEX] = (qulonglong)apiCallItem->globalCallIndex();
81       m_columnData[VOGL_ACTC_FLAGS] = "";
82       dynamic_string strContext;
83       m_columnData[VOGL_ACTC_GLCONTEXT] = strContext.format("0x%" PRIx64, apiCallItem->getGLPacket()->m_context_handle).c_str();
84       //m_columnData[VOGL_ACTC_BEGINTIME] = apiCallItem->startTime();
85       //m_columnData[VOGL_ACTC_ENDTIME] = apiCallItem->endTime();
86       m_columnData[VOGL_ACTC_DURATION] = (qulonglong)apiCallItem->duration();
87    }
88
89    if (m_parentItem != NULL)
90    {
91       m_pModel = m_parentItem->m_pModel;
92    }
93 }
94
95 vogleditor_apiCallTreeItem::~vogleditor_apiCallTreeItem()
96 {
97    if (m_pFrameItem != NULL)
98    {
99       delete m_pFrameItem;
100       m_pFrameItem = NULL;
101    }
102
103    if (m_pApiCallItem != NULL)
104    {
105       delete m_pApiCallItem;
106       m_pApiCallItem = NULL;
107    }
108
109    for (int i = 0; i < m_childItems.size(); i++)
110    {
111       delete m_childItems[i];
112       m_childItems[i] = NULL;
113    }
114
115    m_childItems.clear();
116 }
117
118 vogleditor_apiCallTreeItem* vogleditor_apiCallTreeItem::parent() const
119 {
120    return m_parentItem;
121 }
122
123 void vogleditor_apiCallTreeItem::appendChild(vogleditor_apiCallTreeItem* pChild)
124 {
125    m_childItems.append(pChild);
126 }
127
128 int vogleditor_apiCallTreeItem::childCount() const
129 {
130    return m_childItems.size();
131 }
132
133 vogleditor_apiCallTreeItem* vogleditor_apiCallTreeItem::child(int index) const
134 {
135    if (index < 0 || index >= childCount())
136    {
137       return NULL;
138    }
139
140    return m_childItems[index];
141 }
142
143 vogleditor_apiCallItem* vogleditor_apiCallTreeItem::apiCallItem() const
144 {
145    return m_pApiCallItem;
146 }
147
148 vogleditor_frameItem* vogleditor_apiCallTreeItem::frameItem() const
149 {
150    return m_pFrameItem;
151 }
152
153 void vogleditor_apiCallTreeItem::set_snapshot(vogleditor_gl_state_snapshot* pSnapshot)
154 {
155     if (m_pFrameItem)
156     {
157         m_pFrameItem->set_snapshot(pSnapshot);
158     }
159
160     if (m_pApiCallItem)
161     {
162         m_pApiCallItem->set_snapshot(pSnapshot);
163     }
164 }
165
166 bool vogleditor_apiCallTreeItem::has_snapshot() const
167 {
168     bool bHasSnapshot = false;
169     if (m_pFrameItem)
170     {
171         bHasSnapshot = m_pFrameItem->has_snapshot();
172     }
173
174     if (m_pApiCallItem)
175     {
176         bHasSnapshot = m_pApiCallItem->has_snapshot();
177     }
178     return bHasSnapshot;
179 }
180
181 vogleditor_gl_state_snapshot* vogleditor_apiCallTreeItem::get_snapshot() const
182 {
183     vogleditor_gl_state_snapshot* pSnapshot = NULL;
184     if (m_pFrameItem)
185     {
186         pSnapshot = m_pFrameItem->get_snapshot();
187     }
188
189     if (m_pApiCallItem)
190     {
191         pSnapshot = m_pApiCallItem->get_snapshot();
192     }
193     return pSnapshot;
194 }
195
196 int vogleditor_apiCallTreeItem::columnCount() const
197 {
198    int count = 0;
199    if (m_parentItem == NULL)
200    {
201       count = VOGL_MAX_ACTC;
202    }
203    else
204    {
205       m_pModel->columnCount();
206    }
207
208    return count;
209 }
210
211 QVariant vogleditor_apiCallTreeItem::columnData(int column, int role) const
212 {
213    if (column >= VOGL_MAX_ACTC)
214    {
215       return QVariant();
216    }
217
218    if (role == Qt::DecorationRole)
219    {
220        // handle flags
221        if (column == VOGL_ACTC_FLAGS)
222        {
223            if (has_snapshot())
224            {
225                if (get_snapshot()->is_outdated())
226                {
227                    // snapshot was dirtied due to an earlier edit
228                    return QColor(200, 0, 0);
229                }
230                else if (get_snapshot()->is_edited())
231                {
232                    // snapshot has been edited
233                    return QColor(200, 102, 0);
234                }
235                else
236                {
237                    // snapshot is good
238                    return QColor(0, 0, 255);
239                }
240            }
241        }
242    }
243
244    if (role == Qt::DisplayRole)
245    {
246        return m_columnData[column];
247    }
248
249    return QVariant();
250 }
251
252 int vogleditor_apiCallTreeItem::row() const
253 {
254    // note, this is just the row within the current level of the hierarchy
255    if (m_parentItem)
256       return m_parentItem->m_childItems.indexOf(const_cast<vogleditor_apiCallTreeItem*>(this));
257
258    return 0;
259 }