Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GL.createCapabilities() can't find current context with GLFW OSMesa #595

Closed
skoeven opened this issue Oct 6, 2020 · 2 comments
Closed

Comments

@skoeven
Copy link

skoeven commented Oct 6, 2020

Environment

  • LWJGL version: 3.2.3
  • LWJGL build #: SNAPSHOT
  • Java version: 1.8
  • Platform: Linux (Ubuntu Server 20.04)
  • Module: glfw

Description

I am attempting to use OSMesa with GLFW via the GLFW_OSMESA_CONTEXT_API window hint on a headless VM with no GPU. I can create a window successfully and get an OpenGL context but when I call GL.createCapabilities() it fails with the error: Exception in thread "main" java.lang.IllegalStateException: There is no OpenGL context current in the current thread.

At first I thought that maybe the OSMesa support wasn't working in the GLFW native library provided by LWJGL so I compiled GLFW with only OSMesa but got the same error.

Here is the code I am running to test this:

package test;

import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.GL;

import static org.lwjgl.glfw.GLFW.GLFW_CLIENT_API;
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_CREATION_API;
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR;
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR;
import static org.lwjgl.glfw.GLFW.GLFW_FALSE;
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_API;
import static org.lwjgl.glfw.GLFW.GLFW_OSMESA_CONTEXT_API;
import static org.lwjgl.glfw.GLFW.GLFW_VISIBLE;
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
import static org.lwjgl.glfw.GLFW.glfwDestroyWindow;
import static org.lwjgl.glfw.GLFW.glfwGetCurrentContext;
import static org.lwjgl.glfw.GLFW.glfwGetVersionString;
import static org.lwjgl.glfw.GLFW.glfwGetWindowAttrib;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
import static org.lwjgl.glfw.GLFW.glfwSetErrorCallback;
import static org.lwjgl.glfw.GLFW.glfwTerminate;
import static org.lwjgl.glfw.GLFW.glfwWindowHint;
import static org.lwjgl.opengl.GL11.GL_RENDERER;
import static org.lwjgl.opengl.GL11.GL_VENDOR;
import static org.lwjgl.opengl.GL11.GL_VERSION;
import static org.lwjgl.opengl.GL11.glGetString;

public class TestMain {
    public static void main(String[] args) {
	System.out.println("Attempting to create window using GLFW " + glfwGetVersionString());

	glfwSetErrorCallback(GLFWErrorCallback.createPrint());

	if (!glfwInit()) {
		throw new RuntimeException("Failed to init GLFW");
	}

	glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_OSMESA_CONTEXT_API);
	glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);

	long window = glfwCreateWindow(640, 480, "Test", 0, 0);

	if(window == 0) {
		glfwTerminate();
		throw new RuntimeException("Failed to create window!");
	} else {
		glfwMakeContextCurrent(window);
		long context = glfwGetCurrentContext();
		if (context == window) {
			System.out.println("glfwGetCurrentContext() - Found window context.");
		}

		if (GLFW_OSMESA_CONTEXT_API == glfwGetWindowAttrib(window, GLFW_CONTEXT_CREATION_API)) {
			System.out.println("Using OSMesa context creation api");
		}

		int client = glfwGetWindowAttrib(window, GLFW_CLIENT_API);
		int major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
		int minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
		if (client == GLFW_OPENGL_API) {
			System.out.println("Context = OpenGL " + major + "." + minor);
		}

		GL.createCapabilities();
	}

	System.out.println("OpenGL Vendor: " + glGetString(GL_VENDOR));
	System.out.println("OpenGL Renderer: " + glGetString(GL_RENDERER));
	System.out.println("OpenGL Version: " + glGetString(GL_VERSION));

	glfwDestroyWindow(window);
	glfwTerminate();
    }
}

Here is the command used to run the code while using the LWJGL provided libglfw.so:
Command:
xvfb-run -a -s "-screen 0 1024x768x16" java -Dorg.lwjgl.util.Debug=true -jar OSMesaTest-1.0-SNAPSHOT-all.jar

