LWJGL, JRE Exception: Access Violation @ DirectContext.makeGL
Closed this issue · 2 comments
I tried recreating the skija + lwjgl example, but I can't get it running:
Everytime I start the project the JRE Crashes, showing an EXCEPTION_ACCESS_VIOLATION error.
If I step through the program it crashes at the DirectContext.makeGL() call.
Before that, I was able to create a GL window and GL context. Clearing the window also worked fine.
So I assume the openGL part of the project is working fine.
Maybe I made an obvious error, when I added the libraries to my project.
(I did not follow the gradle/maven etc. guide. I added them manually)
I'm pretty new to programming in Java, so it's likely I made a very stupid and obvious error.
Maybe somebody else can help me figure out, what might be the issue here.
Project Setup:
Platform: Windows 10 x64
JRE: Azul Zulu 17
IDE: IntelliJ
LWJGL: 3.3.1 (Minimal openGL)
Skija: 0.109.1 (Release version)
Code:
(My code is basicly identical to the Skija, lwjgl example)
import java.nio.IntBuffer;
import java.util.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.MemoryStack;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.system.MemoryUtil.*;
import io.github.humbleui.skija.*;
import io.github.humbleui.skija.impl.*;
class Window
{
//GL
public long window;
public int width;
public int height;
public float dpi = 1f;
public int xpos = 0;
public int ypos = 0;
public boolean vsync = true;
public boolean stats = true;
private int[] refreshRates;
private String os = System.getProperty("os.name").toLowerCase();
//SKIA
private DirectContext context;
private BackendRenderTarget renderTarget;
private Surface surface;
private Canvas canvas;
//-----------------------------------------------------------------------------------------------------//
//Create Window
//-----------------------------------------------------------------------------------------------------//
private void createWindow(int x, int y, int width, int height)
{
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
window = glfwCreateWindow(width, height, "Skija LWJGL Demo", 0, 0);
if (window == 0)
{
throw new RuntimeException("Failed to create the GLFW window");
}
glfwSetKeyCallback(window, (window, key, scancode, action, mods) ->
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
{
glfwSetWindowShouldClose(window, true);
}
});
glfwSetWindowPos(window, x, y);
updateDimensions();
xpos = width / 2;
ypos = height / 2;
glfwMakeContextCurrent(window);
glfwSwapInterval(vsync ? 1 : 0); // Enable v-sync
glfwShowWindow(window);
}
//-----------------------------------------------------------------------------------------------------//
//Get Refresh Rates
//-----------------------------------------------------------------------------------------------------//
private int[] getRefreshRates()
{
var monitors = glfwGetMonitors();
int[] res = new int[monitors.capacity()];
for (int i=0; i < monitors.capacity(); ++i)
{
res[i] = glfwGetVideoMode(monitors.get(i)).refreshRate();
}
return res;
}
//-----------------------------------------------------------------------------------------------------//
//Run
//-----------------------------------------------------------------------------------------------------//
public void run(int x, int y, int width, int height)
{
refreshRates = getRefreshRates();
createWindow(x, y, width, height);
loop();
glfwFreeCallbacks(window);
glfwDestroyWindow(window);
glfwTerminate();
glfwSetErrorCallback(null).free();
}
//-----------------------------------------------------------------------------------------------------//
//Update Dimensions
//-----------------------------------------------------------------------------------------------------//
private void updateDimensions()
{
int[] width = new int[1];
int[] height = new int[1];
glfwGetFramebufferSize(window, width, height);
float[] xscale = new float[1];
float[] yscale = new float[1];
glfwGetWindowContentScale(window, xscale, yscale);
assert xscale[0] == yscale[0] : "Horizontal dpi=" + xscale[0] + ", vertical dpi=" + yscale[0];
this.width = (int) (width[0] / xscale[0]);
this.height = (int) (height[0] / yscale[0]);
this.dpi = xscale[0];
System.out.println("FramebufferSize " + width[0] + "x" + height[0] + ", scale " + this.dpi + ", window " + this.width + "x" + this.height);
}
//-----------------------------------------------------------------------------------------------------//
//Initialize Skia
//-----------------------------------------------------------------------------------------------------//
private void initSkia()
{
Stats.enabled = true;
if (surface != null)
{
surface.close();
}
if (renderTarget != null)
{
renderTarget.close();
}
renderTarget = BackendRenderTarget.makeGL(
(int) (width * dpi),
(int) (height * dpi),
/*samples*/16,
/*stencil*/8,
/*fbId*/0,
FramebufferFormat.GR_GL_RGBA8);
surface = Surface.makeFromBackendRenderTarget(
context,
renderTarget,
SurfaceOrigin.BOTTOM_LEFT,
SurfaceColorFormat.RGBA_8888,
ColorSpace.getDisplayP3(), // TODO load monitor profile
new SurfaceProps(PixelGeometry.BGR_H));
canvas = surface.getCanvas();
}
//-----------------------------------------------------------------------------------------------------//
//Draw
//-----------------------------------------------------------------------------------------------------//
private void draw()
{
//var canvas = surface.getCanvas();
//canvas.clear(0);
//Paint paint = new Paint();
//paint.setColor4f(new Color4f(1f, 1f, 1f, 1f), ColorSpace.getSRGB());
//paint.setAntiAlias(true);
//canvas.drawCircle(640f, 360f, 150f, paint);
context.flush();
glfwSwapBuffers(window);
}
//-----------------------------------------------------------------------------------------------------//
//Loop
//-----------------------------------------------------------------------------------------------------//
private void loop()
{
GL.createCapabilities();
if ("false".equals(System.getProperty("skija.staticLoad")))
{
Library.load();
}
context = DirectContext.makeGL();
GLFW.glfwSetWindowSizeCallback(window, (window, width, height) ->
{
updateDimensions();
initSkia();
draw();
});
glfwSetCursorPosCallback(window, (window, xpos, ypos) ->
{
if(os.contains("mac") || os.contains("darwin"))
{
this.xpos = (int) xpos;
this.ypos = (int) ypos;
}
else
{
this.xpos = (int) (xpos / dpi);
this.ypos = (int) (ypos / dpi);
}
});
glfwSetMouseButtonCallback(window, (window, button, action, mods) ->
{
System.out.println("Button " + button + " " + (action == 0 ? "released" : "pressed"));
});
glfwSetScrollCallback(window, (window, xoffset, yoffset) ->
{
System.out.println("Scroll " + xoffset + "/" + yoffset);
});
glfwSetKeyCallback(window, (window, key, scancode, action, mods) ->
{
if (action == GLFW_PRESS)
{
switch (key)
{
case GLFW_KEY_V:
vsync = !vsync;
glfwSwapInterval(vsync ? 1 : 0);
System.out.println("Vsync " + (vsync ? "ON" : "OFF"));
break;
case GLFW_KEY_G:
System.out.println("Before GC " + Stats.allocated);
System.gc();
break;
}
}
});
initSkia();
while (!glfwWindowShouldClose(window))
{
draw();
glfwPollEvents();
}
}
}
public class SkiaMain
{
public static void main(String [] args) throws Exception
{
GLFWErrorCallback.createPrint(System.err).set();
if (!glfwInit())
{
throw new IllegalStateException("Unable to initialize GLFW");
}
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
int width = 1280;
int height = 720;
new Window().run(Math.max(0, (vidmode.width() - width) / 2), Math.max(0, (vidmode.height() - height) / 2), width, height);
}
}
Error log:
Maybe somebody else can get some usefule information from this:
error.log
Well, whatever went wrong, I have no idea.
But I just got Gradle to actually do its job and setup my dependencies correctly and now it works.
I still wish I knew what caused the issue, but I guess I will never know.
I consider this Issue closed (even though its not really resolved).
I’m glad it worked out!