improved caching performance; lwjgl3 for fonttest

This commit is contained in:
minjaesong
2021-09-16 14:51:23 +09:00
parent b9bf9ca10d
commit 810411de7e
7 changed files with 105 additions and 90 deletions

View File

@@ -1,5 +1,5 @@
<component name="libraryTable"> <component name="libraryTable">
<library name="com.badlogicgames.gdx:gdx:1.10.0" type="repository"> <library name="badlogicgames.gdx" type="repository">
<properties maven-id="com.badlogicgames.gdx:gdx:1.10.0" /> <properties maven-id="com.badlogicgames.gdx:gdx:1.10.0" />
<CLASSES> <CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/badlogicgames/gdx/gdx/1.10.0/gdx-1.10.0.jar!/" /> <root url="jar://$MAVEN_REPOSITORY$/com/badlogicgames/gdx/gdx/1.10.0/gdx-1.10.0.jar!/" />

View File

@@ -0,0 +1,48 @@
<component name="libraryTable">
<library name="badlogicgames.gdx.backend.lwjgl3" type="repository">
<properties maven-id="com.badlogicgames.gdx:gdx-backend-lwjgl3:1.10.0" />
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/badlogicgames/gdx/gdx-backend-lwjgl3/1.10.0/gdx-backend-lwjgl3-1.10.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/badlogicgames/gdx/gdx/1.10.0/gdx-1.10.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl/3.2.3/lwjgl-3.2.3.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl/3.2.3/lwjgl-3.2.3-natives-windows.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl/3.2.3/lwjgl-3.2.3-natives-windows-x86.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl/3.2.3/lwjgl-3.2.3-natives-linux.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl/3.2.3/lwjgl-3.2.3-natives-linux-arm32.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl/3.2.3/lwjgl-3.2.3-natives-linux-arm64.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl/3.2.3/lwjgl-3.2.3-natives-macos.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-glfw/3.2.3/lwjgl-glfw-3.2.3.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-glfw/3.2.3/lwjgl-glfw-3.2.3-natives-windows.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-glfw/3.2.3/lwjgl-glfw-3.2.3-natives-windows-x86.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-glfw/3.2.3/lwjgl-glfw-3.2.3-natives-linux.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-glfw/3.2.3/lwjgl-glfw-3.2.3-natives-linux-arm32.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-glfw/3.2.3/lwjgl-glfw-3.2.3-natives-linux-arm64.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-glfw/3.2.3/lwjgl-glfw-3.2.3-natives-macos.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-jemalloc/3.2.3/lwjgl-jemalloc-3.2.3.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-jemalloc/3.2.3/lwjgl-jemalloc-3.2.3-natives-windows.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-jemalloc/3.2.3/lwjgl-jemalloc-3.2.3-natives-windows-x86.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-jemalloc/3.2.3/lwjgl-jemalloc-3.2.3-natives-linux.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-jemalloc/3.2.3/lwjgl-jemalloc-3.2.3-natives-linux-arm32.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-jemalloc/3.2.3/lwjgl-jemalloc-3.2.3-natives-linux-arm64.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-jemalloc/3.2.3/lwjgl-jemalloc-3.2.3-natives-macos.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-opengl/3.2.3/lwjgl-opengl-3.2.3.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-opengl/3.2.3/lwjgl-opengl-3.2.3-natives-windows.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-opengl/3.2.3/lwjgl-opengl-3.2.3-natives-windows-x86.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-opengl/3.2.3/lwjgl-opengl-3.2.3-natives-linux.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-opengl/3.2.3/lwjgl-opengl-3.2.3-natives-linux-arm32.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-opengl/3.2.3/lwjgl-opengl-3.2.3-natives-linux-arm64.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-opengl/3.2.3/lwjgl-opengl-3.2.3-natives-macos.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-openal/3.2.3/lwjgl-openal-3.2.3.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-openal/3.2.3/lwjgl-openal-3.2.3-natives-windows.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-openal/3.2.3/lwjgl-openal-3.2.3-natives-windows-x86.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-openal/3.2.3/lwjgl-openal-3.2.3-natives-linux.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-openal/3.2.3/lwjgl-openal-3.2.3-natives-linux-arm32.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-openal/3.2.3/lwjgl-openal-3.2.3-natives-linux-arm64.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/lwjgl/lwjgl-openal/3.2.3/lwjgl-openal-3.2.3-natives-macos.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/badlogicgames/jlayer/jlayer/1.0.1-gdx/jlayer-1.0.1-gdx.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jcraft/jorbis/0.0.17/jorbis-0.0.17.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

10
.idea/runConfigurations.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>

View File

@@ -7,7 +7,7 @@
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="com.badlogicgames.gdx:gdx:1.10.0" level="project" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" /> <orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="library" name="badlogicgames.gdx" level="project" />
</component> </component>
</module> </module>

View File

@@ -9,5 +9,7 @@
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="BuildJAR_TerrarumSansBitmap" /> <orderEntry type="module" module-name="BuildJAR_TerrarumSansBitmap" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" /> <orderEntry type="library" name="KotlinJavaRuntime" level="project" />
<orderEntry type="library" name="badlogicgames.gdx" level="project" />
<orderEntry type="library" name="badlogicgames.gdx.backend.lwjgl3" level="project" />
</component> </component>
</module> </module>

View File

@@ -1,6 +1,6 @@
import com.badlogic.gdx.* import com.badlogic.gdx.*
import com.badlogic.gdx.backends.lwjgl.LwjglApplication import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration
import com.badlogic.gdx.graphics.* import com.badlogic.gdx.graphics.*
import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.glutils.FrameBuffer import com.badlogic.gdx.graphics.glutils.FrameBuffer
@@ -109,7 +109,7 @@ class FontTestGDX : Game() {
batch.begin() batch.begin()
batch.color = Color.WHITE batch.color = Color.WHITE
batch.draw(tex, 0f, (TEXH.toFloat()/appConfig.height)*TEXH - scrollOffsetY, TEXW.toFloat(), -(TEXH.toFloat() / appConfig.height) * TEXH.toFloat()) batch.draw(tex, 0f, (TEXH.toFloat()/HEIGHT)*TEXH - scrollOffsetY, TEXW.toFloat(), -(TEXH.toFloat() / HEIGHT) * TEXH.toFloat())
batch.end() batch.end()
@@ -129,19 +129,19 @@ class FontTestGDX : Game() {
} }
fun scrollAdd(x: Int = 1) { fun scrollAdd(x: Int = 1) {
scrollOffsetY -= (TEXH.toFloat() / appConfig.height) * 20f * x scrollOffsetY -= (TEXH.toFloat() / HEIGHT) * 20f * x
} }
fun scrollSub(x: Int = 1) { fun scrollSub(x: Int = 1) {
scrollOffsetY += (TEXH.toFloat() / appConfig.height) * 20f * x scrollOffsetY += (TEXH.toFloat() / HEIGHT) * 20f * x
} }
class Navigator(val main: FontTestGDX) : InputAdapter() { class Navigator(val main: FontTestGDX) : InputAdapter() {
override fun scrolled(amount: Int): Boolean { override fun scrolled(amountX: Float, amountY: Float): Boolean {
if (amount >= 0) if (amountY >= 0)
main.scrollSub(amount) main.scrollSub(amountY.toInt())
else else
main.scrollAdd(-amount) main.scrollAdd(-amountY.toInt())
return true return true
} }
@@ -157,17 +157,19 @@ class FontTestGDX : Game() {
} }
} }
lateinit var appConfig: LwjglApplicationConfiguration lateinit var appConfig: Lwjgl3ApplicationConfiguration
const val TEXW = 874 const val TEXW = 874
const val TEXH = 2400 const val TEXH = 2400
fun main(args: Array<String>) { const val WIDTH = TEXW
appConfig = LwjglApplicationConfiguration() const val HEIGHT = 768
appConfig.vSyncEnabled = false
appConfig.resizable = false//true;
appConfig.width = TEXW
appConfig.height = 768
appConfig.title = "Terrarum Sans Bitmap Test (GDX)"
LwjglApplication(FontTestGDX(), appConfig) fun main(args: Array<String>) {
appConfig = Lwjgl3ApplicationConfiguration()
appConfig.useVsync(false)
appConfig.setResizable(false)
appConfig.setWindowedMode(WIDTH, HEIGHT)
appConfig.setTitle("Terrarum Sans Bitmap Test")
Lwjgl3Application(FontTestGDX(), appConfig)
} }

View File

@@ -37,6 +37,7 @@ import java.security.MessageDigest
import java.util.* import java.util.*
import java.util.zip.CRC32 import java.util.zip.CRC32
import java.util.zip.GZIPInputStream import java.util.zip.GZIPInputStream
import kotlin.collections.HashMap
import kotlin.math.roundToInt import kotlin.math.roundToInt
import kotlin.math.sign import kotlin.math.sign
@@ -117,8 +118,11 @@ class GameFontBase(
//private val textCache = HashMap<CharSequence, ShittyGlyphLayout>() //private val textCache = HashMap<CharSequence, ShittyGlyphLayout>()
private data class TextCacheObj(var age: Int, val hash: Long, val glyphLayout: ShittyGlyphLayout?): Comparable<TextCacheObj> { private data class TextCacheObj(var age: Int, val hash: Long, val glyphLayout: ShittyGlyphLayout?): Comparable<TextCacheObj> {
// var disposed = false; private set
fun dispose() { fun dispose() {
glyphLayout?.linotype?.dispose() glyphLayout?.linotype?.dispose()
// disposed = true
} }
override fun compareTo(other: TextCacheObj): Int { override fun compareTo(other: TextCacheObj): Int {
@@ -127,80 +131,41 @@ class GameFontBase(
} }
private var textCacheCap = 0 private var textCacheCap = 0
private val textCache = Array(textCacheSize) { TextCacheObj(-1, -1L, null) } private val textCache = TreeMap<Long, TextCacheObj>()
/** /**
* Insertion sorts the last element fo the textCache * Insertion sorts the last element fo the textCache
*/ */
private fun addToCache(text: CodepointSequence, linotype: Texture, width: Int) { private fun addToCache(text: CodepointSequence, linotype: Texture, width: Int) {
// Caching rules: val cacheObj = TextCacheObj(0, text.getHash(), ShittyGlyphLayout(text, linotype, width))
// 1. always accept new element.
// 2. often-called element have higher chance of survival (see: getCache(long))
if (textCacheCap < textCacheSize) { if (textCacheCap < textCacheSize) {
textCache[textCacheCap] = TextCacheObj(0, text.getHash(), ShittyGlyphLayout(text, linotype, width)) textCache[cacheObj.hash] = cacheObj
textCacheCap += 1 textCacheCap += 1
// make everybody age
textCache.forEach {
it.age += 1
}
} }
else { else {
// search for an oldest element // randomly eliminate one
var oldestElemIndex = 0 textCache.remove(textCache.keys.random())!!.dispose()
var ageOfOldest = textCacheCap
textCache.forEachIndexed { index, it ->
// make everybody age
textCache[index].age += 1
// mark oldest // add new one
if (it.age > ageOfOldest) { textCache[cacheObj.hash] = cacheObj
oldestElemIndex = index
}
}
// dispose of the oldest one before overwriting
textCache[oldestElemIndex].dispose()
// overwrite oldest one
textCache[oldestElemIndex] = TextCacheObj(0, text.getHash(), ShittyGlyphLayout(text, linotype, width))
} }
// sort the list
textCache.sortBy { it.hash }
} }
private fun getCache(hash: Long): TextCacheObj? { private fun getCache(hash: Long): TextCacheObj? {
var low = 0 val cache = textCache[hash]
var high = textCacheCap - 1
var key = -1
if (cache == null)
while (low <= high) {
val mid = (low + high).ushr(1) // safe from overflows
val midVal = textCache[mid]
if (hash > midVal.hash)
low = mid + 1
else if (hash < midVal.hash)
high = mid - 1
else {
key = mid
break // the condition is not enough to break the loop
}
}
if (key < 0)
return null return null
// else if (cache.disposed) {
// decrement age count (see: addToCache(CodepointSequence, Pixmap, Int)) // textCache.remove(hash)
if (textCache[key].age > 0) textCache[key].age -= 1 // return null
// }
return textCache[key] else {
// decrement age count (see: addToCache(CodepointSequence, Pixmap, Int))
if (cache.age > 0) cache.age -= 1
return cache
}
} }
@@ -559,7 +524,7 @@ class GameFontBase(
override fun dispose() { override fun dispose() {
super.dispose() super.dispose()
textCache.forEach { it.dispose() } textCache.values.forEach { it.dispose() }
sheets.forEach { it.dispose() } sheets.forEach { it.dispose() }
} }
@@ -1307,18 +1272,6 @@ class GameFontBase(
private fun CharSequence.sha256(): ByteArray {
val digest = MessageDigest.getInstance("SHA-256")
this.forEach {
val it = it.toInt()
val b1 = it.shl(8).and(255).toByte()
val b2 = it.and(255).toByte()
digest.update(b1)
digest.update(b2)
}
return digest.digest()
}
private fun CharSequence.crc32(): Int { private fun CharSequence.crc32(): Int {
val crc = CRC32() val crc = CRC32()
this.forEach { this.forEach {