Bug 282229 - The scroll in any editor is painfully slow on OS X
Summary: The scroll in any editor is painfully slow on OS X
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.5   Edit
Hardware: PC Mac OS X
: P3 normal with 4 votes (vote)
Target Milestone: ---   Edit
Assignee: Scott Kovatch CLA
QA Contact: Silenio Quarti CLA
URL:
Whiteboard:
Keywords: needinfo
Depends on: 275686
Blocks:
  Show dependency tree
 
Reported: 2009-07-01 22:07 EDT by Michael CLA
Modified: 2016-10-17 13:28 EDT (History)
18 users (show)

See Also:


Attachments
jprofiler output from scrolling in 3.6 (16.75 KB, application/octet-stream)
2010-02-23 08:08 EST, Mike Schrag CLA
no flags Details
ideas (2.42 KB, patch)
2010-04-29 12:25 EDT, Silenio Quarti CLA
no flags Details | Diff
modified version of javaviewer (5.14 KB, application/octet-stream)
2010-04-29 15:52 EDT, Silenio Quarti CLA
no flags Details
javaviewer showing problem in patch (5.74 KB, patch)
2010-04-29 17:32 EDT, Silenio Quarti CLA
no flags Details | Diff
fix (13.13 KB, patch)
2010-04-29 17:59 EDT, Silenio Quarti CLA
no flags Details | Diff
possible patch (19.82 KB, patch)
2010-05-03 02:20 EDT, Scott Kovatch CLA
no flags Details | Diff
patch using the performSelector() idea (20.38 KB, patch)
2010-05-03 12:54 EDT, Silenio Quarti CLA
no flags Details | Diff
patch with flushWindowIfNeeded (23.13 KB, patch)
2010-05-03 14:06 EDT, Scott Kovatch CLA
no flags Details | Diff
final patch (24.54 KB, patch)
2010-05-03 18:46 EDT, Scott Kovatch CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Michael CLA 2009-07-01 22:07:48 EDT
Build ID: I20090611-1540

Steps To Reproduce:
1. Create Java project
2. Create long Java class
3. Try to scroll.


More information:
Comment 1 Felipe Heidrich CLA 2009-07-06 10:07:03 EDT
It works fine for me. Please provide more information:
1. carbon or cocoa 
2. your hardware
3. size of the file (number of line, and number of characters in the longest line).
4. does it behave better if you open the same file in the text editor ?
5. is only scrolling that is slow ? 
6. are you scrolling using the mouse wheel or someother way ?
Comment 2 Kevin Barnes CLA 2009-07-06 10:27:50 EDT
closing as WORKSFORME for now. Please reopen with more information - see comment #1.
Comment 3 Michael CLA 2009-07-06 14:08:12 EDT
1. carbon or cocoa 
   Cocoa - 32-bit

2. your hardware
   Dual Core 3Ghz + 8800GS video card. 

3. size of the file (number of line, and number of characters in the longest
line).

   Any would do. Mine was ~= 200 lines. Longest line ~= 80 characters.

4. does it behave better if you open the same file in the text editor ?
   If you mean other than eclipse - yes, scrolls very fast

5. is only scrolling that is slow ? 
   Yes

6. are you scrolling using the mouse wheel or someother way ?
   Both. Mouse wheel and the up/down keys. You can see it redraws the screen.
   The eclipse doesn't do that on either Windows or Linux.
Comment 4 Kevin Barnes CLA 2009-07-06 14:16:33 EDT
Have you changed your keyboard or mouse preferences in some way? Maybe we aren't reacting to you preferences properly.

> 4. does it behave better if you open the same file in the text editor ?
Try selecting your .java file in the package explorer, then right click and choose "Open With" and "Text Editor" instead of "Java Editor". Does scrolling get faster?
Comment 5 Mike Schrag CLA 2009-07-06 14:48:55 EDT
sorry -- i was in the wrong bug earlier (not sure how i missed this one) ... here's a copy of my comment from bug 268877:

java editor
657 line file (with quite a few errors in it, just for good measure)

holding down the arrow key to scroll through the document:

