properly lock dynamic texture array

This commit is contained in:
Bixilon 2022-06-16 15:00:18 +02:00
parent b7c0390e04
commit 1feb95a387
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.system.opengl.texture.dynamic
import de.bixilon.kotlinglm.vec2.Vec2i
import de.bixilon.kutil.concurrent.lock.thread.ThreadLock
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
import de.bixilon.kutil.latch.CountUpAndDownLatch
import de.bixilon.minosoft.gui.rendering.RenderWindow
@ -44,6 +45,7 @@ class OpenGLDynamicTextureArray(
val resolution: Int,
) : DynamicTextureArray {
private var textures: Array<WeakReference<OpenGLDynamicTexture>?> = arrayOfNulls(initialSize)
private val lock = ThreadLock()
private var textureId = -1
var shaders: MutableSet<Shader> = mutableSetOf()
@ -74,13 +76,14 @@ class OpenGLDynamicTextureArray(
renderWindow.textureManager.staticTextures.activate()
}
@Synchronized
override fun pushBuffer(identifier: UUID, force: Boolean, data: () -> ByteBuffer): OpenGLDynamicTexture {
lock.lock()
check(textureId >= 0) { "Dynamic texture array not yet initialized!" }
cleanup()
for (textureReference in textures) {
val texture = textureReference?.get()
if (texture?.uuid == identifier) {
lock.unlock()
return texture
}
}
@ -94,7 +97,9 @@ class OpenGLDynamicTextureArray(
if (bytes.limit() > resolution * resolution * 4 || bytes.limit() < resolution * 4) { // allow anything in 1..resolution for y size
Log.log(LogMessageType.ASSETS, LogLevels.WARN) { "Dynamic texture $texture, has not a size of ${resolution}x${resolution}!" }
lock.lock()
textures[index] = null
lock.unlock()
texture.state = DynamicTextureState.UNLOADED
return
}
@ -114,6 +119,7 @@ class OpenGLDynamicTextureArray(
} else {
DefaultThreadPool += { load() }
}
lock.unlock()
return texture
}
@ -154,17 +160,21 @@ class OpenGLDynamicTextureArray(
}
private fun getNextIndex(): Int {
lock.lock()
for ((index, texture) in textures.withIndex()) {
if (texture == null) {
lock.unlock()
return index
}
}
val nextIndex = textures.size
grow()
lock.unlock()
return nextIndex
}
private fun reload() {
lock.lock()
glDeleteTextures(textureId)
load(CountUpAndDownLatch(0))
@ -176,19 +186,23 @@ class OpenGLDynamicTextureArray(
for (shader in shaders) {
_use(shader)
}
lock.unlock()
}
private fun grow() {
lock.lock()
val textures: Array<WeakReference<OpenGLDynamicTexture>?> = arrayOfNulls(textures.size + initialSize)
for ((index, texture) in this.textures.withIndex()) {
textures[index] = texture
}
this.textures = textures
renderWindow.queue += { reload() }
lock.unlock()
}
@Synchronized
private fun cleanup() {
lock.lock()
for ((index, reference) in textures.withIndex()) {
if (reference == null) {
continue
@ -204,5 +218,6 @@ class OpenGLDynamicTextureArray(
texture.state = DynamicTextureState.UNLOADED
textures[index] = null
}
lock.unlock()
}
}