]> git.cworth.org Git - apitrace/blob - log.cpp
Fix glGenBuffersARB spec.
[apitrace] / log.cpp
1 /**************************************************************************
2  *
3  * Copyright 2007-2009 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 #include <assert.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include <zlib.h>
34
35 #include "os.hpp"
36 #include "log.hpp"
37 #include "trace_format.hpp"
38
39
40 namespace Log {
41
42
43 static gzFile g_gzFile = NULL;
44 static void _Close(void) {
45    if(g_gzFile != NULL) {
46       gzclose(g_gzFile);
47       g_gzFile = NULL;
48    }
49 }
50
51 static int reentrancy = 0;
52
53 static void _Open(const char *szName, const char *szExtension) {
54    _Close();
55    
56    static unsigned dwCounter = 0;
57
58    char szProcessName[PATH_MAX];
59    char szFileName[PATH_MAX];
60
61    OS::GetProcessName(szProcessName, PATH_MAX);
62
63    for(;;) {
64       FILE *file;
65       
66       if(dwCounter)
67          snprintf(szFileName, PATH_MAX, "%s.%s.%u.%s", szProcessName, szName, dwCounter, szExtension);
68       else
69          snprintf(szFileName, PATH_MAX, "%s.%s.%s", szProcessName, szName, szExtension);
70       
71       file = fopen(szFileName, "rb");
72       if(file == NULL)
73          break;
74       
75       fclose(file);
76       
77       ++dwCounter;
78    }
79
80    fprintf(stderr, "Logging to %s\n", szFileName);
81    g_gzFile = gzopen(szFileName, "wb");
82 }
83
84 static inline void Write(const void *sBuffer, size_t dwBytesToWrite) {
85    if(g_gzFile == NULL)
86       return;
87    
88    if (reentrancy > 1)
89       return;
90
91    gzwrite(g_gzFile, sBuffer, dwBytesToWrite);
92 }
93
94 static inline void 
95 WriteByte(char c) {
96    Write(&c, 1);
97 }
98
99 void inline 
100 WriteUInt(unsigned long long value) {
101    char buf[2 * sizeof value];
102    unsigned len;
103
104    len = 0;
105    do {
106       assert(len < sizeof buf);
107       buf[len] = 0x80 | (value & 0x7f);
108       value >>= 7;
109       ++len;
110    } while (value);
111
112    assert(len);
113    buf[len - 1] &= 0x7f;
114
115    Write(buf, len);
116 }
117
118 static inline void 
119 WriteFloat(float value) {
120    assert(sizeof value == 4);
121    Write((const char *)&value, sizeof value);
122 }
123
124 static inline void 
125 WriteDouble(double value) {
126    assert(sizeof value == 8);
127    Write((const char *)&value, sizeof value);
128 }
129
130 static inline void 
131 WriteString(const char *str) {
132    size_t len = strlen(str);
133    WriteUInt(len);
134    Write(str, len);
135 }
136
137 void Open(const char *name) {
138    _Open(name, "trace");
139    WriteUInt(TRACE_VERSION);
140 }
141
142 void Close(void) {
143    _Close();
144 }
145
146 void BeginCall(const char *function) {
147    OS::AcquireMutex();
148    ++reentrancy;
149    WriteString(function);
150 }
151
152 void EndCall(void) {
153    WriteByte(Trace::CALL_END);
154    --reentrancy;
155    gzflush(g_gzFile, Z_SYNC_FLUSH);
156    OS::ReleaseMutex();
157 }
158
159 void BeginArg(const char *type, const char *name) {
160    WriteByte(Trace::CALL_ARG);
161    WriteString(name);
162 }
163
164 void EndArg(void) { }
165
166 void BeginReturn(const char *type) {
167    WriteByte(Trace::CALL_RET);
168 }
169
170 void EndReturn(void) { }
171
172 void BeginArray(const char *type, size_t length) {
173    WriteByte(Trace::TYPE_ARRAY);
174    WriteUInt(length);
175 }
176
177 void EndArray(void) { }
178
179 void BeginElement(const char *type) { }
180
181 void EndElement(void) { }
182
183 void BeginStruct(const char *type) {
184    WriteByte(Trace::TYPE_STRUCT);
185 }
186
187 void EndStruct(void) {
188    WriteString("");
189 }
190
191 void BeginMember(const char *type, const char *name) {
192    WriteString(name);
193 }
194
195 void EndMember(void) { }
196
197 void BeginBitmask(const char *type) {
198    WriteByte(Trace::TYPE_BITMASK);
199 }
200
201 void EndBitmask(void) {
202    WriteByte(Trace::TYPE_NULL);
203 }
204
205 void BeginPointer(const char *type, const void *addr)
206 {
207    WriteByte(Trace::TYPE_POINTER);
208    WriteUInt((size_t)addr);
209 }
210
211 void EndPointer(void) { }
212
213 void LiteralBool(bool value) {
214    WriteByte(value ? Trace::TYPE_TRUE : Trace::TYPE_FALSE);
215 }
216
217 void LiteralSInt(signed long long value) {
218    if (value < 0) {
219       WriteByte(Trace::TYPE_SINT);
220       WriteUInt(-value);
221    } else {
222       WriteByte(Trace::TYPE_UINT);
223       WriteUInt(value);
224    }
225 }
226
227 void LiteralUInt(unsigned long long value) {
228    WriteByte(Trace::TYPE_UINT);
229    WriteUInt(value);
230 }
231
232 void LiteralFloat(float value) {
233    WriteByte(Trace::TYPE_FLOAT);
234    WriteFloat(value);
235 }
236
237 void LiteralFloat(double value) {
238    WriteByte(Trace::TYPE_DOUBLE);
239    WriteDouble(value);
240 }
241
242 void LiteralString(const char *str) {
243    if (!str) {
244       LiteralNull();
245       return;
246    }
247    WriteByte(Trace::TYPE_STRING);
248    WriteString(str);
249 }
250
251 void LiteralWString(const wchar_t *str) {
252    if (!str) {
253       LiteralNull();
254       return;
255    }
256    WriteByte(Trace::TYPE_STRING);
257    WriteString("<wide-string>");
258 }
259    
260 void LiteralBlob(const void *data, size_t size) {
261    if (!data) {
262       LiteralNull();
263       return;
264    }
265    WriteByte(Trace::TYPE_BLOB);
266    WriteUInt(size);
267    if (size) {
268       Write(data, size);
269    }
270 }
271
272 void LiteralNamedConstant(const char *name, long long value) {
273    WriteByte(Trace::TYPE_CONST);
274    WriteString(name);
275    LiteralSInt(value);
276 }
277
278 void LiteralNull(void) {
279    WriteByte(Trace::TYPE_NULL);
280 }
281
282 void LiteralOpaque(const void *addr) {
283    if (!addr) {
284       LiteralNull();
285       return;
286    }
287    WriteByte(Trace::TYPE_OPAQUE);
288    WriteUInt((size_t)addr);
289 }
290
291 void Abort(void) {
292     Close();
293     OS::Abort();
294 }
295
296 } /* namespace Log */