eclipse 3.5.0 carbon 32bit leopard JDK 1.5 = 24s
eclipse 3.5.0 cocoa 64bit leopard  JDK 1.6 = 61s
eclipse 3.5.0 cocoa 32bit leopard  JDK 1.5 = 71s
eclipse 3.4.2 carbon 32bit leopard  JDK 1.5 = 21s

this basically is showing that it's not 1.6 vs 1.5 (though that DOES give a
decent bump to be on 1.6), but instead it's cocoa vs carbon making the big diff

it appears that there is some degenerative redraw bug being hit here. maybe
it's related to the package explorer scroll bug too?
Comment 6 Michael CLA 2009-07-06 17:22:30 EDT
Hi,

Yes, the plain text editor in Eclipse is a slight bit faster.
Comment 7 Sebastien Sahuc CLA 2009-07-07 12:56:22 EDT
I confirm the slowness of the cocoa version of Eclipse 3.5 in the Java Editor.
Comment 8 Quinton Dolan CLA 2009-09-01 13:10:31 EDT
I believe this slowness issue is in part caused by the compositing of the decorators and the IO cost of using NSImage to do this work, which to the best of my knowledge is not hardware accelerated and is performed by the CPU on a RAM based back buffer that is then DMA'ed back to the GPU.

An easy way to demonstrate this slowness is to create the following class:

public class Test {
	public void test(Object refactor) {
		if (refactor == null) refactor = null;
		if (refactor == null) refactor = null;
		if (refactor == null) refactor = null;
		if (refactor == null) refactor = null;
		if (refactor == null) refactor = null;
		if (refactor == null) refactor = null;
	}
} 

Select the "refactor" argument text in the method signature and do a CMD+OPT+R refactoring, it should popup a yellow popup on the screen, the redraws are painfully slow as you type.

The carbon based version of SWT doesn't appear to suffer from this issue nearly as much, however the carbon implementation utilises CoreGraphics rather than NSImage to do image composition, which I believe IS hardware accelerated.

Profiling this in Shark seems to indicate that the bulk of the time is spend in NSImage:drawInRect.

In addition to this, the size of the editor window being drawn has a significant effect of the appearance of this issue. On at 15" display it is far less noticeable than running on a 24" or 30" display.

On a final note, temporarily disabling the drawing of all decorators while running in the debugger appears to resolve perceived slowness, indicating that it is this drawing activity that is causing the issue.

I would appear that reusing the CoreGraphics implementation from the Carbon version of SWT may be a possible solution to this issue.
Comment 9 Kevin Barnes CLA 2009-09-14 13:24:52 EDT
Is the slowness improved on 10.6? It appears that NSImage may be using CGImage on Snow Leopard.
Comment 10 Michael CLA 2009-09-14 20:51:27 EDT
Hi,

I don't run Snow Leopard and probably won't for a year at the very least.
The scrolling needs fixing on Leopard first IMO, as it is a mainstream OS at the moment.

Regards,
   Michael
Comment 11 Quinton Dolan CLA 2009-09-14 21:08:22 EDT
No, it does not appear that snow leopard makes any noticeable difference to this issue.
Comment 12 Kevin Barnes CLA 2009-09-16 16:54:39 EDT
The refactoring test case in comment 8 is unrelated. Filed bug 289655 against JDT UI for that one.
Drawing the decorations in a java editor currently happens outside of normal paint events. When the patch on Bug 275686 is accepted, we should be able to make some improvements here.
Comment 13 Matthew Phillips CLA 2009-10-06 21:47:37 EDT
Just to add an additional datapoint, I noticed this immediately on switching to Eclipse 3.5.1/Cocoa/64-bit. I see it with files opened in Java mode and basic text mode.

I can see noticeable lag and "tearing" during scrolling, making it painful to track the text as I scroll. Text scrolling under the Carbon SWT used to be rock solid.

System:

  Mac Pro, Mac OS X 10.6.1 (Snow Leopard), Java 1.6.0 (64 bit), Eclipse 3.5.1/Cocoa SWT (64 bit).

Cheers,

Matthew.
Comment 14 Kevin Barnes CLA 2009-10-09 15:03:27 EDT
Bug 275638 was fixed this morning. Please try next weeks integration build and report back if scrolling is improved for you.
Comment 15 Mike Schrag CLA 2009-10-21 23:15:05 EDT
Scrolling is about 75% better with that patch in ... One interesting thing I found is that if I comment out everything in the Control.update(boolean) method, scrolling is 100% faster (than the original unpatched version). This is obviously turning off displayIfNeeded on every control, but it appears that lots of components redraw themselves anyway and that this is actually a pretty expensive operation.

