Fragment shader optimizations
- Dominant language
- Kotlin
- Stars
- 3k
- Forks
- 148
- Avg merge
- 13h 44m
- Merged PRs (30d)
- 1
Description
Device: Tab M10 FHD Plus (TB-X606F)
OS: Android 10
KorGE: 2.4.8
Hi,
I know this device is not the best, but the frame rate slows down very early in my opinion.
I have created a test project that shows the frame rate and in which you can easily add and remove views.
On this device, the frame rate starts to drop below 60fps from 19 views. With 40 views it is only 25 fps.It doesn't matter whether images or solidRects are rendered (roundRects with only stroking increases the frame rate a bit).
The size of the stage also makes no difference if the views on the device have the same real size.
Only scaling down the views improves the frame rate
With a very simple, pure OpenGL test, the device manages to draw the "korge.png" about 700 times before the frame rate decreases, or 1500 times at a frame rate of 25fps. (Connect the texture once and then draw each frame _n_ times)
Why is it that the difference is so big, or am I doing something wrong in general?
For comparison:
Samsung Galaxy S9 Android 10
-> 45 Entites @ 60fps and 105 Entities @ 25fps (not great either)
Apple iPad (6th generation) iOS 15.1
-> 250 Entities @ 60fps and 550 Entities @ 25 fps
Here is my test project.
Klicking in the left half of the stage switches the viewtype and on the right half increases (lower half) or decreases (upper half) the number of views
``` kotlin
val div = 1 // set to 2 or 4, to make the stage smaller, but keep the real size of the views on the device the same.
val stageWidth = 1920 / div
val stageHeight = 1080 / div
suspend fun main() = Korge("Test", stageWidth, stageHeight) {
val bmp = resourcesVfs["korge.png"].readBitmap()
val entities = mutableListOf()
val fpsText = text(entities.size.toString(), 40.0)
.xy(10, stageHeight - 50)
var testNo = 0
fun createEntity(): View {
var wh = 512 / div
var scale = 1.0
val entity = when(testNo) {
1 -> solidRect(wh, wh, RGBA(Random.nextInt(256), Random.nextInt(256), Random.nextInt(256)))
2 -> roundRect(wh, wh, 50 / div, 50 / div, Colors.TRANSPARENT_BLACK, RGBA(Random.nextInt(256), Random.nextInt(256), Random.nextInt(256)), 5.0)
3 -> {
wh /= 2
solidRect(wh, wh, RGBA(Random.nextInt(256), Random.nextInt(256), Random.nextInt(256)))
}
else -> {
scale /= div
image(bmp)
}
}
entity.position((stageWidth - wh) / 2, (stageHeight - wh) / 2)
entity.scale = scale
entity.draggable { }
return entity
}
fun inc(times: Int = 5) {
if (times < 0) {
repeat(times * -1) {
entities.removeFirstOrNull()?.removeFromParent()
}
}
repeat(times) {
entities.add(createEntity())
}
}
fun switch() {
testNo = (testNo + 1) % 4
val cnt = entities.size
while (entities.isNotEmpty()) {
entities.removeFirst().removeFromParent()
}
repeat(cnt) {
entities.add(createEntity())
}
}
inc(1)
var frames = 0
var fps = "0"
var sec = 0L
var down = false
addUpdater {
val t = PerformanceCounter.milliseconds.toLong()
val cur = t / 1000
if (sec != cur) {
fps = frames.toString()
fpsText.text = "FPS: $fps at ${entities.size} entities"
val exit = sec == 0L
sec = cur
frames = 0
if (exit) {
return@addUpdater
}
}
frames++
mouse {
val p = globalToLocal(input.mouse)
if (input.mouseButtons != 0) {
down = true
if (p.x > stageWidth / 2) {
val times = (p.y - stageHeight / 2) / stageHeight * 10
inc(times.toIntCeil())
fpsText.text = "FPS: $fps at ${entities.size} entities"
}
} else {
if (down && p.x < stageWidth / 2) {
switch()
}
down = false
}
}
}
}
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by running the embedded Kotlin test project on the Tab M10 FHD Plus and compare its image, solidRect, roundRect, and scaling cases. Use the reported entity counts and FPS as the baseline, then inspect the relevant rendering and fragment-shader paths to identify the bottleneck. Done means a confirmed cause and a measured improvement on the reported device.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, kotlin
- Domain
- mobile-dev, performance
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100