VirtualBox

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

Last change on this file since 69350 was 69350, checked in by vboxsync, 7 years ago

Additions/WINNT/Video: File header cleanups - first @file sentence should give brief desccription and stand by its lonely self.

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