I don't know exactly what to make of this, because just removing it completely is .... bad :), but maybe there can be some additional API exposed to have better controls on this?  For instance, it doesn't appear that StyledText needs to displayIfNeeded while you're scrolling -- things APPEAR to be fine without it.

Also, I think that AnnotationRulerColumn might be the devil?  It actually seems to request redraws a LOT. The patch to not draw outside the UI thread makes it better, but it still shows up pretty high in profiling.
Comment 16 Silenio Quarti CLA 2009-10-22 10:05:33 EDT
That is great news. Let me try to understand the numbers: if it is 75% faster, it means that the table from comment#5 becomes:

eclipse 3.5.0 carbon 32bit leopard JDK 1.5 = 24s
eclipse 3.5.0 cocoa 64bit leopard  JDK 1.6 = 61s -> 15s
eclipse 3.5.0 cocoa 32bit leopard  JDK 1.5 = 71s -> 17s
eclipse 3.4.2 carbon 32bit leopard  JDK 1.5 = 21s

Is this right? If so, cocoa as already perfoming better than carbon.

The code from update() can not be commented <g>. AnnotationRulerColumn (and other rulers) could just call redraw() instead of redraw()/update(). I tried this before disabling/enabling the window from flushing its buffer. It worked ok on cocoa, but not on GTK and Windows. On Windows/GTK, the rulers would not follow the text as you scroll. I believe it works on cocoa because the equivalent of update always happens in the event loop.

Another option I have not experimented is to implement scrolling on the rulers the same way it is done in StyledText. Instead of redrawing the whole widget, it could call Canvas.scroll() to copy bits on the screen and redraw only obscured areas.  I am not sure it is worth making these changes, if scrolling is faster than carbon...
Comment 17 Mike Schrag CLA 2009-10-22 13:51:35 EDT
We're very much in the ballpark.  I reran tests on 3.4.2, 3.5.1 Carbon, 3.5.1 Cocoa, and 3.5.1+Fix Cocoa. In this test, I use a very large file and I hold the arrow key for 10 seconds from the first line and see how many lines it scrolls through before the time is up.  The numbers come out:

Carbon 3.4.2 - 419 lines
Carbon 3.5.1 - 404 lines
Cocoa 3.5.1 - 165 lines
Cocoa 3.5.1+Fix - 400 lines

So Cocoa 3.5.1+Fix, at this point, is right in the ballpark of Carbon now.  That said, if we can be even faster, that's even better, but I would consider this officially fixed, and maybe a new enhancement opened for NSCopyBits on the ruler.

Incidentally, the tests I ran in the original one had red squiggles ... I believe error squiggles particularly hurt performance before, so probably made the spread look different. So if I tested with a bunch of errors, I suspect the % increase might look even better, but I don't know that we actually beat Carbon, yet.

I do think the annotation ruler fix is a good idea, though, assuming it's not too annoying to do. What might be worth doing is turning off the annotation ruler redraw entirely and see what the speed diff is. That's your best case scenario. If it's not >10% I wouldn't even bother changing to the copy approach, IMO.
Comment 18 Mike Schrag CLA 2009-11-02 14:38:02 EST
The return of slow scroll -- if you open several editors (I did a test with 20 java editors to exacerbate it) and try to scroll in any one of them, scrolling speed drops through the floor. This might be worth opening a different bug, because actually all editor navigation sucks, not just scrolling, but i thought it might all be related.

I did some profiling and found some interesting results:

15% of Eclipse scrolling time is spent redrawing AnnotationRuler, even with the new fixes

10% is spent redrawing CTabFolder while scrolling? I don't even know why that is ...

org.eclipse.jface.text.PaintManager.keyPressed and Display.removePool seem to get disproportionately slower as there are more editors open

TextLayout.computeRuns is called thousands of times even though the text isn't changing ... maybe caching here would help.

