QinL / grafx2

Automatically exported from code.google.com/p/grafx2
0 stars 0 forks source link

Input system cleanup/refactoring (Mouse cursor lag) #80

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
SVN 433 on Linux x86-64 (Ubuntu 8.10).
grafx2-svn380-win32.zip on Windows XP SP3.

Mouse cursor movement lags unusably.

To test:
1. Launch grafx2.
2. Start moving mouse.
3. Observe cursor lag behind mouse movement.
4. Observe lag increase.
5. Stop moving mouse.
6. Observe cursor continue moving until it has caught up.

Just a wild guess, but it looks as though it is redrawing the screen after
processing each and every mouse event (so if drawing is slow enough the
event queue may grow as fast or faster than it is processed), rather than
just redrawing once after processing all the current events in the queue.

Original issue reported on code.google.com by carl.ols...@gmail.com on 28 Dec 2008 at 7:34

GoogleCodeExporter commented 8 years ago
I'm not able to reproduce this one here... (debian sid x86-64)
And yes, each and every event is processed and cause a redraw, so it is 
possible to 
fill in the event queue. This will be more visible when using tools like the 
spray 
or big brushes or complex effects. But it seems that if the queu grows too big, 
the 
X server (or something else) starts merging events and the mouse ends up 
jumping 
quickly between points on the screen. This takes some time to happen, however.

(also, i changed the issue templates to include some incomplete tags : opsys 
and 
milestone. please fill them in when submitting an issue.)

Original comment by pulkoma...@gmail.com on 28 Dec 2008 at 9:21

GoogleCodeExporter commented 8 years ago
Could you provide more info about your system?

Original comment by fallenbl...@gmail.com on 28 Dec 2008 at 10:43

GoogleCodeExporter commented 8 years ago
My system specs:
CPU: Athlon X2 6000+
GPU: GeForce 9600GSO 768MB
Memory: 8GB

I tried the grafx2-svn433-win32.zip windows build and the problem is far less 
than in
the older build, only revealing itself when using very large brushes.
In linux and the old windows build just moving the cursor over the window, not
painting, would get increasingly laggy.

Original comment by carl.ols...@gmail.com on 28 Dec 2008 at 1:26

GoogleCodeExporter commented 8 years ago
This is very surprising considering the machine specs, and you get it on both 
OSes...
I can only propose some profiling, under Linux:
  make clean
  make CC="gcc -pg"
This will recompile everything with profiling activated.
Run grafx2, move the mouse in fast circles over the drawing area, without 
clicking,
for 10 seconds, and exit. (As I understand it, on your machine it's enough to 
trigger
the problem continuously)
The will create a file called gmon.prof in the executable's directory. Run:
  gprof grafx2 > gmon.txt
and attach the resulting file here. Please state again which svn version you 
were
using, so we can follow the same procedure and compare the two reports.

Original comment by yrizoud on 29 Dec 2008 at 2:03

GoogleCodeExporter commented 8 years ago
Oh, one other thing you can try, much simpler:
Hiding the menu (F9 toggles it)
It will remove the display of coordinates every time you move the mouse, and 
also
considerably reduce the screen surface SDL has to redraw.

Original comment by yrizoud on 30 Dec 2008 at 11:51

GoogleCodeExporter commented 8 years ago
SVN 443 on Linux x86-64 (Ubuntu 8.10).

gmon.txt attached.

Hiding the menu removes all appearances of lag for me.

Original comment by carl.ols...@gmail.com on 31 Dec 2008 at 12:47

Attachments:

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
Amendment to last comment: Hiding the menu removes all appearances of lag for 
me for
mouse movement and painting with small brushes. Still get accumulating lag 
using large
brushes, adjust picture tool.

Original comment by carl.ols...@gmail.com on 31 Dec 2008 at 9:32

GoogleCodeExporter commented 8 years ago
Seems like your computer is slow at copying things from main ram to the 
videocard. 
Is your videocard setup correctly with the latest drivers from nvidia ?

Maybe the modern hardware is dropping the paletized 8 bit mode we're using and 
there 
is some software layer emulating that.

Did you try running the program fullscreen and windowed ? maybe one of the 
modes 
could be faster than the other.

Original comment by pulkoma...@gmail.com on 31 Dec 2008 at 9:58

