mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-11 16:36:58 -04:00
outsource allocator, section occlusion: reuse memory
This commit is contained in:
parent
d2dfe2b7f6
commit
b174638aaf
@ -20,6 +20,7 @@ import de.bixilon.minosoft.data.registries.blocks.state.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.state.BlockStateFlags
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.properties.shape.special.FullOpaqueBlock
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.properties.shape.special.PotentialFullOpaqueBlock
|
||||
import de.bixilon.minosoft.gui.rendering.util.allocator.ShortAllocator
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet
|
||||
import java.util.*
|
||||
@ -29,7 +30,6 @@ class SectionOcclusion(
|
||||
) {
|
||||
private var occlusion = EMPTY
|
||||
private var calculate = false
|
||||
private val regions by lazy { ShortArray(ProtocolDefinition.BLOCKS_PER_SECTION) }
|
||||
|
||||
fun clear(notify: Boolean) {
|
||||
update(EMPTY, notify)
|
||||
@ -49,7 +49,13 @@ class SectionOcclusion(
|
||||
clear(notify)
|
||||
return
|
||||
}
|
||||
update(calculateOcclusion(floodFill()), notify)
|
||||
val array = ALLOCATOR.allocate(ProtocolDefinition.BLOCKS_PER_SECTION)
|
||||
try {
|
||||
val regions = floodFill(array)
|
||||
update(calculateOcclusion(regions), notify)
|
||||
} finally {
|
||||
ALLOCATOR.free(array)
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun ShortArray.updateRegion(x: Int, y: Int, z: Int, id: Short): Boolean {
|
||||
@ -85,20 +91,20 @@ class SectionOcclusion(
|
||||
if (y < ProtocolDefinition.SECTION_MAX_Y) trace(regions, x, y + 1, z, nextId)
|
||||
}
|
||||
|
||||
private fun floodFill(): ShortArray {
|
||||
private fun floodFill(array: ShortArray): ShortArray {
|
||||
// mark regions and check direct neighbours
|
||||
Arrays.fill(regions, 0.toShort())
|
||||
Arrays.fill(array, 0.toShort())
|
||||
|
||||
var next: Short = 0
|
||||
for (y in 0 until ProtocolDefinition.SECTION_HEIGHT_Y) {
|
||||
for (z in 0 until ProtocolDefinition.SECTION_WIDTH_Z) {
|
||||
for (x in 0 until ProtocolDefinition.SECTION_WIDTH_X) {
|
||||
startTrace(regions, x, y, z, ++next)
|
||||
startTrace(array, x, y, z, ++next)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return regions
|
||||
return array
|
||||
}
|
||||
|
||||
private fun calculateOcclusion(regions: ShortArray): BooleanArray {
|
||||
@ -198,6 +204,7 @@ class SectionOcclusion(
|
||||
|
||||
companion object {
|
||||
private val EMPTY = BooleanArray(CubeDirections.CUBE_DIRECTION_COMBINATIONS)
|
||||
private val ALLOCATOR = ShortAllocator()
|
||||
|
||||
|
||||
fun BlockState?._isFullyOpaque(): Boolean {
|
||||
|
@ -14,6 +14,7 @@
|
||||
package de.bixilon.minosoft.data.world.container.palette.data.array
|
||||
|
||||
import de.bixilon.minosoft.data.world.container.palette.data.PaletteData
|
||||
import de.bixilon.minosoft.gui.rendering.util.allocator.LongAllocator
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_1_16
|
||||
import de.bixilon.minosoft.protocol.protocol.buffers.play.PlayInByteBuffer
|
||||
|
||||
@ -39,7 +40,7 @@ class ArrayPaletteData(
|
||||
} else {
|
||||
(this.size + valuesPerLong - 1) / valuesPerLong
|
||||
}
|
||||
this.data = LongArrayAllocator.claim(this.size)
|
||||
this.data = ALLOCATOR.allocate(this.size)
|
||||
if (packetSize != size) {
|
||||
buffer.pointer += packetSize * Long.SIZE_BYTES // data is ignored
|
||||
return
|
||||
@ -69,10 +70,12 @@ class ArrayPaletteData(
|
||||
}
|
||||
|
||||
override fun free() {
|
||||
LongArrayAllocator.free(data)
|
||||
ALLOCATOR.free(data)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val ALLOCATOR = LongAllocator()
|
||||
const val LONG_BIT_SPLITTING_VERSION = V_1_16 // ToDo: When did this changed? is just a guess
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2025 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.util.allocator
|
||||
|
||||
@Deprecated("kutil 1.27.1")
|
||||
class LongAllocator : TemporaryAllocator<LongArray>() {
|
||||
|
||||
override fun getSize(value: LongArray) = value.size
|
||||
|
||||
override fun create(size: Int) = LongArray(size)
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2025 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.util.allocator
|
||||
|
||||
@Deprecated("kutil 1.27.1")
|
||||
class ShortAllocator : TemporaryAllocator<ShortArray>() {
|
||||
|
||||
override fun getSize(value: ShortArray) = value.size
|
||||
|
||||
override fun create(size: Int) = ShortArray(size)
|
||||
}
|
@ -11,15 +11,16 @@
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.world.container.palette.data.array
|
||||
package de.bixilon.minosoft.gui.rendering.util.allocator
|
||||
|
||||
import de.bixilon.kutil.concurrent.lock.locks.reentrant.ReentrantLock
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
|
||||
object LongArrayAllocator {
|
||||
@Deprecated("kutil 1.27.1")
|
||||
abstract class TemporaryAllocator<T> {
|
||||
private val lock = ReentrantLock()
|
||||
private val list: ArrayList<WeakReference<LongArray>> = ArrayList()
|
||||
private val list: ArrayList<WeakReference<T>> = ArrayList()
|
||||
|
||||
private fun cleanup() {
|
||||
lock.lock()
|
||||
@ -33,36 +34,41 @@ object LongArrayAllocator {
|
||||
lock.unlock()
|
||||
}
|
||||
|
||||
fun free(array: LongArray) {
|
||||
fun free(array: T) {
|
||||
lock.lock()
|
||||
cleanup()
|
||||
list.add(0, WeakReference(array))
|
||||
lock.unlock()
|
||||
}
|
||||
|
||||
fun claim(size: Int): LongArray {
|
||||
fun allocate(size: Int): T {
|
||||
lock.lock()
|
||||
|
||||
var array: LongArray? = null
|
||||
var array: T? = null
|
||||
val iterator = list.iterator()
|
||||
while (iterator.hasNext()) {
|
||||
val reference = iterator.next()
|
||||
array = reference.get()
|
||||
if (array == null) {
|
||||
val entry = reference.get()
|
||||
if (entry == null) {
|
||||
iterator.remove()
|
||||
continue
|
||||
}
|
||||
if (array.size >= size) {
|
||||
if (getSize(entry) >= size) {
|
||||
array = entry
|
||||
iterator.remove()
|
||||
break
|
||||
}
|
||||
}
|
||||
lock.unlock()
|
||||
|
||||
if (array != null && array.size >= size) return array
|
||||
if (array != null) return array
|
||||
|
||||
// println("Allocating long array of size $size")
|
||||
// println("Allocating array of size $size")
|
||||
|
||||
return LongArray(size)
|
||||
return create(size)
|
||||
}
|
||||
|
||||
protected abstract fun getSize(value: T): Int
|
||||
|
||||
abstract fun create(size: Int): T
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user