Curiously it appears that the relative cost of almost most calls is about the same as more editors open. This is actually surprising, because it's so much slower, it means everything is just getting slower. The keyPressed and removePools were definitely non-linearly slower, so those seemed like prime candidates to look at.  I still would have expected more standout "badness" though not just everything getting slow proportionally -- i would expect other editors to not have any impact. I'm wondering if they're all getting events delivered to them and slowing things down even when they're not visible in the CTabFolder.
Comment 19 Kevin Barnes CLA 2009-11-02 15:57:45 EST
Mike, can you try hacking Composite.isOpaque() to return true always? That change is likely going to introduce other bugs, but if scrolling gets faster for you, we'd have a clue at least.
Comment 20 Mike Schrag CLA 2009-11-02 16:10:59 EST
still slow ... definitely0 EVERYTHING gets slow, not just scrolling. as you start to open upwards of 20 java files, it looks like the entire UI just becomes less sluggish and less responsive.
Comment 21 Kevin Barnes CLA 2009-11-02 16:40:39 EST
Does scrolling get slower on carbon as you open more editors.
Sorry about all the questions, we haven't been able to replicate your experience so far.
Comment 22 Mike Schrag CLA 2009-11-02 16:56:13 EST
Another data point -- I'm on a 30" display with Eclipse maximized ... it does seem to be noticeably worse when i do that. I presume with an excessive repainting bug that would tend to be the case.  Is it weird that scrolling triggers a CTabFolder repaint?
Comment 23 Mike Schrag CLA 2009-11-02 16:57:30 EST
carbon is very fast ... no noticeable slowdown at all.
Comment 24 Kevin Barnes CLA 2009-11-02 17:21:04 EST
> Another data point -- I'm on a 30" display 

Lucky you! The biggest we have is 20" iMacs. I do notice a difference between scrolling a maximized editor and a small one so I guess that's what you're seeing. On our machines it never gets painful, and I don't notice it slowing down as I open more editors.

