editor painting speed optimization
authorDmitry Batrak <Dmitry.Batrak@jetbrains.com>
Wed, 25 Nov 2015 18:53:03 +0000 (21:53 +0300)
committerDmitry Batrak <Dmitry.Batrak@jetbrains.com>
Wed, 25 Nov 2015 18:53:49 +0000 (21:53 +0300)
platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/softwrap/CompositeSoftWrapPainter.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorPainter.java
platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorPaintingPerformanceTest.java

index 20accf2f7d74d4bdc32df36ff4f9809a2f9d6337..596613e3b98207e449b11fb9ec99dc01e741ae3b 100644 (file)
@@ -341,6 +341,17 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedInternalDo
     if (!isSoftWrappingEnabled()) {
       return 0;
     }
+    if (!myEditor.getSettings().isAllSoftWrapsShown()) {
+      int visualLine = y / lineHeight;
+      LogicalPosition position = myEditor.visualToLogicalPosition(new VisualPosition(visualLine, 0));
+      if (position.line != myEditor.getCaretModel().getLogicalPosition().line) {
+        return myPainter.getDrawingHorizontalOffset(g, drawingType, x, y, lineHeight);
+      }
+    }
+    return doPaint(g, drawingType, x, y, lineHeight);
+  }
+  
+  public int doPaint(@NotNull Graphics g, @NotNull SoftWrapDrawingType drawingType, int x, int y, int lineHeight) {
     return myPainter.paint(g, drawingType, x, y, lineHeight);
   }
 
index 32f95d95a2b4edac566d4bec61997f3fbfe56b25..0eb31983df29cee77f9d866f7c29470fbca96018 100644 (file)
@@ -16,8 +16,6 @@
 package com.intellij.openapi.editor.impl.softwrap;
 
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.LogicalPosition;
-import com.intellij.openapi.editor.VisualPosition;
 import com.intellij.openapi.editor.colors.EditorColors;
 import com.intellij.openapi.editor.ex.EditorEx;
 import com.intellij.openapi.editor.impl.ColorProvider;
