LWJGL Forum

Programming => OpenGL => Topic started by: Qudus on January 19, 2008, 02:00:22

Title: expensive input polls
Post by: Qudus on January 19, 2008, 02:00:22
In my benchmark (the Q3 flight one) polling keyboard and mouse (each frame) costs me 3% of the resulting 213 FPS. This is quite a lot. And using YourKit to profile the benachmark I found out, that the Keyboard and Mouse are polled again in the Display.update() method.

So it seems, that calling Keyboard.poll() and Mouse.poll() is unnecessary, if Display.update() is used. Is this correct? In my input test (in the other thread here in this forum) I discussed a problem with the input on Windows, which was caused by the poll() method not called by my input system even if Display.update() was called.

So is it correct, that Keyboard.poll() and Mouse.poll() have to be called before querying the input state changes? Or is this unnecessary?

Is there a way to improve the input polling performance?

Marvin
Title: Re: expensive input polls
Post by: Qudus on January 19, 2008, 02:20:21
From reading Display's source I found out, that I can simply call

if ( Display.isVisible() || Display.isDirty() )
{
    Display.swapBuffers();
}

instead of

Display.update();

This will result in the input devices not being polled, which I can do, when I need it. My test has become faster now :). And the pollMessages() method is not needed to be called, since it does nothing else than

display_impl.update();

which is already done by the isVisible() and isDirty() calls. I suggest to change that in the source, since it just costs performance.

And is it really necessary to call display_impl from within each method. I would like to have methods like isVisible() and isDirty(), that don't call display_impl.update() (maybe an additional boolean parameter), since it costs me 1% for each of these calls. And as far as I understand it, this display_impl.update() method should only be necessary to be called once per frame. Is this correct?

My initial question stays though. Is it possible to do input polling in a cheaper way?

Marvin
Title: Re: expensive input polls
Post by: Qudus on January 19, 2008, 02:53:53
After further profiling I found out, that polling Keyboard and mouse both internally calls LinuxDisplay.update() multiple times. This should be changed. It is the most important reason for expensive input polls.

I would offer to do this, but since I am not to familiar with LWGJL internals, I would risk to mess things up. Could please somebody of the LWJGL gurus do this? Would be very cool.

Thanks.
Marvin
Title: Re: expensive input polls
Post by: Matzon on January 19, 2008, 09:14:02
elias comitted some changes - can you compile and run from SVN ?
Title: Re: expensive input polls
Post by: elias on January 19, 2008, 09:15:33
Thank you for investigating this issue. I've removed the update()s from the poll() and read() methods, but I'm not sure how to remove the one in Display.update(), without breaking existing LWJGL programs. For example, a program might never call isDirty() or isActive(), making the processMessages() call in Display important. Ideally, a program should:


Display.processMessages();
if (Display.isVisible() || Display.isDirty()){
    Display.swapBuffers();
} else {
    try { Thread.sleep(A_WHILE); } catch (InterruptedException e) {}
}


where neither isVisible() nor isDirty() should call processMessages().

- elias
Title: Re: expensive input polls
Post by: elias on January 19, 2008, 09:55:01
I also changed Display.update() to only call display_impl.update() once, by replacing isVisible() and isDirty() with display_impl.isVisible() and display_impl.isDirty().

- elias
Title: Re: expensive input polls
Post by: Qudus on January 19, 2008, 13:58:16
Quote from: Matzon on January 19, 2008, 09:14:02
elias comitted some changes - can you compile and run from SVN ?

Unfortunately not. I pulled the SVN trunk three days ago and tried to make it compilable in eclipse. But it seems, that there are classes (in the generated folder), that need to be generated (by an ant task, I assume). and since I don't have a working ant environment, I cannot compile the source. Would be great, if I could download a nightly build somewhere.

Quote from: elias on January 19, 2008, 09:15:33
Thank you for investigating this issue.

You're welcome. It is the least I can do to give something back to you making this great library :).

Quote from: elias on January 19, 2008, 09:15:33
I've removed the update()s from the poll() and read() methods, but I'm not sure how to remove the one in Display.update(), without breaking existing LWJGL programs.

This could be easily done by overloading the Display.update() method with one, that has an additional boolean parameter, that tells, if these sub-updates and polls are to be done.

