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