Skip to content

Commit

Permalink
FXAA integration on macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
Штенгауэр Никита Дмитриевич committed Dec 4, 2023
1 parent 6239005 commit 2144cd4
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -28,19 +30,21 @@ 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
private lateinit var context: GLContext

private var needsRepaint = AtomicBoolean(false)

private val fxaaShader by lazy { FXAAShader() }

override fun renderContent(g: Graphics) {
if(scaledWidth == 0 || scaledHeight == 0 || disposed)
return
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(){
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down
Binary file not shown.
9 changes: 9 additions & 0 deletions modules/native/src/openglfx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ glfun(void, nInitGLFunctions)(JNIEnv* env, jobject) {
a_glUseProgram = (glUseProgramPtr)a_GetProcAddress("glUseProgram");
a_glUseProgram = (glUseProgramPtr)a_GetProcAddress("glUseProgram");
a_glGetUniformLocation = (glGetUniformLocationPtr)a_GetProcAddress("glGetUniformLocation");
a_glGetAttribLocation = (glGetAttribLocationPtr)a_GetProcAddress("glGetAttribLocation");
a_glUniform2f = (glUniform2fPtr)a_GetProcAddress("glUniform2f");
a_glGetShaderiv = (glGetShaderivPtr)a_GetProcAddress("glGetShaderiv");
a_glGetShaderInfoLog = (glGetShaderInfoLogPtr)a_GetProcAddress("glGetShaderInfoLog");
Expand Down Expand Up @@ -234,6 +235,14 @@ glfun(jint, glGetUniformLocation)(JNIEnv* env, jobject, jint program, jstring na
return location;
}

glfun(jint, glGetAttribLocation)(JNIEnv* env, jobject, jint program, jstring name) {
const char* nameCh = env->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);
}
Expand Down
2 changes: 2 additions & 0 deletions modules/native/src/openglfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 2144cd4

Please sign in to comment.