Add layer and post buffer caching
This commit is contained in:
@@ -4,6 +4,21 @@ import org.openrndr.color.ColorRGBa
|
||||
import org.openrndr.draw.*
|
||||
import org.openrndr.math.Matrix44
|
||||
|
||||
|
||||
private val postBufferCache = mutableListOf<ColorBuffer>()
|
||||
|
||||
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<Filter, Filter.() -> Unit>? = null
|
||||
val postFilters: MutableList<Pair<Filter, Filter.() -> 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()
|
||||
|
||||
val llt = layerTarget
|
||||
if (llt == null || (llt.width != rt.width || llt.height != rt.height)) {
|
||||
layerTarget?.deepDestroy()
|
||||
layerTarget = renderTarget(rt.width, rt.height) {
|
||||
colorBuffer()
|
||||
depthBuffer()
|
||||
}
|
||||
}
|
||||
|
||||
drawer.isolatedWithTarget(layerTarget) {
|
||||
drawer.background(ColorRGBa.TRANSPARENT)
|
||||
drawFunc()
|
||||
children.forEach {
|
||||
it.draw(drawer)
|
||||
layerTarget?.let { target ->
|
||||
drawer.isolatedWithTarget(target) {
|
||||
drawer.background(ColorRGBa.TRANSPARENT)
|
||||
drawFunc()
|
||||
children.forEach {
|
||||
it.draw(drawer)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (postFilters.size > 0) {
|
||||
val sizeMismatch = if (postBufferCache.isNotEmpty()) {
|
||||
postBufferCache[0].width != rt.width || postBufferCache[0].height != rt.height
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
val (tmpTargets, layerPost) = postFilters.let { filters ->
|
||||
val targets = List(Math.min(filters.size, 2)) {
|
||||
colorBuffer(rt.width, rt.height)
|
||||
if (sizeMismatch) {
|
||||
postBufferCache.forEach { it.destroy() }
|
||||
postBufferCache.clear()
|
||||
}
|
||||
|
||||
if (postBufferCache.isEmpty()) {
|
||||
postBufferCache += colorBuffer(rt.width, rt.height)
|
||||
postBufferCache += colorBuffer(rt.width, rt.height)
|
||||
}
|
||||
}
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
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 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))
|
||||
}
|
||||
} else {
|
||||
lblend.first.apply(lblend.second)
|
||||
lblend.first.apply(arrayOf(rt.colorBuffer(0), layerPost), rt.colorBuffer(0))
|
||||
}
|
||||
|
||||
tmpTargets.forEach {
|
||||
it.destroy()
|
||||
}
|
||||
|
||||
layerTarget.colorBuffer(0).destroy()
|
||||
layerTarget.depthBuffer?.destroy()
|
||||
layerTarget.detachColorBuffers()
|
||||
layerTarget.detachDepthBuffer()
|
||||
layerTarget.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user