Project

General

Profile

performance_issue_2.txt

Sergey Ivanovskiy, 02/13/2016 05:05 PM

Download (5.31 KB)

 
1
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js'
2
--- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js	2016-01-29 15:50:34 +0000
3
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js	2016-02-13 21:50:19 +0000
4
@@ -23,6 +23,7 @@
5
 **     SBI 20160111 Rewrite the copy of the target image taking into account the Chrome's
6
 **                  getImageData implementation.
7
 **     CA  20160129 Removed the "ctx" parameter from the CanvasRenderer APIs.
8
+**     SBI 20160213 Reduced putImageData invocations for horizontal and vertical lines.
9
 */
10
 
11
 "use strict";
12
@@ -88,6 +89,9 @@
13
    /** True value indicates XOR composite operation will be applied. */
14
    this.compositeModeOn = false;
15
    
16
+   /** The screen capture used by drawing primitives */
17
+   this.screenCapture = this.ctx.getImageData(0, 0, 1, 1);
18
+   
19
    // force all drawing to be inside pixel "cells" instead of "stradling" between two cells
20
    // which is the default; this eliminates much of the worst of the anti-aliasing and
21
    // positioning problems inherent in canvas operations; this will also save off the
22
@@ -502,7 +506,7 @@
23
 {
24
    // holds the line pixels to draw
25
    var path = [];
26
-
27
+   
28
    x1 = x1 + this.origin.x;
29
    x2 = x2 + this.origin.x;
30
    
31
@@ -523,6 +527,93 @@
32
    var dx = Math.abs(x2 - x1);
33
    var dy = Math.abs(y2 - y1);
34
    
35
+   var directStroke = this.strokesManager.isDirectDrawingStrokeStyle(this.strokeStyleId);
36
+   
37
+   if (dx === 0 || dy === 0)
38
+   {
39
+      var width  = dx + 1;
40
+      var height = dy + 1;
41
+      
42
+      var buffer = new ArrayBuffer(4 * width * height);
43
+      
44
+      var imageData = new Uint8ClampedArray(buffer);
45
+      
46
+      var x = x1;
47
+      var y = y1;
48
+      var curr = 0;
49
+      while(x <= x2 && y <= y2)
50
+      {
51
+         if (directStroke)
52
+         {
53
+            imageData[curr++] = color[0];
54
+            imageData[curr++] = color[1];
55
+            imageData[curr++] = color[2];
56
+            imageData[curr++] = 255;
57
+         }
58
+         path.push({x : x, y : y});
59
+         if (dy === 0)
60
+         {
61
+            x = x + 1;
62
+         }
63
+         else
64
+         {
65
+            y = y + 1;
66
+         }
67
+         
68
+      }
69
+      if (directStroke)
70
+      {
71
+         this.screenCapture = this.ctx.getImageData(x1, y1, width, height);
72
+         if (p2j.isChrome)
73
+         {
74
+            copyImage(this.screenCapture, this.screenCapture.data, imageData, width, height, 0);
75
+         }
76
+         else
77
+         {
78
+            this.screenCapture.data.set(imageData, 0);
79
+         }
80
+         this.ctx.putImageData(this.screenCapture, x1, y1);
81
+      }
82
+   }
83
+   else
84
+   {
85
+      path = drawSlopedLineSegment(this, x1, y1, x2, y2, color, directStroke);
86
+   }
87
+   
88
+   return path;
89
+};
90
+
91
+/**
92
+ * Draw a sloped line in the given color from (x1, y1) to (x2, y2) inclusive, using direct drawing.
93
+ * <p>
94
+ * This is an implementation of the well known 50+ year old Bresenham algorithm.
95
+ *
96
+ * @param    {CanvasRenderer} renderer
97
+ *           The canvas renderer.
98
+ * @param    {Number} x1
99
+ *           X coordinate of the starting pixel to be drawn.
100
+ * @param    {Number} y1
101
+ *           Y coordinate of the starting pixel to be drawn.
102
+ * @param    {Number} x2
103
+ *           X coordinate of the ending pixel to be drawn.
104
+ * @param    {Number} y2
105
+ *           Y coordinate of the ending pixel to be drawn.
106
+ * @param    {Number[]} color
107
+ *           Array of 3 integer values between 0 and 255 inclusive, representing an RGB color.
108
+ * @param    {Boolean} draw
109
+ *           True indicates that the line pixels are drawn on the canvas by the renderer.
110
+ * 
111
+ * @return   {Array} path
112
+ *           The {x:.,y:.} point per a pixel array that represents the drawing line segment.
113
+ */
114
+function drawSlopedLineSegment(renderer, x1, y1, x2, y2, color, draw)
115
+{
116
+   // holds the line pixels to draw
117
+   var path = [];
118
+   
119
+   var dx = Math.abs(x2 - x1);
120
+   var dy = Math.abs(y2 - y1);
121
+
122
    var xIncr = x1 < x2 ? 1 : -1;
123
    var yIncr = y1 < y2 ? 1 : -1;
124
    
125
@@ -533,15 +624,13 @@
126
    
127
    var x = x1;
128
    var y = y1;
129
-   
130
    var tooMany = 0;
131
-   var directStroke = this.strokesManager.isDirectDrawingStrokeStyle(this.strokeStyleId);
132
    
133
    while (true)
134
    {
135
-      if (directStroke)
136
+      if (draw)
137
       {
138
-         this.drawPixel(x, y, color);
139
+         renderer.drawPixel(x, y, color);
140
       }
141
       path.push({x : x, y : y});
142
       
143
@@ -555,7 +644,7 @@
144
       {
145
          if (tooMany > 10000)
146
          {
147
-            this.logger.logFormatted("Bresenham is out of control for x1 = %d, y1 = %d,"
148
+            renderer.logger.logFormatted("Bresenham is out of control for x1 = %d, y1 = %d,"
149
                      + " x2 = %d, y2 = %d and current x = %d, y = %d!",[x1, y1, x2, y2, x, y]);
150
             console.trace();
151
             break;
152
@@ -578,7 +667,7 @@
153
    }
154
    
155
    return path;
156
-};
157
+}
158
 
159
 /**
160
  * Draw a line in the given color from (x1, y1) to (x2, y2) inclusive, using direct drawing and
161
@@ -631,12 +720,12 @@
162
  */
163
 CanvasRenderer.prototype.strokeLineSegment = function(x1, y1, x2, y2, color)
164
 {
165
-   var path = this.drawLineSegment(x1, y1, x2, y2, color);
166
+   var segment = this.drawLineSegment(x1, y1, x2, y2, color);
167
    this.strokesManager.applyStrokeToPath(this,
168
          this.strokeStyleId,
169
          this.strokeWidth,
170
          color,
171
-         path);
172
+         segment);
173
 }
174
 
175
 /**
176