Bug 27869 - StyledText overuse of Font.getFontData
Summary: StyledText overuse of Font.getFontData
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 2.1   Edit
Hardware: PC All
: P2 normal (vote)
Target Milestone: 2.1 M5   Edit
Assignee: Lynne Kues CLA
QA Contact:
URL:
Whiteboard:
Keywords: performance
Depends on:
Blocks:
 
Reported: 2002-12-06 15:27 EST by Felipe Heidrich CLA
Modified: 2002-12-23 14:36 EST (History)
2 users (show)

See Also:


Attachments
Patch for StyledText and other (73.66 KB, application/octet-stream)
2002-12-06 15:30 EST, Felipe Heidrich CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Felipe Heidrich CLA 2002-12-06 15:27:42 EST
Running eclipse, using the Java Editor: A single key stroke can cause the API 
Font.getFontData() to be called 13 times. I believe, and many people agree, 
that this API don't need to be used at all by the StyledText when it's been 
typed. This API is also overused when we are scrolling the StyledText and 
selecting text. Try to add system.out.println in the first line of method 
Font#getFontData, run a selfhosted eclipse, watch the console.

I concerned about this problem cause in some platform the performance of this 
method is very pour if compared with Windows.

For example, Motif running on UTF-8. Each Font has 7 FontData, therefore every 
time I type 'a' in the JavaEditor 91 (7*13) FontData will be loaded. Btw, UTF-8 
is the default english encoding for Redhat 8.

FontMetrics API is also very used by the StyledText, I believe that the metric 
information should be cached in the StyledText and update only when the font is 
changed.
Comment 1 Felipe Heidrich CLA 2002-12-06 15:29:31 EST
I've locked in the StyledText code to know why getFontData is need, and as far 
as I understand the code this API is only been used to check the style in the 
(first) FontData and pick the rigth font (regular/bold) for the GC. 

I've changed this in the StyledText, I'm attaching my changes in.
Comment 2 Felipe Heidrich CLA 2002-12-06 15:30:54 EST
Created attachment 2691 [details]
Patch for StyledText and other

A version of StyledText that doesn't use getFontData.
Comment 3 Christophe Cornu CLA 2002-12-06 16:32:45 EST
Felipe found on a particular motif box that calling getFontData a hundred 
times could take 2 seconds. Typing 10 characters per second, a not so 
unrealistic rate, would cause 130 calls.

Lynne/Knut to investigate and advise. Please let us know what you think of the 
suggested change. Thanks!


Comment 4 Felipe Heidrich CLA 2002-12-06 16:59:52 EST
I just realized that I changed a protected method in StyledTextRender 
(drawLineSelectionBackground), Even though I've already changed DisplayRenderer 
and PrintRenderer this method is part of StyledText API and may cause problems 
in anothers implementations of the type (if they exist).

Anyhow, Knut & Lynne can take care of this.
Comment 5 Lynne Kues CLA 2002-12-07 12:04:01 EST
Thanks Felipe.  We did do a pass on calling getFontData() less awhile ago, but 
I guess more calls to it leaked into the code.  The changes look okay to me, 
but Knut should verify this.  

StyledTextRenderer does not have any public API, so the changes won't break 
anything.
Comment 6 Steve Northover CLA 2002-12-17 18:25:00 EST
You guys should do this soon (for M5) to give us a nice long time to test it.
Comment 7 Lynne Kues CLA 2002-12-18 10:37:12 EST
Related report [Bug 26057].
Comment 8 Lynne Kues CLA 2002-12-18 10:48:22 EST
From KR:

I don't understand the new code in StyledTextRenderer.setLineFont. The purpose 
of the old code was to avoid setting the font on the GC if it is already set. 
We basically just used the fontdata to hold the current font style. We probably 
could have used an int[] argument that gets passed back up or a global variable.
The new identity check doesn't make sense to me. I think this test always 
resolves to true on Windows because getFont always returns a new object. Other 
platforms probably work the same way. In addition the font that is passed in as 
currentFont is the gc.getFont, i.e., the font currently set in the GC. So even 
if we tested equality it would still always resolve to true.  The result would 
be that the font is always set, every time setLineFont is called.  If 
GC.setFont is not expensive on any of the platforms we can just get rid of the 
passed in Font.

From FH:

Agreed, to use identity or equality are both wrong...
But we should not call GC.setFont all the time, it can be a performance problem.

I believe setLine should be something like this:
private void setLineFont(GC gc, int style) {
    if (currentStyle != style) {
        if (style == SWT.BOLD) {
	    gc.setFont(boldFont);
	}
	else if (style == SWT.NORMAL) {
	    gc.setFont(regularFont);
	}
	currentStyle = style; //this would be the global variable Knut said.
    }
}

Getting rid of passing Font in all those methods makes the code more simple.
I've tried this but I was not able to get caret in the right place when moving 
it over a a bold text.
Comment 9 Lynne Kues CLA 2002-12-23 14:36:21 EST
Changed to cache current font style.  Also put in change to minimize the number 
of times setFont is called when text includes different font styles.