Hi, i want to display a small FPS counter when a d...
# compose-desktop
s
Hi, i want to display a small FPS counter when a debugging option is enabled. This is what i did to achieve that. Could somebody review and check if this is ok?
Copy code
// Data class holding the total count
val renderFrame = RenderFrame(0)

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun FrameRate() {
    var frameRate by remember { mutableStateOf(0L) }

    LaunchedEffect(Unit) {
        withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
            var prevCount = renderFrame.count
            while (isActive) {
                val count = renderFrame.count
                delay(1000)
                frameRate = count - prevCount
                prevCount = count
       
            }
        }
    }

    LaunchedEffect(Unit) {
        while (isActive) {
            withFrameNanos {
                renderFrame.inc()
            }
        }
    }
}
 Text("Frame rate: $frameRate fps")
}
i
Looks OK, this should show FPS with +- 2 precision. To be more precise we probably shouldn't use delay(1000), on Windows the actual delay can be 1015 ms. We can write something like this:
Copy code
@Composable
fun FrameRate() {
    var frameRate by remember { mutableStateOf(0) }

    LaunchedEffect(Unit) {
        var frameCount = 0
        var prevTime = withFrameNanos { it }

        while (isActive) {
            withFrameNanos {
                frameCount++

                val seconds = (it - prevTime) / 1E9 // 1E9 nanoseconds is 1 second
                if (seconds >= 1) {
                    frameRate = (frameCount / seconds).toInt()
                    prevTime = it
                    frameCount = 0
                }
            }
        }
    }

    Text("Frame rate: $frameRate fps")
}
P.S.1. This should work only in 0.3.0-build146, before this version withFrameNanos isn't synchronized with the actual window frames. P.S.2. there is a built-in FPS counter for desktop, you can enable it with system properties:
Copy code
skiko.fps.enabled=true
skiko.fps.count=200 // show fps every 200 frames
You can set them with
System.setProperty(name, value)
or with gradle:
Copy code
compose.desktop {
    application {
        jvmArgs("-Dskiko.fps.enabled=true", "-Dskiko.fps.count=200")
P.S.3. currently the FPS can't be more than the display refresh rate because of vsync. in the future we will add the ability to disable vsync:
skiko.vsync.enabled=false
🙏 2
👍 1
r
note that fps isn't a very good performance tool. You should look at the frame time of each frame and also make sure frames are scheduled at the right time
s
@Igor Demin @romainguy thanks v much for the feedback!