StyledText is currently answering false to isOpaque so it's not too surprising that the parent control (ie the CTabFolder) thinks it should be drawing itself.
Comment 25 Mike Schrag CLA 2009-11-02 17:32:18 EST
On a related note, I wonder if the opacity of StyledText is related to Bug 239109?  I haven't noticed that bug happening on 3.5 Cocoa. Any chance Carbon returned true for isOpaque but wasn't actually redrawing everything whereas Cocoa returns false for isOpaque (and is fast) so the OS doesn't presume the background is filled?  Totally out on a limb, but it just made me think of that bug.
Comment 26 Silenio Quarti CLA 2009-11-03 09:37:04 EST
(In reply to comment #22)
> Another data point -- I'm on a 30" display with Eclipse maximized ... it does
> seem to be noticeably worse when i do that. I presume with an excessive
> repainting bug that would tend to be the case.  Is it weird that scrolling
> triggers a CTabFolder repaint?

We thought that returning true all the time in Composite.isOpaque() should avoid the CTabFolder from drawing when the StyledText scrolls. Was that the case when you hacked the code?
Comment 27 Silenio Quarti CLA 2009-11-03 09:38:47 EST
(In reply to comment #25)
> On a related note, I wonder if the opacity of StyledText is related to Bug
> 239109?  I haven't noticed that bug happening on 3.5 Cocoa. Any chance Carbon
> returned true for isOpaque but wasn't actually redrawing everything whereas
> Cocoa returns false for isOpaque (and is fast) so the OS doesn't presume the
> background is filled?  Totally out on a limb, but it just made me think of that
> bug.

I believe carbon returns false to is opaque (see bug#227520).
Comment 28 Mike Schrag CLA 2009-11-03 09:49:17 EST
I'll check if the opaque setting stopped the CTabFolder repaint and see if i can get some timing differences between the two as well.
Comment 29 Mike Schrag CLA 2010-01-18 13:53:56 EST
I don't have timings of this one, but things were definitely still slow even after that setting. I tried 3.6M4, which I saw a tweet that implied that it fixed some OS-level performance issues, but it seems just as rough.
Comment 30 Mike Schrag CLA 2010-01-18 14:02:15 EST
This is a video showing Xcode and Eclipse scrolling the same file in the same sized-window. ScreenFlow slows both of them proportionally (maybe a 20% perf hit for the recording):

http://webobjects.mdimension.com/wolips/support/misc/SlowScrolling.mov

This is on a 2.6Ghz Core 2 Duo MBP.
Comment 31 Kevin Barnes CLA 2010-02-10 15:35:59 EST
Made a small change for bug 290449 that might make this a little better. Change is in I20100209-2300.
Comment 32 Mike Schrag CLA 2010-02-23 08:08:31 EST
Created attachment 159914 [details]
jprofiler output from scrolling in 3.6

The latest I-build is definitely better than previous Cococa builds, but we are still 50-60% slower than Xcode scrolling the same file. I'm attaching my JProfiler results from scrolling through 500 lines of a 10,000 line java file.
Comment 33 Mike Schrag CLA 2010-02-23 08:10:16 EST
One interesting point there is that it spent 10% of time redrawing the annotation ruler, which seems particularly excessive.
Comment 34 Mike Schrag CLA 2010-02-23 10:10:52 EST
Incidentally, this profile was taken from the latest I-build of 3.6.

I scrolled about 500 lines, which roughly seems to correspond to the "458 invocations" that are throughout -- so it looks like a lot of this happens maybe once per scroll line (maybe every keystroke? not sure).

Another thing that looks wrong is that the ctabfolder tabs redraw its tabs every time -- seems like it should check the clipping bounds and only redraw if it intersects. it doesn't seem necessary to redraw the tabs when only scrolling is happening. this accounts for something like 5% of scroll time. ... actually.. maybe worse? it seems to be triggering a repaint for both the text view updating AND the annotation ruler updating as well as some third widget paint op down towards the bottom. If I'm interpreting this right, it might account for as much as 15+% of scroll time.
Comment 35 Mike Schrag CLA 2010-02-23 10:17:17 EST
just discovered something interesting .... it appears that overall speed is FAR more impacted by the size of the eclipse window than the size of the editor view, which is VERY curious.

if i full-screen eclipse on my 30" display but shrink the editor view way down, scrolling is still slow. if i shrink my eclipse window down but maximize my editor view, scrolling is substantially faster.
Comment 36 Scott Kovatch CLA 2010-04-29 02:45:40 EDT
(In reply to comment #15)
> Scrolling is about 75% better with that patch in ... One interesting thing I
> found is that if I comment out everything in the Control.update(boolean)
> method, scrolling is 100% faster (than the original unpatched version). This is
> obviously turning off displayIfNeeded on every control, but it appears that
> lots of components redraw themselves anyway and that this is actually a pretty
> expensive operation.
> 
> I don't know exactly what to make of this, because just removing it completely
> is .... bad :), but maybe there can be some additional API exposed to have
> better controls on this?  For instance, it doesn't appear that StyledText needs
> to displayIfNeeded while you're scrolling -- things APPEAR to be fine without
> it.

displayIfNeeded is the wrong call for the implementation of update(), since it's only supposed to force that Control to draw. displayIfNeeded walks up the view hierarchy until it finds an opaque ancestor, so it may draw more views than you think it should be drawing. In this case, it looks like it's working its way back up to the tab folder and repaints them as well. I added [NSView displayIfNeededIgnoringOpacity], which draws ONLY the messaged view and its children. This appears to help for me.
Comment 37 Silenio Quarti CLA 2010-04-29 12:11:25 EDT
I do not think calling displayIfNeededIgnoringOpacity() for widgets that are partially transparent (like buttons) is correct. You will most certainly get corrupted pixels.

I believe Composite.isOpaque() should return true for StyledText and them displayIfNeeded() would not go up the hierarchy. Try this code (in Composite). It should have the same effect.

boolean isOpaque (int /*long*/ id, int /*long*/ sel) {
	if ((state & CANVAS) != 0) {
		if (id == view.id) {
			return region == null && ((background != null && background[3] == 1) || (style & SWT.NO_BACKGROUND) != 0) && !isObscured ();
		}
	}
	return super.isOpaque (id, sel);
}

Note that we experimented with this in the past (see comment#19) and it did not seem to help. I am ok to release the change if it improves performance.
Comment 38 Silenio Quarti CLA 2010-04-29 12:25:21 EDT
Created attachment 166515 [details]
ideas

This patch has the change I mentioned above and another idea I had: it disables window flush while handling a key down event. It is the same approach I used to get rid of the visual tearing while scrolling with the scrollbars. This should help while scrolling with page and arrow keys. I have not tested the patch that much. 

One thing that really makes a difference to me while scrolling with the keyboard is to change the repeat rate in the System preferences to be the fasted possible.
Comment 39 Scott Kovatch CLA 2010-04-29 12:29:41 EDT
(In reply to comment #37)
> I believe Composite.isOpaque() should return true for StyledText and them
> displayIfNeeded() would not go up the hierarchy. Try this code (in Composite).
> It should have the same effect.
> 
> boolean isOpaque (int /*long*/ id, int /*long*/ sel) {
>     if ((state & CANVAS) != 0) {
>         if (id == view.id) {
>             return region == null && ((background != null && background[3] ==
> 1) || (style & SWT.NO_BACKGROUND) != 0) && !isObscured ();
>         }
>     }
>     return super.isOpaque (id, sel);
> }

I'll give this a try -- I agree, this should have the same effect.

> Note that we experimented with this in the past (see comment#19) and it did not
> seem to help. I am ok to release the change if it improves performance.

After some more investigation this morning I'm inclined to agree with you. QuartzDebug is showing a bigger problem with our scrolling compared to Xcode.

Launch QuartzDebug and turn on 'Flash screen updates' Then, scroll a long document line by line. Do this in both Xcode and Eclipse and compare the behavior. (For Xcode you should split the editor horizontally). In Xcode only the line being scrolled into view is being drawn. In Eclipse the updated line plus the entire contents of the editor from the cursor down is being redrawn, even past the bounds of the scrollview. This can't be good.
Comment 40 Scott Kovatch CLA 2010-04-29 12:35:31 EDT
> Launch QuartzDebug and turn on 'Flash screen updates' Then, scroll a long
> document line by line. Do this in both Xcode and Eclipse and compare the
> behavior. (For Xcode you should split the editor horizontally). In Xcode only
> the line being scrolled into view is being drawn. In Eclipse the updated line
> plus the entire contents of the editor from the cursor down is being redrawn,
> even past the bounds of the scrollview. This can't be good.

This also happens in Carbon, by the way, so there could be something in Cocoa that's just making it worse or more readily apparent.
Comment 41 Silenio Quarti CLA 2010-04-29 13:45:25 EDT
I do not think comparing Xcode and Eclipse is fair when scrolling with the arrow down key. Xcode scrolls half a page instead of line by line.
Comment 42 Silenio Quarti CLA 2010-04-29 15:52:33 EDT
Created attachment 166563 [details]
modified version of javaviewer

I think that Quartz Debug is showing the union of the rectangles that needed to be updated. When you scroll down, the status area is updated (changes the line number). So the union of the bottom line and the status area is the whole area under the editor.

This attachment is a modified version of the JavaViewer. It behaves as you expect.
Comment 43 Silenio Quarti CLA 2010-04-29 15:57:49 EDT
(In reply to comment #41)
> I do not think comparing Xcode and Eclipse is fair when scrolling with the
> arrow down key. Xcode scrolls half a page instead of line by line.

Interesting. TextEdit and Xcode scroll by half page to me, but not for you. There must a system settings to control this behavior
Comment 44 Silenio Quarti CLA 2010-04-29 16:07:13 EDT
(In reply to comment #35)
> just discovered something interesting .... it appears that overall speed is FAR
> more impacted by the size of the eclipse window than the size of the editor
> view, which is VERY curious.
> 
> if i full-screen eclipse on my 30" display but shrink the editor view way down,
> scrolling is still slow. if i shrink my eclipse window down but maximize my
> editor view, scrolling is substantially faster.

Mike, would you be able to try my patch from comment#38?

I believe that flushing the window buffer is what makes scrolling slow for you. The bigger the window, the bigger the buffer to flush. The size of the editor does not matter if the whole buffer is flushed all the time.
Comment 45 Mike Schrag CLA 2010-04-29 16:13:41 EDT
Sure -- It's the last day at my job tomorrow, so it's a little hectic, but I'll give it a go on Sat for sure.
Comment 46 Silenio Quarti CLA 2010-04-29 16:18:57 EDT
I tried my patch on a duo monitor mac. I made my window big so that it span over both screens. It really makes a huge difference.
Comment 47 Mike Schrag CLA 2010-04-29 16:21:57 EDT
That's awesome. This is by far the #1 complaint for us with Cocoa. I might put this in tonight and give it a go.
Comment 48 Scott Kovatch CLA 2010-04-29 17:15:52 EDT
I'm liking this patch more and more. Before it I was seeing the last line painted twice while holding down the down arrow key as it scrolled down one line at a time, and I no longer see that. It certainly feels faster, but I don't have a big enough screen to get the full benefit of the change. Once we get confirmation from someone who sees it all the time (Mike S.) you should definitely check it in.
Comment 49 Silenio Quarti CLA 2010-04-29 17:32:07 EDT
Created attachment 166575 [details]
javaviewer showing problem in patch

Well, not so fast. The patch is a prove of concept <g>.  The way it is not, it will cause a huge problem for any one that opens a dialog inside a key listener (for example). While the dialog event loop is running, the window buffer will never be flush to the screen. Run this sample and type F2. A dialog will open. The bottom text should start scrolling in a timer, but nothing changes until the dialog is closed.

The only idea I got so far to solve this problem is to add the window too a list and re-enable flushing if the event loop is touched some how.
Comment 50 Silenio Quarti CLA 2010-04-29 17:59:17 EDT
Created attachment 166577 [details]
fix

This is what I had in mind.
Comment 51 Mike Schrag CLA 2010-05-01 17:29:15 EDT
2.41x speed increase with this patch ... fantastic work, guys.

I did a test scrolling through CCombo.java for 500 lines:

3.6M7 Cocoa 64bit without patch = 41 seconds
3.6M7 Cocoa 64bit WITH patch = 17 seconds
Xcode = _19_ seconds

take that, Xcode.
Comment 52 Pascal Rapicault CLA 2010-05-01 20:05:08 EDT
When do we get that in the I Build? Please :)))
Comment 53 Scott Kovatch CLA 2010-05-02 00:13:21 EDT
Silenio and I talked about a similar but smaller patch. Disabling window updates for every keystroke seems like too heavy of a thing to do when we just need to detect when we're in a case where we want Canvas.scroll() to happen quickly. As it is now, any key activity disables screen updates until the key handling is done, which is overkill. I'm working on a refinement this weekend, and we hope to put it in next week.
Comment 54 Scott Kovatch CLA 2010-05-03 02:20:54 EDT
Created attachment 166749 [details]
possible patch

This patch skips calling displayIfNeeded if we are handling an event that might trigger a scroll. Unlike the previous patch we only skip updating when a scroll is about to happen, instead of preemptively disabling all screen updates.

Looking at this again, I probably should add disabling window flushing before calling update(all) in Canvas.scroll and re-enabling it in clearDeferUpdates. That's probably the safer change, but I also didn't see any visual problems with this change. It's getting late....

I was also able to simplify clearing the skip-update flag by using a performSelector:withObject:afterDelay: with a delay of 0.0, which has the equivalent effect of performing the selector after the current pass of the runloop finishes processing. That way we don't have to manage the windows that need to have the deferral flag cleared -- Cocoa does it for us.
Comment 55 Silenio Quarti CLA 2010-05-03 12:51:49 EDT
This patch does not fix the problem. There are other calls to update() in the rulers (jface) beside the StyledText.  You are only catching the one from Canvas.scroll().

We cannot add a boolean field to Widget. It is to expensive for Items. I believe the flag would go into Shell.

We cannot avoid the call to update() all together because we break our API. All the SWT.Paint events should happen as usual. The only thing we have to avoid is the flushing of the window buffer the screen. 

I am going to attach a modified patch that uses the flag and performSelector() to the clear the flag, but it disables window flush around the call to displayIfNeeded() (which still needs a try/finally block). I am not sure this patch is much better than the other one from comment#50.
Comment 56 Silenio Quarti CLA 2010-05-03 12:54:27 EDT
Created attachment 166808 [details]
patch using the performSelector() idea
Comment 57 Scott Kovatch CLA 2010-05-03 13:37:24 EDT
(In reply to comment #55)

> I am going to attach a modified patch that uses the flag and performSelector()
> to the clear the flag, but it disables window flush around the call to
> displayIfNeeded() (which still needs a try/finally block). I am not sure this
> patch is much better than the other one from comment#50.

On the contrary, this is much better because it doesn't assume that any keydown or scroll event will automatically lead to a call to update(). That was my biggest concern about the earlier patch, and this takes care of it. I had added the disable/enableFlushWindow change locally this morning, but didn't catch that the rulers were redrawing.

Do we need a call to flushWindowIfNeeded in clearDeferUpdates? The window won't be flushed until something calls NSView.display or displayIfNeeded, but since scrolling is dirtying the window that will happen anyway.
Comment 58 Scott Kovatch CLA 2010-05-03 14:06:09 EDT
Created attachment 166816 [details]
patch with flushWindowIfNeeded

This patch adds flushWindowIfNeeded in clearDeferFlushing. I renamed a few things because we aren't deferring updates themselves, just the flushing. It doesn't break the speed improvements for me, but someone with a bigger screen should double-check.
Comment 59 Silenio Quarti CLA 2010-05-03 14:14:55 EDT
(In reply to comment #58)
> Created an attachment (id=166816) [details]
> patch with flushWindowIfNeeded
> 
> This patch adds flushWindowIfNeeded in clearDeferFlushing. I renamed a few
> things because we aren't deferring updates themselves, just the flushing. It
> doesn't break the speed improvements for me, but someone with a bigger screen
> should double-check.

The call to flushWindowIfNeeded() is not need. This is done by cocoa automatically when we return to the event loop.

We need to add calls to window.retain()/release() in Control.update().
Comment 60 Silenio Quarti CLA 2010-05-03 14:26:45 EDT
I am also concerned that the flag does not gets cleared soon enough by selector we schedule using  performSelector:withObject:afterDelay:. The doc says it will run as soon as possible for a delay of 0.0, but it does not really say it is going to happen before any event is dispatched. Also it says the timer only runs in the default run loop mode (not in tracking).

Should we just clear the flag ourselves in a try finally in scrollWheel/keyDown/sendSelection and in display.applicationNextEventMatchingMask?
Comment 61 Scott Kovatch CLA 2010-05-03 15:02:29 EDT
(In reply to comment #60)
> I am also concerned that the flag does not gets cleared soon enough by selector
> we schedule using  performSelector:withObject:afterDelay:. The doc says it will
> run as soon as possible for a delay of 0.0, but it does not really say it is
> going to happen before any event is dispatched. Also it says the timer only
> runs in the default run loop mode (not in tracking).

Passing afterDelay: of 0 is a common technique that ensures the method will be called at a safe time in the future, but not immediately when performSelector: is called. In my experience it always calls on the next pass of the runloop, even with that warning.

For the runloop modes, yes, there is another version of performSelector -- performSelector:withObject:afterDelay:inModes: -- that lets you specify the modes it should run in. We should use that, and pass an array with NSEventTrackingRunLoopMode, NSDefaultRunLoopMode, and NSModalPanelRunLoopMode.
Comment 62 Scott Kovatch CLA 2010-05-03 18:46:29 EDT
Created attachment 166883 [details]
final patch

This should do it. The modes array never changes, so I create it once in the Display and every performSelector invocation gets it from there. Also retained and released the window around the flush disabling.
Comment 63 Scott Kovatch CLA 2010-05-03 18:47:04 EDT
Silenio, please review for this week's i-build.
Comment 64 Silenio Quarti CLA 2010-05-03 21:52:24 EDT
Patch has been release (>20100503)

Everyone, please try the next integration build.
Comment 65 Pascal Rapicault CLA 2010-05-03 22:54:02 EDT
And the best way to get this update is to use p2 of course ! 
Here is the site where all the I builds get published: http://download.eclipse.org/eclipse/updates/3.6-I-builds
Comment 66 Fabian Peters CLA 2010-05-11 07:47:54 EDT
I'm using eclipse-SDK-I20100506-0800-macosx-cocoa-x86_64 on 10.6.3 since two days now and the scrolling behaviour is much better. Thanks!
Comment 67 Radu Toader CLA 2013-12-16 09:20:55 EST
go to system preferences -> mouse -> scrooling speed : FAST 

And check it out.
I had the same issue, now it works really fast. (mac mini@Mavriks)