mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-09 07:20:04 -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.opengl.buffer.FloatOpenGLBuffer
|
||||
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.glGenVertexArrays
|
||||
import org.lwjgl.opengl.GL11.*
|
||||
@ -33,7 +32,6 @@ class FloatOpenGLVertexBuffer(override val structure: MeshStruct, data: FloatBuf
|
||||
glBufferData(type.gl, buffer, drawTypes.gl)
|
||||
state = RenderBufferStates.UPLOADED
|
||||
|
||||
buffer.clean()
|
||||
_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.system.base.buffer.vertex.FloatVertexBuffer
|
||||
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_.vec3.Vec3
|
||||
|
||||
@ -27,8 +27,8 @@ abstract class Mesh(
|
||||
initialCacheSize: Int = 10000,
|
||||
) {
|
||||
val order = renderWindow.renderSystem.primitiveMeshOrder
|
||||
private var _data: ArrayFloatList? = ArrayFloatList(initialCacheSize)
|
||||
var data: ArrayFloatList
|
||||
private var _data: DirectArrayFloatList? = DirectArrayFloatList(initialCacheSize)
|
||||
var data: DirectArrayFloatList
|
||||
get() = _data!!
|
||||
set(value) {
|
||||
_data = value
|
||||
@ -45,8 +45,9 @@ abstract class Mesh(
|
||||
|
||||
fun load() {
|
||||
buffer = renderWindow.renderSystem.createVertexBuffer(struct, data.buffer, primitiveType)
|
||||
_data = null
|
||||
buffer.init()
|
||||
data.unload()
|
||||
_data = null
|
||||
vertices = buffer.vertices
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,6 @@ import glm_.vec2.Vec2t
|
||||
import glm_.vec3.Vec3t
|
||||
import glm_.vec4.Vec4t
|
||||
import okio.Buffer
|
||||
import org.lwjgl.system.MemoryUtil.memFree
|
||||
import sun.misc.Unsafe
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
@ -506,8 +505,4 @@ object KUtil {
|
||||
this.get(array)
|
||||
return array
|
||||
}
|
||||
|
||||
fun java.nio.Buffer.clean() {
|
||||
memFree(this)
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,27 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
* 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 de.bixilon.minosoft.util.KUtil.clean
|
||||
import org.lwjgl.system.MemoryUtil.memAllocFloat
|
||||
import java.nio.FloatBuffer
|
||||
|
||||
class ArrayFloatList(
|
||||
initialSize: Int = DEFAULT_INITIAL_SIZE,
|
||||
) {
|
||||
var buffer: FloatBuffer = memAllocFloat(initialSize) // ToDo: Clear when disconnected
|
||||
private set
|
||||
private var data: FloatArray = FloatArray(initialSize)
|
||||
var finalized: Boolean = false
|
||||
private set
|
||||
val capacity: Int
|
||||
get() = buffer.capacity()
|
||||
val size: Int
|
||||
get() = buffer.position()
|
||||
val limit: Int
|
||||
get() = data.size
|
||||
var size = 0
|
||||
private set
|
||||
val isEmpty: Boolean
|
||||
get() = size == 0
|
||||
|
||||
@ -49,66 +42,55 @@ class ArrayFloatList(
|
||||
|
||||
fun clear() {
|
||||
checkFinalized()
|
||||
buffer.clean()
|
||||
size = 0
|
||||
outputUpToDate = false
|
||||
output = FloatArray(0)
|
||||
}
|
||||
|
||||
private fun ensureSize(needed: Int) {
|
||||
checkFinalized()
|
||||
if (capacity - size >= needed) {
|
||||
if (limit - size >= needed) {
|
||||
return
|
||||
}
|
||||
var newSize = capacity
|
||||
var newSize = data.size
|
||||
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())
|
||||
}
|
||||
oldBuffer.clean()
|
||||
val oldData = data
|
||||
data = FloatArray(newSize)
|
||||
System.arraycopy(oldData, 0, data, 0, oldData.size)
|
||||
}
|
||||
|
||||
fun add(float: Float) {
|
||||
ensureSize(1)
|
||||
buffer.put(float)
|
||||
data[size++] = float
|
||||
outputUpToDate = false
|
||||
}
|
||||
|
||||
fun addAll(floats: FloatArray) {
|
||||
ensureSize(floats.size)
|
||||
buffer.put(floats)
|
||||
System.arraycopy(floats, 0, data, size, floats.size)
|
||||
size += floats.size
|
||||
outputUpToDate = false
|
||||
}
|
||||
|
||||
fun addAll(floatList: ArrayFloatList) {
|
||||
ensureSize(floatList.size)
|
||||
if (FLOAT_PUT_METHOD == null) { // Java < 16
|
||||
for (i in 0 until floatList.buffer.position()) {
|
||||
buffer.put(floatList.buffer.get(i))
|
||||
}
|
||||
val source = if (floatList.finalized) {
|
||||
floatList.output
|
||||
} else {
|
||||
FLOAT_PUT_METHOD.invoke(buffer, buffer.position(), floatList.buffer, 0, floatList.buffer.position())
|
||||
buffer.position(buffer.position() + floatList.buffer.position())
|
||||
floatList.data
|
||||
}
|
||||
System.arraycopy(source, 0, data, size, floatList.size)
|
||||
size += floatList.size
|
||||
}
|
||||
|
||||
private fun checkOutputArray() {
|
||||
if (outputUpToDate) {
|
||||
return
|
||||
}
|
||||
val position = buffer.position()
|
||||
output = FloatArray(position)
|
||||
buffer.position(0)
|
||||
buffer.get(output, 0, position)
|
||||
buffer.position(position)
|
||||
output = FloatArray(size)
|
||||
System.arraycopy(data, 0, output, 0, size)
|
||||
outputUpToDate = true
|
||||
}
|
||||
|
||||
@ -119,22 +101,12 @@ class ArrayFloatList(
|
||||
|
||||
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())
|
||||
}
|
||||
oldBuffer.clean()
|
||||
checkOutputArray()
|
||||
data = FloatArray(0)
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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