Skip to content

Commit

Permalink
Dispose improvements, added NVDXInterop objects
Browse files Browse the repository at this point in the history
  • Loading branch information
Штенгауэр Никита Дмитриевич committed Nov 21, 2023
1 parent 3eed041 commit 7d48de7
Show file tree
Hide file tree
Showing 17 changed files with 185 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ abstract class GLCanvas(
open fun dispose(){
disposed = true
animator = null
onDispose.dispatchEvent(createDisposeEvent())
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ open class BlitCanvasImpl(
}

private var initialized = false
private var context: GLContext? = null
private lateinit var context: GLContext

private var image = WritableImage(1, 1)

private var pixelByteBuffer: ByteBuffer? = null
private lateinit var pixelByteBuffer: ByteBuffer
private lateinit var pixelBuffer: PixelBuffer<ByteBuffer>

private lateinit var fbo: Framebuffer
Expand All @@ -57,11 +57,10 @@ open class BlitCanvasImpl(
initialized = true

context = GLContext.create(0L, profile == GLProfile.Core)
context!!.makeCurrent()
context.makeCurrent()
executor.initGLFunctions()
fireInitEvent()
}
context!!.makeCurrent()

lastSize.onDifference(scaledWidth, scaledHeight){
updateFramebufferSize(scaledWidth, scaledHeight)
Expand Down Expand Up @@ -92,11 +91,11 @@ open class BlitCanvasImpl(
return

if(image.width.toInt() != renderWidth || image.height.toInt() != renderHeight){
if(pixelByteBuffer != null)
unsafe.invokeCleaner(pixelByteBuffer!!)
if(::pixelByteBuffer.isInitialized)
unsafe.invokeCleaner(pixelByteBuffer)

pixelByteBuffer = ByteBuffer.allocateDirect(renderWidth * renderHeight * 4)
pixelBuffer = PixelBuffer(renderWidth, renderHeight, pixelByteBuffer!!, PixelFormat.getByteBgraPreInstance())
pixelBuffer = PixelBuffer(renderWidth, renderHeight, pixelByteBuffer, PixelFormat.getByteBgraPreInstance())

image = WritableImage(pixelBuffer)
}
Expand All @@ -105,7 +104,7 @@ open class BlitCanvasImpl(
val oldReadBuffer = GLExecutor.glGetInteger(GL_READ_FRAMEBUFFER_BINDING)

fbo.bindFramebuffer()
glReadPixels(0, 0, renderWidth, renderHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixelByteBuffer!!)
glReadPixels(0, 0, renderWidth, renderHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixelByteBuffer)

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oldDrawBuffer)
glBindFramebuffer(GL_READ_FRAMEBUFFER, oldReadBuffer)
Expand Down Expand Up @@ -137,7 +136,7 @@ open class BlitCanvasImpl(

override fun dispose() {
super.dispose()
unsafe.invokeCleaner(pixelByteBuffer!!)
GLContext.delete(context!!)
if(::pixelByteBuffer.isInitialized) unsafe.invokeCleaner(pixelByteBuffer)
if(::context.isInitialized) GLContext.delete(context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,11 @@ open class IOSurfaceCanvasImpl(

override fun dispose() {
super.dispose()
GLContext.delete(context)
ioSurface.dispose()
fxTexture.dispose()
if(::sharedFboFX.isInitialized) sharedFboFX.delete()
if(::fboFX.isInitialized) fboFX.delete()
if(::fxTexture.isInitialized) fxTexture.dispose()

if(::context.isInitialized) GLContext.delete(context)
if(::ioSurface.isInitialized) ioSurface.dispose()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,7 @@ import com.huskerdev.openglfx.internal.fbo.Framebuffer
import com.huskerdev.openglfx.internal.d3d9.D3D9Device
import com.huskerdev.openglfx.internal.d3d9.D3D9Texture
import com.huskerdev.openglfx.internal.d3d9.NVDXInterop
import com.huskerdev.openglfx.internal.d3d9.NVDXInterop.Companion.interopHandle
import com.huskerdev.openglfx.internal.d3d9.NVDXInterop.Companion.wglDXLockObjectsNV
import com.huskerdev.openglfx.internal.d3d9.NVDXInterop.Companion.wglDXRegisterObjectNV
import com.huskerdev.openglfx.internal.d3d9.NVDXInterop.Companion.wglDXSetResourceShareHandleNV
import com.huskerdev.openglfx.internal.d3d9.NVDXInterop.Companion.wglDXUnlockObjectsNV
import com.huskerdev.openglfx.internal.d3d9.NVDXInterop.Companion.wglDXUnregisterObjectNV
import com.huskerdev.openglfx.internal.d3d9.NVDXInterop.Companion.interopDevice
import com.huskerdev.openglfx.internal.d3d9.WGL_ACCESS_WRITE_DISCARD_NV
import com.sun.prism.Graphics
import com.sun.prism.GraphicsPipeline
Expand All @@ -35,54 +30,50 @@ open class NVDXInteropCanvasImpl(
) : GLCanvas(GLInteropType.NVDXInterop, profile, flipY, msaa, false){

private var lastSize = Size(-1, -1)
private var initialized = false

private var needsRepaint = AtomicBoolean(false)

private lateinit var fbo: Framebuffer
private lateinit var msaaFBO: MultiSampledFramebuffer

private var context: GLContext? = null
private lateinit var context: GLContext
private val fxDevice = D3D9Device.fxInstance

private lateinit var fxD3DTexture: D3D9Texture
private lateinit var fxTexture: Texture

private var interopTexture = -1L
private lateinit var interopObject: NVDXInterop.NVDXObject

override fun onNGRender(g: Graphics) {
if(width == 0.0 || height == 0.0)
return

if(!initialized){
initialized = true

if(!::context.isInitialized){
context = GLContext.create(0, profile == GLProfile.Core)
context!!.makeCurrent()
context.makeCurrent()
executor.initGLFunctions()
}
context!!.makeCurrent()

lastSize.onDifference(scaledWidth, scaledHeight) {
updateFramebufferSize(scaledWidth, scaledHeight)

wglDXLockObjectsNV(interopHandle, interopTexture)
interopObject.lock()
fireReshapeEvent(scaledWidth, scaledHeight)
}
wglDXLockObjectsNV(interopHandle, interopTexture)
interopObject.lock()

glViewport(0, 0, lastSize.width, lastSize.height)
fireRenderEvent(if(msaa != 0) msaaFBO.id else fbo.id)
if(msaa != 0)
msaaFBO.blitTo(fbo.id)

wglDXUnlockObjectsNV(interopHandle, interopTexture)
interopObject.unlock()
drawResultTexture(g, fxTexture)
}

private fun updateFramebufferSize(width: Int, height: Int) {
if (::fbo.isInitialized) {
wglDXUnregisterObjectNV(interopHandle, interopTexture)
interopObject.dispose()
fxTexture.dispose()

fbo.delete()
Expand All @@ -101,18 +92,15 @@ open class NVDXInteropCanvasImpl(

// Create and register D3D9 shared texture
fxD3DTexture = fxDevice.createTexture(width, height)
wglDXSetResourceShareHandleNV(fxD3DTexture.handle, fxD3DTexture.sharedHandle)
NVDXInterop.linkShareHandle(fxD3DTexture.handle, fxD3DTexture.sharedHandle)

// Create default JavaFX texture and replace native handle with custom one
// Create default JavaFX texture and replace a native handle with custom one.
fxTexture = GraphicsPipeline.getDefaultResourceFactory().createTexture(PixelFormat.BYTE_BGRA_PRE, Texture.Usage.DYNAMIC, Texture.WrapMode.CLAMP_TO_EDGE, width, height)
fxTexture.makePermanent()
NVDXInterop.replaceD3DTextureInResource(fxTexture.D3DTextureResource, fxD3DTexture.handle)
D3D9Device.replaceD3DTextureInResource(fxTexture.D3DTextureResource, fxD3DTexture.handle)

// Create interop texture
interopTexture = wglDXRegisterObjectNV(interopHandle, fxD3DTexture.handle, fbo.texture, GL_TEXTURE_2D, WGL_ACCESS_WRITE_DISCARD_NV)

// For some reason the context resets by this time, so make it current again
context!!.makeCurrent()
interopObject = interopDevice.registerObject(fxD3DTexture.handle, fbo.texture, GL_TEXTURE_2D, WGL_ACCESS_WRITE_DISCARD_NV)
}

override fun repaint() = needsRepaint.set(true)
Expand All @@ -124,6 +112,8 @@ open class NVDXInteropCanvasImpl(

override fun dispose() {
super.dispose()
GLContext.delete(context!!)
if(::interopObject.isInitialized) interopObject.dispose()
if(::fxTexture.isInitialized) fxTexture.dispose()
if(::context.isInitialized) GLContext.delete(context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,23 @@ open class SharedCanvasImpl(

private var lastSize = Size(-1, -1)

private var context: GLContext? = null
private var fxContext: GLContext? = null
private lateinit var context: GLContext
private lateinit var fxContext: GLContext

private lateinit var fbo: Framebuffer
private lateinit var msaaFBO: MultiSampledFramebuffer

private var fxTexture: Texture? = null
private lateinit var fxTexture: Texture

private var needsRepaint = AtomicBoolean(false)

override fun onNGRender(g: Graphics) {
if (context == null) {
if (!::context.isInitialized) {
fxContext = GLContext.current()
context = GLContext.create(fxContext!!, profile == GLProfile.Core)
context = GLContext.create(fxContext, profile == GLProfile.Core)
executor.initGLFunctions()
}
context!!.makeCurrent()
context.makeCurrent()

lastSize.onDifference(scaledWidth, scaledHeight){
updateFramebufferSize(scaledWidth, scaledHeight)
Expand All @@ -55,9 +55,9 @@ open class SharedCanvasImpl(
msaaFBO.blitTo(fbo.id)

glFinish()
fxContext!!.makeCurrent()
fxContext.makeCurrent()

drawResultTexture(g, fxTexture!!)
drawResultTexture(g, fxTexture)
}

private fun updateFramebufferSize(width: Int, height: Int) {
Expand All @@ -66,15 +66,16 @@ open class SharedCanvasImpl(
if(msaa != 0) msaaFBO.delete()
}

fxContext!!.makeCurrent()
fxContext.makeCurrent()
// Create JavaFX texture
fxTexture?.dispose()
if(::fxTexture.isInitialized)
fxTexture.dispose()
fxTexture = GraphicsPipeline.getDefaultResourceFactory().createTexture(PixelFormat.BYTE_BGRA_PRE, Texture.Usage.DYNAMIC, Texture.WrapMode.CLAMP_TO_EDGE, width, height)
fxTexture!!.makePermanent()
context!!.makeCurrent()
fxTexture.makePermanent()
context.makeCurrent()

// Create framebuffer that connected to JavaFX's texture
fbo = Framebuffer(width, height, existingTexture = fxTexture!!.GLTextureId)
fbo = Framebuffer(width, height, existingTexture = fxTexture.GLTextureId)
fbo.bindFramebuffer()

// Create multi-sampled framebuffer
Expand All @@ -93,6 +94,7 @@ open class SharedCanvasImpl(

override fun dispose() {
super.dispose()
GLContext.delete(context!!)
if(::fxTexture.isInitialized) fxTexture.dispose()
if(::context.isInitialized) GLContext.delete(context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ open class AsyncBlitCanvasImpl(

private lateinit var context: GLContext

private var pixelByteBuffer: ByteBuffer? = null
private lateinit var pixelByteBuffer: ByteBuffer
private lateinit var pixelBuffer: PixelBuffer<ByteBuffer>
private lateinit var image: WritableImage

Expand All @@ -66,7 +66,7 @@ open class AsyncBlitCanvasImpl(
lastResultSize.onDifference(lastDrawSize.width, lastDrawSize.height){
updateResultTextureSize(lastDrawSize.width, lastDrawSize.height)
}
fbo.readPixels(0, 0, lastResultSize.width, lastResultSize.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixelByteBuffer!!)
fbo.readPixels(0, 0, lastResultSize.width, lastResultSize.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixelByteBuffer)
pixelBuffer.bufferDirty(null)
}
needsBlit.set(true)
Expand Down Expand Up @@ -122,10 +122,10 @@ open class AsyncBlitCanvasImpl(
}

private fun updateResultTextureSize(width: Int, height: Int) {
if(pixelByteBuffer != null)
unsafe.invokeCleaner(pixelByteBuffer!!)
if(::pixelByteBuffer.isInitialized)
unsafe.invokeCleaner(pixelByteBuffer)
pixelByteBuffer = ByteBuffer.allocateDirect(width * height * 4)
pixelBuffer = PixelBuffer(width, height, pixelByteBuffer!!, PixelFormat.getByteBgraPreInstance())
pixelBuffer = PixelBuffer(width, height, pixelByteBuffer, PixelFormat.getByteBgraPreInstance())
image = WritableImage(pixelBuffer)
}

Expand All @@ -145,7 +145,7 @@ open class AsyncBlitCanvasImpl(
synchronized(paintLock){
paintLock.notifyAll()
}
unsafe.invokeCleaner(pixelByteBuffer!!)
GLContext.delete(context)
if(::pixelByteBuffer.isInitialized) unsafe.invokeCleaner(pixelByteBuffer)
if(::context.isInitialized) GLContext.delete(context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ open class AsyncIOSurfaceCanvasImpl(

private fun initializeThread(){
fxContext = GLContext.current()
thread {
thread(isDaemon = true) {
context = GLContext.create(0, profile == GLProfile.Core)
context.makeCurrent()
executor.initGLFunctions()
Expand Down Expand Up @@ -168,8 +168,11 @@ open class AsyncIOSurfaceCanvasImpl(
synchronized(paintLock){
paintLock.notifyAll()
}
GLContext.delete(context)
ioSurface.dispose()
fxTexture.dispose()
if(::sharedFboFX.isInitialized) sharedFboFX.delete()
if(::fboFX.isInitialized) fboFX.delete()
if(::fxTexture.isInitialized) fxTexture.dispose()

if(::context.isInitialized) GLContext.delete(context)
if(::ioSurface.isInitialized) ioSurface.dispose()
}
}
Loading

0 comments on commit 7d48de7

Please sign in to comment.