alexiscreuzot / SwiftyGif

High performance GIF engine
MIT License
1.99k stars 210 forks source link

Issues with M1 ipad Pro with playback speed #170

Closed frank137 closed 1 year ago

frank137 commented 2 years ago

Hi,

I am having gif play back issues on the ipad pro with the M1 chip only. The weirdest thing is that it was working before and stopped working after updating to version 5.4.3. I am pretty sure this has to do with the pro motion display.

The gif is played much faster than on other devices.

To be precise, in all my devices the gifs are run at 20fps (which is what I need), on the ipad pro it is much faster. Is there a way I can force the playback speed to be 20fps?

This is how it's implemented:

func setupAnimation(gifName: String) {
    do {
        let gif = try UIImage(gifName: gifName + ".gif", levelOfIntegrity: .highestNoFrameSkipping)
        imageView.setGifImage(gif, loopCount: 1)
    } catch {
        print(error)
    }
}

This is what I tried without success:

  1. keep level of integrity to default and .highestNoFrameSkipping
frank137 commented 2 years ago

Reverting to version 5.4.0 fixed my specific issue. So I will keep using 5.4.0 for now.

cryptoAlgorithm commented 2 years ago

macOS app running on macOS 13, M1 Pro. Same issue, GIFs rendering much faster than they should. I'll see if reverting fixes it.

cryptoAlgorithm commented 2 years ago

No luck, after reverting to 5.4.0, cleaning build folder and rebuilding, the issue still persists. For more context, this is a SwiftUI app, but using a very similar snippet of code to instantiate SwiftyGIF.

cryptoAlgorithm commented 2 years ago

Ok, I fixed this in my fork. It was quite a simple issue, the refresh rates are hardcoded and assumed a max of 60FPS, but the 2021 MBPs and iPad Pros have a 120Hz screen.

donmai-me commented 1 year ago

This might be a regression caused by #165 when fixing #164. I had a quick look and can send a quick fix which solved the problem on my M1 iPad pro. But I found another problem at line 225 in UIImage+SwiftyGif

let maximumFramesPerSecond = UIScreen.main.maximumFramesPerSecond

This is problematic since this is 120 even when a high refresh rate device is in low power mode or when the system decides to throttle the framerate of the display. CADisplayLink and CVDisplayLink should be used to get the current refresh rate, however, this requires some refactoring as the code seems to assume the device is running at a fixed frame rate. More info here https://developer.apple.com/videos/play/wwdc2021/10147/

I'll send a quick fix to address OP's problem but this is a band aid solution to the problem. If there's interest in using display links, I can help. Cheers!