@@ -145,13 +143,6 @@ public class CompositeSoftWrapPainter implements SoftWrapPainter {
   @Override
   public int paint(@NotNull Graphics g, @NotNull SoftWrapDrawingType drawingType, int x, int y, int lineHeight) {
     initDelegateIfNecessary();
-    if (!myEditor.getSettings().isAllSoftWrapsShown()) {
-      int visualLine = y / lineHeight;
-      LogicalPosition position = myEditor.visualToLogicalPosition(new VisualPosition(visualLine, 0));
-      if (position.line != myEditor.getCaretModel().getLogicalPosition().line) {
-        return myDelegate.getDrawingHorizontalOffset(g, drawingType, x, y, lineHeight);
-      }
-    }
     return myDelegate.paint(g, drawingType, x, y, lineHeight);
   }
 
index 781637c180485f3d32c97fd3716ef7923cfc6550..454c81be13ef71ed4f1110f0e544e0dd8d4d9b58 100644 (file)
@@ -83,8 +83,8 @@ class EditorPainter implements TextDrawingCallback {
     
     int startLine = myView.yToVisualLine(Math.max(clip.y, 0));
     int endLine = myView.yToVisualLine(Math.max(clip.y + clip.height, 0));
-    int startOffset = myView.visualPositionToOffset(new VisualPosition(startLine, 0));
-    int endOffset = myView.visualPositionToOffset(new VisualPosition(endLine + 1, 0, true));
+    int startOffset = myView.visualLineToOffset(startLine);
+    int endOffset = myView.visualLineToOffset(endLine + 1);
     ClipDetector clipDetector = new ClipDetector(myEditor, clip);
     
     paintBackground(g, clip, startLine, endLine);
@@ -134,7 +134,11 @@ class EditorPainter implements TextDrawingCallback {
 
   private void paintBackground(Graphics2D g, Rectangle clip, int startVisualLine, int endVisualLine) {
     int lineCount = myEditor.getVisibleLineCount();
-    final Map<Integer, Couple<Integer>> virtualSelectionMap = createVirtualSelectionMap(startVisualLine, endVisualLine); 
+    
+    final Map<Integer, Couple<Integer>> virtualSelectionMap = createVirtualSelectionMap(startVisualLine, endVisualLine);
+    final VisualPosition primarySelectionStart = myEditor.getSelectionModel().getSelectionStartPosition();
+    final VisualPosition primarySelectionEnd = myEditor.getSelectionModel().getSelectionEndPosition();
+    
     VisualLinesIterator visLinesIterator = new VisualLinesIterator(myView, startVisualLine);
     while (!visLinesIterator.atEnd()) {
       int visualLine = visLinesIterator.getVisualLine();
@@ -149,7 +153,7 @@ class EditorPainter implements TextDrawingCallback {
         @Override
         public void paintBeforeLineStart(Graphics2D g, TextAttributes attributes, int columnEnd, float xEnd, int y) {
           paintBackground(g, attributes, 0, y, xEnd);
-          paintSelectionOnSecondSoftWrapLineIfNecessary(g, columnEnd, xEnd, y);
+          paintSelectionOnSecondSoftWrapLineIfNecessary(g, columnEnd, xEnd, y, primarySelectionStart, primarySelectionEnd);
         }
 
         @Override
@@ -167,7 +171,8 @@ class EditorPainter implements TextDrawingCallback {
             paintVirtualSelectionIfNecessary(g, virtualSelectionMap, columnStart, x, clip.x + clip.width, y);
           }
           else {
-            paintSelectionOnFirstSoftWrapLineIfNecessary(g, columnStart, x, clip.x + clip.width, y);
+            paintSelectionOnFirstSoftWrapLineIfNecessary(g, columnStart, x, clip.x + clip.width, y, 
+                                                         primarySelectionStart, primarySelectionEnd);
           }
         }
       });
@@ -207,9 +212,8 @@ class EditorPainter implements TextDrawingCallback {
     paintBackground(g, myEditor.getColorsScheme().getColor(EditorColors.SELECTION_BACKGROUND_COLOR), startX, y, endX - startX);
   }
 
-  private void paintSelectionOnSecondSoftWrapLineIfNecessary(Graphics2D g, int columnEnd, float xEnd, int y) {
-    VisualPosition selectionStartPosition = myEditor.getSelectionModel().getSelectionStartPosition();
-    VisualPosition selectionEndPosition = myEditor.getSelectionModel().getSelectionEndPosition();
+  private void paintSelectionOnSecondSoftWrapLineIfNecessary(Graphics2D g, int columnEnd, float xEnd, int y,
+                                                             VisualPosition selectionStartPosition, VisualPosition selectionEndPosition) {
     int visualLine = myView.yToVisualLine(y);
     
     if (selectionStartPosition.equals(selectionEndPosition) || 
@@ -227,9 +231,8 @@ class EditorPainter implements TextDrawingCallback {
     paintBackground(g, myEditor.getColorsScheme().getColor(EditorColors.SELECTION_BACKGROUND_COLOR), startX, y, endX - startX);
   }
 
-  private void paintSelectionOnFirstSoftWrapLineIfNecessary(Graphics2D g, int columnStart, float xStart, float xEnd, int y) {
-    VisualPosition selectionStartPosition = myEditor.getSelectionModel().getSelectionStartPosition();
-    VisualPosition selectionEndPosition = myEditor.getSelectionModel().getSelectionEndPosition();
+  private void paintSelectionOnFirstSoftWrapLineIfNecessary(Graphics2D g, int columnStart, float xStart, float xEnd, int y,
+                                                            VisualPosition selectionStartPosition, VisualPosition selectionEndPosition) {
     int visualLine = myView.yToVisualLine(y);
 
     if (selectionStartPosition.equals(selectionEndPosition) || 
@@ -323,6 +326,7 @@ class EditorPainter implements TextDrawingCallback {
   private void paintTextWithEffects(Graphics2D g, Rectangle clip, int startVisualLine, int endVisualLine) {
     final CharSequence text = myDocument.getImmutableCharSequence();
     final EditorImpl.LineWhitespacePaintingStrategy whitespacePaintingStrategy = myEditor.new LineWhitespacePaintingStrategy();
+    boolean paintAllSoftWraps = myEditor.getSettings().isAllSoftWrapsShown();
     int lineCount = myEditor.getVisibleLineCount();
     VisualLinesIterator visLinesIterator = new VisualLinesIterator(myView, startVisualLine);
     while (!visLinesIterator.atEnd()) {
@@ -337,15 +341,19 @@ class EditorPainter implements TextDrawingCallback {
       }
       if (visualLine >= lineCount) break;
       
+      final boolean paintSoftWraps = paintAllSoftWraps || 
+                                     myEditor.getCaretModel().getLogicalPosition().line == visLinesIterator.getStartLogicalLine();
       final int[] currentLogicalLine = new int[] {-1}; 
       
       paintLineFragments(g, clip, visLinesIterator, y, new LineFragmentPainter() {
         @Override
         public void paintBeforeLineStart(Graphics2D g, TextAttributes attributes, int columnEnd, float xEnd, int y) {
-          SoftWrapModelImpl softWrapModel = myEditor.getSoftWrapModel();
-          int symbolWidth = softWrapModel.getMinDrawingWidthInPixels(SoftWrapDrawingType.AFTER_SOFT_WRAP);
-          softWrapModel.paint(g, SoftWrapDrawingType.AFTER_SOFT_WRAP, 
-                              (int)xEnd - symbolWidth, y - myView.getAscent(), myView.getLineHeight());
+          if (paintSoftWraps) {
+            SoftWrapModelImpl softWrapModel = myEditor.getSoftWrapModel();
+            int symbolWidth = softWrapModel.getMinDrawingWidthInPixels(SoftWrapDrawingType.AFTER_SOFT_WRAP);
+            softWrapModel.doPaint(g, SoftWrapDrawingType.AFTER_SOFT_WRAP, 
+                                  (int)xEnd - symbolWidth, y - myView.getAscent(), myView.getLineHeight());
+          }
         }
 
         @Override
@@ -376,8 +384,9 @@ class EditorPainter implements TextDrawingCallback {
             int logicalLine = myDocument.getLineNumber(offset);
             paintLineExtensions(g, logicalLine, x, y);
           }
-          else {
-            softWrapModel.paint(g, SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED, (int)x, y - myView.getAscent(), myView.getLineHeight());
+          else if (paintSoftWraps) {
+            softWrapModel.doPaint(g, SoftWrapDrawingType.BEFORE_SOFT_WRAP_LINE_FEED, 
+                                  (int)x, y - myView.getAscent(), myView.getLineHeight());
           }
         }
       });
index dd5f68405fe3992146443df603c5a5187ee550fb..bd189dac103d2cafa399bf5c4f7f1e1d28489056 100644 (file)
@@ -38,7 +38,7 @@ public class EditorPaintingPerformanceTest extends AbstractEditorTest {
     initText(StringUtil.repeat(LOREM_IPSUM + ' ', 15000));
     EditorTestUtil.configureSoftWraps(myEditor, EDITOR_WIDTH_PX, TEST_CHAR_WIDTH);
     
-    doTestScrollingPerformance("scrolling through long soft wrapped line", 1800);
+    doTestScrollingPerformance("scrolling through long soft wrapped line", 1600);
   }
 
   private static void doTestScrollingPerformance(String message, int expectedMs) {