Some time ago phjanderson (from Freaktab forum) found a solution to this:
It basically eliminated a blocking condition on a function on rk_fb.c, which also happened to apparently solve the stutter problem. This was called phjanderson's Vsync fix and lots of ROMs have added this patch since.
I then set out to test it on Linux along with my framebuffer fix (see https://github.com/Galland/3188-SRC-AP6210/commit/a3ddf7e46c4426e6cc67e09d7eee2a14baeea1f0 ) just to find that after a random amount of minutes after boot, there appeared a new thread called "fb-vsync" that utilized 100% of one of the 4 cores on the RK3188, regardless of the system being idle or never even opening a video.
To me, this is unacceptable since it forces the CPU to run at higher frequencies all the time, as well as consume lots more of power and a 25% performance penalty hit.
I initially thought it had something to do with Linux' screen usage or even with my framebuffer fix. However it did happen without the framebuffer fix, so I just let it out of my kernels.
However, I recently read on a forum ( http://www.rikomagic.co.uk/forum/viewtopic.php?p=15682&sid=e872d9b5e003da9082af7976a28fa50c#p15682 ) that Android people are seeing also the 25% CPU usage constant (1 core out of 4) due to this thread.
So I heavily suspect this patch is great for fixing the Vsync video stutter problems, but at the cost of losing 25% of the CPU performance, consuming more power all the time (+heat!), and thus reducing the component's life.
If you happen to have flashed a rooted ROM with Vsync fix and have an Android monitor installed (able to track system threads), please write a comment sharing if you've been able to see the thread in action.
I'll try to explain a bit the code related to this problem.
Most of it is located in rk_fb.c where:
1) upon registering fb0 (the main framebuffer) a thread called "fb-vsync" is created.
2) This thread executes the function "rk_fb_wait_for_vsync_thread"
3) This function is an "infinite" loop that emits a "vsync" notification to user-space apps subscribed to it, whenever a Vsync happens, meanwhile it waits idle.
How does it wait for a Vsync?
Through the use of "wait_event_interruptible" with arguments:
- waitqueue: this is the event queue we're hanging on: dev_drv->vsync_info.wait
!ktime_equal(timestamp, dev_drv->vsync_info.timestamp) && dev_drv->vsync_info.active
The 2nd part of the condition (dev_drv->vsync_info.active) should always be met since it is set to 1 just after creating this thread.
What about the 1st part? It compares:
a) variable "timestamp": which is constant!! and set to the value of "dev_drv->vsync_info.timestamp" as it was just before calling "wait_event_interruptible".
b) dev_drv->vsync_info.timestamp as it IS any time the waitqueue is awaken
Naturally this condition is meant to become true (and exit the wait event to send the "vsync" notification) at the next Vsync.
Why? Because "dev_drv->vsync_info.timestamp" is updated by the lcdc interrupt service routine, which at the same time wakes up our "wait_event_interruptible" above!
Then the !ktime_equal compares the "timestamp" variable that holds the PREVIOUSLY set vsync_info.timestamp (before the wait_event is triggered) with the CURRENT, just updated, vsync_info.timestamp.
Hence the condition may indeed become true.
What did phjanderson's fix do? It just made this wait event to always have a true condition, hence the "while" loop is constantly executing (no wait) and notifying a "vsync".
How does it interact with Galland's framebuffer fix? Note that in the lcdc isr, the fb fix excludes the wake_up_... call, so what it does is make the wait event above to never be woken up. Kind of the opposite to phjanderson's.
The union of both fixes is... unfortunate too :) so I just left out phjanderson's fix, since the isr changes are needed for the overall fb fix.