Minecraft Input Lag Problem

Started by Movementcat, August 14, 2014, 21:57:25

Previous topic - Next topic

Movementcat

Good Evening,

first im not a Programmer, but im a good Researcher, and i think i did consume whole google about this Problem.

And i think i finally found the source of my Problems.

Yes it is LWJGL. This is really no Offense, but i did try all common Minecraft fixes. So i really hope someone can help me find a Solution for me.

So i think i should start with my Spec's.

I have a fresh installed Windows 7 64 Bit Home Edition,

I7 2600k
580 GTX
8 GB Ram
SSD 256 GB


So my Problem is if i have VSync turned on and i move in Minecraft and Watching around i get "Microstuttering" my FPS never drop down, i get without VSync ~300 FPS.

I know if i use Keyboard and Mouse that the Stutter occurs. Example: If i drive a Minecart and watching and spinning my Mouse around no Lag occurs. But if i walk bymyself with WASD and then Watching around the Stutter appear.

So i hope i did explain my Problem well enough, if not and you need some more Questions answered just let me know i try provide best Informations i can. Here is another Guy who maybe explain the Bug better -->

https://bugs.mojang.com/browse/MC-48219

and my Original Post.

http://www.minecraftforum.net/forums/minecraft-discussion/discussion/2182263-minecraft-input-lag-1-7-10

kind regards

Movementcat


quew8

You clearly have very detailed info about this bug, however without knowledge of the inner workings of Minecraft it is very unlikely that any LWJGL dev would be able to trace this to a bug in LWJGL. The only ones with the knowledge of the inner workings of Minecraft would be the Minecraft devs.

You have submitted the bug to their tracker, the ball is now in their court. It is up to them to trace the source of the bug whether it be in LWJGL, Minecraft or hardware. If it is LWJGL, then they then come here and provide the LWJGL devs with the details and/or a proposed fix. Until they have done this then there is nothing you or I can do. That is the necessary and established process I'm afraid.

I know waiting for small bug fixes can be frustrating but my two tips are thus:
1) Encourage others experiencing the bug to upvote it on the Minecraft bug tracker. This makes it more visible to the developers.
2) It sounds like this is a problem you only experience with vsync turned on. So play without vsync?

TaylorR

I have ran into the same thing with the game I am making, this does seem to be an issue with LWJGL.

This happens when I am using both:

Display.sync(FRAME_RATE);
and
Mouse.setGrabbed(true);

Using any of these calls without the other doesn't create the issue.

I have to use "Mouse.setGrabbed(true)" as its the only way I can see to do the controls, manually moving the mouse back to the center will add a mouse event, so my rotation control just moves back to the center as there is reverse move for every mouse move made.

My work around is to simply not use "Display.sync", was simple to update all my update functions to handle variable frame rate, though this was not my ideal fix, I would prefer to have a fixed frame rate.

I must assume that it is related to the input event queue, as the cause is the spamming of keyboard events from holding down a key.

Has any one else hit this issue??

I am using the latest version 2, I am thinking of moving up to 3, but there will be a bit of rework and as I'm also using TWL I will need to re-build that to fit the new input model.

As Keyboard and Mouse have been removed in 3 I would think that this would no longer be an issue, as one would have to build their own handlers for this.






spasi

I'll have a look, but it would be very helpful if you could write a simple demo that reproduces the issue.

spasi

I was able to reproduce this and it looks like a behavior of Windows, not an LWJGL bug. However, I may have found a decent workaround. Could you please confirm that you're using an event loop? That is:

while ( Mouse.next() ) {
	int dx = Mouse.getEventDX();
	int dy = Mouse.getEventDY();
	// do stuff with dx/dy
}

and not:

int dx = Mouse.getDX();
int dy = Mouse.getDY();
// do stuff with dx/dy

TaylorR


Yes I am using an event loop, though I have noticed that I only ever have one event per frame which holds the same data as the non event get functions.



spasi

Quote from: TaylorR on January 08, 2015, 02:54:47though I have noticed that I only ever have one event per frame which holds the same data as the non event get functions.

Don't you get 2 events per frame when holding down a key on the keyboard? Because that's what I'm seeing on my machine (Win 8.1). If you do get 2 events in that situation, does using the non-event methods fix the stuttering issue?

TaylorR

I'm only using the loop for mouse, for keyboard I am simply using Keyboard.isKeyDown for the moment.

I was under the impression that isKeyDown doesnt require the event loop?

I was referring to the mouse loop when I stated that I only saw one event.

I agree that this must be something to do with windows and its implementation, otherwise a lot of other people would have this issue, but as it only happens while the isGrabbed function is used I have to assume that the root cause is in the windows implementation of lwjgl.




TaylorR

I have tried both event and no event calls to the mouse class, and both are giving the same results.

I have previously tried adding in a loop for the keyboard events also, as I though the issue could be the fact that the keyboard buffer was simply filling up too fast and causing the issue, but that made to change.

I would be nice if I could implement my own "isGrabbed" functionality as I have done in the past, but as a call to "setPosition" of the mouse sends a mouse update event I can't do it within lwjgl.

@spasi, Was it simple to reproduce this issue? and you did state that you had a simple workaround, was that simply using the event loop instead of the direct call?
If you do not have a simple program reproducing this I will put one together.

Though it looks at this point I will just have to deal with the variable frame rate, as I am almost completely out of ideas here.





spasi

Hey TaylorR,

