1
1
import 'dart:async' ;
2
- import 'dart:ui' ;
2
+ import 'dart:ui' show TimingsCallback, FrameTiming, FramePhase ;
3
3
4
4
import 'package:flutter/widgets.dart' ;
5
5
import 'package:instabug_flutter/src/models/instabug_frame_data.dart' ;
@@ -18,14 +18,14 @@ enum UiTraceType {
18
18
@internal
19
19
class InstabugScreenRenderManager {
20
20
WidgetsBinding ? _widgetsBinding;
21
- late int _buildTime ;
22
- late int _rasterTime ;
23
- late int _totalTime ;
21
+ late int _buildTimeMs ;
22
+ late int _rasterTimeMs ;
23
+ late int _totalTimeMs ;
24
24
late TimingsCallback _timingsCallback;
25
25
late InstabugScreenRenderData _screenRenderForAutoUiTrace;
26
26
late InstabugScreenRenderData _screenRenderForCustomUiTrace;
27
- int _slowFramesTotalDurationMs = 0 ;
28
- int _frozenFramesTotalDurationMs = 0 ;
27
+ int _slowFramesTotalDurationMicro = 0 ;
28
+ int _frozenFramesTotalDurationMicro = 0 ;
29
29
int ? _epochOffset;
30
30
bool _isTimingsListenerAttached = false ;
31
31
bool screenRenderEnabled = false ;
@@ -42,7 +42,7 @@ class InstabugScreenRenderManager {
42
42
/// Default frozen frame threshold in milliseconds (700ms)
43
43
final _frozenFrameThresholdMs = 700 ;
44
44
45
- final _microsecondsPerMillisecond = 1000 ;
45
+ // final _microsecondsPerMillisecond = 1000;
46
46
47
47
InstabugScreenRenderManager ._();
48
48
@@ -75,46 +75,45 @@ class InstabugScreenRenderManager {
75
75
}
76
76
}
77
77
78
- /// analyze frame data in order to detect slow/ frozen frame .
78
+ /// Analyze frame data to detect slow or frozen frames efficiently .
79
79
@visibleForTesting
80
80
void analyzeFrameTiming (FrameTiming frameTiming) {
81
- _buildTime = frameTiming.buildDuration.inMilliseconds;
82
- _rasterTime = frameTiming.rasterDuration.inMilliseconds;
83
- _totalTime = frameTiming.totalSpan.inMilliseconds;
84
-
85
- if (_isUiFrozen) {
86
- _frozenFramesTotalDurationMs += _buildTime;
87
- } else if (_isRasterFrozen) {
88
- _frozenFramesTotalDurationMs += _rasterTime;
89
- } else if (_isTotalTimeLarge) {
90
- _frozenFramesTotalDurationMs += _totalTime;
91
- }
92
- if (_isUiSlow) {
93
- _slowFramesTotalDurationMs += _buildTime;
94
- } else if (_isRasterSlow) {
95
- _slowFramesTotalDurationMs += _rasterTime;
96
- }
81
+ _buildTimeMs = frameTiming.buildDuration.inMilliseconds;
82
+ _rasterTimeMs = frameTiming.rasterDuration.inMilliseconds;
83
+ _totalTimeMs = frameTiming.totalSpan.inMilliseconds;
97
84
98
- if (_isUiDelayed) {
85
+ if (_isTotalTimeLarge) {
86
+ final micros = frameTiming.totalSpan.inMicroseconds;
87
+ _frozenFramesTotalDurationMicro += micros;
99
88
_onDelayedFrameDetected (
100
89
_getMicrosecondsSinceEpoch (
101
- frameTiming.timestampInMicroseconds (FramePhase .buildStart ),
90
+ frameTiming.timestampInMicroseconds (FramePhase .vsyncStart ),
102
91
),
103
- _buildTime ,
92
+ micros ,
104
93
);
105
- } else if (_isRasterDelayed) {
94
+ return ;
95
+ }
96
+
97
+ if (_isUiSlow) {
98
+ final micros = frameTiming.buildDuration.inMicroseconds;
99
+ _slowFramesTotalDurationMicro += micros;
106
100
_onDelayedFrameDetected (
107
101
_getMicrosecondsSinceEpoch (
108
- frameTiming.timestampInMicroseconds (FramePhase .rasterStart ),
102
+ frameTiming.timestampInMicroseconds (FramePhase .buildStart ),
109
103
),
110
- _rasterTime ,
104
+ micros ,
111
105
);
112
- } else if (_isTotalTimeLarge) {
106
+ return ;
107
+ }
108
+
109
+ if (_isRasterSlow) {
110
+ final micros = frameTiming.rasterDuration.inMicroseconds;
111
+ _slowFramesTotalDurationMicro += micros;
113
112
_onDelayedFrameDetected (
114
113
_getMicrosecondsSinceEpoch (
115
- frameTiming.timestampInMicroseconds (FramePhase .vsyncStart ),
114
+ frameTiming.timestampInMicroseconds (FramePhase .rasterStart ),
116
115
),
117
- _totalTime ,
116
+ micros ,
118
117
);
119
118
}
120
119
}
@@ -215,23 +214,15 @@ class InstabugScreenRenderManager {
215
214
216
215
/// --------------------------- private methods ---------------------
217
216
218
- bool get _isUiDelayed => _isUiSlow || _isUiFrozen;
219
-
220
- bool get _isRasterDelayed => _isRasterSlow || _isRasterFrozen;
221
-
222
217
bool get _isUiSlow =>
223
- _buildTime > _slowFrameThresholdMs &&
224
- _buildTime < _frozenFrameThresholdMs;
218
+ _buildTimeMs > _slowFrameThresholdMs &&
219
+ _buildTimeMs < _frozenFrameThresholdMs;
225
220
226
221
bool get _isRasterSlow =>
227
- _rasterTime > _slowFrameThresholdMs &&
228
- _rasterTime < _frozenFrameThresholdMs;
229
-
230
- bool get _isTotalTimeLarge => _totalTime >= _frozenFrameThresholdMs;
231
-
232
- bool get _isUiFrozen => _buildTime >= _frozenFrameThresholdMs;
222
+ _rasterTimeMs > _slowFrameThresholdMs &&
223
+ _rasterTimeMs < _frozenFrameThresholdMs;
233
224
234
- bool get _isRasterFrozen => _rasterTime >= _frozenFrameThresholdMs;
225
+ bool get _isTotalTimeLarge => _totalTimeMs >= _frozenFrameThresholdMs;
235
226
236
227
/// Calculate the target time for the frame to be drawn in milliseconds based on the device refresh rate.
237
228
double _targetMsPerFrame (double displayRefreshRate) =>
@@ -302,18 +293,17 @@ class InstabugScreenRenderManager {
302
293
303
294
/// Reset the memory cashed data
304
295
void _resetCachedFrameData () {
305
- _slowFramesTotalDurationMs = 0 ;
306
- _frozenFramesTotalDurationMs = 0 ;
296
+ _slowFramesTotalDurationMicro = 0 ;
297
+ _frozenFramesTotalDurationMicro = 0 ;
307
298
_delayedFrames.clear ();
308
299
}
309
300
310
301
/// Save Slow/Frozen Frames data
311
- void _onDelayedFrameDetected (int startTime, int durationInMilliseconds ) {
302
+ void _onDelayedFrameDetected (int startTime, int durationInMicroseconds ) {
312
303
_delayedFrames.add (
313
304
InstabugFrameData (
314
305
startTime,
315
- durationInMilliseconds *
316
- _microsecondsPerMillisecond, // Convert duration from milliseconds to microSeconds
306
+ durationInMicroseconds,
317
307
),
318
308
);
319
309
}
@@ -342,8 +332,8 @@ class InstabugScreenRenderManager {
342
332
try {
343
333
// Save the end time for the running ui trace, it's only needed in Android SDK.
344
334
screenRenderData.saveEndTime ();
345
-
346
335
await APM .endScreenRenderForAutoUiTrace (screenRenderData);
336
+
347
337
return true ;
348
338
} catch (error, stackTrace) {
349
339
_logExceptionErrorAndStackTrace (error, stackTrace);
@@ -370,9 +360,9 @@ class InstabugScreenRenderManager {
370
360
/// or synced with the native side.
371
361
void _updateCustomUiData () {
372
362
_screenRenderForCustomUiTrace.slowFramesTotalDurationMicro +=
373
- _slowFramesTotalDurationMs * _microsecondsPerMillisecond ;
363
+ _slowFramesTotalDurationMicro ;
374
364
_screenRenderForCustomUiTrace.frozenFramesTotalDurationMicro +=
375
- _frozenFramesTotalDurationMs * _microsecondsPerMillisecond ;
365
+ _frozenFramesTotalDurationMicro ;
376
366
_screenRenderForCustomUiTrace.frameData.addAll (_delayedFrames);
377
367
}
378
368
@@ -385,9 +375,9 @@ class InstabugScreenRenderManager {
385
375
/// or synced with the native side.
386
376
void _updateAutoUiData () {
387
377
_screenRenderForAutoUiTrace.slowFramesTotalDurationMicro +=
388
- _slowFramesTotalDurationMs * _microsecondsPerMillisecond ;
378
+ _slowFramesTotalDurationMicro ;
389
379
_screenRenderForAutoUiTrace.frozenFramesTotalDurationMicro +=
390
- _frozenFramesTotalDurationMs * _microsecondsPerMillisecond ;
380
+ _frozenFramesTotalDurationMicro ;
391
381
_screenRenderForAutoUiTrace.frameData.addAll (_delayedFrames);
392
382
}
393
383
@@ -426,9 +416,7 @@ class InstabugScreenRenderManager {
426
416
@visibleForTesting
427
417
void setFrameData (InstabugScreenRenderData data) {
428
418
_delayedFrames.addAll (data.frameData);
429
- _frozenFramesTotalDurationMs =
430
- data.frozenFramesTotalDurationMicro ~ / _microsecondsPerMillisecond;
431
- _slowFramesTotalDurationMs =
432
- data.slowFramesTotalDurationMicro ~ / _microsecondsPerMillisecond;
419
+ _frozenFramesTotalDurationMicro = data.frozenFramesTotalDurationMicro;
420
+ _slowFramesTotalDurationMicro = data.slowFramesTotalDurationMicro;
433
421
}
434
422
}
0 commit comments