@@ -189,6 +189,9 @@ namespace p2c::pmon
189189 else if (el.metricId == PM_METRIC_CPU_FRAME_TIME) {
190190 frametimeElementIdx_ = int (queryElements_.size () - 1 );
191191 }
192+ else if (el.metricId == PM_METRIC_ANIMATION_ERROR) {
193+ animationErrorElementIdx_ = int (queryElements_.size () - 1 );
194+ }
192195 }
193196 // if any specially-required fields are missing, add to query (but not to annotations)
194197 if (totalTimeElementIdx_ < 0 ) {
@@ -209,6 +212,16 @@ namespace p2c::pmon
209212 });
210213 frametimeElementIdx_ = int (queryElements_.size () - 1 );
211214 }
215+ if (animationErrorElementIdx_ < 0 ) {
216+ queryElements_.push_back (PM_QUERY_ELEMENT{
217+ .metric = PM_METRIC_ANIMATION_ERROR,
218+ .stat = PM_STAT_NONE,
219+ .deviceId = 0 ,
220+ .arrayIndex = 0 ,
221+ });
222+ animationErrorElementIdx_ = int (queryElements_.size () - 1 );
223+ }
224+
212225 // register query
213226 query_ = session.RegisterFrameQuery (queryElements_);
214227 }
@@ -228,6 +241,10 @@ namespace p2c::pmon
228241 {
229242 return reinterpret_cast <const double &>(pBlob[queryElements_[frametimeElementIdx_].dataOffset ]);
230243 }
244+ double ExtractAnimationErrorFromBlob (const uint8_t * pBlob) const
245+ {
246+ return reinterpret_cast <const double &>(pBlob[queryElements_[animationErrorElementIdx_].dataOffset ]);
247+ }
231248 void WriteFrame (uint32_t pid, const std::string& procName, std::ostream& out, const uint8_t * pBlob)
232249 {
233250 // TODO: use metrics from procname and pid
@@ -260,6 +277,7 @@ namespace p2c::pmon
260277 // query elements referenced used for summary stats gathering
261278 int totalTimeElementIdx_ = -1 ;
262279 int frametimeElementIdx_ = -1 ;
280+ int animationErrorElementIdx_ = -1 ;
263281 };
264282
265283 RawFrameDataWriter::RawFrameDataWriter (std::wstring path, const pmapi::ProcessTracker& procTrackerIn, std::wstring processName, uint32_t activeDeviceId,
@@ -269,6 +287,7 @@ namespace p2c::pmon
269287 procName{ ToNarrow (processName) },
270288 frameStatsPath{ std::move (frameStatsPathIn) },
271289 pStatsTracker{ frameStatsPath ? std::make_unique<StatisticsTracker>() : nullptr },
290+ pAnimationErrorTracker{ frameStatsPath ? std::make_unique<StatisticsTracker>() : nullptr },
272291 file{ path }
273292 {
274293 auto queryElements = GetRawFrameDataMetricList (activeDeviceId);
@@ -298,6 +317,12 @@ namespace p2c::pmon
298317 // tracking frame times
299318 pStatsTracker->Push (pQueryElementContainer->ExtractFrameTimeFromBlob (pBlob));
300319 }
320+ if (pAnimationErrorTracker) {
321+ auto animationError = (pQueryElementContainer->ExtractAnimationErrorFromBlob (pBlob));
322+ if (std::isnan (animationError) == false ) {
323+ pAnimationErrorTracker->Push (std::abs (animationError));
324+ }
325+ }
301326 pQueryElementContainer->WriteFrame (procTracker.GetPid (), procName, file, pBlob);
302327 }
303328 } while (blobs.AllBlobsPopulated ()); // if container filled, means more might be left
@@ -312,6 +337,7 @@ namespace p2c::pmon
312337 void RawFrameDataWriter::WriteStats_ ()
313338 {
314339 auto & stats = *pStatsTracker;
340+ auto & aeStats = *pAnimationErrorTracker;
315341
316342 std::ofstream statsFile{ *frameStatsPath, std::ios::trunc };
317343
@@ -323,7 +349,9 @@ namespace p2c::pmon
323349 " Minimum FPS,"
324350 " 99th Percentile FPS,"
325351 " 95th Percentile FPS,"
326- " Maximum FPS\n " ;
352+ " Maximum FPS,"
353+ " AnimationErrorPerSecond,"
354+ " AnimationErrorPerFrame\n " ;
327355
328356 // lambda to make sure we don't divide by zero
329357 // caps max fps output to 1,000,000 fps
@@ -340,7 +368,16 @@ namespace p2c::pmon
340368 SafeInvert (stats.GetMax ()) << " ," <<
341369 SafeInvert (stats.GetPercentile (.99 )) << " ," <<
342370 SafeInvert (stats.GetPercentile (.95 )) << " ," <<
343- SafeInvert (stats.GetMin ()) << " \n " ;
371+ SafeInvert (stats.GetMin ()) << " ," ;
372+ if (aeStats.GetCount () > 0 && GetDuration_ () != 0 .) {
373+ const double aeSumSecs = aeStats.GetSum () / 1000 .;
374+ statsFile << (aeSumSecs / GetDuration_ ()) << " ," <<
375+ (aeStats.GetSum () / aeStats.GetCount ()) << " \n " ;
376+ }
377+ else {
378+ statsFile << 0 . << 0 . << " \n " ;
379+ }
380+
344381 }
345382 else {
346383 // write null data
@@ -351,6 +388,7 @@ namespace p2c::pmon
351388 0 . << " ," <<
352389 0 . << " ," <<
353390 0 . << " ," <<
391+ 0 . << " ," <<
354392 0 . << " \n " ;
355393 }
356394 }
0 commit comments