gpu: add support for osx

Compute shaders must be forced off due to macos not supporting opengl
4.3
This commit is contained in:
Adam
2020-04-29 18:24:57 -04:00
parent f95c5af4e4
commit 0e6f9f9aec
2 changed files with 180 additions and 94 deletions

View File

@@ -117,6 +117,13 @@
<classifier>natives-linux-amd64</classifier> <classifier>natives-linux-amd64</classifier>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency>
<groupId>net.runelite.jogl</groupId>
<artifactId>jogl-all</artifactId>
<version>${jogl.version}</version>
<classifier>natives-macosx-universal</classifier>
<scope>runtime</scope>
</dependency>
<dependency> <dependency>
<groupId>net.runelite.gluegen</groupId> <groupId>net.runelite.gluegen</groupId>
<artifactId>gluegen-rt</artifactId> <artifactId>gluegen-rt</artifactId>
@@ -143,6 +150,13 @@
<classifier>natives-linux-amd64</classifier> <classifier>natives-linux-amd64</classifier>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency>
<groupId>net.runelite.gluegen</groupId>
<artifactId>gluegen-rt</artifactId>
<version>${jogl.version}</version>
<classifier>natives-macosx-universal</classifier>
<scope>runtime</scope>
</dependency>
<dependency> <dependency>
<groupId>net.runelite</groupId> <groupId>net.runelite</groupId>
<artifactId>archive-patcher</artifactId> <artifactId>archive-patcher</artifactId>

View File

