Using Slick2D's Image.getGraphics crashes on some machines

On some machines, creating a new Image and calling getGraphics() on it causes lwjgl to enter into some kind of faulty state that crashes when swapping buffers. Any idea what causes this and how to make Slick clean up after itself properly?

Reproduction code:


    package crashrepro;

    import org.newdawn.slick.*;

    public class CrashRepro extends BasicGame {
        public static void main(String[] args) throws Exception {
            CrashRepro cr = new CrashRepro("CrashRepro");
            // Crash only happens in fullscreen mode.
            AppGameContainer agc = new AppGameContainer(cr, 800, 600, true);
            agc.start();
        }

        public CrashRepro(String title) { super(title); }

        @Override
        public void init(GameContainer gc) throws SlickException {}

        @Override
        public void update(GameContainer gc, int i) throws SlickException {}

        @Override
        public void render(GameContainer gc, Graphics grphcs) throws SlickException {
            Image img = new Image(128, 128);
            img.getGraphics(); // This crashes the game.
        }
    }

Stack trace:

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.lwjgl.opengl.WindowsContextImplementation.nSwapBuffers(Ljava/nio/ByteBuffer;)V+0
j  org.lwjgl.opengl.WindowsContextImplementation.swapBuffers()V+35
j  org.lwjgl.opengl.ContextGL.swapBuffers()V+3
j  org.lwjgl.opengl.DrawableGL.swapBuffers()V+0
j  org.lwjgl.opengl.Display.swapBuffers()V+39
j  org.lwjgl.opengl.Display.update(Z)V+44
j  org.lwjgl.opengl.Display.update()V+1
j  org.newdawn.slick.AppGameContainer.gameLoop()V+78
j  org.newdawn.slick.AppGameContainer.start()V+17
j  crashrepro.CrashRepro.main([Ljava/lang/String;)V+27
v  ~StubRoutines::call_stub

Post the exception/error message as well as the stack trace.

It’s a native crash :point: There won’t be an Exception.

Anyway, as you are creating an image every frame, you might run out of vRAM, making the texture allocation fail, after which Slick2D might be sending/reading its pixels to/from a null pointer.

This happens on the very first frame. Sorry if the example is misleading. In-game, I don’t recreate the image each time.

I use getGraphics all the time and I’ve never experienced any issues on any OS, nor have any of my users.

Are you using a good version of slick or LWJGL? I don’t see why this code snippit should be crashing, aside from you wasting resources recreating the image a million times. But you said the actual game doesn’t so that’s obviously not the problem.

In your real code, are you doing this:
[icode]Graphics g = img.getGraphics()[/icode] and use the graphics object or are you calling it the same way you are in your sample code?

In the real code, I create the Image once only, and I do use the Graphics, of course. But having minimized the reproduction, the thing that causes the crash is getGraphics() alone. Note that it doesn’t crash at getGraphics. It crashes later, at the end of the frame, during nSwapBuffers.

Depending on what you’re doing with getGraphics(), I’ve found it better to create an instance of a Graphics object with it, use the object as needed and throw it out when you’re done.


	Image someImage = new Image(64,64);
	Image someOtherImage = new Image("pathTo.png")

	public void drawToSomeImage() throws SlickException {
		Graphics g = someImage.getGraphics();
		g.drawImage(someImageYouLoaded, someX, someY;
		g.flush();
	}

later…


	public void render() throws SlickException {
		someImage.draw(x,y);
	}

Now someImage can be rendered, with someOtherImage drawn on it. This is totally impractical code, but you get the idea. :smiley:

I’m afraid none of this matters, because it’s the call to getGraphics that makes things crash!

OK, this turns out to be caused by a lwjgl bug.

Actually that looks like a driver bug to me.

Cas :slight_smile:

Well, I was running off the assumption you were actually using getGraphics() incorrectly. But Cas may be right, and it’s actually a driver issue.

Yeah, driver bug is probably more precise. :slight_smile: I’ve patched Slick to not check for pbuffers, and now it’s fixed.