VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispProfile.h@ 44529

Last change on this file since 44529 was 44529, checked in by vboxsync, 12 years ago

header (C) fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.7 KB
Line 
1/* $Id: VBoxDispProfile.h 44529 2013-02-04 15:54:15Z vboxsync $ */
2
3/** @file
4 * VBoxVideo Display D3D User mode dll
5 */
6
7/*
8 * Copyright (C) 2011-2012 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#ifndef ___VBoxDispProfile_h__
20#define ___VBoxDispProfile_h__
21#include "VBoxDispD3DCmn.h"
22
23#include <iprt/ctype.h>
24#include <iprt/time.h>
25
26#define VBOXDISPPROFILE_MAX_SETSIZE 512
27#define VBOXDISPPROFILE_GET_TIME_NANO() RTTimeNanoTS()
28#define VBOXDISPPROFILE_GET_TIME_MILLI() RTTimeMilliTS()
29#define VBOXDISPPROFILE_DUMP(_m) do {\
30 LOGREL_EXACT(_m); \
31 } while (0)
32
33class VBoxDispProfileEntry
34{
35public:
36 VBoxDispProfileEntry() :
37 m_cCalls(0),
38 m_cTime(0),
39 m_pName(NULL)
40 {}
41
42 VBoxDispProfileEntry(const char *pName) :
43 m_cCalls(0),
44 m_cTime(0),
45 m_pName(pName)
46 {}
47
48 void step(uint64_t cTime)
49 {
50 ++m_cCalls;
51 m_cTime+= cTime;
52 }
53
54 void reset()
55 {
56 m_cCalls = 0;
57 m_cTime = 0;
58 }
59
60 uint64_t getTime() const
61 {
62 return m_cTime;
63 }
64
65 uint32_t getNumCalls() const
66 {
67 return m_cCalls;
68 }
69
70 const char* getName() const
71 {
72 return m_pName;
73 }
74
75 void dump(void *pvObj, uint64_t cTotalEntriesTime, uint64_t cTotalTime) const
76 {
77// VBOXDISPPROFILE_DUMP((pDevice, "Entry '%s': calls(%d), time: nanos(%I64u), micros(%I64u), millis(%I64u)\n",
78// m_pName, m_cCalls,
79// m_cTime, m_cTime/1000, m_cTime/1000000));
80 VBOXDISPPROFILE_DUMP(("'%s' [0x%p]: \t%d\t%u\t%u\t%u\t%u\t%u", m_pName, pvObj,
81 m_cCalls,
82 (uint32_t)m_cTime, (uint32_t)(m_cTime/1000), (uint32_t)(m_cTime/1000000),
83 (uint32_t)(((double)m_cTime)/cTotalEntriesTime),
84 (uint32_t)(((double)m_cTime)/cTotalTime)));
85 }
86private:
87 uint32_t m_cCalls;
88 uint64_t m_cTime;
89 const char * m_pName;
90};
91
92class VBoxDispProfileSet
93{
94public:
95 VBoxDispProfileSet(const char *pName) :
96 m_cEntries(0),
97 m_cIterations(0),
98 m_pName(pName)
99 {
100 m_cTime = VBOXDISPPROFILE_GET_TIME_NANO();
101 }
102
103 VBoxDispProfileSet() :
104 m_cEntries(0),
105 m_cIterations(0),
106 m_pName("global")
107 {
108 m_cTime = VBOXDISPPROFILE_GET_TIME_NANO();
109 }
110
111 VBoxDispProfileEntry * alloc(const char *pName)
112 {
113 if (m_cEntries < RT_ELEMENTS(m_Entries))
114 {
115 VBoxDispProfileEntry * entry = &m_Entries[m_cEntries];
116 ++m_cEntries;
117 *entry = VBoxDispProfileEntry(pName);
118 return entry;
119 }
120 return NULL;
121 }
122
123 VBoxDispProfileEntry * get(uint32_t u32Entry, const char *pName)
124 {
125 if (u32Entry < RT_ELEMENTS(m_Entries))
126 {
127 VBoxDispProfileEntry * entry = &m_Entries[u32Entry];
128 if (entry->getName())
129 return entry;
130 ++m_cEntries;
131 *entry = VBoxDispProfileEntry(pName);
132 return entry;
133 }
134 return NULL;
135 }
136
137 uint32_t reportIteration()
138 {
139 return ++m_cIterations;
140 }
141
142 uint32_t getNumIterations() const
143 {
144 return m_cIterations;
145 }
146
147 uint32_t getNumEntries() const
148 {
149 return m_cEntries;
150 }
151
152#define VBOXDISPPROFILESET_FOREACHENTRY(_op) \
153 for (uint32_t i = 0, e = 0; e < m_cEntries && i < RT_ELEMENTS(m_Entries); ++i) { \
154 if (m_Entries[i].getName()) { \
155 { \
156 _op \
157 } \
158 ++e; \
159 } \
160 } \
161
162 void resetEntries()
163 {
164 VBOXDISPPROFILESET_FOREACHENTRY( m_Entries[i].reset(); );
165 m_cTime = VBOXDISPPROFILE_GET_TIME_NANO();
166 }
167
168 void reset()
169 {
170 m_cEntries = 0;
171 m_cTime = VBOXDISPPROFILE_GET_TIME_NANO();
172 }
173
174 void dump(void *pvObj)
175 {
176 uint64_t cEntriesTime = 0;
177 VBOXDISPPROFILESET_FOREACHENTRY( cEntriesTime += m_Entries[i].getTime(); );
178
179 VBOXDISPPROFILE_DUMP((">>>> '%s' [0x%p]: Start of VBox Disp Dump: num entries(%d), et(%u), tt(%u) >>>>>", m_pName, pvObj, m_cEntries,
180 (uint32_t)(cEntriesTime / 1000000), (uint32_t)(m_cTime / 1000000)));
181 VBOXDISPPROFILE_DUMP(("Name\tCalls\tNanos\tMicros\tMillis\tentries_quota\ttotal_quota"));
182 VBOXDISPPROFILESET_FOREACHENTRY(
183 if (m_Entries[i].getNumCalls())
184 m_Entries[i].dump(pvObj, cEntriesTime, m_cTime); );
185 VBOXDISPPROFILE_DUMP(("<<<< '%s' [0x%p]: End of VBox Disp Dump <<<<<", m_pName, pvObj));
186 }
187
188private:
189 VBoxDispProfileEntry m_Entries[VBOXDISPPROFILE_MAX_SETSIZE];
190 uint32_t m_cEntries;
191 uint32_t m_cIterations;
192 uint64_t m_cTime;
193 const char * m_pName;
194};
195
196class VBoxDispProfileDummyPostProcess
197{
198public:
199 void postProcess(){}
200};
201
202template<typename T, typename P> class VBoxDispProfileScopeLogger
203{
204public:
205 VBoxDispProfileScopeLogger(T *pEntry, P PostProcess) :
206 m_pEntry(pEntry),
207 m_PostProcess(PostProcess),
208 m_bDisable(FALSE)
209 {
210 m_cTime = VBOXDISPPROFILE_GET_TIME_NANO();
211 }
212
213 ~VBoxDispProfileScopeLogger()
214 {
215 if (!m_bDisable)
216 {
217 logStep();
218 }
219 }
220
221 void disable()
222 {
223 m_bDisable = TRUE;
224 }
225
226 void logAndDisable()
227 {
228 logStep();
229 disable();
230 }
231
232private:
233 void logStep()
234 {
235 m_PostProcess.postProcess();
236 uint64_t cNewTime = VBOXDISPPROFILE_GET_TIME_NANO();
237 m_pEntry->step(cNewTime - m_cTime);
238 }
239 T *m_pEntry;
240 P m_PostProcess;
241 uint64_t m_cTime;
242 BOOL m_bDisable;
243};
244
245
246class VBoxDispProfileFpsCounter
247{
248public:
249 VBoxDispProfileFpsCounter(uint32_t cPeriods)
250 {
251 init(cPeriods);
252 }
253
254 VBoxDispProfileFpsCounter()
255 {
256 memset(&m_Data, 0, sizeof (m_Data));
257 }
258
259 ~VBoxDispProfileFpsCounter()
260 {
261 term();
262 }
263
264 void term()
265 {
266 if (m_Data.mpaPeriods)
267 {
268 RTMemFree(m_Data.mpaPeriods);
269 m_Data.mpaPeriods = NULL;
270 }
271 if (m_Data.mpaCalls)
272 {
273 RTMemFree(m_Data.mpaCalls);
274 m_Data.mpaCalls = NULL;
275 }
276 if (m_Data.mpaTimes)
277 {
278 RTMemFree(m_Data.mpaTimes);
279 m_Data.mpaTimes = NULL;
280 }
281 m_Data.mcPeriods = 0;
282 }
283
284 /* to be called in case fps counter was created with default constructor */
285 void init(uint32_t cPeriods)
286 {
287 memset(&m_Data, 0, sizeof (m_Data));
288 m_Data.mcPeriods = cPeriods;
289 if (cPeriods)
290 {
291 m_Data.mpaPeriods = (uint64_t *)RTMemAllocZ(sizeof (m_Data.mpaPeriods[0]) * cPeriods);
292 m_Data.mpaCalls = (uint32_t *)RTMemAllocZ(sizeof (m_Data.mpaCalls[0]) * cPeriods);
293 m_Data.mpaTimes = (uint64_t *)RTMemAllocZ(sizeof (m_Data.mpaTimes[0]) * cPeriods);
294 }
295 }
296
297 void ReportFrame()
298 {
299 uint64_t cur = VBOXDISPPROFILE_GET_TIME_NANO();
300
301 if(m_Data.mPrevTime)
302 {
303 uint64_t curPeriod = cur - m_Data.mPrevTime;
304
305 m_Data.mPeriodSum += curPeriod - m_Data.mpaPeriods[m_Data.miPeriod];
306 m_Data.mpaPeriods[m_Data.miPeriod] = curPeriod;
307
308 m_Data.mCallsSum += m_Data.mCurCalls - m_Data.mpaCalls[m_Data.miPeriod];
309 m_Data.mpaCalls[m_Data.miPeriod] = m_Data.mCurCalls;
310
311 m_Data.mTimeUsedSum += m_Data.mCurTimeUsed - m_Data.mpaTimes[m_Data.miPeriod];
312 m_Data.mpaTimes[m_Data.miPeriod] = m_Data.mCurTimeUsed;
313
314 ++m_Data.miPeriod;
315 m_Data.miPeriod %= m_Data.mcPeriods;
316 }
317 m_Data.mPrevTime = cur;
318 ++m_Data.mcFrames;
319
320 m_Data.mCurTimeUsed = 0;
321 m_Data.mCurCalls = 0;
322 }
323
324 void step(uint64_t Time)
325 {
326 m_Data.mCurTimeUsed += Time;
327 ++m_Data.mCurCalls;
328 }
329
330 uint64_t GetEveragePeriod()
331 {
332 return m_Data.mPeriodSum / m_Data.mcPeriods;
333 }
334
335 double GetFps()
336 {
337 return ((double)1000000000.0) / GetEveragePeriod();
338 }
339
340 double GetCps()
341 {
342 return GetFps() * m_Data.mCallsSum / m_Data.mcPeriods;
343 }
344
345 double GetTimeProcPercent()
346 {
347 return 100.0*m_Data.mTimeUsedSum/m_Data.mPeriodSum;
348 }
349
350 uint64_t GetNumFrames()
351 {
352 return m_Data.mcFrames;
353 }
354private:
355 struct
356 {
357 uint64_t mPeriodSum;
358 uint64_t *mpaPeriods;
359 uint64_t mPrevTime;
360 uint64_t mcFrames;
361 uint32_t mcPeriods;
362 uint32_t miPeriod;
363
364 uint64_t mCallsSum;
365 uint32_t *mpaCalls;
366
367 uint64_t mTimeUsedSum;
368 uint64_t *mpaTimes;
369
370 uint64_t mCurTimeUsed;
371 uint64_t mCurCalls;
372 } m_Data;
373};
374
375#define VBOXDISPPROFILE_FUNCTION_LOGGER_DISABLE_CURRENT() do { \
376 __vboxDispProfileFunctionLogger.disable();\
377 } while (0)
378
379#define VBOXDISPPROFILE_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT() do { \
380 __vboxDispProfileFunctionLogger.logAndDisable();\
381 } while (0)
382
383#ifdef VBOXDISPPROFILE_FUNCTION_LOGGER_GLOBAL_PROFILE
384# define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p, _T, _v) \
385 static VBoxDispProfileEntry * __pVBoxDispProfileEntry = NULL; \
386 if (!__pVBoxDispProfileEntry) { __pVBoxDispProfileEntry = _p.alloc(__FUNCTION__); } \
387 VBoxDispProfileScopeLogger<VBoxDispProfileEntry, _T> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry, _v);
388#else
389# ifndef VBOXDISPPROFILE_FUNCTION_LOGGER_INDEX_GEN
390# error "VBOXDISPPROFILE_FUNCTION_LOGGER_INDEX_GEN should be fedined!"
391# endif
392# define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p, _T, _v) \
393 static uint32_t __u32VBoxDispProfileIndex = VBOXDISPPROFILE_FUNCTION_LOGGER_INDEX_GEN(); \
394 VBoxDispProfileEntry * __pVBoxDispProfileEntry = _p.get(__u32VBoxDispProfileIndex, __FUNCTION__); \
395 VBoxDispProfileScopeLogger<VBoxDispProfileEntry, _T> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry, _v);
396#endif
397
398#define VBOXDISPPROFILE_STATISTIC_LOGGER_DISABLE_CURRENT() do { \
399 __vboxDispProfileStatisticLogger.disable();\
400 } while (0)
401
402#define VBOXDISPPROFILE_STATISTIC_LOGGER_LOG_AND_DISABLE_CURRENT() do { \
403 __vboxDispProfileStatisticLogger.logAndDisable();\
404 } while (0)
405
406
407#define VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(_p, _T, _v) \
408 VBoxDispProfileScopeLogger<VBoxDispProfileFpsCounter, _T> __vboxDispProfileStatisticLogger(_p, _v);
409
410//#define VBOXDISPPROFILE_FUNCTION_PROLOGUE(_p) \
411// VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p)
412
413#endif /* #ifndef ___VBoxDispProfile_h__ */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette