improve hud performance: caching, delete texture data on cpu when loaded

This commit is contained in:
Bixilon 2021-09-12 20:23:46 +02:00
parent c12746f5ac
commit b7aa711581
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
7 changed files with 83 additions and 7 deletions

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.gui.elements
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.util.vec.Vec2Util.EMPTY
import de.bixilon.minosoft.gui.rendering.util.vec.Vec2Util.MAX
@ -29,7 +30,8 @@ abstract class Element(val hudRenderer: HUDRenderer) {
field = value
onParentChange()
}
open var prepared: Boolean = false
protected var cache = GUIMeshCache(hudRenderer.matrix)
open var cacheUpToDate: Boolean = false
/**
* If maxSize was infinity, what size would the element have?

View File

@ -26,7 +26,7 @@ class GridCell(
private val child: Element,
override var parent: Element?,
) : Element(hudRenderer) {
override var prepared: Boolean by child::prepared
override var cacheUpToDate: Boolean by child::cacheUpToDate
override var size: Vec2i by child::size
override var margin: Vec4i by child::margin
override var prefSize: Vec2i by child::prefSize

View File

@ -24,6 +24,7 @@ import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments
import de.bixilon.minosoft.gui.rendering.gui.elements.ElementAlignments.Companion.getOffset
import de.bixilon.minosoft.gui.rendering.gui.elements.InfiniteSizeElement
import de.bixilon.minosoft.gui.rendering.gui.hud.HUDRenderer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.util.vec.Vec2Util.EMPTY
import de.bixilon.minosoft.gui.rendering.util.vec.Vec4Util.offset
@ -36,6 +37,9 @@ open class TextElement(
var background: Boolean = true,
var backgroundColor: RGBColor = RenderConstants.TEXT_BACKGROUND_COLOR,
) : LabeledElement(hudRenderer) {
private var previousOffset = Vec2i.EMPTY
private var previousMatrix = hudRenderer.matrix
private var preparedSize = Vec2i.EMPTY
private var renderInfo = TextRenderInfo()
@ -43,7 +47,7 @@ open class TextElement(
set(value) {
textComponent = ChatComponent.of(value)
field = value
prepared = false
cacheUpToDate = false
}
private var emptyMessage: Boolean = true
@ -75,6 +79,7 @@ open class TextElement(
this.renderInfo = renderInfo
}
this.cacheUpToDate = false
this.size = size
preparedSize = size
}
@ -103,18 +108,32 @@ open class TextElement(
if (emptyMessage) {
return 0
}
if (previousOffset != offset || previousMatrix != hudRenderer.matrix) {
cacheUpToDate = false
}
if (cacheUpToDate) {
consumer.addCache(cache)
return LAYERS
}
val cache = GUIMeshCache(hudRenderer.matrix)
val initialOffset = offset + margin.offset
ChatComponentRenderer.render(initialOffset, Vec2i(initialOffset), Vec2i.EMPTY, z + 1, this, fontAlignment, renderWindow, consumer, renderInfo, textComponent)
ChatComponentRenderer.render(initialOffset, Vec2i(initialOffset), Vec2i.EMPTY, z + 1, this, fontAlignment, renderWindow, cache, renderInfo, textComponent)
renderInfo.currentLineNumber = 0
if (background) {
for ((line, info) in renderInfo.lines.withIndex()) {
val start = initialOffset + Vec2i(fontAlignment.getOffset(size.x, info.width), line * Font.TOTAL_CHAR_HEIGHT)
consumer.addQuad(start, start + Vec2i(info.width + Font.CHAR_MARGIN, Font.TOTAL_CHAR_HEIGHT), z, renderWindow.WHITE_TEXTURE, backgroundColor)
cache.addQuad(start, start + Vec2i(info.width + Font.CHAR_MARGIN, Font.TOTAL_CHAR_HEIGHT), z, renderWindow.WHITE_TEXTURE, backgroundColor)
}
}
consumer.addCache(cache)
this.cache = cache
this.previousOffset = offset
this.previousMatrix = hudRenderer.matrix
this.cacheUpToDate = true
return LAYERS
}

View File

@ -43,6 +43,10 @@ class GUIMesh(
))
}
override fun addCache(cache: GUIMeshCache) {
data.addAll(cache.data)
}
data class HUDMeshStruct(
val position: Vec3,
val uv: Vec2,
@ -53,7 +57,7 @@ class GUIMesh(
}
companion object {
private const val BASE_Z = -0.99f
private const val Z_MULTIPLIER = -0.00001f
const val BASE_Z = -0.99f
const val Z_MULTIPLIER = -0.00001f
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.gui.mesh
import de.bixilon.minosoft.data.text.RGBColor
import de.bixilon.minosoft.gui.rendering.RenderConstants
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.AbstractTexture
import de.bixilon.minosoft.util.collections.ArrayFloatList
import glm_.mat4x4.Mat4
import glm_.vec2.Vec2
import glm_.vec2.Vec2t
import glm_.vec4.Vec4
class GUIMeshCache(
val matrix: Mat4,
initialCahceSize: Int = 1000,
) : GUIVertexConsumer {
val data: ArrayFloatList = ArrayFloatList(initialCahceSize)
override fun addVertex(position: Vec2t<*>, z: Int, texture: AbstractTexture, uv: Vec2, tint: RGBColor) {
val outPosition = matrix * Vec4(position.x.toFloat(), position.y.toFloat(), 1.0f, 1.0f)
data.addAll(floatArrayOf(
outPosition.x,
outPosition.y,
GUIMesh.BASE_Z + GUIMesh.Z_MULTIPLIER * z,
uv.x,
uv.y,
Float.fromBits(texture.renderData?.layer ?: RenderConstants.DEBUG_TEXTURE_ID),
Float.fromBits(tint.rgba),
))
}
override fun addCache(cache: GUIMeshCache) {
data.addAll(cache.data)
}
}

View File

@ -46,4 +46,6 @@ interface GUIVertexConsumer {
fun addQuad(start: Vec2t<*>, end: Vec2t<*>, z: Int, texture: TextureLike, tint: RGBColor) {
addQuad(start, end, z, texture.texture, texture.uvStart, texture.uvEnd, tint)
}
fun addCache(cache: GUIMeshCache)
}

View File

@ -152,6 +152,8 @@ class OpenGLTextureArray(
for ((mipMapLevel, data) in mipMaps.withIndex()) {
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, mipMapLevel, 0, 0, renderData.index, data.first.x, data.first.y, mipMapLevel + 1, GL_RGBA, GL_UNSIGNED_BYTE, data.second)
}
texture.data = null
}
return textureId