]> git.cworth.org Git - apitrace/blob - common/trace_callset.hpp
Rename trim::CallSet to trace::FastCallSet
[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     // Aliases for call flags
60     enum {
61         FREQUENCY_NONE         = 0,
62         FREQUENCY_FRAME        = CALL_FLAG_END_FRAME,
63         FREQUENCY_RENDERTARGET = CALL_FLAG_END_FRAME | CALL_FLAG_SWAP_RENDERTARGET,
64         FREQUENCY_RENDER       = CALL_FLAG_RENDER,
65         FREQUENCY_ALL          = 0xffffffff
66     };
67
68     // A linear range of calls
69     class CallRange
70     {
71     public:
72         CallNo start;
73         CallNo stop;
74         CallNo step;
75         CallFlags freq;
76
77         CallRange(CallNo callNo) :
78             start(callNo),
79             stop(callNo),
80             step(1),
81             freq(FREQUENCY_ALL)
82         {}
83
84         CallRange(CallNo _start, CallNo _stop, CallNo _step = 1, CallFlags _freq = FREQUENCY_ALL) :
85             start(_start),
86             stop(_stop),
87             step(_step),
88             freq(_freq)
89         {}
90
91         bool
92         contains(CallNo callNo, CallFlags callFlags) const {
93             return callNo >= start &&
94                    callNo <= stop &&
95                    ((callNo - start) % step) == 0 &&
96                    ((callFlags & freq) ||
97                     freq == FREQUENCY_ALL);
98         }
99     };
100
101
102     // A collection of call ranges
103     class CallSet
104     {
105     private:
106         CallRange limits;
107
108     public:
109         // TODO: use binary tree to speed up lookups
110         typedef std::list< CallRange > RangeList;
111         RangeList ranges;
112
113         CallSet(): limits(std::numeric_limits<CallNo>::min(), std::numeric_limits<CallNo>::max()) {}
114
115         CallSet(CallFlags freq);
116
117         CallSet(const char *str);
118
119         // Not empty set
120         inline bool
121         empty() const {
122             return ranges.empty();
123         }
124
125         void
126         addRange(const CallRange & range) {
127             if (range.start <= range.stop &&
128                 range.freq != FREQUENCY_NONE) {
129
130                 if (empty()) {
131                     limits.start = range.start;
132                     limits.stop = range.stop;
133                 } else {
134                     if (range.start < limits.start)
135                         limits.start = range.start;
136                     if (range.stop > limits.stop)
137                         limits.stop = range.stop;
138                 }
139
140                 RangeList::iterator it = ranges.begin();
141                 while (it != ranges.end() && it->start < range.start) {
142                     ++it;
143                 }
144
145                 ranges.insert(it, range);
146             }
147         }
148
149         inline bool
150         contains(CallNo callNo, CallFlags callFlags = FREQUENCY_ALL) const {
151             if (empty()) {
152                 return false;
153             }
154             RangeList::const_iterator it;
155             for (it = ranges.begin(); it != ranges.end() && it->start <= callNo; ++it) {
156                 if (it->contains(callNo, callFlags)) {
157                     return true;
158                 }
159             }
160             return false;
161         }
162
163         inline bool
164         contains(const trace::Call &call) {
165             return contains(call.no, call.flags);
166         }
167
168         CallNo getFirst() {
169             return limits.start;
170         }
171
172         CallNo getLast() {
173             return limits.stop;
174         }
175     };
176
177
178     CallSet parse(const char *string);
179
180
181 } /* namespace trace */
182
183
184 #endif /* _TRACE_CALLSET_HPP_ */