Output:
[LWJGL] Version: 3.2.3 SNAPSHOT
[LWJGL] OS: Linux v5.4.0-48-generic
[LWJGL] JRE: 1.8.0_265 amd64
[LWJGL] JVM: OpenJDK 64-Bit Server VM v25.265-b01 by Private Build
[LWJGL] Loading JNI library: lwjgl
[LWJGL] Module: org.lwjgl
[LWJGL] Loaded from org.lwjgl.librarypath: /tmp/lwjglender/3.2.3-SNAPSHOT/liblwjgl.so
[LWJGL] Loading library: glfw
[LWJGL] Module: org.lwjgl.glfw
[LWJGL] Loaded from org.lwjgl.librarypath: /tmp/lwjglender/3.2.3-SNAPSHOT/libglfw.so
Attempting to create window using GLFW 3.4.0 X11 GLX EGL OSMesa clock_gettime evdev shared
[LWJGL] Warning: Failed to instantiate memory allocator: org.lwjgl.system.jemalloc.JEmallocAllocator. Using the system default.
[LWJGL] MemoryUtil allocator: StdlibAllocator
glfwGetCurrentContext() - Found window context.
Using OSMesa context creation api
Context = OpenGL 3.1
[LWJGL] Loading JNI library: lwjgl_opengl
[LWJGL] Module: org.lwjgl.opengl
[LWJGL] Loaded from org.lwjgl.librarypath: /tmp/lwjglender/3.2.3-SNAPSHOT/liblwjgl_opengl.so
[LWJGL] Loading library: libGL.so.1
[LWJGL] Module: org.lwjgl.opengl
[LWJGL] libGL.so.1 not found in org.lwjgl.librarypath=/tmp/lwjglender/3.2.3-SNAPSHOT
[LWJGL] Loaded from system paths: /lib/x86_64-linux-gnu/libGL.so.1
Exception in thread "main" java.lang.IllegalStateException: There is no OpenGL context current in the current thread.
at org.lwjgl.opengl.GL.createCapabilities(GL.java:378)
at org.lwjgl.opengl.GL.createCapabilities(GL.java:322)
at TestMain.checkOpenGLCompatability(TestMain.java:68)
at TestMain.main(TestMain.java:27)

Here is the command I ran while using GLFW compiled with only OSMesa support (no need for xvfb with OSMesa only):
Command:
java -Dorg.lwjgl.util.Debug=true -jar OSMesaTest-1.0-SNAPSHOT-all.jar

Output:
[LWJGL] Version: 3.2.3 SNAPSHOT
[LWJGL] OS: Linux v5.4.0-48-generic
[LWJGL] JRE: 1.8.0_265 amd64
[LWJGL] JVM: OpenJDK 64-Bit Server VM v25.265-b01 by Private Build
[LWJGL] Loading JNI library: lwjgl
[LWJGL] Module: org.lwjgl
[LWJGL] Loaded from org.lwjgl.librarypath: /tmp/lwjglender/3.2.3-SNAPSHOT/liblwjgl.so
[LWJGL] Loading library: glfw
[LWJGL] Module: org.lwjgl.glfw
[LWJGL] Loaded from org.lwjgl.librarypath: /tmp/lwjglender/3.2.3-SNAPSHOT/libglfw.so
Attempting to create window using GLFW 3.4.0 null OSMesa
[LWJGL] Warning: Failed to instantiate memory allocator: org.lwjgl.system.jemalloc.JEmallocAllocator. Using the system default.
[LWJGL] MemoryUtil allocator: StdlibAllocator
glfwGetCurrentContext() - Found window context.
Using OSMesa context creation api
Context = OpenGL 3.1
[LWJGL] Loading JNI library: lwjgl_opengl
[LWJGL] Module: org.lwjgl.opengl
[LWJGL] Loaded from org.lwjgl.librarypath: /tmp/lwjglender/3.2.3-SNAPSHOT/liblwjgl_opengl.so
[LWJGL] Loading library: libGL.so.1
[LWJGL] Module: org.lwjgl.opengl
[LWJGL] libGL.so.1 not found in org.lwjgl.librarypath=/tmp/lwjglender/3.2.3-SNAPSHOT
[LWJGL] Loaded from system paths: /lib/x86_64-linux-gnu/libGL.so.1
Exception in thread "main" java.lang.IllegalStateException: There is no OpenGL context current in the current thread.
at org.lwjgl.opengl.GL.createCapabilities(GL.java:378)
at org.lwjgl.opengl.GL.createCapabilities(GL.java:322)
at TestMain.checkOpenGLCompatability(TestMain.java:68)
at TestMain.main(TestMain.java:27)

The output is identical aside from the GLFW version used. Any idea why this is happening? Is this a bug in LWJGL or am I doing something stupid?

@Spasi
Copy link
Member

Spasi commented Oct 8, 2020

LWJGL must use OSMesaGetProcAddress to retrieve OpenGL function pointers. Will be fixed in the next snapshot. Bindings for GLFW's OSMesa functions will also be added.

@skoeven
Copy link
Author

skoeven commented Oct 10, 2020

Awesome, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants