mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-10 16:01:50 -04:00
improve some memory stuff
This commit is contained in:
parent
69bd39bd45
commit
f5c9afebae
@ -5,7 +5,6 @@ import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.FloatVertexBu
|
|||||||
import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.PrimitiveTypes
|
import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.PrimitiveTypes
|
||||||
import de.bixilon.minosoft.gui.rendering.system.opengl.buffer.FloatOpenGLBuffer
|
import de.bixilon.minosoft.gui.rendering.system.opengl.buffer.FloatOpenGLBuffer
|
||||||
import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct
|
import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct
|
||||||
import de.bixilon.minosoft.util.KUtil.clean
|
|
||||||
import org.lwjgl.opengl.ARBVertexArrayObject.glBindVertexArray
|
import org.lwjgl.opengl.ARBVertexArrayObject.glBindVertexArray
|
||||||
import org.lwjgl.opengl.ARBVertexArrayObject.glGenVertexArrays
|
import org.lwjgl.opengl.ARBVertexArrayObject.glGenVertexArrays
|
||||||
import org.lwjgl.opengl.GL11.*
|
import org.lwjgl.opengl.GL11.*
|
||||||
@ -33,7 +32,6 @@ class FloatOpenGLVertexBuffer(override val structure: MeshStruct, data: FloatBuf
|
|||||||
glBufferData(type.gl, buffer, drawTypes.gl)
|
glBufferData(type.gl, buffer, drawTypes.gl)
|
||||||
state = RenderBufferStates.UPLOADED
|
state = RenderBufferStates.UPLOADED
|
||||||
|
|
||||||
buffer.clean()
|
|
||||||
_data = null
|
_data = null
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ package de.bixilon.minosoft.gui.rendering.util.mesh
|
|||||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.FloatVertexBuffer
|
import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.FloatVertexBuffer
|
||||||
import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.PrimitiveTypes
|
import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.PrimitiveTypes
|
||||||
import de.bixilon.minosoft.util.collections.ArrayFloatList
|
import de.bixilon.minosoft.util.collections.DirectArrayFloatList
|
||||||
import glm_.vec2.Vec2
|
import glm_.vec2.Vec2
|
||||||
import glm_.vec3.Vec3
|
import glm_.vec3.Vec3
|
||||||
|
|
||||||
@ -27,8 +27,8 @@ abstract class Mesh(
|
|||||||
initialCacheSize: Int = 10000,
|
initialCacheSize: Int = 10000,
|
||||||
) {
|
) {
|
||||||
val order = renderWindow.renderSystem.primitiveMeshOrder
|
val order = renderWindow.renderSystem.primitiveMeshOrder
|
||||||
private var _data: ArrayFloatList? = ArrayFloatList(initialCacheSize)
|
private var _data: DirectArrayFloatList? = DirectArrayFloatList(initialCacheSize)
|
||||||
var data: ArrayFloatList
|
var data: DirectArrayFloatList
|
||||||
get() = _data!!
|
get() = _data!!
|
||||||
set(value) {
|
set(value) {
|
||||||
_data = value
|
_data = value
|
||||||
@ -45,8 +45,9 @@ abstract class Mesh(
|
|||||||
|
|
||||||
fun load() {
|
fun load() {
|
||||||
buffer = renderWindow.renderSystem.createVertexBuffer(struct, data.buffer, primitiveType)
|
buffer = renderWindow.renderSystem.createVertexBuffer(struct, data.buffer, primitiveType)
|
||||||
_data = null
|
|
||||||
buffer.init()
|
buffer.init()
|
||||||
|
data.unload()
|
||||||
|
_data = null
|
||||||
vertices = buffer.vertices
|
vertices = buffer.vertices
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@ import glm_.vec2.Vec2t
|
|||||||
import glm_.vec3.Vec3t
|
import glm_.vec3.Vec3t
|
||||||
import glm_.vec4.Vec4t
|
import glm_.vec4.Vec4t
|
||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
import org.lwjgl.system.MemoryUtil.memFree
|
|
||||||
import sun.misc.Unsafe
|
import sun.misc.Unsafe
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
@ -506,8 +505,4 @@ object KUtil {
|
|||||||
this.get(array)
|
this.get(array)
|
||||||
return array
|
return array
|
||||||
}
|
}
|
||||||
|
|
||||||
fun java.nio.Buffer.clean() {
|
|
||||||
memFree(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,25 +10,18 @@
|
|||||||
*
|
*
|
||||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package de.bixilon.minosoft.util.collections
|
package de.bixilon.minosoft.util.collections
|
||||||
|
|
||||||
import de.bixilon.minosoft.util.KUtil
|
|
||||||
import de.bixilon.minosoft.util.KUtil.clean
|
|
||||||
import org.lwjgl.system.MemoryUtil.memAllocFloat
|
|
||||||
import java.nio.FloatBuffer
|
|
||||||
|
|
||||||
class ArrayFloatList(
|
class ArrayFloatList(
|
||||||
initialSize: Int = DEFAULT_INITIAL_SIZE,
|
initialSize: Int = DEFAULT_INITIAL_SIZE,
|
||||||
) {
|
) {
|
||||||
var buffer: FloatBuffer = memAllocFloat(initialSize) // ToDo: Clear when disconnected
|
private var data: FloatArray = FloatArray(initialSize)
|
||||||
private set
|
|
||||||
var finalized: Boolean = false
|
var finalized: Boolean = false
|
||||||
private set
|
private set
|
||||||
val capacity: Int
|
val limit: Int
|
||||||
get() = buffer.capacity()
|
get() = data.size
|
||||||
val size: Int
|
var size = 0
|
||||||
get() = buffer.position()
|
private set
|
||||||
val isEmpty: Boolean
|
val isEmpty: Boolean
|
||||||
get() = size == 0
|
get() = size == 0
|
||||||
|
|
||||||
@ -49,66 +42,55 @@ class ArrayFloatList(
|
|||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
checkFinalized()
|
checkFinalized()
|
||||||
buffer.clean()
|
size = 0
|
||||||
outputUpToDate = false
|
outputUpToDate = false
|
||||||
output = FloatArray(0)
|
output = FloatArray(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ensureSize(needed: Int) {
|
private fun ensureSize(needed: Int) {
|
||||||
checkFinalized()
|
checkFinalized()
|
||||||
if (capacity - size >= needed) {
|
if (limit - size >= needed) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var newSize = capacity
|
var newSize = data.size
|
||||||
while (newSize - size < needed) {
|
while (newSize - size < needed) {
|
||||||
newSize += nextGrowStep
|
newSize += nextGrowStep
|
||||||
}
|
}
|
||||||
val oldBuffer = buffer
|
val oldData = data
|
||||||
buffer = memAllocFloat(newSize)
|
data = FloatArray(newSize)
|
||||||
if (FLOAT_PUT_METHOD == null) { // Java < 16
|
System.arraycopy(oldData, 0, data, 0, oldData.size)
|
||||||
for (i in 0 until oldBuffer.position()) {
|
|
||||||
buffer.put(oldBuffer.get(i))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FLOAT_PUT_METHOD.invoke(buffer, 0, oldBuffer, 0, oldBuffer.position())
|
|
||||||
buffer.position(oldBuffer.position())
|
|
||||||
}
|
|
||||||
oldBuffer.clean()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun add(float: Float) {
|
fun add(float: Float) {
|
||||||
ensureSize(1)
|
ensureSize(1)
|
||||||
buffer.put(float)
|
data[size++] = float
|
||||||
outputUpToDate = false
|
outputUpToDate = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addAll(floats: FloatArray) {
|
fun addAll(floats: FloatArray) {
|
||||||
ensureSize(floats.size)
|
ensureSize(floats.size)
|
||||||
buffer.put(floats)
|
System.arraycopy(floats, 0, data, size, floats.size)
|
||||||
|
size += floats.size
|
||||||
outputUpToDate = false
|
outputUpToDate = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addAll(floatList: ArrayFloatList) {
|
fun addAll(floatList: ArrayFloatList) {
|
||||||
ensureSize(floatList.size)
|
ensureSize(floatList.size)
|
||||||
if (FLOAT_PUT_METHOD == null) { // Java < 16
|
val source = if (floatList.finalized) {
|
||||||
for (i in 0 until floatList.buffer.position()) {
|
floatList.output
|
||||||
buffer.put(floatList.buffer.get(i))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
FLOAT_PUT_METHOD.invoke(buffer, buffer.position(), floatList.buffer, 0, floatList.buffer.position())
|
floatList.data
|
||||||
buffer.position(buffer.position() + floatList.buffer.position())
|
|
||||||
}
|
}
|
||||||
|
System.arraycopy(source, 0, data, size, floatList.size)
|
||||||
|
size += floatList.size
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkOutputArray() {
|
private fun checkOutputArray() {
|
||||||
if (outputUpToDate) {
|
if (outputUpToDate) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val position = buffer.position()
|
output = FloatArray(size)
|
||||||
output = FloatArray(position)
|
System.arraycopy(data, 0, output, 0, size)
|
||||||
buffer.position(0)
|
|
||||||
buffer.get(output, 0, position)
|
|
||||||
buffer.position(position)
|
|
||||||
outputUpToDate = true
|
outputUpToDate = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,22 +101,12 @@ class ArrayFloatList(
|
|||||||
|
|
||||||
fun finish() {
|
fun finish() {
|
||||||
finalized = true
|
finalized = true
|
||||||
val oldBuffer = buffer
|
checkOutputArray()
|
||||||
buffer = memAllocFloat(oldBuffer.position())
|
data = FloatArray(0)
|
||||||
if (FLOAT_PUT_METHOD == null) { // Java < 16
|
|
||||||
for (i in 0 until oldBuffer.position()) {
|
|
||||||
buffer.put(oldBuffer.get(i))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FLOAT_PUT_METHOD.invoke(buffer, 0, oldBuffer, 0, oldBuffer.position())
|
|
||||||
buffer.position(buffer.limit())
|
|
||||||
}
|
|
||||||
oldBuffer.clean()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
private val FLOAT_PUT_METHOD = KUtil.tryCatch { FloatBuffer::class.java.getMethod("put", Int::class.java, FloatBuffer::class.java, Int::class.java, Int::class.java) }
|
|
||||||
private const val DEFAULT_INITIAL_SIZE = 1000
|
private const val DEFAULT_INITIAL_SIZE = 1000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* 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.collections
|
||||||
|
|
||||||
|
import de.bixilon.minosoft.util.KUtil
|
||||||
|
import org.lwjgl.system.MemoryUtil.memAllocFloat
|
||||||
|
import org.lwjgl.system.MemoryUtil.memFree
|
||||||
|
import java.nio.FloatBuffer
|
||||||
|
|
||||||
|
class DirectArrayFloatList(
|
||||||
|
initialSize: Int = DEFAULT_INITIAL_SIZE,
|
||||||
|
) {
|
||||||
|
var buffer: FloatBuffer = memAllocFloat(initialSize) // ToDo: Clear when disconnected
|
||||||
|
private set
|
||||||
|
var finalized: Boolean = false
|
||||||
|
private set
|
||||||
|
val capacity: Int
|
||||||
|
get() = buffer.capacity()
|
||||||
|
val size: Int
|
||||||
|
get() = buffer.position()
|
||||||
|
val isEmpty: Boolean
|
||||||
|
get() = size == 0
|
||||||
|
private var unloaded = false
|
||||||
|
|
||||||
|
private val nextGrowStep = when {
|
||||||
|
initialSize <= 0 -> DEFAULT_INITIAL_SIZE
|
||||||
|
initialSize <= 50 -> 50
|
||||||
|
else -> initialSize
|
||||||
|
}
|
||||||
|
|
||||||
|
private var output: FloatArray = FloatArray(0)
|
||||||
|
private var outputUpToDate = false
|
||||||
|
|
||||||
|
private fun checkFinalized() {
|
||||||
|
if (finalized) {
|
||||||
|
throw IllegalStateException("ArrayFloatList is already finalized!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ensureSize(needed: Int) {
|
||||||
|
checkFinalized()
|
||||||
|
if (capacity - size >= needed) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var newSize = capacity
|
||||||
|
while (newSize - size < needed) {
|
||||||
|
newSize += nextGrowStep
|
||||||
|
}
|
||||||
|
val oldBuffer = buffer
|
||||||
|
buffer = memAllocFloat(newSize)
|
||||||
|
if (FLOAT_PUT_METHOD == null) { // Java < 16
|
||||||
|
for (i in 0 until oldBuffer.position()) {
|
||||||
|
buffer.put(oldBuffer.get(i))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FLOAT_PUT_METHOD.invoke(buffer, 0, oldBuffer, 0, oldBuffer.position())
|
||||||
|
buffer.position(oldBuffer.position())
|
||||||
|
}
|
||||||
|
memFree(oldBuffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(float: Float) {
|
||||||
|
ensureSize(1)
|
||||||
|
buffer.put(float)
|
||||||
|
outputUpToDate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addAll(floats: FloatArray) {
|
||||||
|
ensureSize(floats.size)
|
||||||
|
buffer.put(floats)
|
||||||
|
outputUpToDate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addAll(floatList: DirectArrayFloatList) {
|
||||||
|
ensureSize(floatList.size)
|
||||||
|
if (FLOAT_PUT_METHOD == null) { // Java < 16
|
||||||
|
for (i in 0 until floatList.buffer.position()) {
|
||||||
|
buffer.put(floatList.buffer.get(i))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FLOAT_PUT_METHOD.invoke(buffer, buffer.position(), floatList.buffer, 0, floatList.buffer.position())
|
||||||
|
buffer.position(buffer.position() + floatList.buffer.position())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addAll(floatList: ArrayFloatList) {
|
||||||
|
ensureSize(floatList.size)
|
||||||
|
buffer.put(floatList.toArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkOutputArray() {
|
||||||
|
if (outputUpToDate) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val position = buffer.position()
|
||||||
|
output = FloatArray(position)
|
||||||
|
buffer.position(0)
|
||||||
|
buffer.get(output, 0, position)
|
||||||
|
buffer.position(position)
|
||||||
|
outputUpToDate = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toArray(): FloatArray {
|
||||||
|
checkOutputArray()
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unload() {
|
||||||
|
check(!unloaded) { "Already unloaded!" }
|
||||||
|
unloaded = true
|
||||||
|
finalized = true // Is unloaded
|
||||||
|
memFree(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun finish() {
|
||||||
|
finalized = true
|
||||||
|
val oldBuffer = buffer
|
||||||
|
buffer = memAllocFloat(oldBuffer.position())
|
||||||
|
if (FLOAT_PUT_METHOD == null) { // Java < 16
|
||||||
|
for (i in 0 until oldBuffer.position()) {
|
||||||
|
buffer.put(oldBuffer.get(i))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FLOAT_PUT_METHOD.invoke(buffer, 0, oldBuffer, 0, oldBuffer.position())
|
||||||
|
buffer.position(buffer.limit())
|
||||||
|
}
|
||||||
|
memFree(oldBuffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun finalize() {
|
||||||
|
if (unloaded) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
memFree(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
private val FLOAT_PUT_METHOD = KUtil.tryCatch { FloatBuffer::class.java.getMethod("put", Int::class.java, FloatBuffer::class.java, Int::class.java, Int::class.java) }
|
||||||
|
private const val DEFAULT_INITIAL_SIZE = 1000
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user