@@ -35,6 +35,7 @@ import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLDrawable; import com.jogamp.opengl.GLDrawable;
import com.jogamp.opengl.GLDrawableFactory; import com.jogamp.opengl.GLDrawableFactory;
import com.jogamp.opengl.GLException; import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLFBODrawable;
import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.GLProfile;
import java.awt.Canvas; import java.awt.Canvas;
import java.awt.Dimension; import java.awt.Dimension;
@@ -51,6 +52,7 @@ import javax.inject.Inject;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import jogamp.nativewindow.SurfaceScaleUtils; import jogamp.nativewindow.SurfaceScaleUtils;
import jogamp.nativewindow.jawt.x11.X11JAWTWindow; import jogamp.nativewindow.jawt.x11.X11JAWTWindow;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.newt.awt.NewtFactoryAWT; import jogamp.newt.awt.NewtFactoryAWT;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.runelite.api.BufferProvider; import net.runelite.api.BufferProvider;
@@ -286,7 +288,8 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
return false; return false;
} }
useComputeShaders = config.useComputeShaders(); // OSX supports up to OpenGL 4.1, however 4.3 is required for compute shaders
useComputeShaders = config.useComputeShaders() && OSType.getOSType() != OSType.MacOS;
canvas.setIgnoreRepaint(true); canvas.setIgnoreRepaint(true);
@@ -304,6 +307,8 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
GLProfile.initSingleton(); GLProfile.initSingleton();
invokeOnMainThread(() ->
{
GLProfile glProfile = GLProfile.get(GLProfile.GL4); GLProfile glProfile = GLProfile.get(GLProfile.GL4);
GLCapabilities glCaps = new GLCapabilities(glProfile); GLCapabilities glCaps = new GLCapabilities(glProfile);
@@ -314,6 +319,9 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
GLDrawableFactory glDrawableFactory = GLDrawableFactory.getFactory(glProfile); GLDrawableFactory glDrawableFactory = GLDrawableFactory.getFactory(glProfile);
jawtWindow.lockSurface();
try
{
glDrawable = glDrawableFactory.createGLDrawable(jawtWindow); glDrawable = glDrawableFactory.createGLDrawable(jawtWindow);
glDrawable.setRealized(true); glDrawable.setRealized(true);
@@ -323,6 +331,11 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
// Debug config on context needs to be set before .makeCurrent call // Debug config on context needs to be set before .makeCurrent call
glContext.enableGLDebugMessage(true); glContext.enableGLDebugMessage(true);
} }
}
finally
{
jawtWindow.unlockSurface();
}
int res = glContext.makeCurrent(); int res = glContext.makeCurrent();
if (res == GLContext.CONTEXT_NOT_CURRENT) if (res == GLContext.CONTEXT_NOT_CURRENT)
@@ -349,10 +362,18 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
} }
initVao(); initVao();
try
{
initProgram(); initProgram();
}
catch (ShaderException ex)
{
throw new RuntimeException(ex);
}
initInterfaceTexture(); initInterfaceTexture();
initUniformBuffer(); initUniformBuffer();
initBuffers(); initBuffers();
});
client.setDrawCallbacks(this); client.setDrawCallbacks(this);
client.setGpu(true); client.setGpu(true);
@@ -408,6 +429,8 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
client.setGpu(false); client.setGpu(false);
client.setDrawCallbacks(null); client.setDrawCallbacks(null);
invokeOnMainThread(() ->
{
if (gl != null) if (gl != null)
{ {
if (textureArrayId != -1) if (textureArrayId != -1)
@@ -441,8 +464,16 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
glContext.destroy(); glContext.destroy();
} }
// this crashes on osx when the plugin is turned back on, don't know why
// we'll just leak the window...
if (OSType.getOSType() != OSType.MacOS)
{
NewtFactoryAWT.destroyNativeWindow(jawtWindow); NewtFactoryAWT.destroyNativeWindow(jawtWindow);
} }
}
});
GLProfile.shutdown();
jawtWindow = null; jawtWindow = null;
gl = null; gl = null;
@@ -839,6 +870,42 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
@Override @Override
public void draw() public void draw()
{
invokeOnMainThread(this::drawFrame);
}
private void resize(int canvasWidth, int canvasHeight, int viewportWidth, int viewportHeight)
{
// If the viewport has changed, update the projection matrix
if (viewportWidth > 0 && viewportHeight > 0 && (viewportWidth != lastViewportWidth || viewportHeight != lastViewportHeight))
{
lastViewportWidth = viewportWidth;
lastViewportHeight = viewportHeight;
createProjectionMatrix(0, viewportWidth, viewportHeight, 0, 0, Constants.SCENE_SIZE * Perspective.LOCAL_TILE_SIZE);
}
if (canvasWidth != lastCanvasWidth || canvasHeight != lastCanvasHeight)
{
lastCanvasWidth = canvasWidth;
lastCanvasHeight = canvasHeight;
gl.glBindTexture(gl.GL_TEXTURE_2D, interfaceTexture);
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, canvasWidth, canvasHeight, 0, gl.GL_BGRA, gl.GL_UNSIGNED_INT_8_8_8_8_REV, null);
gl.glBindTexture(gl.GL_TEXTURE_2D, 0);
if (OSType.getOSType() == OSType.MacOS && glDrawable instanceof GLFBODrawable)
{
// GLDrawables created with createGLDrawable() do not have a resize listener
// I don't know why this works with Windows/Linux, but on OSX
// it prevents JOGL from resizing its FBOs and underlying GL textures. So,
// we manually trigger a resize here.
GLFBODrawable glfboDrawable = (GLFBODrawable) glDrawable;
glfboDrawable.resetSize(gl);
}
}
}
private void drawFrame()
{ {
if (jawtWindow.getAWTComponent() != client.getCanvas()) if (jawtWindow.getAWTComponent() != client.getCanvas())
{ {
@@ -862,13 +929,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
final int viewportHeight = client.getViewportHeight(); final int viewportHeight = client.getViewportHeight();
final int viewportWidth = client.getViewportWidth(); final int viewportWidth = client.getViewportWidth();
// If the viewport has changed, update the projection matrix resize(canvasWidth, canvasHeight, viewportWidth, viewportHeight);
if (viewportWidth > 0 && viewportHeight > 0 && (viewportWidth != lastViewportWidth || viewportHeight != lastViewportHeight))
{
createProjectionMatrix(0, viewportWidth, viewportHeight, 0, 0, Constants.SCENE_SIZE * Perspective.LOCAL_TILE_SIZE);
lastViewportWidth = viewportWidth;
lastViewportHeight = viewportHeight;
}
// Setup anti-aliasing // Setup anti-aliasing
final AntiAliasingMode antiAliasingMode = config.antiAliasingMode(); final AntiAliasingMode antiAliasingMode = config.antiAliasingMode();
@@ -1176,16 +1237,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA); gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA);
gl.glBindTexture(gl.GL_TEXTURE_2D, interfaceTexture); gl.glBindTexture(gl.GL_TEXTURE_2D, interfaceTexture);
if (canvasWidth != lastCanvasWidth || canvasHeight != lastCanvasHeight)
{
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0, gl.GL_BGRA, gl.GL_UNSIGNED_INT_8_8_8_8_REV, interfaceBuffer);
lastCanvasWidth = canvasWidth;
lastCanvasHeight = canvasHeight;
}
else
{
gl.glTexSubImage2D(gl.GL_TEXTURE_2D, 0, 0, 0, width, height, gl.GL_BGRA, gl.GL_UNSIGNED_INT_8_8_8_8_REV, interfaceBuffer); gl.glTexSubImage2D(gl.GL_TEXTURE_2D, 0, 0, 0, width, height, gl.GL_BGRA, gl.GL_UNSIGNED_INT_8_8_8_8_REV, interfaceBuffer);
}
// Use the texture bound in the first pass // Use the texture bound in the first pass
final UIScalingMode uiScalingMode = config.uiScalingMode(); final UIScalingMode uiScalingMode = config.uiScalingMode();
@@ -1525,6 +1577,13 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
} }
private void glDpiAwareViewport(final int x, final int y, final int width, final int height) private void glDpiAwareViewport(final int x, final int y, final int width, final int height)
{
if (OSType.getOSType() == OSType.MacOS)
{
// JOGL seems to handle DPI scaling for us already
gl.glViewport(x, y, width, height);
}
else
{ {
final AffineTransform t = ((Graphics2D) canvas.getGraphics()).getTransform(); final AffineTransform t = ((Graphics2D) canvas.getGraphics()).getTransform();
gl.glViewport( gl.glViewport(
@@ -1533,10 +1592,23 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
getScaledValue(t.getScaleX(), width), getScaledValue(t.getScaleX(), width),
getScaledValue(t.getScaleY(), height)); getScaledValue(t.getScaleY(), height));
} }
}
private int getDrawDistance() private int getDrawDistance()
{ {
final int limit = useComputeShaders ? MAX_DISTANCE : DEFAULT_DISTANCE; final int limit = useComputeShaders ? MAX_DISTANCE : DEFAULT_DISTANCE;
return Ints.constrainToRange(config.drawDistance(), 0, limit); return Ints.constrainToRange(config.drawDistance(), 0, limit);
} }
private static void invokeOnMainThread(Runnable runnable)
{
if (OSType.getOSType() == OSType.MacOS)
{
OSXUtil.RunOnMainThread(true, false, runnable);
}
else
{
runnable.run();
}
}
} }