juj / fbcp-ili9341

A blazing fast display driver for SPI-based LCD displays for Raspberry Pi A, B, 2, 3, 4 and Zero
MIT License
1.58k stars 265 forks source link

Display lags a bit after being left mostly static #223

Closed RustyReich closed 2 years ago

RustyReich commented 3 years ago

I have ili9341 installed on my pigrrl 2, which is using a Raspberry pi 3 and the piTFT display. Everything works perfectly apart from odd lag that happens occasionally. I think I've narrowed it down to only happening after the screen has had very little change over the past dozen or so seconds. For example, when playing pokemon red, after exiting a battle, where not much movement happens on the screen, if I immediately start running around, the framerate plummets for a good 2-3 seconds before becoming fine again.

I can reliably reproduce this in other games, and even the Emulation Station menu, by just not moving anything for a bit and then moving a lot.

juj commented 3 years ago

This is certainly due to the heuristic that aims to save battery when there are no updates on the screen. See issue #102.

Comment out line https://github.com/juj/fbcp-ili9341/blob/486a32e7f23b41d49b0e9da4845a86709f6f9c8a/config.h#L147-L149 to remove this logic. That should remove the lag altogether.

juj commented 3 years ago

See also this option

https://github.com/juj/fbcp-ili9341/blob/486a32e7f23b41d49b0e9da4845a86709f6f9c8a/config.h#L225-L228

juj commented 3 years ago

Instead of commenting out SAVE_BATTERY_BY_SLEEPING_WHEN_IDLE, it may actually be better to just remove these two lines:

https://github.com/juj/fbcp-ili9341/blob/7c4a05aabc1d88e22eb126ccb18835ebfbd28853/gpu.cpp#L320-L322

or increase the timeout values there so something like 10x of the current values.

RustyReich commented 3 years ago

Thank you for the quick response. I just got finished trying all three of your solutions. I first commented out:

//if (timeNow - mostRecentFrame > 60000000) { histogramSize = 1; return lastFramePollTime + 100000; } // if it's been more than one minute since last seen update, assume interval of 100ms. 
//if (timeNow - mostRecentFrame > 5000000) return lastFramePollTime + 100000; // if it's been more than 5 seconds since last seen update, assume interval of 100ms. 

And then commented out:

 //#define SAVE_BATTERY_BY_SLEEPING_WHEN_IDLE 

And finally tried setting the percentage to 0 here:

 #define DISPLAY_CONSIDERED_INACTIVE_PERCENTAGE (0.0)

I rebuilt after each modification but none of them seem to have fixed the problem, unfortunately.

zarcade commented 3 years ago

Interested in a solution to this. It doesn't prevent using the device but one of those quirks I would love to get rid of.

juj commented 3 years ago

Hmm.. you can try disabling the other sleep config variables in config.h then, it should be one of those that causes it, maybe the input frame rate detection logic.

RustyReich commented 3 years ago
// Builds a histogram of observed frame intervals and uses that to sync to a known update rate. This aims
// to detect if an application uses a non-60Hz update rate, and synchronizes to that instead.
#define SAVE_BATTERY_BY_PREDICTING_FRAME_ARRIVAL_TIMES

appears to have been the culprit. Reversing all previous modifications, and only commenting out:

//#define SAVE_BATTERY_BY_PREDICTING_FRAME_ARRIVAL_TIMES

appears to have fixed the problem entirely! I will update if I notice it still happening after more playing.