Explorar o código

Revert the SDDisplayLink for watchOS, fix the animated image duration bug

DreamPiggy %!s(int64=3) %!d(string=hai) anos
pai
achega
4cee95d5a2
Modificáronse 1 ficheiros con 11 adicións e 17 borrados
  1. 11 17
      SDWebImage/Private/SDDisplayLink.m

+ 11 - 17
SDWebImage/Private/SDDisplayLink.m

@@ -19,18 +19,6 @@
 static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *inNow, const CVTimeStamp *inOutputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext);
 #endif
 
-#if SD_WATCH
-static CFTimeInterval CACurrentMediaTime(void)
-{
-    mach_timebase_info_data_t timebase;
-    mach_timebase_info(&timebase);
-
-    uint64_t time = mach_absolute_time();
-    double seconds = (double)time * (double)timebase.numer / (double)timebase.denom / 1e9;
-    return seconds;
-}
-#endif
-
 #define kSDDisplayLinkInterval 1.0 / 60
 
 @interface SDDisplayLink ()
@@ -101,14 +89,20 @@ static CFTimeInterval CACurrentMediaTime(void)
     if (periodPerSecond > 0) {
         duration = (double)outputTime.videoRefreshPeriod / periodPerSecond;
     }
-#else
+#elif SD_UIKIT
     // iOS 10+/watchOS use `nextTime`
-    if (@available(iOS 10.0, tvOS 10.0, watchOS 2.0, *)) {
+    if (@available(iOS 10.0, tvOS 10.0, *)) {
         duration = self.nextFireTime - CACurrentMediaTime();
     } else {
         // iOS 9 use `previousTime`
         duration = CACurrentMediaTime() - self.previousFireTime;
     }
+#else
+    if (self.nextFireTime != 0) {
+        // `CFRunLoopTimerGetNextFireDate`: This time could be a date in the past if a run loop has not been able to process the timer since the firing time arrived.
+        // Don't rely on this, always calculate based on elapsed time
+        duration = CFRunLoopTimerGetNextFireDate((__bridge CFRunLoopTimerRef)self.displayLink) - self.nextFireTime;
+    }
 #endif
     // When system sleep, the targetTimestamp will mass up, fallback refresh rate
     if (duration < 0) {
@@ -230,13 +224,13 @@ static CFTimeInterval CACurrentMediaTime(void)
         self.previousFireTime = self.displayLink.timestamp;
     }
 #endif
-#if SD_WATCH
-    self.nextFireTime = CFRunLoopTimerGetNextFireDate((__bridge CFRunLoopTimerRef)self.displayLink);
-#endif
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
     [_target performSelector:_selector withObject:self];
 #pragma clang diagnostic pop
+#if SD_WATCH
+    self.nextFireTime = CFRunLoopTimerGetNextFireDate((__bridge CFRunLoopTimerRef)self.displayLink);
+#endif
 }
 
 @end