Precalculate more instructions

This commit is contained in:
Tom Payne
2013-11-07 16:43:23 +01:00
parent 8e68134624
commit 1adfa15830
+107 -31
View File
@@ -17,11 +17,24 @@ goog.require('ol.style.stroke');
* @enum {number} * @enum {number}
*/ */
ol.replay.canvas.InstructionType = { ol.replay.canvas.InstructionType = {
DRAW_LINE_STRING_GEOMETRY: 0, BEGIN_PATH: 0,
SET_STROKE_STYLE: 1 CLOSE_PATH: 1,
DRAW_LINE_STRING_GEOMETRY: 2,
FILL: 3,
SET_STROKE_STYLE: 4,
STROKE: 5
}; };
/**
* @typedef {{beginPath: boolean,
* fillPending: boolean,
* strokePending: boolean,
* strokeStyle: ?ol.style.Stroke}}
*/
ol.replay.canvas.State;
/** /**
* @typedef {{argument: ?, * @typedef {{argument: ?,
* type: ol.replay.canvas.InstructionType}} * type: ol.replay.canvas.InstructionType}}
@@ -56,66 +69,74 @@ ol.replay.canvas.Batch = function() {
/** /**
* @private * @private
* @type {?ol.style.Stroke} * @type {?ol.replay.canvas.State}
*/ */
this.currentStrokeStyle_ = null; this.state_ = {
beginPath: true,
fillPending: false,
strokePending: false,
strokeStyle: null
};
}; };
/**
* @private
*/
ol.replay.canvas.Batch.prototype.beginPath_ = function() {
goog.asserts.assert(!goog.isNull(this.state_));
if (this.state_.beginPath) {
this.instructions_.push({
type: ol.replay.canvas.InstructionType.BEGIN_PATH
});
this.state_.beginPath = false;
}
};
/** /**
* @param {CanvasRenderingContext2D} context Context. * @param {CanvasRenderingContext2D} context Context.
* @param {goog.vec.Mat4.AnyType} transform Transform. * @param {goog.vec.Mat4.AnyType} transform Transform.
*/ */
ol.replay.canvas.Batch.prototype.draw = function(context, transform) { ol.replay.canvas.Batch.prototype.draw = function(context, transform) {
goog.asserts.assert(goog.isNull(this.state_));
var pixelCoordinates = ol.replay.transformCoordinates( var pixelCoordinates = ol.replay.transformCoordinates(
this.coordinates_, transform, this.pixelCoordinates_); this.coordinates_, transform, this.pixelCoordinates_);
this.pixelCoordinates_ = pixelCoordinates; // FIXME ? this.pixelCoordinates_ = pixelCoordinates; // FIXME ?
var begunPath = false;
var fillPending = false;
var strokePending = false;
var flushPath = function() {
if (strokePending || fillPending) {
if (strokePending) {
context.stroke();
strokePending = false;
}
if (fillPending) {
context.fill();
fillPending = false;
}
context.beginPath();
begunPath = true;
}
};
var instructions = this.instructions_; var instructions = this.instructions_;
var i = 0; var i = 0;
var j, jj; var j, jj;
for (j = 0, jj = instructions.length; j < jj; ++j) { for (j = 0, jj = instructions.length; j < jj; ++j) {
var instruction = instructions[j]; var instruction = instructions[j];
if (instruction.type == if (instruction.type ==
ol.replay.canvas.InstructionType.BEGIN_PATH) {
context.beginPath();
} else if (instruction.type ==
ol.replay.canvas.InstructionType.CLOSE_PATH) {
context.closePath();
} else if (instruction.type ==
ol.replay.canvas.InstructionType.DRAW_LINE_STRING_GEOMETRY) { ol.replay.canvas.InstructionType.DRAW_LINE_STRING_GEOMETRY) {
if (!begunPath) {
context.beginPath();
begunPath = true;
}
context.moveTo(pixelCoordinates[i], pixelCoordinates[i + 1]); context.moveTo(pixelCoordinates[i], pixelCoordinates[i + 1]);
goog.asserts.assert(goog.isNumber(instruction.argument)); goog.asserts.assert(goog.isNumber(instruction.argument));
var ii = /** @type {number} */ (instruction.argument); var ii = /** @type {number} */ (instruction.argument);
for (i += 2; i < ii; i += 2) { for (i += 2; i < ii; i += 2) {
context.lineTo(pixelCoordinates[i], pixelCoordinates[i + 1]); context.lineTo(pixelCoordinates[i], pixelCoordinates[i + 1]);
} }
strokePending = true; } else if (instruction.type ==
ol.replay.canvas.InstructionType.FILL) {
context.fill();
} else if (instruction.type == } else if (instruction.type ==
ol.replay.canvas.InstructionType.SET_STROKE_STYLE) { ol.replay.canvas.InstructionType.SET_STROKE_STYLE) {
flushPath();
goog.asserts.assert(goog.isObject(instruction.argument)); goog.asserts.assert(goog.isObject(instruction.argument));
var strokeStyle = /** @type {ol.style.Stroke} */ (instruction.argument); var strokeStyle = /** @type {ol.style.Stroke} */ (instruction.argument);
context.strokeStyle = strokeStyle.color; context.strokeStyle = strokeStyle.color;
context.lineWidth = strokeStyle.width; context.lineWidth = strokeStyle.width;
} else if (instruction.type ==
ol.replay.canvas.InstructionType.STROKE) {
context.stroke();
} }
} }
flushPath();
goog.asserts.assert(i == pixelCoordinates.length); goog.asserts.assert(i == pixelCoordinates.length);
}; };
@@ -125,6 +146,8 @@ ol.replay.canvas.Batch.prototype.draw = function(context, transform) {
*/ */
ol.replay.canvas.Batch.prototype.drawLineStringGeometry = ol.replay.canvas.Batch.prototype.drawLineStringGeometry =
function(lineStringGeometry) { function(lineStringGeometry) {
goog.asserts.assert(!goog.isNull(this.state_));
this.beginPath_();
var coordinates = this.coordinates_; var coordinates = this.coordinates_;
var lineStringCoordinates = lineStringGeometry.getCoordinates(); var lineStringCoordinates = lineStringGeometry.getCoordinates();
var i = coordinates.length; var i = coordinates.length;
@@ -137,6 +160,41 @@ ol.replay.canvas.Batch.prototype.drawLineStringGeometry =
type: ol.replay.canvas.InstructionType.DRAW_LINE_STRING_GEOMETRY, type: ol.replay.canvas.InstructionType.DRAW_LINE_STRING_GEOMETRY,
argument: i argument: i
}); });
this.state_.strokePending = true;
};
/**
* FIXME empty description for jsdoc
*/
ol.replay.canvas.Batch.prototype.finish = function() {
goog.asserts.assert(!goog.isNull(this.state_));
this.flush_(true);
this.state_ = null;
};
/**
* @param {boolean} finish Finish.
* @private
*/
ol.replay.canvas.Batch.prototype.flush_ = function(finish) {
goog.asserts.assert(!goog.isNull(this.state_));
if (this.state_.fillPending || this.state_.strokePending) {
if (this.state_.fillPending) {
this.instructions_.push({
type: ol.replay.canvas.InstructionType.FILL
});
this.state_.fillPending = false;
}
if (this.state_.strokePending) {
this.instructions_.push({
type: ol.replay.canvas.InstructionType.STROKE
});
this.state_.strokePending = false;
}
this.state_.beginPath = true;
}
}; };
@@ -144,13 +202,16 @@ ol.replay.canvas.Batch.prototype.drawLineStringGeometry =
* @inheritDoc * @inheritDoc
*/ */
ol.replay.canvas.Batch.prototype.setStrokeStyle = function(strokeStyle) { ol.replay.canvas.Batch.prototype.setStrokeStyle = function(strokeStyle) {
if (goog.isNull(this.currentStrokeStyle_) || goog.asserts.assert(!goog.isNull(this.state_));
!ol.style.stroke.equals(this.currentStrokeStyle_, strokeStyle)) { // FIXME should only change styles before draws
if (goog.isNull(this.state_.strokeStyle) ||
!ol.style.stroke.equals(this.state_.strokeStyle, strokeStyle)) {
this.flush_(false);
this.instructions_.push({ this.instructions_.push({
type: ol.replay.canvas.InstructionType.SET_STROKE_STYLE, type: ol.replay.canvas.InstructionType.SET_STROKE_STYLE,
argument: strokeStyle argument: strokeStyle
}); });
this.currentStrokeStyle_ = strokeStyle; this.state_.strokeStyle = strokeStyle;
} }
}; };
@@ -193,6 +254,21 @@ ol.replay.canvas.BatchGroup.prototype.draw = function(context, transform) {
}; };
/**
* @inheritDoc
*/
ol.replay.canvas.BatchGroup.prototype.finish = function() {
var zKey;
for (zKey in this.batchesByZIndex_) {
var batches = this.batchesByZIndex_[zKey];
var batchKey;
for (batchKey in batches) {
batches[batchKey].finish();
}
}
};
/** /**
* @inheritDoc * @inheritDoc
*/ */