[orx-panel] Fix handling of render targets in multi window setups

This commit is contained in:
Edwin Jakobs
2024-05-14 08:30:25 +02:00
parent badfbe9379
commit dcf04b06d6

View File

@@ -12,60 +12,6 @@ import org.openrndr.panel.style.*
import org.openrndr.panel.style.Display import org.openrndr.panel.style.Display
import org.openrndr.shape.Rectangle import org.openrndr.shape.Rectangle
//class SurfaceCache(val width: Int, val height: Int, val contentScale:Double) {
// val cache = renderTarget(width, height, contentScale) {
// colorMap()
// depthBuffer()
// }
//
// private val atlas = mutableMapOf<Element, IntRectangle>()
//
// private var root: PackNode = PackNode(IntRectangle(0, 0, width, height))
// val packer = IntPacker()
//
// fun flush() {
// atlas.clear()
// root = PackNode(IntRectangle(0, 0, width, height))
// }
//
// fun drawCached(drawer: Drawer, element: Element, f: () -> Unit): IntRectangle {
// val rectangle = atlas.getOrPut(element) {
// val r = packer.insert(root, IntRectangle(0, 0, Math.ceil(element.layout.screenWidth).toInt(),
// Math.ceil(element.layout.screenHeight).toInt()))?.area?:throw RuntimeException("bork")
// draw(drawer, r, f)
// r
// }
// if (element.draw.dirty) {
// draw(drawer, rectangle, f)
// }
// drawer.ortho()
// drawer.isolated {
// drawer.model = Matrix44.IDENTITY
// drawer.image(cache.colorMap(0), Rectangle(rectangle.corner.x * 1.0, rectangle.corner.y * 1.0, rectangle.width * 1.0, rectangle.height * 1.0),
// element.screenArea)
// }
// return rectangle
// }
//
// fun draw(drawer: Drawer, rectangle: IntRectangle, f: () -> Unit) {
// drawer.isolatedWithTarget(cache) {
// drawer.ortho(cache)
// drawer.drawStyle.blendMode = BlendMode.REPLACE
// drawer.drawStyle.fill = ColorRGBa.BLACK.opacify(0.0)
// drawer.drawStyle.stroke = null
// drawer.view = Matrix44.IDENTITY
// drawer.model = Matrix44.IDENTITY
// drawer.rectangle(Rectangle(rectangle.x * 1.0, rectangle.y * 1.0, rectangle.width * 1.0, rectangle.height * 1.0))
//
// drawer.drawStyle.blendMode = BlendMode.OVER
// drawer.drawStyle.clip = Rectangle(rectangle.x * 1.0, rectangle.y * 1.0, rectangle.width * 1.0, rectangle.height * 1.0)
// drawer.view = Matrix44.IDENTITY
// drawer.model = org.openrndr.math.transforms.translate(rectangle.x * 1.0, rectangle.y * 1.0, 0.0)
// f()
// }
// }
//}
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
class ControlManager : Extension { class ControlManager : Extension {
@@ -79,7 +25,7 @@ class ControlManager : Extension {
override var enabled: Boolean = true override var enabled: Boolean = true
var contentScale = 1.0 var contentScale = 1.0
lateinit var renderTarget: RenderTarget var renderTarget: RenderTarget? = null
init { init {
fontManager.register("default", resourceUrl("/fonts/Roboto-Regular.ttf")) fontManager.register("default", resourceUrl("/fonts/Roboto-Regular.ttf"))
@@ -96,8 +42,6 @@ class ControlManager : Extension {
val dropInput = DropInput() val dropInput = DropInput()
inner class KeyboardInput { inner class KeyboardInput {
private var lastTarget: Element? = null private var lastTarget: Element? = null
var target: Element? = null var target: Element? = null
@@ -130,7 +74,8 @@ class ControlManager : Extension {
if (event.key == KEY_TAB) { if (event.key == KEY_TAB) {
val focusableControls = body?.findAllVisible { it.handlesKeyboardFocus } ?: emptyList() val focusableControls = body?.findAllVisible { it.handlesKeyboardFocus } ?: emptyList()
val index = target?.let { focusableControls.indexOf(it) } ?: lastTarget?.let { focusableControls.indexOf(it) } ?: -1 val index = target?.let { focusableControls.indexOf(it) }
?: lastTarget?.let { focusableControls.indexOf(it) } ?: -1
if (focusableControls.isNotEmpty()) { if (focusableControls.isNotEmpty()) {
target = if (target != null) { target = if (target != null) {
@@ -282,7 +227,16 @@ class ControlManager : Extension {
val toRemove = insideElements.filter { (event.position !in it.screenArea) } val toRemove = insideElements.filter { (event.position !in it.screenArea) }
toRemove.forEach { toRemove.forEach {
it.mouse.exited.trigger(MouseEvent(event.position, Vector2.ZERO, Vector2.ZERO, MouseEventType.MOVED, MouseButton.NONE, event.modifiers)) it.mouse.exited.trigger(
MouseEvent(
event.position,
Vector2.ZERO,
Vector2.ZERO,
MouseEventType.MOVED,
MouseButton.NONE,
event.modifiers
)
)
} }
insideElements.removeAll(toRemove) insideElements.removeAll(toRemove)
@@ -327,9 +281,7 @@ class ControlManager : Extension {
contentScale = program.window.contentScale contentScale = program.window.contentScale
window = program.window window = program.window
//surfaceCache = SurfaceCache(4096, 4096, contentScale)
fontManager.contentScale = contentScale fontManager.contentScale = contentScale
// program.mouse.buttonUp.listen { mouseInput.release(it) }
program.mouse.buttonUp.listen { mouseInput.click(it) } program.mouse.buttonUp.listen { mouseInput.click(it) }
program.mouse.moved.listen { mouseInput.move(it) } program.mouse.moved.listen { mouseInput.move(it) }
program.mouse.scrolled.listen { mouseInput.scroll(it) } program.mouse.scrolled.listen { mouseInput.scroll(it) }
@@ -346,9 +298,6 @@ class ControlManager : Extension {
width = program.width width = program.width
height = program.height height = program.height
renderTarget = renderTarget(program.width, program.height, contentScale) {
colorBuffer()
}
body?.draw?.dirty = true body?.draw?.dirty = true
} }
@@ -363,14 +312,17 @@ class ControlManager : Extension {
// check if user did not minimize window // check if user did not minimize window
if (width > 0 && height > 0) { if (width > 0 && height > 0) {
body?.draw?.dirty = true body?.draw?.dirty = true
if (renderTarget.colorAttachments.isNotEmpty()) { val lrc = renderTarget
renderTarget.colorBuffer(0).destroy() if (lrc != null) {
renderTarget.depthBuffer?.destroy() if (lrc.colorAttachments.isNotEmpty()) {
renderTarget.detachColorAttachments() lrc.colorBuffer(0).destroy()
renderTarget.detachDepthBuffer() lrc.depthBuffer?.destroy()
renderTarget.destroy() lrc.detachColorAttachments()
} else { lrc.detachDepthBuffer()
logger.error { "that is strange. no color buffers" } lrc.destroy()
} else {
logger.error { "that is strange. no color buffers" }
}
} }
renderTarget = renderTarget(program.width, program.height, contentScale) { renderTarget = renderTarget(program.width, program.height, contentScale) {
@@ -378,9 +330,9 @@ class ControlManager : Extension {
depthBuffer() depthBuffer()
} }
renderTarget.bind() renderTarget?.bind()
program.drawer.clear(ColorRGBa.BLACK.opacify(0.0)) program.drawer.clear(ColorRGBa.BLACK.opacify(0.0))
renderTarget.unbind() renderTarget?.unbind()
renderTargetCache.forEach { (_, u) -> u.destroy() } renderTargetCache.forEach { (_, u) -> u.destroy() }
renderTargetCache.clear() renderTargetCache.clear()
@@ -389,12 +341,12 @@ class ControlManager : Extension {
private fun drawElement(element: Element, drawer: Drawer, zIndex: Int, zComp: Int) { private fun drawElement(element: Element, drawer: Drawer, zIndex: Int, zComp: Int) {
val newZComp = val newZComp =
element.computedStyle.zIndex.let { element.computedStyle.zIndex.let {
when (it) { when (it) {
is ZIndex.Value -> it.value is ZIndex.Value -> it.value
else -> zComp else -> zComp
}
} }
}
if (element.computedStyle.display != Display.NONE) { if (element.computedStyle.display != Display.NONE) {
if (element.computedStyle.overflow == Overflow.Visible) { if (element.computedStyle.overflow == Overflow.Visible) {
@@ -404,12 +356,6 @@ class ControlManager : Extension {
if (newZComp == zIndex) { if (newZComp == zIndex) {
element.draw(drawer) element.draw(drawer)
} }
// if (newZComp == zIndex) {
// surfaceCache.drawCached(drawer, element) {
// element.draw(drawer)
// }
//
// }
} }
element.children.forEach { element.children.forEach {
drawElement(it, drawer, zIndex, newZComp) drawElement(it, drawer, zIndex, newZComp)
@@ -446,8 +392,10 @@ class ControlManager : Extension {
drawer.drawStyle.blendMode = BlendMode.OVER drawer.drawStyle.blendMode = BlendMode.OVER
//drawer.image(rt.colorMap(0)) //drawer.image(rt.colorMap(0))
drawer.image(rt.colorBuffer(0), Rectangle(Vector2(area.x, area.y), area.width, area.height), drawer.image(
Rectangle(Vector2(area.x, area.y), area.width, area.height)) rt.colorBuffer(0), Rectangle(Vector2(area.x, area.y), area.width, area.height),
Rectangle(Vector2(area.x, area.y), area.width, area.height)
)
} }
} }
element.draw.dirty = false element.draw.dirty = false
@@ -475,67 +423,63 @@ class ControlManager : Extension {
var drawCount = 0 var drawCount = 0
override fun afterDraw(drawer: Drawer, program: Program) { override fun afterDraw(drawer: Drawer, program: Program) {
if (program.width > 0 && program.height > 0) { if (program.width > 0 && program.height > 0) {
profile("after draw") { if (program.width != renderTarget?.width || program.height != renderTarget?.height) {
body?.draw?.dirty = true
if (program.width != renderTarget.width || program.height != renderTarget.height) { renderTarget?.colorBuffer(0)?.destroy()
profile("resize target") { renderTarget?.destroy()
body?.draw?.dirty = true renderTarget = null
renderTarget.colorBuffer(0).destroy()
renderTarget.destroy()
renderTarget = renderTarget(program.width, program.height, contentScale) {
colorBuffer()
}
renderTarget.bind()
program.drawer.clear(ColorRGBa.BLACK.opacify(0.0))
renderTarget.unbind()
}
}
val redraw = body?.any {
it.draw.dirty
} ?: false
if (redraw) {
drawer.ortho()
drawer.view = Matrix44.IDENTITY
drawer.defaults()
profile("redraw") {
renderTarget.bind()
body?.style = StyleSheet(CompoundSelector())
body?.style?.width = program.width.px
body?.style?.height = program.height.px
body?.let {
program.drawer.clear(ColorRGBa.BLACK.opacify(0.0))
layouter.computeStyles(it)
layouter.layout(it)
drawElement(it, program.drawer, 0, 0)
drawElement(it, program.drawer, 1, 0)
drawElement(it, program.drawer, 1000, 0)
}
renderTarget.unbind()
}
}
body?.visit {
draw.dirty = false
}
profile("draw image") {
drawer.ortho(RenderTarget.active)
drawer.view = Matrix44.IDENTITY
drawer.defaults()
program.drawer.image(renderTarget.colorBuffer(0), 0.0, 0.0)
}
drawCount++
} }
if (renderTarget == null) {
renderTarget = renderTarget(program.width, program.height, contentScale) {
colorBuffer()
}
renderTarget!!.bind()
program.drawer.clear(ColorRGBa.BLACK.opacify(0.0))
renderTarget!!.unbind()
}
val redraw = body?.any {
it.draw.dirty
} ?: false
if (redraw) {
drawer.ortho()
drawer.view = Matrix44.IDENTITY
drawer.defaults()
renderTarget!!.bind()
body?.style = StyleSheet(CompoundSelector())
body?.style?.width = program.width.px
body?.style?.height = program.height.px
body?.let {
program.drawer.clear(ColorRGBa.BLACK.opacify(0.0))
layouter.computeStyles(it)
layouter.layout(it)
drawElement(it, program.drawer, 0, 0)
drawElement(it, program.drawer, 1, 0)
drawElement(it, program.drawer, 1000, 0)
}
renderTarget!!.unbind()
}
body?.visit {
draw.dirty = false
}
drawer.ortho(RenderTarget.active)
drawer.view = Matrix44.IDENTITY
drawer.defaults()
program.drawer.image(renderTarget!!.colorBuffer(0), 0.0, 0.0)
drawCount++
} }
} }
} }
@Deprecated("use new style extend")
class ControlManagerBuilder(val controlManager: ControlManager) { class ControlManagerBuilder(val controlManager: ControlManager) {
fun styleSheet(selector: CompoundSelector, init: StyleSheet.() -> Unit): StyleSheet { fun styleSheet(selector: CompoundSelector, init: StyleSheet.() -> Unit): StyleSheet {
val styleSheet = StyleSheet(selector).apply { init() } val styleSheet = StyleSheet(selector).apply { init() }
@@ -571,17 +515,10 @@ fun ControlManager.layout(init: Body.() -> Unit) {
this.body = body this.body = body
} }
@Deprecated("use Program.controlManager") fun Program.controlManager(
fun controlManager(defaultStyles: List<StyleSheet> = defaultStyles(), builder: ControlManagerBuilder.() -> Unit): ControlManager { defaultStyles: List<StyleSheet> = defaultStyles(),
val cm = ControlManager() builder: ControlManagerBuilder.() -> Unit
cm.fontManager.register("default", resourceUrl("/fonts/Roboto-Regular.ttf")) ): ControlManager {
cm.layouter.styleSheets.addAll(defaultStyles.flatMap { it.flatten() })
val cmb = ControlManagerBuilder(cm)
cmb.builder()
return cm
}
fun Program.controlManager(defaultStyles: List<StyleSheet> = defaultStyles(), builder: ControlManagerBuilder.() -> Unit): ControlManager {
val cm = ControlManager() val cm = ControlManager()
cm.program = this cm.program = this
cm.fontManager.register("default", resourceUrl("/fonts/Roboto-Regular.ttf")) cm.fontManager.register("default", resourceUrl("/fonts/Roboto-Regular.ttf"))