diff --git a/orx-compositor/src/main/kotlin/Compositor.kt b/orx-compositor/src/main/kotlin/Compositor.kt index dbb72e2fb..a7c383236 100644 --- a/orx-compositor/src/main/kotlin/Compositor.kt +++ b/orx-compositor/src/main/kotlin/Compositor.kt @@ -4,6 +4,21 @@ import org.openrndr.color.ColorRGBa import org.openrndr.draw.* import org.openrndr.math.Matrix44 + +private val postBufferCache = mutableListOf() + +fun RenderTarget.deepDestroy() { + val cbcopy = colorBuffers.map { it} + val dbcopy = depthBuffer + detachDepthBuffer() + detachColorBuffers() + cbcopy.forEach { + it.destroy() + } + dbcopy?.destroy() + destroy() +} + /** * A single layer representation */ @@ -13,60 +28,75 @@ class Layer internal constructor() { var blendFilter: Pair Unit>? = null val postFilters: MutableList Unit>> = mutableListOf() + private var layerTarget:RenderTarget? = null + /** * draw the layer */ fun draw(drawer: Drawer) { val rt = RenderTarget.active - val layerTarget = renderTarget(rt.width, rt.height) { - colorBuffer() - depthBuffer() - } - drawer.isolatedWithTarget(layerTarget) { - drawer.background(ColorRGBa.TRANSPARENT) - drawFunc() - children.forEach { - it.draw(drawer) + val llt = layerTarget + if (llt == null || (llt.width != rt.width || llt.height != rt.height)) { + layerTarget?.deepDestroy() + layerTarget = renderTarget(rt.width, rt.height) { + colorBuffer() + depthBuffer() } - } - val (tmpTargets, layerPost) = postFilters.let { filters -> - val targets = List(Math.min(filters.size, 2)) { - colorBuffer(rt.width, rt.height) + layerTarget?.let { target -> + drawer.isolatedWithTarget(target) { + drawer.background(ColorRGBa.TRANSPARENT) + drawFunc() + children.forEach { + it.draw(drawer) + } } - val result = filters.foldIndexed(layerTarget.colorBuffer(0)) { i, source, filter -> - val target = targets[i % targets.size] - filter.first.apply(filter.second) - filter.first.apply(source, target) - target + + if (postFilters.size > 0) { + val sizeMismatch = if (postBufferCache.isNotEmpty()) { + postBufferCache[0].width != rt.width || postBufferCache[0].height != rt.height + } else { + false + } + + if (sizeMismatch) { + postBufferCache.forEach { it.destroy() } + postBufferCache.clear() + } + + if (postBufferCache.isEmpty()) { + postBufferCache += colorBuffer(rt.width, rt.height) + postBufferCache += colorBuffer(rt.width, rt.height) + } } - Pair(targets, result) - } - val lblend = blendFilter - if (lblend == null) { - drawer.isolatedWithTarget(rt) { - drawer.ortho(rt) - drawer.view = Matrix44.IDENTITY - drawer.model = Matrix44.IDENTITY - drawer.image(layerPost, layerPost.bounds, drawer.bounds) + val layerPost = postFilters.let { filters -> + val targets = postBufferCache + val result = filters.foldIndexed(target.colorBuffer(0)) { i, source, filter -> + val target = targets[i % targets.size] + filter.first.apply(filter.second) + filter.first.apply(source, target) + target + } + result } - } else { - lblend.first.apply(lblend.second) - lblend.first.apply(arrayOf(rt.colorBuffer(0), layerPost), rt.colorBuffer(0)) - } - tmpTargets.forEach { - it.destroy() + val lblend = blendFilter + if (lblend == null) { + drawer.isolatedWithTarget(rt) { + //drawer.ortho(rt) + drawer.ortho() + drawer.view = Matrix44.IDENTITY + drawer.model = Matrix44.IDENTITY + drawer.image(layerPost, layerPost.bounds, drawer.bounds) + } + } else { + lblend.first.apply(lblend.second) + lblend.first.apply(arrayOf(rt.colorBuffer(0), layerPost), rt.colorBuffer(0)) + } } - - layerTarget.colorBuffer(0).destroy() - layerTarget.depthBuffer?.destroy() - layerTarget.detachColorBuffers() - layerTarget.detachDepthBuffer() - layerTarget.destroy() } }