app: cap Coil's parallel fetch and decode work on TV hardware
A sched trace on the TV (release build) caught the real "2fps": not a slow frame, but a starved one. During navigation the render pipeline (app RenderThread, SurfaceFlinger/RenderEngine, the mali driver worker, the Dolby audio service) saturated all four cores together with Coil's image work — a burst of parallel ~30 ms bitmap decodes split across the whole IO pool descheduled the main thread hundreds of times and froze navigation for over a second. The image loader now caps the request dispatcher at 2 parallel ops and the decode/transformation pools at 2/1: images still fill in steadily while scrolling but can no longer eat every core at once. Combined with the release build on the TV (debug's JIT bursts produced 900 ms+ frames by themselves), the same navigation settles at p90 ~13 ms per frame with a worst frame of ~180 ms when a new row composes.
This commit is contained in:
parent
22d87d2398
commit
9b96d03384
1 changed files with 14 additions and 2 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
package net.jeena.jtubetv
|
package net.jeena.jtubetv
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import coil.ImageLoaderFactory
|
import coil.ImageLoaderFactory
|
||||||
import net.jeena.jtubetv.data.PeerTubeRepository
|
import net.jeena.jtubetv.data.PeerTubeRepository
|
||||||
|
|
@ -33,9 +34,20 @@ class JTubeApp : Application(), coil.ImageLoaderFactory {
|
||||||
* TVs are slow compositors: decode thumbnails as RGB_565 at capped size so
|
* TVs are slow compositors: decode thumbnails as RGB_565 at capped size so
|
||||||
* scrolling rows keep a smooth frame rate (user: "the animation has very low fps").
|
* scrolling rows keep a smooth frame rate (user: "the animation has very low fps").
|
||||||
*/
|
*/
|
||||||
override fun newImageLoader(): ImageLoader =
|
override fun newImageLoader(): ImageLoader {
|
||||||
ImageLoader.Builder(this)
|
// A sched trace on the TV (release build) showed the main thread being
|
||||||
|
// descheduled hundreds of times during navigation while the render
|
||||||
|
// pipeline (Mali/RenderThread/SF/Dolby) saturated all 4 cores together
|
||||||
|
// with Coil's image work — a burst of parallel 30 ms bitmap decodes
|
||||||
|
// starved the main thread for over a second (the felt "2fps"). Capping
|
||||||
|
// Coil's parallel work: images still fill in steadily while scrolling,
|
||||||
|
// but the decode/fetch pool can no longer eat every core at once.
|
||||||
|
return ImageLoader.Builder(this)
|
||||||
.bitmapConfig(android.graphics.Bitmap.Config.RGB_565)
|
.bitmapConfig(android.graphics.Bitmap.Config.RGB_565)
|
||||||
.crossfade(false)
|
.crossfade(false)
|
||||||
|
.dispatcher(Dispatchers.IO.limitedParallelism(2))
|
||||||
|
.decoderDispatcher(Dispatchers.Default.limitedParallelism(2))
|
||||||
|
.transformationDispatcher(Dispatchers.Default.limitedParallelism(1))
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue