Skip to content

Commit ad4c0f5

Browse files
deyihufuzhenn
authored andcommitted
optimize linestring, polygon rendering performance (through the pixel alternative path) close #1266
1 parent 074f272 commit ad4c0f5

File tree

3 files changed

+83
-10
lines changed

3 files changed

+83
-10
lines changed

src/core/Canvas.js

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -609,15 +609,15 @@ const Canvas = {
609609
const u0 = 1.0 - t0;
610610
const u1 = 1.0 - t1;
611611

612-
const qxa = x1 * u0 * u0 + bx1 * 2 * t0 * u0 + bx2 * t0 * t0;
613-
const qxb = x1 * u1 * u1 + bx1 * 2 * t1 * u1 + bx2 * t1 * t1;
614-
const qxc = bx1 * u0 * u0 + bx2 * 2 * t0 * u0 + x2 * t0 * t0;
615-
const qxd = bx1 * u1 * u1 + bx2 * 2 * t1 * u1 + x2 * t1 * t1;
612+
const qxa = x1 * u0 * u0 + bx1 * 2 * t0 * u0 + bx2 * t0 * t0;
613+
const qxb = x1 * u1 * u1 + bx1 * 2 * t1 * u1 + bx2 * t1 * t1;
614+
const qxc = bx1 * u0 * u0 + bx2 * 2 * t0 * u0 + x2 * t0 * t0;
615+
const qxd = bx1 * u1 * u1 + bx2 * 2 * t1 * u1 + x2 * t1 * t1;
616616

617-
const qya = y1 * u0 * u0 + by1 * 2 * t0 * u0 + by2 * t0 * t0;
618-
const qyb = y1 * u1 * u1 + by1 * 2 * t1 * u1 + by2 * t1 * t1;
619-
const qyc = by1 * u0 * u0 + by2 * 2 * t0 * u0 + y2 * t0 * t0;
620-
const qyd = by1 * u1 * u1 + by2 * 2 * t1 * u1 + y2 * t1 * t1;
617+
const qya = y1 * u0 * u0 + by1 * 2 * t0 * u0 + by2 * t0 * t0;
618+
const qyb = y1 * u1 * u1 + by1 * 2 * t1 * u1 + by2 * t1 * t1;
619+
const qyc = by1 * u0 * u0 + by2 * 2 * t0 * u0 + y2 * t0 * t0;
620+
const qyd = by1 * u1 * u1 + by2 * 2 * t1 * u1 + y2 * t1 * t1;
621621

622622
// const xa = qxa * u0 + qxc * t0;
623623
const xb = qxa * u1 + qxc * t1;
@@ -873,6 +873,31 @@ const Canvas = {
873873
target.height = canvas.height;
874874
target.getContext('2d').drawImage(canvas, 0, 0);
875875
return target;
876+
},
877+
878+
// pixel render
879+
pixelRect(ctx, point, lineOpacity, fillOpacity) {
880+
const lineWidth = ctx.lineWidth;
881+
const alpha = ctx.globalAlpha;
882+
if (lineWidth > 0 && lineOpacity > 0) {
883+
if (ctx.fillStyle !== ctx.strokeStyle) {
884+
ctx.fillStyle = ctx.strokeStyle;
885+
}
886+
if (lineOpacity < 1) {
887+
ctx.globalAlpha *= lineOpacity;
888+
}
889+
} else if (fillOpacity > 0) {
890+
if (fillOpacity < 1) {
891+
ctx.globalAlpha *= fillOpacity;
892+
}
893+
} else {
894+
return;
895+
}
896+
ctx.canvas._drawn = true;
897+
ctx.fillRect(point[0], point[1], 1, 1);
898+
if (ctx.globalAlpha !== alpha) {
899+
ctx.globalAlpha = alpha;
900+
}
876901
}
877902
};
878903

src/renderer/geometry/Painter.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ const TEMP_FIXED_EXTENT = new PointExtent();
3030
const TEMP_CLIP_EXTENT1 = new PointExtent();
3131
// const TEMP_CONTAINER_EXTENT = new PointExtent();
3232

33+
const TEMP_BBOX = {
34+
minx: Infinity,
35+
miny: Infinity,
36+
maxx: -Infinity,
37+
maxy: -Infinity
38+
};
39+
3340
/**
3441
* @classdesc
3542
* Painter class for all geometry types except the collection types.
@@ -215,6 +222,7 @@ class Painter extends Class {
215222
}
216223
let cPoints;
217224
const roundPoint = this.getLayer().options['roundPoint'];
225+
let minx = Infinity, miny = Infinity, maxx = -Infinity, maxy = -Infinity;
218226
function pointsContainerPoints(viewPoints = [], alts = []) {
219227
const pts = map._pointsToContainerPoints(viewPoints, glZoom, alts);
220228
for (let i = 0, len = pts.length; i < len; i++) {
@@ -228,6 +236,10 @@ class Painter extends Class {
228236
p.x = Math.ceil(p.x);
229237
p.y = Math.ceil(p.y);
230238
}
239+
minx = Math.min(p.x, minx);
240+
miny = Math.min(p.y, miny);
241+
maxx = Math.max(p.x, maxx);
242+
maxy = Math.max(p.y, maxy);
231243
}
232244
return pts;
233245
}
@@ -307,6 +319,12 @@ class Painter extends Class {
307319
cPoints._add(dx, dy);
308320
}
309321
}
322+
//cache geometry bbox
323+
TEMP_BBOX.minx = minx;
324+
TEMP_BBOX.miny = miny;
325+
TEMP_BBOX.maxx = maxx;
326+
TEMP_BBOX.maxy = maxy;
327+
this.__bbox = TEMP_BBOX;
310328
return cPoints;
311329
}
312330

src/renderer/geometry/VectorRenderer.js

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,28 @@ import Path from '../../geometry/Path';
1010
import LineString from '../../geometry/LineString';
1111
import Polygon from '../../geometry/Polygon';
1212

13+
const TEMP_WITHIN = {
14+
within: false,
15+
center: [0, 0]
16+
};
17+
// bbox in pixel
18+
function isWithinPixel(painter) {
19+
if (!painter || (!painter.__bbox)) {
20+
TEMP_WITHIN.within = false;
21+
} else {
22+
TEMP_WITHIN.within = false;
23+
const { minx, miny, maxx, maxy } = painter.__bbox;
24+
const offsetx = Math.abs(maxx - minx);
25+
const offsety = Math.abs(maxy - miny);
26+
if (offsetx <= 1 && offsety <= 1) {
27+
TEMP_WITHIN.within = true;
28+
TEMP_WITHIN.center[0] = (minx + maxx) / 2;
29+
TEMP_WITHIN.center[1] = (miny + maxy) / 2;
30+
}
31+
}
32+
return TEMP_WITHIN;
33+
}
34+
1335
Geometry.include({
1436
_redrawWhenPitch: () => false,
1537

@@ -156,7 +178,10 @@ LineString.include({
156178
},
157179

158180
_paintOn(ctx, points, lineOpacity, fillOpacity, dasharray) {
159-
if (this.options['smoothness']) {
181+
const r = isWithinPixel(this._painter);
182+
if (r.within) {
183+
Canvas.pixelRect(ctx, r.center, lineOpacity, fillOpacity);
184+
} else if (this.options['smoothness']) {
160185
Canvas.paintSmoothLine(ctx, points, lineOpacity, this.options['smoothness'], false, this._animIdx, this._animTailRatio);
161186
} else {
162187
Canvas.path(ctx, points, lineOpacity, null, dasharray);
@@ -280,7 +305,12 @@ Polygon.include({
280305
},
281306

282307
_paintOn(ctx, points, lineOpacity, fillOpacity, dasharray) {
283-
Canvas.polygon(ctx, points, lineOpacity, fillOpacity, dasharray, this.options['smoothness']);
308+
const r = isWithinPixel(this._painter);
309+
if (r.within) {
310+
Canvas.pixelRect(ctx, r.center, lineOpacity, fillOpacity);
311+
} else {
312+
Canvas.polygon(ctx, points, lineOpacity, fillOpacity, dasharray, this.options['smoothness']);
313+
}
284314
}
285315
});
286316

0 commit comments

Comments
 (0)