VirtualBox

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

Last change on this file since 77046 was 76563, checked in by vboxsync, 6 years ago

Additions: Use GA_INCLUDED_ and variations_ as header guard prefixes with scm.

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

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