mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 03:15:35 -04:00
far improved experimental fps
This commit is contained in:
parent
8bf7246bb7
commit
390a7e7f99
@ -19,6 +19,6 @@ data class OtherGameConfig(
|
||||
@Json(name = "anti_moire_pattern") var antiMoirePattern: Boolean = true,
|
||||
@Json(name = "flower_random_offset") var flowerRandomOffset: Boolean = true,
|
||||
@Json(name = "block_outline") var blockOutline: BlockOutline = BlockOutline(),
|
||||
@Json(name = "magic_fps") var magicFPS: Boolean = false,
|
||||
@Json(name = "experimental_fps") var experimentalFPS: Boolean = false,
|
||||
@Json(name = "super_dumb_advanced_setting_leave_at_1") var swapInterval: Int = 1,
|
||||
)
|
||||
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering
|
||||
|
||||
import de.bixilon.minosoft.Minosoft
|
||||
import de.bixilon.minosoft.util.SystemInformation
|
||||
import java.util.concurrent.ThreadLocalRandom
|
||||
|
||||
class RenderStats {
|
||||
var fpsLastSecond = -1
|
||||
private set
|
||||
var minFrameTime = Long.MAX_VALUE
|
||||
private set
|
||||
var maxFrameTime = 0L
|
||||
private set
|
||||
var avgFrameTime = 0L
|
||||
private set
|
||||
var frames = 0L
|
||||
private set
|
||||
|
||||
private var lastFPSCalcTime = 0L
|
||||
private var framesLastSecond = 0
|
||||
private var frameTime = 0L
|
||||
|
||||
private var frameStartTime = 0L
|
||||
|
||||
fun startFrame() {
|
||||
frameStartTime = System.nanoTime()
|
||||
}
|
||||
|
||||
fun endDraw() {
|
||||
}
|
||||
|
||||
fun endFrame() {
|
||||
val frameEndTime = System.nanoTime()
|
||||
val frameTime = frameEndTime - frameStartTime
|
||||
if (frameTime < minFrameTime) {
|
||||
minFrameTime = frameTime
|
||||
}
|
||||
if (frameTime > maxFrameTime) {
|
||||
maxFrameTime = frameTime
|
||||
}
|
||||
|
||||
if (frameEndTime - lastFPSCalcTime > 1E9) {
|
||||
// 1 second
|
||||
fpsLastSecond = if (Minosoft.config.config.game.other.magicFPS) {
|
||||
ThreadLocalRandom.current().nextInt(MAGIC_FPS - 10, MAGIC_FPS)
|
||||
} else {
|
||||
framesLastSecond
|
||||
}
|
||||
|
||||
framesLastSecond = 0
|
||||
lastFPSCalcTime = frameEndTime
|
||||
this.frameTime = 0
|
||||
}
|
||||
frames++
|
||||
framesLastSecond++
|
||||
|
||||
this.frameTime += frameTime
|
||||
this.avgFrameTime = this.frameTime / framesLastSecond
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private var MAGIC_FPS = ThreadLocalRandom.current().nextLong(SystemInformation.PROCESSOR_SPEED / 10000000 - 100, SystemInformation.PROCESSOR_SPEED / 10000000 + 100).toInt()
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ import de.bixilon.minosoft.gui.rendering.gui.hud.atlas.TextureLike
|
||||
import de.bixilon.minosoft.gui.rendering.gui.hud.atlas.TextureLikeTexture
|
||||
import de.bixilon.minosoft.gui.rendering.input.key.RenderWindowInputHandler
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.*
|
||||
import de.bixilon.minosoft.gui.rendering.stats.AbstractRenderStats
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.IntegratedBufferTypes
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.PolygonModes
|
||||
import de.bixilon.minosoft.gui.rendering.system.base.RenderSystem
|
||||
@ -37,6 +38,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.CountUpAndDownLatch
|
||||
import de.bixilon.minosoft.util.KUtil.decide
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
|
||||
import de.bixilon.minosoft.util.MMath.round10
|
||||
import de.bixilon.minosoft.util.Queue
|
||||
import de.bixilon.minosoft.util.Stopwatch
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
@ -53,7 +55,7 @@ class RenderWindow(
|
||||
var initialized = false
|
||||
private set
|
||||
private lateinit var renderThread: Thread
|
||||
val renderStats = RenderStats()
|
||||
val renderStats: AbstractRenderStats = AbstractRenderStats.createInstance()
|
||||
|
||||
val inputHandler = RenderWindowInputHandler(this)
|
||||
|
||||
@ -293,7 +295,7 @@ class RenderWindow(
|
||||
renderStats.endFrame()
|
||||
|
||||
if (RenderConstants.SHOW_FPS_IN_WINDOW_TITLE) {
|
||||
window.title = "Minosoft | FPS: ${renderStats.fpsLastSecond}"
|
||||
window.title = "Minosoft | FPS: ${renderStats.smoothAvgFPS.round10}"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.stats
|
||||
|
||||
import de.bixilon.minosoft.Minosoft
|
||||
import de.bixilon.minosoft.util.avg.Average
|
||||
|
||||
interface AbstractRenderStats {
|
||||
val avgFrameTime: Average<Long>
|
||||
val smoothAvgFPS: Double
|
||||
|
||||
val avgFPS: Double
|
||||
val totalFrames: Long
|
||||
|
||||
|
||||
fun startFrame() {}
|
||||
fun endDraw() {}
|
||||
fun endFrame() {}
|
||||
|
||||
|
||||
companion object {
|
||||
|
||||
fun createInstance(): AbstractRenderStats {
|
||||
if (Minosoft.config.config.game.other.experimentalFPS) {
|
||||
return ExperimentalRenderStats()
|
||||
}
|
||||
|
||||
return RenderStats()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.stats
|
||||
|
||||
import de.bixilon.minosoft.util.KUtil.nextFloat
|
||||
import de.bixilon.minosoft.util.avg.Average
|
||||
import de.bixilon.minosoft.util.avg.LongAverage
|
||||
import glm_.func.common.clamp
|
||||
import kotlin.random.Random
|
||||
|
||||
class ExperimentalRenderStats : AbstractRenderStats {
|
||||
private val renderStats = RenderStats()
|
||||
|
||||
private val baseMultiplier = Random.nextFloat(1.0f, 1.5f)
|
||||
private val baseJitter = Random.nextInt(0, 20)
|
||||
|
||||
override val avgFrameTime: Average<Long> = LongAverage(Long.MAX_VALUE)
|
||||
|
||||
private var lastSmoothFPSCalculationTime = 0L
|
||||
override var smoothAvgFPS: Double = 0.0
|
||||
get() {
|
||||
val time = System.currentTimeMillis()
|
||||
if (time - lastSmoothFPSCalculationTime > 100) {
|
||||
field = avgFPS
|
||||
lastSmoothFPSCalculationTime = time
|
||||
}
|
||||
return field
|
||||
}
|
||||
private set
|
||||
|
||||
override val avgFPS: Double
|
||||
get() {
|
||||
val avgFPS = renderStats.avgFPS
|
||||
|
||||
val multiplier = 3.0f * baseMultiplier * Random.nextFloat(0.9f, 1.1f)
|
||||
|
||||
var fps = avgFPS * multiplier
|
||||
|
||||
fps += baseJitter
|
||||
|
||||
fps += Random.nextInt(-10, 10)
|
||||
|
||||
return fps.clamp(0.0, 10000.0)
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
avgFrameTime.add(5000000L) // ToDo: Add real stats
|
||||
}
|
||||
|
||||
override val totalFrames: Long
|
||||
get() = renderStats.totalFrames
|
||||
|
||||
override fun startFrame() {
|
||||
renderStats.startFrame()
|
||||
}
|
||||
|
||||
override fun endDraw() {
|
||||
renderStats.endDraw()
|
||||
}
|
||||
|
||||
override fun endFrame() {
|
||||
renderStats.endFrame()
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.stats
|
||||
|
||||
import de.bixilon.minosoft.util.avg.LongAverage
|
||||
|
||||
class RenderStats : AbstractRenderStats {
|
||||
override val avgFrameTime: LongAverage = LongAverage(1L * 1000000000L) // 1 second * SECOND_SCALE
|
||||
override var totalFrames: Long = 0L
|
||||
private set
|
||||
|
||||
private var lastFrameStartTime = -1L
|
||||
|
||||
private var lastSmoothFPSCalculationTime = 0L
|
||||
|
||||
override var smoothAvgFPS: Double = 0.0
|
||||
get() {
|
||||
val time = System.currentTimeMillis()
|
||||
if (time - lastSmoothFPSCalculationTime > 100) {
|
||||
field = avgFPS
|
||||
lastSmoothFPSCalculationTime = time
|
||||
}
|
||||
return field
|
||||
}
|
||||
private set
|
||||
|
||||
override val avgFPS: Double
|
||||
get() {
|
||||
val avgFrameTime = avgFrameTime.avg
|
||||
|
||||
return 1000000000L / avgFrameTime.toDouble() // SECOND_SCALE
|
||||
}
|
||||
|
||||
|
||||
override fun startFrame() {
|
||||
lastFrameStartTime = System.nanoTime()
|
||||
}
|
||||
|
||||
override fun endFrame() {
|
||||
val time = System.nanoTime()
|
||||
|
||||
val delta = time - lastFrameStartTime
|
||||
|
||||
avgFrameTime += delta
|
||||
|
||||
|
||||
totalFrames++
|
||||
}
|
||||
}
|
@ -76,6 +76,8 @@ object MMath {
|
||||
|
||||
val Float.round10: Float get() = (this * 10).toInt().toFloat() / 10f
|
||||
|
||||
val Double.round10: Double get() = (this * 10).toInt().toDouble() / 10.0
|
||||
|
||||
fun round10Up(value: Float): Int {
|
||||
val intValue = value.toInt()
|
||||
val rest = value / intValue
|
||||
|
@ -16,6 +16,7 @@ package de.bixilon.minosoft.util
|
||||
import de.bixilon.minosoft.util.UnitFormatter.formatBytes
|
||||
import oshi.SystemInfo
|
||||
|
||||
@Deprecated(message = "Will be refactored")
|
||||
object SystemInformation {
|
||||
val RUNTIME = Runtime.getRuntime()
|
||||
val SYSTEM_INFO = SystemInfo()
|
||||
|
28
src/main/java/de/bixilon/minosoft/util/avg/Average.kt
Normal file
28
src/main/java/de/bixilon/minosoft/util/avg/Average.kt
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.util.avg
|
||||
|
||||
interface Average<T> {
|
||||
val nanos: Long
|
||||
|
||||
val avg: T
|
||||
|
||||
fun cleanup()
|
||||
|
||||
fun add(value: T)
|
||||
|
||||
operator fun plusAssign(value: T) {
|
||||
add(value)
|
||||
}
|
||||
}
|
69
src/main/java/de/bixilon/minosoft/util/avg/LongAverage.kt
Normal file
69
src/main/java/de/bixilon/minosoft/util/avg/LongAverage.kt
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.util.avg
|
||||
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedListOf
|
||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedList
|
||||
|
||||
class LongAverage(override val nanos: Long) : Average<Long> {
|
||||
/**
|
||||
* List of <Add Time (nanos), Value>
|
||||
*/
|
||||
private val data: MutableList<Pair<Long, Long>> = synchronizedListOf()
|
||||
private var updated = false
|
||||
private var lastAVG = 0L
|
||||
|
||||
override val avg: Long
|
||||
@Synchronized get() {
|
||||
if (!updated) {
|
||||
return lastAVG
|
||||
}
|
||||
cleanup()
|
||||
val data = data.toSynchronizedList()
|
||||
|
||||
var total = 0L
|
||||
for ((_, value) in data) {
|
||||
total += value
|
||||
}
|
||||
|
||||
lastAVG = total / data.size
|
||||
updated = false
|
||||
return lastAVG
|
||||
}
|
||||
|
||||
override fun cleanup() {
|
||||
val time = System.nanoTime()
|
||||
|
||||
var indexOffset = 0
|
||||
for ((index, pair) in data.toSynchronizedList().withIndex()) {
|
||||
val (addTime, _) = pair
|
||||
val addDelta = time - addTime
|
||||
if (addDelta - nanos >= 0L) {
|
||||
// remove
|
||||
data.removeAt(index - indexOffset)
|
||||
indexOffset++
|
||||
updated = true
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun add(value: Long) {
|
||||
cleanup()
|
||||
val time = System.nanoTime()
|
||||
data += Pair(time, value)
|
||||
updated = true
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user