I was asking about the mouse loop, not the keyboard loop. What happens on my machine is (with setGrabbed(true)):

a) when moving the mouse around, without holding any key on the keyboard, I get 1 mouse event per frame.
b) when moving the mouse around, while holding any key on the keyboard, I get 2 mouse events per frame. One of the two has tiny dx/dy.
c) with high DPI settings, it becomes horrible (sometimes I get dx values > 5000).

But that's on Windows 8.1. If this is different from Windows 7, then the workaround I had in mind won't work. That's why it'd be useful if you could post the exact code you're using and the behavior you're seeing. It's also not exactly clear if what you're seeing is rendering stuttering, or simply the dx/dy values are wrong and cause your animations to stutter.

If you don't have time to write a demo, you could do the following: Disable mouse grabbing, move your mouse slowly from left to right and print the dx values you're getting. Then do the same with mouse grabbing enabled and attach both results in a reply here.

TaylorR

Sorry for the slow reply, the holidays are over now and I have a job to do... not much time for the game again.

Ok so I took another demo I found on the internet and added a few things, so please don't judge it lol :)
I have far too much code to post here.

So with the code below I have the issue, but commenting out either the Mouse.setGrabbed(true); or the Display.sync(30); and the problem goes away.

Just move the mouse around in a consistent circular motion while holding down any key, you will see the movement on screen degrade into the center then snap back out to the full size.

I have been looking at my logs for about a week now trying to figure out whats happening, and I see that the values returned from the events degrade over time when a key is held down.

I have several vertex shader functions that are based on time / framerate that do not stutter at all durring this, and of course I have my frame rate visible and I dont see a drop in anything else.


import org.lwjgl.LWJGLException;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

public class QuadExample {

	public void start() {
		try {
			Display.setDisplayMode(new DisplayMode(800,600));
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
			System.exit(0);
		}

		// init OpenGL
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, 800, 0, 600, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);

		Mouse.setGrabbed(true);

		while (!Display.isCloseRequested()) {

			Display.sync(30);

			this.updateMouseVars();

			// Clear the screen and depth buffer
			GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

			// set the color of the quad (R,G,B,A)
			GL11.glColor3f(0.5f,0.5f,1.0f);

			// draw quad
			GL11.glBegin(GL11.GL_QUADS);
			GL11.glVertex2f(mouseDx, mouseDy);
			GL11.glVertex2f(200 + mouseDx, mouseDy);
			GL11.glVertex2f(200 + mouseDx, 200 + mouseDy);
			GL11.glVertex2f(mouseDx, 200 + mouseDy);
			GL11.glEnd();

			Display.update();
		}

		Display.destroy();
	}

	int mouseDx = 0;
	int mouseDy = 0;

	public void updateMouseVars(){

		int localMouseDx = 0;
		int localMouseDy = 0;

		while(Mouse.next()){

			localMouseDx += Mouse.getEventDX();
			localMouseDy += Mouse.getEventDY();

		}

		mouseDx += localMouseDx;
		mouseDy += localMouseDy;

	}

	public static void main(String[] argv) {
		QuadExample quadExample = new QuadExample();
		quadExample.start();
	}
}


spasi

Hey TaylorR,

I have pushed a fix for this, but I'm afraid the nightly builds are currently not working. Could you please try this build? (unsigned lwjgl.jar)

What I did was add support for raw input events (thanks to Kai for giving me the idea) and compare those with the events LWJGL normally uses (WM_MOUSEMOVE). I first had to make sure that there was an 1-to-1 mapping between my mouse movement and the cursor. There's a very nice tool that you can use to verify that, called Mouse Movement Recorder. On Windows, you're basically required to set the pointer speed slider to the middle (6th out of 11 "ticks") and disable "Enhance pointer precision". If you do this and verify it with MMR, in theory, the WM_MOUSEMOVE events should give the exact same values as the raw input ones. This was indeed true without holding a keyboard key (except very minor drifting every few seconds), but broke down once keyboard repeat fired up.

The problem isn't as big as you describe, but I'm sure that's because of the differences between Windows 7 and Windows 8.1 (there have been mouse handling adjustments in both 8 and 8.1 and also in an 8.1 patch). Anyway, the problem was indeed there and I could "feel" it with your quad demo. Interestingly, the problem went away if I didn't reset the cursor position to the center of the window after every WM_MOUSEMOVE. That was a good hint for the fix:

Before

QuoteEnter event loop
...
WM_MOUSEMOVE -> Center cursor
WM_MOUSEMOVE -> Center cursor
...
Exit event loop

After

QuoteEnter event loop
...
WM_MOUSEMOVE
WM_MOUSEMOVE
...
Exit event loop
Center cursor

Note that are more than one WM_MOUSEMOVE events in there. This happens when a keyboard key is held down, you get at least 2 and sometimes 3 events per frame. With the above change, I get smooth cursor movement, always.

TaylorR

That's fantastic! I'll give the new jar a go when I get home tonight and let you know the results.

Yes that does make sense to me, I had a feeling there was something up with the centering of the "grabbed" mode.

TaylorR

@spasi you sir are a champion! It is now working perfectly, I see absolutely no lag at all.
Thank you for the support on this, I will definitely be recommending the use of lwjgl for any java graphics jobs in the future.

spasi

Quote from: ElgranLuciano on January 17, 2015, 18:18:43can you please tell me how do you fixed the problem? I mean where do I have to replace the lwjgl file ?

You can find instructions here.