VirtualBox

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

Last change on this file since 64186 was 62522, checked in by vboxsync, 8 years ago

(C) 2016

  • 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 62522 2016-07-22 19:17:25Z vboxsync $ */
2
3/** @file
4 * VBoxVideo Display D3D User mode dll
5 */
6
7/*
8 * Copyright (C) 2011-2016 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
81// VBOXDISPPROFILE_DUMP(("'%s' [0x%p]: \t%d\t%u\t%u\t%u\t%f\t%f", m_pName, pvObj,
82// m_cCalls,
83// (uint32_t)m_cTime, (uint32_t)(m_cTime/1000), (uint32_t)(m_cTime/1000000),
84// (((double)m_cTime)/cTotalEntriesTime),
85// (((double)m_cTime)/cTotalTime)));
86
87 VBOXDISPPROFILE_DUMP(("'%s' [0x%p]: \t%d\t%u\t%f\t%f", m_pName, pvObj,
88 m_cCalls,
89 (uint32_t)(m_cTime/1000000),
90 (((double)m_cTime)/cTotalEntriesTime),
91 (((double)m_cTime)/cTotalTime)));
92
93 }
94private:
95 uint32_t m_cCalls;
96 uint64_t m_cTime;
97 const char * m_pName;
98};
99
100class VBoxDispProfileSet
101{
102public:
103 VBoxDispProfileSet(const char *pName) :
104 m_cEntries(0),
105 m_cIterations(0),
106 m_pName(pName)
107 {
108 m_cTime = VBOXDISPPROFILE_GET_TIME_NANO();
109 }
110
111 VBoxDispProfileSet() :
112 m_cEntries(0),
113 m_cIterations(0),
114 m_pName("global")
115 {
116 m_cTime = VBOXDISPPROFILE_GET_TIME_NANO();
117 }
118
119 VBoxDispProfileEntry * alloc(const char *pName)
120 {
121 if (m_cEntries < RT_ELEMENTS(m_Entries))
122 {
123 VBoxDispProfileEntry * entry = &m_Entries[m_cEntries];
124 ++m_cEntries;
125 *entry = VBoxDispProfileEntry(pName);
126 return entry;
127 }
128 return NULL;
129 }
130
131 VBoxDispProfileEntry * get(uint32_t u32Entry, const char *pName)
132 {
133 if (u32Entry < RT_ELEMENTS(m_Entries))
134 {
135 VBoxDispProfileEntry * entry = &m_Entries[u32Entry];
136 if (entry->getName())
137 return entry;
138 ++m_cEntries;
139 *entry = VBoxDispProfileEntry(pName);
140 return entry;
141 }
142 return NULL;
143 }
144
145 uint32_t reportIteration()
146 {
147 return ++m_cIterations;
148 }
149
150 uint32_t getNumIterations() const
151 {
152 return m_cIterations;
153 }
154
155 uint32_t getNumEntries() const
156 {
157 return m_cEntries;
158 }
159
160#define VBOXDISPPROFILESET_FOREACHENTRY(_op) \
161 for (uint32_t i = 0, e = 0; e < m_cEntries && i < RT_ELEMENTS(m_Entries); ++i) { \
162 if (m_Entries[i].getName()) { \
163 { \
164 _op \
165 } \
166 ++e; \
167 } \
168 } \
169
170 void resetEntries()
171 {
172 VBOXDISPPROFILESET_FOREACHENTRY( m_Entries[i].reset(); );
173 m_cTime = VBOXDISPPROFILE_GET_TIME_NANO();
174 }
175
176 void reset()
177 {
178 m_cEntries = 0;
179 m_cTime = VBOXDISPPROFILE_GET_TIME_NANO();
180 }
181
182 void dump(void *pvObj)
183 {
184 uint64_t cEntriesTime = 0;
185 VBOXDISPPROFILESET_FOREACHENTRY( cEntriesTime += m_Entries[i].getTime(); );
186
187 VBOXDISPPROFILE_DUMP((">>>> '%s' [0x%p]: Start of VBox Disp Dump: num entries(%d), et(%u), tt(%u) >>>>>", m_pName, pvObj, m_cEntries,
188 (uint32_t)(cEntriesTime / 1000000), (uint32_t)(m_cTime / 1000000)));
189 VBOXDISPPROFILE_DUMP(("Name\tCalls\tNanos\tMicros\tMillis\tentries_quota\ttotal_quota"));
190 VBOXDISPPROFILESET_FOREACHENTRY(
191 if (m_Entries[i].getNumCalls())
192 m_Entries[i].dump(pvObj, cEntriesTime, m_cTime); );
193 VBOXDISPPROFILE_DUMP(("<<<< '%s' [0x%p]: End of VBox Disp Dump <<<<<", m_pName, pvObj));
194 }
195
196private:
197 VBoxDispProfileEntry m_Entries[VBOXDISPPROFILE_MAX_SETSIZE];
198 uint32_t m_cEntries;
199 uint32_t m_cIterations;
200 uint64_t m_cTime;
201 const char * m_pName;
202};
203
204class VBoxDispProfileDummyPostProcess
205{
206public:
207 void postProcess(){}
208};
209
210template<typename T, typename P> class VBoxDispProfileScopeLogger
211{
212public:
213 VBoxDispProfileScopeLogger(T *pEntry, P PostProcess) :
214 m_pEntry(pEntry),
215 m_PostProcess(PostProcess),
216 m_bDisable(FALSE)
217 {
218 m_cTime = VBOXDISPPROFILE_GET_TIME_NANO();
219 }
220
221 ~VBoxDispProfileScopeLogger()
222 {
223 if (!m_bDisable)
224 {
225 logStep();
226 }
227 }
228
229 void disable()
230 {
231 m_bDisable = TRUE;
232 }
233
234 void logAndDisable()
235 {
236 logStep();
237 disable();
238 }
239
240private:
241 void logStep()
242 {
243 m_PostProcess.postProcess();
244 uint64_t cNewTime = VBOXDISPPROFILE_GET_TIME_NANO();
245 m_pEntry->step(cNewTime - m_cTime);
246 }
247 T *m_pEntry;
248 P m_PostProcess;
249 uint64_t m_cTime;
250 BOOL m_bDisable;
251};
252
253
254class VBoxDispProfileFpsCounter
255{
256public:
257 VBoxDispProfileFpsCounter(uint32_t cPeriods)
258 {
259 init(cPeriods);
260 }
261
262 VBoxDispProfileFpsCounter()
263 {
264 memset(&m_Data, 0, sizeof (m_Data));
265 }
266
267 ~VBoxDispProfileFpsCounter()
268 {
269 term();
270 }
271
272 void term()
273 {
274 if (m_Data.mpaPeriods)
275 {
276 RTMemFree(m_Data.mpaPeriods);
277 m_Data.mpaPeriods = NULL;
278 }
279 if (m_Data.mpaCalls)
280 {
281 RTMemFree(m_Data.mpaCalls);
282 m_Data.mpaCalls = NULL;
283 }
284 if (m_Data.mpaTimes)
285 {
286 RTMemFree(m_Data.mpaTimes);
287 m_Data.mpaTimes = NULL;
288 }
289 m_Data.mcPeriods = 0;
290 }
291
292 /* to be called in case fps counter was created with default constructor */
293 void init(uint32_t cPeriods)
294 {
295 memset(&m_Data, 0, sizeof (m_Data));
296 m_Data.mcPeriods = cPeriods;
297 if (cPeriods)
298 {
299 m_Data.mpaPeriods = (uint64_t *)RTMemAllocZ(sizeof (m_Data.mpaPeriods[0]) * cPeriods);
300 m_Data.mpaCalls = (uint32_t *)RTMemAllocZ(sizeof (m_Data.mpaCalls[0]) * cPeriods);
301 m_Data.mpaTimes = (uint64_t *)RTMemAllocZ(sizeof (m_Data.mpaTimes[0]) * cPeriods);
302 }
303 }
304
305 void ReportFrame()
306 {
307 uint64_t cur = VBOXDISPPROFILE_GET_TIME_NANO();
308
309 if(m_Data.mPrevTime)
310 {
311 uint64_t curPeriod = cur - m_Data.mPrevTime;
312
313 m_Data.mPeriodSum += curPeriod - m_Data.mpaPeriods[m_Data.miPeriod];
314 m_Data.mpaPeriods[m_Data.miPeriod] = curPeriod;
315
316 m_Data.mCallsSum += m_Data.mCurCalls - m_Data.mpaCalls[m_Data.miPeriod];
317 m_Data.mpaCalls[m_Data.miPeriod] = m_Data.mCurCalls;
318
319 m_Data.mTimeUsedSum += m_Data.mCurTimeUsed - m_Data.mpaTimes[m_Data.miPeriod];
320 m_Data.mpaTimes[m_Data.miPeriod] = m_Data.mCurTimeUsed;
321
322 ++m_Data.miPeriod;
323 m_Data.miPeriod %= m_Data.mcPeriods;
324 }
325 m_Data.mPrevTime = cur;
326 ++m_Data.mcFrames;
327
328 m_Data.mCurTimeUsed = 0;
329 m_Data.mCurCalls = 0;
330 }
331
332 void step(uint64_t Time)
333 {
334 m_Data.mCurTimeUsed += Time;
335 ++m_Data.mCurCalls;
336 }
337
338 uint64_t GetEveragePeriod()
339 {
340 return m_Data.mPeriodSum / m_Data.mcPeriods;
341 }
342
343 double GetFps()
344 {
345 return ((double)1000000000.0) / GetEveragePeriod();
346 }
347
348 double GetCps()
349 {
350 return GetFps() * m_Data.mCallsSum / m_Data.mcPeriods;
351 }
352
353 double GetTimeProcPercent()
354 {
355 return 100.0*m_Data.mTimeUsedSum/m_Data.mPeriodSum;
356 }
357
358 uint64_t GetNumFrames()
359 {
360 return m_Data.mcFrames;
361 }
362private:
363 struct
364 {
365 uint64_t mPeriodSum;
366 uint64_t *mpaPeriods;
367 uint64_t mPrevTime;
368 uint64_t mcFrames;
369 uint32_t mcPeriods;
370 uint32_t miPeriod;
371
372 uint64_t mCallsSum;
373 uint32_t *mpaCalls;
374
375 uint64_t mTimeUsedSum;
376 uint64_t *mpaTimes;
377
378 uint64_t mCurTimeUsed;
379 uint64_t mCurCalls;
380 } m_Data;
381};
382
383#define VBOXDISPPROFILE_FUNCTION_LOGGER_DISABLE_CURRENT() do { \
384 __vboxDispProfileFunctionLogger.disable();\
385 } while (0)
386
387#define VBOXDISPPROFILE_FUNCTION_LOGGER_LOG_AND_DISABLE_CURRENT() do { \
388 __vboxDispProfileFunctionLogger.logAndDisable();\
389 } while (0)
390
391#ifdef VBOXDISPPROFILE_FUNCTION_LOGGER_GLOBAL_PROFILE
392# define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p, _T, _v) \
393 static VBoxDispProfileEntry * __pVBoxDispProfileEntry = NULL; \
394 if (!__pVBoxDispProfileEntry) { __pVBoxDispProfileEntry = _p.alloc(__FUNCTION__); } \
395 VBoxDispProfileScopeLogger<VBoxDispProfileEntry, _T> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry, _v);
396#else
397# ifndef VBOXDISPPROFILE_FUNCTION_LOGGER_INDEX_GEN
398# error "VBOXDISPPROFILE_FUNCTION_LOGGER_INDEX_GEN should be fedined!"
399# endif
400# define VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p, _T, _v) \
401 static uint32_t __u32VBoxDispProfileIndex = VBOXDISPPROFILE_FUNCTION_LOGGER_INDEX_GEN(); \
402 VBoxDispProfileEntry * __pVBoxDispProfileEntry = _p.get(__u32VBoxDispProfileIndex, __FUNCTION__); \
403 VBoxDispProfileScopeLogger<VBoxDispProfileEntry, _T> __vboxDispProfileFunctionLogger(__pVBoxDispProfileEntry, _v);
404#endif
405
406#define VBOXDISPPROFILE_STATISTIC_LOGGER_DISABLE_CURRENT() do { \
407 __vboxDispProfileStatisticLogger.disable();\
408 } while (0)
409
410#define VBOXDISPPROFILE_STATISTIC_LOGGER_LOG_AND_DISABLE_CURRENT() do { \
411 __vboxDispProfileStatisticLogger.logAndDisable();\
412 } while (0)
413
414
415#define VBOXDISPPROFILE_STATISTIC_LOGGER_DEFINE(_p, _T, _v) \
416 VBoxDispProfileScopeLogger<VBoxDispProfileFpsCounter, _T> __vboxDispProfileStatisticLogger(_p, _v);
417
418//#define VBOXDISPPROFILE_FUNCTION_PROLOGUE(_p) \
419// VBOXDISPPROFILE_FUNCTION_LOGGER_DEFINE(_p)
420
421#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