GoogleCodeExporter commented 8 years ago
It's strange because the profiling shows no significant difference with some 
random
XP machine I'm testing. The graphics are redrawn by Flush_update(), and in your 
log
it was called 3704 times for a total CPU cost of 0.2ms. If anything was slow, it
didn't report as a CPU-consuming task. (or maybe I just misunderstand how 
profiling
works with external calls)

It's normal to get lag with Continuous Drawing or Lines, if you have large 
brushes,
because in memory it "prints" the brush on every pixel between the starting and
ending mouse position, checking transparent color etc. But in this case, the 
profile
show that functions like Lire_pixel are called several millions of time and hog 
80%
of grafx2's CPU activity.

The "adjust picture" is a big hint, because it causes a full screen redraw, 
just once
per mouse movement (no matter how many pixels your mouse has moved.).
Could you please try the following:
With menu displayed, without drawing, just run the mouse in circle in the 
upper-right
quarter of the screen. See the kind of lag you get. Then do the same in the
bottom-left quarter of the screen (without entering the menu). If the lag is 
reduced
there, it would be a proof of SDL drawing slowness, because Grafx2 does exactly 
the
same number of tasks; the only difference is that the redrawn SDL rectangle is 
at
least 4 times smaller (it extends to the coordinates printed in the menu - this 
would
explain why you get better results when menu is disabled).

Original comment by yrizoud on 31 Dec 2008 at 10:54

GoogleCodeExporter commented 8 years ago
Fullscreen or windowed it doesn't seem to make any difference.

With menu shown moving mouse in the bottom-left is much less laggy than 
top-right or
elsewhere on the screen.

Is it redrawing one all encompassing bounds rather than redrawing separate tight
bounds per dirtied graphical element?

I understand that expensive painting operations will always suffer accumulating 
lag,
but IMHO the mouse cursor should never lag more than one redraw. Having to guess
where the mouse cursor is, rather than where it is shown, is a usability 
killer. I
don't need to know where the mouse has been, but where it is now.

Original comment by carl.ols...@gmail.com on 31 Dec 2008 at 1:29

GoogleCodeExporter commented 8 years ago
"one all encompassing bounds", that's the default mode since mid-December.

You can use the individual rectangles however:
Delete the file obj/unix/sdlscreen.o (to force its compilation), then compile 
with 
  make METHODE_UPDATE=METHODE_UPDATE_MULTI_RECTANGLE
This won't be enough for you however, because in many usual cases, a large part 
of
the screen needs redraw: adjust picture, tools that use a giant XOR crosshair...

The slowness you get is really unique and abnormal...I'm developing and often 
testing on:
CPU: Intel P-III 600Mhz
GPU: GeForce2 MX 400 (64Mb, AGP 2x)
Memory: 768Mb
Even if I compile with a total screen redraw on every mouse movement, in a
"fullscreen" window over a 32bit desktop, the program can process mouse actions 
as
fast as I can manage them.

Note, I had suspected you had an unnaturaly fast mouse, giving hundreds of mouse
events per seconds; but it doesn't fit with your recent reports and profile 
stats.

Original comment by yrizoud on 31 Dec 2008 at 2:35

GoogleCodeExporter commented 8 years ago
Building with multi rectangle doesn't seem to have any effect on the problem.

I do have a high DPI gaming mouse, so I tried with other pointing devices at my
disposal. With my tablet I still have the lag, but it is significantly 
decreased.
With the trackpad on my cordless keyboard there is no apparent lag at all, 
though
strokes are far less smooth.

Original comment by carl.ols...@gmail.com on 31 Dec 2008 at 3:09

GoogleCodeExporter commented 8 years ago
I had some thoughts about merging mouse events when several are pending in the 
event
queue, but the program still has almost the same work to do, and in
performance-sensitive situations the pencil would no longer retrace the user's
movement (lagged), instead it would cut corners and go to the latest position.

In your case, the effects are so big that it could be Grafx2 receiving and 
processing
mouse events even when the mouse hasn't moved!
I'll see if I can make a kind of FPS counter to record the top "mouse events 
per second".

Original comment by yrizoud on 31 Dec 2008 at 4:14

GoogleCodeExporter commented 8 years ago
I see in the profiling that Wait_VBL is called less than 500 times, that seems 
a 
very low count.
This function should be called evrytime the mouse did not move. So this seems 
to be 
where the problem is.

