From 2144cd4aa0043acf58277853c1428abbf139998b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A8=D1=82=D0=B5=D0=BD=D0=B3=D0=B0=D1=83=D1=8D=D1=80=20?= =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20=D0=94=D0=BC=D0=B8=D1=82?= =?UTF-8?q?=D1=80=D0=B8=D0=B5=D0=B2=D0=B8=D1=87?= Date: Mon, 4 Dec 2023 13:05:22 +0300 Subject: [PATCH] FXAA integration on macOS --- .../com/huskerdev/openglfx/GLExecutor.kt | 5 +- .../internal/canvas/IOSurfaceCanvasImpl.kt | 60 ++++++++++++------ .../canvas/async/AsyncIOSurfaceCanvasImpl.kt | 25 +++++--- .../internal/shaders/PassthroughShader.kt | 14 ++-- .../huskerdev/openglfx/natives/openglfx.dylib | Bin 141520 -> 141664 bytes modules/native/src/openglfx.cpp | 9 +++ modules/native/src/openglfx.h | 2 + 7 files changed, 76 insertions(+), 39 deletions(-) diff --git a/modules/core/src/main/kotlin/com/huskerdev/openglfx/GLExecutor.kt b/modules/core/src/main/kotlin/com/huskerdev/openglfx/GLExecutor.kt index fccbed7..333b1d2 100644 --- a/modules/core/src/main/kotlin/com/huskerdev/openglfx/GLExecutor.kt +++ b/modules/core/src/main/kotlin/com/huskerdev/openglfx/GLExecutor.kt @@ -15,9 +15,7 @@ import com.huskerdev.openglfx.internal.canvas.async.AsyncBlitCanvasImpl import com.huskerdev.openglfx.internal.canvas.async.AsyncIOSurfaceCanvasImpl import com.huskerdev.openglfx.internal.canvas.async.AsyncNVDXInteropCanvasImpl import com.huskerdev.openglfx.internal.canvas.async.AsyncSharedCanvasImpl -import java.nio.ByteBuffer -import java.nio.ByteOrder -import java.nio.FloatBuffer +import java.nio.* internal const val GL_BGRA = 0x80E1 @@ -90,6 +88,7 @@ open class GLExecutor { @JvmStatic external fun glLinkProgram(program: Int) @JvmStatic external fun glUseProgram(program: Int) @JvmStatic external fun glGetUniformLocation(program: Int, name: String): Int + @JvmStatic external fun glGetAttribLocation(program: Int, name: String): Int @JvmStatic external fun glUniform2f(location: Int, value1: Float, value2: Float) @JvmStatic external fun glGetShaderi(shader: Int, pname: Int): Int @JvmStatic external fun glGetShaderInfoLog(shader: Int): String diff --git a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/IOSurfaceCanvasImpl.kt b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/IOSurfaceCanvasImpl.kt index 5fc200c..647b761 100644 --- a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/IOSurfaceCanvasImpl.kt +++ b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/IOSurfaceCanvasImpl.kt @@ -3,6 +3,7 @@ package com.huskerdev.openglfx.internal.canvas import com.huskerdev.ojgl.GLContext import com.huskerdev.openglfx.* import com.huskerdev.openglfx.GLExecutor.Companion.glBindTexture +import com.huskerdev.openglfx.GLExecutor.Companion.glFinish import com.huskerdev.openglfx.GLExecutor.Companion.glGenTextures import com.huskerdev.openglfx.GLExecutor.Companion.glViewport import com.huskerdev.openglfx.canvas.GLCanvas @@ -15,6 +16,7 @@ import com.huskerdev.openglfx.internal.Size import com.huskerdev.openglfx.internal.fbo.Framebuffer import com.huskerdev.openglfx.internal.fbo.MultiSampledFramebuffer import com.huskerdev.openglfx.internal.iosurface.IOSurface +import com.huskerdev.openglfx.internal.shaders.FXAAShader import com.sun.prism.Graphics import com.sun.prism.Texture import java.util.concurrent.atomic.AtomicBoolean @@ -28,12 +30,12 @@ open class IOSurfaceCanvasImpl( private lateinit var ioSurface: IOSurface private lateinit var fxTexture: Texture - private val lastSize = Size() + private val drawSize = Size() private lateinit var fboFX: Framebuffer private lateinit var sharedFboFX: Framebuffer private lateinit var sharedFboGL: Framebuffer - private lateinit var msaaFBO: MultiSampledFramebuffer + private var msaaFBO: MultiSampledFramebuffer? = null private lateinit var fxContext: GLContext private lateinit var fxWrapperContext: GLContext @@ -41,6 +43,8 @@ open class IOSurfaceCanvasImpl( private var needsRepaint = AtomicBoolean(false) + private val fxaaShader by lazy { FXAAShader() } + override fun renderContent(g: Graphics) { if(scaledWidth == 0 || scaledHeight == 0 || disposed) return @@ -54,42 +58,50 @@ open class IOSurfaceCanvasImpl( } context.makeCurrent() - lastSize.executeOnDifferenceWith(scaledSize, ::updateFramebufferSize, canvas::fireReshapeEvent) + if(drawSize != scaledSize || + msaa != (msaaFBO?.requestedSamples ?: 0) + ){ + scaledSize.copyTo(drawSize) + updateFramebufferSize(drawSize.width, drawSize.height) + canvas.fireReshapeEvent(drawSize.width, drawSize.height) + } - glViewport(0, 0, lastSize.width, lastSize.height) - canvas.fireRenderEvent(if(msaa != 0) msaaFBO.id else sharedFboGL.id) - if(msaa != 0) - msaaFBO.blitTo(sharedFboGL) + glViewport(0, 0, drawSize.width, drawSize.height) + canvas.fireRenderEvent(msaaFBO?.id ?: sharedFboGL.id) + msaaFBO?.blitTo(sharedFboGL) + glFinish() fxWrapperContext.makeCurrent() - glViewport(0, 0, lastSize.width, lastSize.height) + glViewport(0, 0, drawSize.width, drawSize.height) sharedFboFX.blitTo(fboFX) + if(fxaa) fxaaShader.apply(fboFX, fboFX) + glFinish() fxContext.makeCurrent() drawResultTexture(g, fxTexture) } private fun updateFramebufferSize(width: Int, height: Int){ - if (::sharedFboGL.isInitialized) { + if(::ioSurface.isInitialized) ioSurface.dispose() - fxTexture.dispose() - - fboFX.delete() - sharedFboFX.delete() - sharedFboGL.delete() - if(msaa != 0) msaaFBO.delete() - } - ioSurface = IOSurface(width, height) // Create JavaFX texture fxContext.makeCurrent() + if(::fxTexture.isInitialized) + fxTexture.dispose() fxTexture = GLFXUtils.createPermanentFXTexture(width, height) + fxWrapperContext.makeCurrent() + if(::fboFX.isInitialized){ + fboFX.delete() + sharedFboFX.delete() + } + // Create FX-side shared texture val ioFXTexture = glGenTextures() glBindTexture(GL_TEXTURE_RECTANGLE, ioFXTexture) - ioSurface.cglTexImageIOSurface2D(fxContext, GL_TEXTURE_RECTANGLE, GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0) + ioSurface.cglTexImageIOSurface2D(fxWrapperContext, GL_TEXTURE_RECTANGLE, GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0) glBindTexture(GL_TEXTURE_RECTANGLE, 0) // Create JavaFX buffers @@ -98,6 +110,11 @@ open class IOSurfaceCanvasImpl( // Create GL-side shared texture context.makeCurrent() + if(::sharedFboGL.isInitialized){ + sharedFboGL.delete() + msaaFBO?.delete() + } + val ioGLTexture = glGenTextures() glBindTexture(GL_TEXTURE_RECTANGLE, ioGLTexture) ioSurface.cglTexImageIOSurface2D(context, GL_TEXTURE_RECTANGLE, GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0) @@ -109,8 +126,11 @@ open class IOSurfaceCanvasImpl( // Create multi-sampled framebuffer if(msaa != 0) { msaaFBO = MultiSampledFramebuffer(msaa, width, height) - msaaFBO.bindFramebuffer() - } else sharedFboGL.bindFramebuffer() + msaaFBO?.bindFramebuffer() + } else { + msaaFBO = null + sharedFboGL.bindFramebuffer() + } } override fun repaint() = needsRepaint.set(true) diff --git a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncIOSurfaceCanvasImpl.kt b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncIOSurfaceCanvasImpl.kt index a7d9830..ea8ec6f 100644 --- a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncIOSurfaceCanvasImpl.kt +++ b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/canvas/async/AsyncIOSurfaceCanvasImpl.kt @@ -3,6 +3,7 @@ package com.huskerdev.openglfx.internal.canvas.async import com.huskerdev.ojgl.GLContext import com.huskerdev.openglfx.* import com.huskerdev.openglfx.GLExecutor.Companion.glBindTexture +import com.huskerdev.openglfx.GLExecutor.Companion.glFinish import com.huskerdev.openglfx.GLExecutor.Companion.glGenTextures import com.huskerdev.openglfx.GLExecutor.Companion.glViewport import com.huskerdev.openglfx.canvas.GLCanvas @@ -50,7 +51,6 @@ open class AsyncIOSurfaceCanvasImpl( private var needsBlit = AtomicBoolean(false) - private val passthroughShader by lazy { PassthroughShader() } private val fxaaShader by lazy { FXAAShader() } private fun initializeThread(){ @@ -112,15 +112,19 @@ open class AsyncIOSurfaceCanvasImpl( initializeThread() if (needsBlit.getAndSet(false)) { - fxContextWrapper.makeCurrent() synchronized(blitLock){ resultSize.executeOnDifferenceWith(interopTextureSize) { width, height -> updateResultTextureSize(width, height) - glViewport(0, 0, scaledWidth, scaledHeight) + fxContextWrapper.makeCurrent() + glViewport(0, 0, width, height) } - (if(fxaa) fxaaShader else passthroughShader).apply(sharedFboFX, fboFX) - fxContext.makeCurrent() + fxContextWrapper.makeCurrent() + // We can't skip this blit, so blit at first, then apply shader + sharedFboFX.blitTo(fboFX) + if(fxaa) fxaaShader.apply(fboFX, fboFX) + glFinish() } + fxContext.makeCurrent() } if(this::fxTexture.isInitialized) drawResultTexture(g, fxTexture) @@ -161,20 +165,21 @@ open class AsyncIOSurfaceCanvasImpl( } private fun updateResultTextureSize(width: Int, height: Int){ - if (::fxTexture.isInitialized) { + // Create JavaFX texture + if (::fxTexture.isInitialized) fxTexture.dispose() + fxTexture = GLFXUtils.createPermanentFXTexture(width, height) + fxContextWrapper.makeCurrent() + if(::fboFX.isInitialized){ fboFX.delete() sharedFboFX.delete() } - // Create JavaFX texture - fxTexture = GLFXUtils.createPermanentFXTexture(width, height) - // Create FX-side shared texture val ioFXTexture = glGenTextures() glBindTexture(GL_TEXTURE_RECTANGLE, ioFXTexture) - ioSurface.cglTexImageIOSurface2D(fxContext, GL_TEXTURE_RECTANGLE, GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0) + ioSurface.cglTexImageIOSurface2D(fxContextWrapper, GL_TEXTURE_RECTANGLE, GL_RGBA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0) glBindTexture(GL_TEXTURE_RECTANGLE, 0) // Create JavaFX buffers diff --git a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/shaders/PassthroughShader.kt b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/shaders/PassthroughShader.kt index 77174ae..9804450 100644 --- a/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/shaders/PassthroughShader.kt +++ b/modules/core/src/main/kotlin/com/huskerdev/openglfx/internal/shaders/PassthroughShader.kt @@ -20,6 +20,7 @@ import com.huskerdev.openglfx.GLExecutor.Companion.glLinkProgram import com.huskerdev.openglfx.GLExecutor.Companion.glShaderSource import com.huskerdev.openglfx.GLExecutor.Companion.glVertexAttribPointer import com.huskerdev.openglfx.GLExecutor.Companion.glEnableVertexAttribArray +import com.huskerdev.openglfx.GLExecutor.Companion.glGetAttribLocation import com.huskerdev.openglfx.GLExecutor.Companion.glGetShaderInfoLog import com.huskerdev.openglfx.GLExecutor.Companion.glGetShaderi import com.huskerdev.openglfx.GLExecutor.Companion.glGetUniformLocation @@ -46,7 +47,8 @@ internal open class PassthroughShader( ) { private val program: Int private val vao: Int - private val texSizeLoc: Int + private val positionLoc: Int + private val sizeLoc: Int init { val vertex = glCreateShader(GL_VERTEX_SHADER) @@ -68,7 +70,8 @@ internal open class PassthroughShader( glDeleteShader(vertex) glDeleteShader(fragment) - texSizeLoc = glGetUniformLocation(program, "size") + positionLoc = glGetAttribLocation(program, "position") + sizeLoc = glGetUniformLocation(program, "size") vao = glGenVertexArrays() glBindVertexArray(vao) @@ -79,16 +82,15 @@ internal open class PassthroughShader( -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f )), GL_STATIC_DRAW) - glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0) - glEnableVertexAttribArray(0) + glVertexAttribPointer(positionLoc, 2, GL_FLOAT, false, 0, 0) + glEnableVertexAttribArray(positionLoc) glBindVertexArray(0) - glDeleteBuffers(vbo) } fun apply(source: Framebuffer, target: Framebuffer){ glUseProgram(program) - glUniform2f(texSizeLoc, target.width.toFloat(), target.height.toFloat()) + glUniform2f(sizeLoc, target.width.toFloat(), target.height.toFloat()) glBindTexture(GL_TEXTURE_2D, source.texture) glBindFramebuffer(GL_FRAMEBUFFER, target.id) diff --git a/modules/core/src/main/resources/com/huskerdev/openglfx/natives/openglfx.dylib b/modules/core/src/main/resources/com/huskerdev/openglfx/natives/openglfx.dylib index 7602d2fb5b905c65f8ba4fbfe13ac28a48ed8c21..c5cd7fab564bd18177ce7316a2a9b4fc69f1a07b 100755 GIT binary patch delta 9982 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 z%~r$g2md8@GetStringUTFChars(name, 0); + + jint location = (jint)a_glGetAttribLocation(program, nameCh); + env->ReleaseStringUTFChars(name, nameCh); + return location; +} + glfun(void, glUniform2f)(JNIEnv* env, jobject, jint program, jfloat value1, jfloat value2) { a_glUniform2f(program, value1, value2); } diff --git a/modules/native/src/openglfx.h b/modules/native/src/openglfx.h index 5f9a8fe..1387277 100644 --- a/modules/native/src/openglfx.h +++ b/modules/native/src/openglfx.h @@ -94,6 +94,7 @@ typedef void (*glAttachShaderPtr)(GLuint program, GLuint shader); typedef void (*glLinkProgramPtr)(GLuint program); typedef void (*glUseProgramPtr)(GLuint program); typedef GLint (*glGetUniformLocationPtr)(GLuint program, const GLchar *name); +typedef GLint (*glGetAttribLocationPtr)(GLuint program, const GLchar *name); typedef void (*glUniform2fPtr)(GLint location, GLfloat v0, GLfloat v1); typedef void (*glGetShaderivPtr)(GLuint shader, GLenum pname, GLint *params); typedef void (*glGetShaderInfoLogPtr)(GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog); @@ -139,6 +140,7 @@ static glAttachShaderPtr a_glAttachShader; static glLinkProgramPtr a_glLinkProgram; static glUseProgramPtr a_glUseProgram; static glGetUniformLocationPtr a_glGetUniformLocation; +static glGetAttribLocationPtr a_glGetAttribLocation; static glUniform2fPtr a_glUniform2f; static glGetShaderivPtr a_glGetShaderiv; static glGetShaderInfoLogPtr a_glGetShaderInfoLog;