Quote from: elias on January 19, 2008, 09:15:33
For example, a program might never call isDirty() or isActive(), making the processMessages() call in Display important. Ideally, a program should:


Display.processMessages();
if (Display.isVisible() || Display.isDirty()){
    Display.swapBuffers();
} else {
    try { Thread.sleep(A_WHILE); } catch (InterruptedException e) {}
}


where neither isVisible() nor isDirty() should call processMessages().

Well, simply overload the isVisible() and isDirty() methods, too with this additional boolean. And then simply forward the boolean from Display.update(boolean).

Thanks again.

Marvin
Title: Re: expensive input polls
Post by: Qudus on January 21, 2008, 20:05:00
I tried the new 1.1.4 release. And this is my result:
Before I can actually poll the input I have to call Display.processMessages(), if I didn't call any other method, that calls display_impl.update() before. This is principally ok. But it leads me to the conclusion, that display_impl.update() works in a too general way. Is there a way to only process the input related messages, since polling input is still very expensive, if it needs a call to processMessages()?

Marvin
Title: Re: expensive input polls
Post by: elias on January 21, 2008, 20:17:33
Surely you already call processMessages once per loop? There's no way to filter out input related messages from display_impl.update().

- elias
Title: Re: expensive input polls
Post by: Qudus on January 21, 2008, 20:52:35
Quote from: elias on January 21, 2008, 20:17:33
Surely you already call processMessages once per loop? There's no way to filter out input related messages from display_impl.update().

Well, I call it before polling input only. It doesn't seem to be necessary to be called for anything else. Rendering is done without any problems without the call to display_impl.update(). I don't need the isDirty() check and if isVisible() steals me 4% of rendering performance in my testcase (because of the implicit call to display_impl.update(), I don't need/want it neither. This is exactly, why I ask so vehemently ;).

Marvin
Title: Re: expensive input polls
Post by: elias on January 21, 2008, 21:04:51
You won't get good behaviour if you don't process the messages from the windowing system, so a call to processMessages() is required, at least once in a while.

- elias
Title: Re: expensive input polls
Post by: Qudus on January 21, 2008, 21:35:54
Quote from: elias on January 21, 2008, 21:04:51
You won't get good behaviour if you don't process the messages from the windowing system, so a call to processMessages() is required, at least once in a while.

And polling the window-messages is the expensive part? If this is true, there's definitely a need for the users to poll different things separately to manage, when to poll what.

What would be the expected problems, if window-messages are never polled?
Would it be sufficient to poll the window-messages each (e.g.) 100-th frame?

Marvin
Title: Re: expensive input polls
Post by: elias on January 21, 2008, 21:41:20
Window messages includes mouse and keyboard messages, so I can't see how you would avoid it. You can filter events when polling to exclude anything else than input events, but I don't think that's the expensive part.

- elias
Title: Re: expensive input polls
Post by: Qudus on January 23, 2008, 22:05:16
I tried to get a closer look at the polling methods. But I can't find the implementation of the XPending method. Is it true, that to input methods are all polled? If it is true, can't this be done through a callback? Shouldn't this be much faster?

After I further tuned Xith3D the time part, that is taken for the display_impl.update() call is getting higher. Now it is 6% (of 470 FPS). So this is getting more and more annoying the more I tune my own code.

Marvin
Title: Re: expensive input polls
Post by: Matzon on January 24, 2008, 07:49:32
it would be relevant to locate the part of update that is taking a long time. Fwiw, you should poll every time you render a frame. Furthermore I am not sure that you can - or even should - do it using somekind of callback mechanism.
Title: Re: expensive input polls
Post by: elias on January 24, 2008, 10:42:32
XPending is a X11 native function,

http://linux.die.net/man/3/xpending

There really only are two choices, poll for events every frame or have another thread block, waiting for events (AWT style). Have you tried LWJGL 2.0 alpha where all but one processMessages have been removed?

- elias
Title: Re: expensive input polls
Post by: Qudus on January 24, 2008, 11:45:25
Quote from: elias on January 24, 2008, 10:42:32
Have you tried LWJGL 2.0 alpha where all but one processMessages have been removed?

Not yet. I just found this release. I will have a look at it tonight. Thanks.

Marvin