]> git.cworth.org Git - apitrace/blob - common/trace_callset.hpp
Merge branch 'directxtex'
[apitrace] / common / trace_callset.hpp
1 /**************************************************************************
2  *
3  * Copyright 2012 VMware, Inc.
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 /*
27  * Representation of call sets.
28  *
29  * Grammar:
30  *
31  *     set = '@' filename
32  *         | range ( ',' ? range ) *
33  *
34  *     range = interval ( '/' frequency )
35  *
36  *     interval = '*'
37  *              | number
38  *              | start_number '-' end_number
39  *
40  *     frequency = divisor
41  *               | "frame"
42  *               | "rendertarget" | "fbo"
43  *               | "render | "draw"
44  *
45  */
46
47 #ifndef _TRACE_CALLSET_HPP_
48 #define _TRACE_CALLSET_HPP_
49
50
51 #include <limits>
52 #include <list>
53
54 #include "trace_model.hpp"
55
56
57 namespace trace {
58
59
60     // Should match Call::no
61     typedef unsigned CallNo;
62
63
64     // Aliases for call flags
65     enum {
66         FREQUENCY_NONE         = 0,
67         FREQUENCY_FRAME        = CALL_FLAG_END_FRAME,
68         FREQUENCY_RENDERTARGET = CALL_FLAG_END_FRAME | CALL_FLAG_SWAP_RENDERTARGET,
69         FREQUENCY_RENDER       = CALL_FLAG_RENDER,
70         FREQUENCY_ALL          = 0xffffffff
71     };
72
73     // A linear range of calls
74     class CallRange
75     {
76     public:
77         CallNo start;
78         CallNo stop;
79         CallNo step;
80         CallFlags freq;
81
82         CallRange(CallNo callNo) :
83             start(callNo),
84             stop(callNo),
85             step(1),
86             freq(FREQUENCY_ALL)
87         {}
88
89         CallRange(CallNo _start, CallNo _stop, CallNo _step = 1, CallFlags _freq = FREQUENCY_ALL) :
90             start(_start),
91             stop(_stop),
92             step(_step),
93             freq(_freq)
94         {}
95
96         bool
97         contains(CallNo callNo, CallFlags callFlags) const {
98             return callNo >= start &&
99                    callNo <= stop &&
100                    ((callNo - start) % step) == 0 &&
101                    ((callFlags & freq) ||
102                     freq == FREQUENCY_ALL);
103         }
104     };
105
106
107     // A collection of call ranges
108     class CallSet
109     {
110     private:
111         CallRange limits;
112
113     public:
114         // TODO: use binary tree to speed up lookups
115         typedef std::list< CallRange > RangeList;
116         RangeList ranges;
117
118         CallSet(): limits(std::numeric_limits<CallNo>::min(), std::numeric_limits<CallNo>::max()) {}
119
120         CallSet(CallFlags freq);
121
122         CallSet(const char *str);
123
124         // Not empty set
125         inline bool
126         empty() const {
127             return ranges.empty();
128         }
129
130         void
131         addRange(const CallRange & range) {
132             if (range.start <= range.stop &&
133                 range.freq != FREQUENCY_NONE) {
134
135                 if (empty()) {
136                     limits.start = range.start;
137                     limits.stop = range.stop;
138                 } else {
139                     if (range.start < limits.start)
140                         limits.start = range.start;
141                     if (range.stop > limits.stop)
142                         limits.stop = range.stop;
143                 }
144
145                 RangeList::iterator it = ranges.begin();
146                 while (it != ranges.end() && it->start < range.start) {
147                     ++it;
148                 }
149
150                 ranges.insert(it, range);
151             }
152         }
153
154         inline bool
155         contains(CallNo callNo, CallFlags callFlags = FREQUENCY_ALL) const {
156             if (empty()) {
157                 return false;
158             }
159             RangeList::const_iterator it;
160             for (it = ranges.begin(); it != ranges.end() && it->start <= callNo; ++it) {
161                 if (it->contains(callNo, callFlags)) {
162                     return true;
163                 }
164             }
165             return false;
166         }
167
168         inline bool
169         contains(const trace::Call &call) {
170             return contains(call.no, call.flags);
171         }
172
173         CallNo getFirst() {
174             return limits.start;
175         }
176
177         CallNo getLast() {
178             return limits.stop;
179         }
180     };
181
182
183     CallSet parse(const char *string);
184
185
186 } /* namespace trace */
187
188
189 #endif /* _TRACE_CALLSET_HPP_ */