Skip to content

Commit

Permalink
feat: move DoubleDestructionProtection into separate class
Browse files Browse the repository at this point in the history
  • Loading branch information
silenium-dev committed Oct 7, 2024
1 parent 755c624 commit b484368
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 38 deletions.
22 changes: 8 additions & 14 deletions src/main/java/dev/silenium/compose/gl/fbo/FBO.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ package dev.silenium.compose.gl.fbo
import androidx.compose.ui.unit.IntSize
import dev.silenium.compose.gl.objects.Renderbuffer
import dev.silenium.compose.gl.objects.Texture
import dev.silenium.compose.gl.util.DoubleDestructionProtection
import dev.silenium.compose.gl.util.checkGLError
import org.lwjgl.opengl.GL30.*
import org.slf4j.LoggerFactory
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference

data class FBO(
val id: Int,
override val id: Int,
val size: IntSize,
val colorAttachment: Texture,
val depthStencilAttachment: Renderbuffer,
) {
) : DoubleDestructionProtection<Int>() {
fun bind() {
glBindFramebuffer(GL_FRAMEBUFFER, id)
checkGLError("glBindFramebuffer")
Expand All @@ -25,20 +26,13 @@ data class FBO(
checkGLError("glBindFramebuffer")
}

private val destroyed = AtomicBoolean(false)
fun destroy() {
if (destroyed.compareAndExchange(false, true)) {
glDeleteFramebuffers(id)
colorAttachment.destroy()
depthStencilAttachment.destroy()
} else {
logger.trace("FBO $id is already destroyed", Exception())
}
override fun destroyInternal() {
glDeleteFramebuffers(id)
colorAttachment.destroy()
depthStencilAttachment.destroy()
}

companion object {
private val logger = LoggerFactory.getLogger(FBO::class.java)

fun create(
colorAttachment: Texture,
depthStencilAttachment: Renderbuffer,
Expand Down
16 changes: 4 additions & 12 deletions src/main/java/dev/silenium/compose/gl/objects/Renderbuffer.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package dev.silenium.compose.gl.objects

import androidx.compose.ui.unit.IntSize
import dev.silenium.compose.gl.util.DoubleDestructionProtection
import dev.silenium.compose.gl.util.checkGLError
import org.lwjgl.opengl.GL30.*
import org.slf4j.LoggerFactory
import java.util.concurrent.atomic.AtomicBoolean

data class Renderbuffer(
override val id: Int,
override val size: IntSize,
override val internalFormat: Int,
) : TextureOrRenderbuffer {
) : TextureOrRenderbuffer, DoubleDestructionProtection<Int>() {
override val target: Int = GL_RENDERBUFFER
override val binding: Int = GL_RENDERBUFFER_BINDING

Expand All @@ -24,18 +23,11 @@ data class Renderbuffer(
checkGLError("glBindRenderbuffer")
}

private val destroyed = AtomicBoolean(false)
override fun destroy() {
if (destroyed.compareAndExchange(false, true)) {
glDeleteRenderbuffers(id)
} else {
logger.trace("Texture $id is already destroyed")
}
override fun destroyInternal() {
glDeleteRenderbuffers(id)
}

companion object {
private val logger = LoggerFactory.getLogger(Renderbuffer::class.java)

fun create(size: IntSize, internalFormat: Int): Renderbuffer {
val id = glGenRenderbuffers()
checkGLError("glGenRenderbuffers")
Expand Down
16 changes: 4 additions & 12 deletions src/main/java/dev/silenium/compose/gl/objects/Texture.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@ package dev.silenium.compose.gl.objects

import androidx.compose.ui.unit.IntSize
import dev.silenium.compose.gl.objects.TextureOrRenderbuffer.Companion.textureTargetBindings
import dev.silenium.compose.gl.util.DoubleDestructionProtection
import dev.silenium.compose.gl.util.checkGLError
import org.lwjgl.opengl.GL11.*
import org.slf4j.LoggerFactory
import java.util.concurrent.atomic.AtomicBoolean

data class Texture(
override val id: Int,
override val size: IntSize,
override val target: Int,
override val internalFormat: Int,
) : TextureOrRenderbuffer {
) : TextureOrRenderbuffer, DoubleDestructionProtection<Int>() {
init {
require(target in textureTargetBindings) { "Unsupported texture target: $target" }
}
Expand All @@ -29,18 +28,11 @@ data class Texture(
checkGLError("glBindTexture")
}

private val destroyed = AtomicBoolean(false)
override fun destroy() {
if (destroyed.compareAndExchange(false, true)) {
glDeleteTextures(id)
} else {
logger.trace("Texture $id is already destroyed")
}
override fun destroyInternal() {
glDeleteTextures(id)
}

companion object {
private val logger = LoggerFactory.getLogger(Texture::class.java)

fun create(
target: Int,
size: IntSize,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package dev.silenium.compose.gl.util

import org.slf4j.LoggerFactory
import java.util.concurrent.atomic.AtomicBoolean

abstract class DoubleDestructionProtection<ID> {
abstract val id: ID

private val destroyed = AtomicBoolean(false)
private var destructionPoint: Throwable? = null
fun destroy() {
if (destroyed.compareAndSet(false, true)) {
destroyInternal()
destructionPoint = Exception()
} else {
logger.trace(
"{} {} was already destroyed at: {}",
javaClass.simpleName,
id,
destroyed.get(),
Exception(),
)
}
}

protected abstract fun destroyInternal()

companion object {
private val logger = LoggerFactory.getLogger(DoubleDestructionProtection::class.java)
}
}

0 comments on commit b484368

Please sign in to comment.