Batch polygon fill and stroke instructions

This commit is contained in:
Andreas Hocevar
2016-03-30 22:10:58 +02:00
parent cf9e24feb1
commit 18f3d7243d

View File

@@ -1196,7 +1196,9 @@ ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution) {
* lineDash: Array.<number>,
* lineJoin: (string|undefined),
* lineWidth: (number|undefined),
* miterLimit: (number|undefined)}|null}
* miterLimit: (number|undefined),
* pendingFill: number,
* pendingStroke: number}|null}
*/
this.state_ = {
currentFillStyle: undefined,
@@ -1212,7 +1214,9 @@ ol.render.canvas.PolygonReplay = function(tolerance, maxExtent, resolution) {
lineDash: null,
lineJoin: undefined,
lineWidth: undefined,
miterLimit: undefined
miterLimit: undefined,
pendingFill: 0,
pendingStroke: 0
};
};
@@ -1229,8 +1233,13 @@ goog.inherits(ol.render.canvas.PolygonReplay, ol.render.canvas.Replay);
*/
ol.render.canvas.PolygonReplay.prototype.drawFlatCoordinatess_ = function(flatCoordinates, offset, ends, stride) {
var state = this.state_;
if (state.pendingFill > 200 || state.pendingStroke > 200) {
this.fillStroke_();
}
var beginPathInstruction = [ol.render.canvas.Instruction.BEGIN_PATH];
this.instructions.push(beginPathInstruction);
if (!state.pendingFill && !state.pendingStroke) {
this.instructions.push(beginPathInstruction);
}
this.hitDetectionInstructions.push(beginPathInstruction);
var i, ii;
for (i = 0, ii = ends.length; i < ii; ++i) {
@@ -1246,19 +1255,15 @@ ol.render.canvas.PolygonReplay.prototype.drawFlatCoordinatess_ = function(flatCo
closePathInstruction);
offset = end;
}
// FIXME is it quicker to fill and stroke each polygon individually,
// FIXME or all polygons together?
var fillInstruction = [ol.render.canvas.Instruction.FILL];
this.hitDetectionInstructions.push(fillInstruction);
this.hitDetectionInstructions.push([ol.render.canvas.Instruction.FILL]);
if (state.fillStyle !== undefined) {
this.instructions.push(fillInstruction);
state.pendingFill++;
}
if (state.strokeStyle !== undefined) {
goog.asserts.assert(state.lineWidth !== undefined,
'state.lineWidth should be defined');
var strokeInstruction = [ol.render.canvas.Instruction.STROKE];
this.instructions.push(strokeInstruction);
this.hitDetectionInstructions.push(strokeInstruction);
state.pendingStroke++;
this.hitDetectionInstructions.push([ol.render.canvas.Instruction.STROKE]);
}
return offset;
};
@@ -1298,19 +1303,20 @@ ol.render.canvas.PolygonReplay.prototype.drawCircle = function(circleGeometry, f
flatCoordinates, 0, flatCoordinates.length, stride, false);
var beginPathInstruction = [ol.render.canvas.Instruction.BEGIN_PATH];
var circleInstruction = [ol.render.canvas.Instruction.CIRCLE, myBegin];
this.instructions.push(beginPathInstruction, circleInstruction);
this.hitDetectionInstructions.push(beginPathInstruction, circleInstruction);
var fillInstruction = [ol.render.canvas.Instruction.FILL];
this.hitDetectionInstructions.push(fillInstruction);
if (!state.pendingFill && !state.pendingStroke) {
this.instructions.push(beginPathInstruction);
}
this.instructions.push(circleInstruction);
this.hitDetectionInstructions.push(circleInstruction, beginPathInstruction);
this.hitDetectionInstructions.push([ol.render.canvas.Instruction.FILL]);
if (state.fillStyle !== undefined) {
this.instructions.push(fillInstruction);
state.pendingFill++;
}
if (state.strokeStyle !== undefined) {
goog.asserts.assert(state.lineWidth !== undefined,
'state.lineWidth should be defined');
var strokeInstruction = [ol.render.canvas.Instruction.STROKE];
this.instructions.push(strokeInstruction);
this.hitDetectionInstructions.push(strokeInstruction);
state.pendingStroke++;
this.hitDetectionInstructions.push([ol.render.canvas.Instruction.STROKE]);
}
this.endGeometry(circleGeometry, feature);
};
@@ -1391,13 +1397,28 @@ ol.render.canvas.PolygonReplay.prototype.drawMultiPolygon = function(multiPolygo
};
/**
* @private
*/
ol.render.canvas.PolygonReplay.prototype.fillStroke_ = function() {
var state = this.state_;
if (state.pendingFill) {
this.instructions.push([ol.render.canvas.Instruction.FILL]);
state.pendingFill = 0;
}
if (state.pendingStroke) {
this.instructions.push([ol.render.canvas.Instruction.STROKE]);
state.pendingStroke = 0;
}
};
/**
* @inheritDoc
*/
ol.render.canvas.PolygonReplay.prototype.finish = function() {
goog.asserts.assert(this.state_, 'this.state_ should not be null');
this.reverseHitDetectionInstructions_();
this.state_ = null;
// We want to preserve topology when drawing polygons. Polygons are
// simplified using quantization and point elimination. However, we might
// have received a mix of quantized and non-quantized geometries, so ensure
@@ -1410,6 +1431,8 @@ ol.render.canvas.PolygonReplay.prototype.finish = function() {
coordinates[i] = ol.geom.flat.simplify.snap(coordinates[i], tolerance);
}
}
this.fillStroke_();
this.state_ = null;
};
@@ -1492,6 +1515,7 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function() {
var lineWidth = state.lineWidth;
var miterLimit = state.miterLimit;
if (fillStyle !== undefined && state.currentFillStyle != fillStyle) {
this.fillStroke_();
this.instructions.push(
[ol.render.canvas.Instruction.SET_FILL_STYLE, fillStyle]);
state.currentFillStyle = state.fillStyle;
@@ -1509,6 +1533,7 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function() {
state.currentLineJoin != lineJoin ||
state.currentLineWidth != lineWidth ||
state.currentMiterLimit != miterLimit) {
this.fillStroke_();
this.instructions.push(
[ol.render.canvas.Instruction.SET_STROKE_STYLE,
strokeStyle, lineWidth, lineCap, lineJoin, miterLimit, lineDash]);