If the CPU is used at 100% when doing nothing (not even moving the mouse), then 
it 
is probably the cause of the problem. Try launching the program, and if the cpu 
is 
at 100%, unplug your mouse. If the CPU usage drop down, we've found the problem.

Now, we must find a way to avoid it ...

Original comment by pulkoma...@gmail.com on 31 Dec 2008 at 4:53

GoogleCodeExporter commented 8 years ago
CPU usage when not using the mouse isn't noticeably above ambient, but when 
moving
the mouse in grafx2 it ups to about 50% for both cores.

Original comment by carl.ols...@gmail.com on 31 Dec 2008 at 9:22

GoogleCodeExporter commented 8 years ago
Ok I think I got it: I can experience the same problem if I configure my mouse 
to
send 200 updates per second instead of my older mouse's 80-100 : just moving the
cursor causes a cumulative lag if the redrawn surface is important (ie: 
coordinates
shown in menu).

The higher sensitivy can be useful if you draw with fast strokes in high 
resolution,
but then the program attempts to update the screen as often as new input is 
received,
ie 200 times per second on average. Multiply that with a fullscreen 1600x1200 
mode
that is completely redrawn each time, and it lags.

With such mouse setting, I think GrafX2 performs much better if compiled with:
make METHODE_UPDATE=METHODE_UPDATE_MULTI_RECTANGLE
This setting updates the screen as many small areas, instead of a cumulative
rectangle that goes from the display of mouse coordinates to the cursor.

Original comment by yrizoud on 10 Jan 2009 at 6:01

GoogleCodeExporter commented 8 years ago
This needs too much code rewrite and will probably lead to many bugs. So 
pushing it 
forward to 2.0 release so we can get a beta out.

Original comment by pulkoma...@gmail.com on 15 Jan 2009 at 10:27

GoogleCodeExporter commented 8 years ago
I'm working on it.

Original comment by pulkoma...@gmail.com on 21 Jan 2009 at 11:03

GoogleCodeExporter commented 8 years ago
Latest revisions should run better. Carl, can you test the latest svn revs and 
see 
if there is an improvement ?

Original comment by pulkoma...@gmail.com on 4 Feb 2009 at 6:02

GoogleCodeExporter commented 8 years ago
Could perhaps be a little faster (though I'm by no means certain of that 
certain of
that) but still very much problematic.

Original comment by carl.ols...@gmail.com on 6 Feb 2009 at 9:54

GoogleCodeExporter commented 8 years ago
Carl, version 613 normally solves the issue:
After running grafx2 once, you'll see at the bottom of gfx2.ini (Windows:
"Application Data\Grafx2", Linux: "~/.Grafx2/") a setting called Merge_movement.
For now, I've set the default at 100 so you can immediately see if it works 
better.
Hit B to activate Brush tool so you'll have a huge Cross cursor, run the mouse 
in
circles anywhere on the screen, and you'll see the lag (or not).

100 means that grafx2 merges a maximum of 100 successive mouse movements before
updating the screen once. Setting 0 gives the original behaviour of grafx2, 
which is
to draw and display the result once for each mouse movement in the event queue, 
no
matter how often these are received.
Ideally, you should set the value to the lowest that doesn't give you any lag. 
It's
very likely that a number below 10 would be enough.

Original comment by yrizoud on 8 Feb 2009 at 1:55

GoogleCodeExporter commented 8 years ago
You can try version 619 in the Downloads section.

Original comment by yrizoud on 9 Feb 2009 at 12:27

GoogleCodeExporter commented 8 years ago
Sweet SVN 619 did the trick. No lag now. Thanks heaps.

Original comment by carl.ols...@gmail.com on 9 Feb 2009 at 1:50

GoogleCodeExporter commented 8 years ago
fixed in r619 , so :)

Original comment by pulkoma...@gmail.com on 9 Feb 2009 at 7:30

GoogleCodeExporter commented 8 years ago
Well, I'm glad we found the reason, but I'd prefer to set Merge_movement to 0 by
default, and let the user modify it when it's needed (we can put it in FAQ)

Original comment by yrizoud on 9 Feb 2009 at 8:29

GoogleCodeExporter commented 8 years ago
May be a good use for the "mouse sensivity" slider in the settings screen :)
(i don't think we're using it for anything else ?)

Original comment by pulkoma...@gmail.com on 9 Feb 2009 at 9:03