Adapt the WebGL worker to use the new buffer generation utils
This commit is contained in:
@@ -2,60 +2,174 @@
|
||||
* A worker that does cpu-heavy tasks related to webgl rendering.
|
||||
* @module ol/worker/webgl
|
||||
*/
|
||||
import {
|
||||
WebGLWorkerMessageType,
|
||||
writePointFeatureToBuffers,
|
||||
} from '../renderer/webgl/Layer.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {WebGLWorkerMessageType} from '../render/webgl/constants.js';
|
||||
import {
|
||||
writeLineSegmentToBuffers,
|
||||
writePointFeatureToBuffers,
|
||||
writePolygonTrianglesToBuffers,
|
||||
} from '../render/webgl/utils.js';
|
||||
import {
|
||||
create as createTransform,
|
||||
makeInverse as makeInverseTransform,
|
||||
} from '../transform.js';
|
||||
|
||||
/** @type {any} */
|
||||
const worker = self;
|
||||
|
||||
worker.onmessage = (event) => {
|
||||
const received = event.data;
|
||||
if (received.type === WebGLWorkerMessageType.GENERATE_BUFFERS) {
|
||||
// This is specific to point features (x, y, index)
|
||||
const baseVertexAttrsCount = 3;
|
||||
const baseInstructionsCount = 2;
|
||||
switch (received.type) {
|
||||
case WebGLWorkerMessageType.GENERATE_POINT_BUFFERS: {
|
||||
// This is specific to point features (x, y, index)
|
||||
const baseVertexAttrsCount = 3;
|
||||
const baseInstructionsCount = 2;
|
||||
|
||||
const customAttrsCount = received.customAttributesCount;
|
||||
const instructionsCount = baseInstructionsCount + customAttrsCount;
|
||||
const renderInstructions = new Float32Array(received.renderInstructions);
|
||||
const customAttrsCount = received.customAttributesCount;
|
||||
const instructionsCount = baseInstructionsCount + customAttrsCount;
|
||||
const renderInstructions = new Float32Array(received.renderInstructions);
|
||||
|
||||
const elementsCount = renderInstructions.length / instructionsCount;
|
||||
const indicesCount = elementsCount * 6;
|
||||
const verticesCount =
|
||||
elementsCount * 4 * (customAttrsCount + baseVertexAttrsCount);
|
||||
const indexBuffer = new Uint32Array(indicesCount);
|
||||
const vertexBuffer = new Float32Array(verticesCount);
|
||||
const elementsCount = renderInstructions.length / instructionsCount;
|
||||
const indicesCount = elementsCount * 6;
|
||||
const verticesCount =
|
||||
elementsCount * 4 * (customAttrsCount + baseVertexAttrsCount);
|
||||
const indexBuffer = new Uint32Array(indicesCount);
|
||||
const vertexBuffer = new Float32Array(verticesCount);
|
||||
|
||||
let bufferPositions;
|
||||
for (let i = 0; i < renderInstructions.length; i += instructionsCount) {
|
||||
bufferPositions = writePointFeatureToBuffers(
|
||||
renderInstructions,
|
||||
i,
|
||||
vertexBuffer,
|
||||
indexBuffer,
|
||||
customAttrsCount,
|
||||
bufferPositions
|
||||
let bufferPositions;
|
||||
for (let i = 0; i < renderInstructions.length; i += instructionsCount) {
|
||||
bufferPositions = writePointFeatureToBuffers(
|
||||
renderInstructions,
|
||||
i,
|
||||
vertexBuffer,
|
||||
indexBuffer,
|
||||
customAttrsCount,
|
||||
bufferPositions
|
||||
);
|
||||
}
|
||||
|
||||
/** @type {import('../render/webgl/constants.js').WebGLWorkerGenerateBuffersMessage} */
|
||||
const message = assign(
|
||||
{
|
||||
vertexBuffer: vertexBuffer.buffer,
|
||||
indexBuffer: indexBuffer.buffer,
|
||||
renderInstructions: renderInstructions.buffer,
|
||||
},
|
||||
received
|
||||
);
|
||||
|
||||
worker.postMessage(message, [
|
||||
vertexBuffer.buffer,
|
||||
indexBuffer.buffer,
|
||||
renderInstructions.buffer,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
case WebGLWorkerMessageType.GENERATE_LINE_STRING_BUFFERS: {
|
||||
const vertices = [];
|
||||
const indices = [];
|
||||
|
||||
/** @type {import('../renderer/webgl/Layer').WebGLWorkerGenerateBuffersMessage} */
|
||||
const message = assign(
|
||||
{
|
||||
vertexBuffer: vertexBuffer.buffer,
|
||||
indexBuffer: indexBuffer.buffer,
|
||||
renderInstructions: renderInstructions.buffer,
|
||||
},
|
||||
received
|
||||
);
|
||||
const customAttrsCount = received.customAttributesCount;
|
||||
const instructionsPerVertex = 2;
|
||||
|
||||
worker.postMessage(message, [
|
||||
vertexBuffer.buffer,
|
||||
indexBuffer.buffer,
|
||||
renderInstructions.buffer,
|
||||
]);
|
||||
const renderInstructions = new Float32Array(received.renderInstructions);
|
||||
let currentInstructionsIndex = 0;
|
||||
|
||||
const transform = received.renderInstructionsTransform;
|
||||
const invertTransform = createTransform();
|
||||
makeInverseTransform(invertTransform, transform);
|
||||
|
||||
let verticesCount, customAttributes;
|
||||
while (currentInstructionsIndex < renderInstructions.length) {
|
||||
customAttributes = Array.from(
|
||||
renderInstructions.slice(
|
||||
currentInstructionsIndex,
|
||||
currentInstructionsIndex + customAttrsCount
|
||||
)
|
||||
);
|
||||
currentInstructionsIndex += customAttrsCount;
|
||||
verticesCount = renderInstructions[currentInstructionsIndex++];
|
||||
|
||||
// last point is only a segment end, do not loop over it
|
||||
for (let i = 0; i < verticesCount - 1; i++) {
|
||||
writeLineSegmentToBuffers(
|
||||
renderInstructions,
|
||||
currentInstructionsIndex + i * instructionsPerVertex,
|
||||
currentInstructionsIndex + (i + 1) * instructionsPerVertex,
|
||||
i > 0
|
||||
? currentInstructionsIndex + (i - 1) * instructionsPerVertex
|
||||
: null,
|
||||
i < verticesCount - 2
|
||||
? currentInstructionsIndex + (i + 2) * instructionsPerVertex
|
||||
: null,
|
||||
vertices,
|
||||
indices,
|
||||
customAttributes,
|
||||
transform,
|
||||
invertTransform
|
||||
);
|
||||
}
|
||||
currentInstructionsIndex += verticesCount * instructionsPerVertex;
|
||||
}
|
||||
|
||||
const indexBuffer = Uint32Array.from(indices);
|
||||
const vertexBuffer = Float32Array.from(vertices);
|
||||
|
||||
/** @type {import('../render/webgl/constants.js').WebGLWorkerGenerateBuffersMessage} */
|
||||
const message = assign(
|
||||
{
|
||||
vertexBuffer: vertexBuffer.buffer,
|
||||
indexBuffer: indexBuffer.buffer,
|
||||
renderInstructions: renderInstructions.buffer,
|
||||
},
|
||||
received
|
||||
);
|
||||
|
||||
worker.postMessage(message, [
|
||||
vertexBuffer.buffer,
|
||||
indexBuffer.buffer,
|
||||
renderInstructions.buffer,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
case WebGLWorkerMessageType.GENERATE_POLYGON_BUFFERS: {
|
||||
const vertices = [];
|
||||
const indices = [];
|
||||
|
||||
const customAttrsCount = received.customAttributesCount;
|
||||
const renderInstructions = new Float32Array(received.renderInstructions);
|
||||
|
||||
let currentInstructionsIndex = 0;
|
||||
while (currentInstructionsIndex < renderInstructions.length) {
|
||||
currentInstructionsIndex = writePolygonTrianglesToBuffers(
|
||||
renderInstructions,
|
||||
currentInstructionsIndex,
|
||||
vertices,
|
||||
indices,
|
||||
customAttrsCount
|
||||
);
|
||||
}
|
||||
|
||||
const indexBuffer = Uint32Array.from(indices);
|
||||
const vertexBuffer = Float32Array.from(vertices);
|
||||
|
||||
/** @type {import('../render/webgl/constants.js').WebGLWorkerGenerateBuffersMessage} */
|
||||
const message = assign(
|
||||
{
|
||||
vertexBuffer: vertexBuffer.buffer,
|
||||
indexBuffer: indexBuffer.buffer,
|
||||
renderInstructions: renderInstructions.buffer,
|
||||
},
|
||||
received
|
||||
);
|
||||
|
||||
worker.postMessage(message, [
|
||||
vertexBuffer.buffer,
|
||||
indexBuffer.buffer,
|
||||
renderInstructions.buffer,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import {WebGLWorkerMessageType} from '../../../../../src/ol/renderer/webgl/Layer.js';
|
||||
import {WebGLWorkerMessageType} from '../../../../../src/ol/render/webgl/constants.js';
|
||||
import {create} from '../../../../../src/ol/worker/webgl.js';
|
||||
import {create as createTransform} from '../../../../../src/ol/transform.js';
|
||||
|
||||
describe('ol/worker/webgl', function () {
|
||||
let worker;
|
||||
beforeEach(function () {
|
||||
worker = create();
|
||||
worker.addEventListener('error', function (error) {
|
||||
expect().fail(error.message);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
@@ -15,35 +19,145 @@ describe('ol/worker/webgl', function () {
|
||||
});
|
||||
|
||||
describe('messaging', function () {
|
||||
describe('GENERATE_BUFFERS', function () {
|
||||
it('responds with buffer data', function (done) {
|
||||
worker.addEventListener('error', function (error) {
|
||||
expect().fail(error.message);
|
||||
});
|
||||
|
||||
worker.addEventListener('message', function (event) {
|
||||
expect(event.data.type).to.eql(
|
||||
WebGLWorkerMessageType.GENERATE_BUFFERS
|
||||
);
|
||||
expect(event.data.renderInstructions.byteLength).to.greaterThan(0);
|
||||
expect(event.data.indexBuffer.byteLength).to.greaterThan(0);
|
||||
expect(event.data.vertexBuffer.byteLength).to.greaterThan(0);
|
||||
expect(event.data.testInt).to.be(101);
|
||||
expect(event.data.testString).to.be('abcd');
|
||||
done();
|
||||
});
|
||||
|
||||
const instructions = new Float32Array(10);
|
||||
|
||||
describe('GENERATE_POINT_BUFFERS', function () {
|
||||
let responseData;
|
||||
beforeEach(function (done) {
|
||||
const renderInstructions = Float32Array.from([0, 10, 111, 20, 30, 222]);
|
||||
const id = Math.floor(Math.random() * 10000);
|
||||
const message = {
|
||||
type: WebGLWorkerMessageType.GENERATE_BUFFERS,
|
||||
renderInstructions: instructions,
|
||||
customAttributesCount: 0,
|
||||
type: WebGLWorkerMessageType.GENERATE_POINT_BUFFERS,
|
||||
renderInstructions,
|
||||
customAttributesCount: 1,
|
||||
testInt: 101,
|
||||
testString: 'abcd',
|
||||
id,
|
||||
};
|
||||
|
||||
responseData = null;
|
||||
worker.postMessage(message);
|
||||
|
||||
worker.addEventListener('message', function (event) {
|
||||
if (event.data.id === id) {
|
||||
responseData = event.data;
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
it('responds with info passed in the message', function () {
|
||||
expect(responseData.type).to.eql(
|
||||
WebGLWorkerMessageType.GENERATE_POINT_BUFFERS
|
||||
);
|
||||
expect(responseData.renderInstructions.byteLength).to.greaterThan(0);
|
||||
expect(responseData.testInt).to.be(101);
|
||||
expect(responseData.testString).to.be('abcd');
|
||||
});
|
||||
it('responds with buffer data', function () {
|
||||
const indices = Array.from(new Uint32Array(responseData.indexBuffer));
|
||||
const vertices = Array.from(
|
||||
new Float32Array(responseData.vertexBuffer)
|
||||
);
|
||||
expect(indices).to.eql([0, 1, 3, 1, 2, 3, 4, 5, 7, 5, 6, 7]);
|
||||
expect(vertices).to.eql([
|
||||
0, 10, 0, 111, 0, 10, 1, 111, 0, 10, 2, 111, 0, 10, 3, 111, 20, 30, 0,
|
||||
222, 20, 30, 1, 222, 20, 30, 2, 222, 20, 30, 3, 222,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GENERATE_LINE_STRING_BUFFERS', function () {
|
||||
let responseData;
|
||||
beforeEach(function (done) {
|
||||
const renderInstructions = Float32Array.from([
|
||||
111, 4, 20, 30, 40, 50, 6, 7, 80, 90,
|
||||
]);
|
||||
const id = Math.floor(Math.random() * 10000);
|
||||
const renderInstructionsTransform = createTransform();
|
||||
const message = {
|
||||
type: WebGLWorkerMessageType.GENERATE_LINE_STRING_BUFFERS,
|
||||
renderInstructions,
|
||||
customAttributesCount: 1,
|
||||
testInt: 101,
|
||||
testString: 'abcd',
|
||||
id,
|
||||
renderInstructionsTransform,
|
||||
};
|
||||
responseData = null;
|
||||
worker.postMessage(message);
|
||||
|
||||
worker.addEventListener('message', function (event) {
|
||||
if (event.data.id === id) {
|
||||
responseData = event.data;
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
it('responds with info passed in the message', function () {
|
||||
expect(responseData.type).to.eql(
|
||||
WebGLWorkerMessageType.GENERATE_LINE_STRING_BUFFERS
|
||||
);
|
||||
expect(responseData.renderInstructions.byteLength).to.greaterThan(0);
|
||||
expect(responseData.testInt).to.be(101);
|
||||
expect(responseData.testString).to.be('abcd');
|
||||
});
|
||||
it('responds with buffer data', function () {
|
||||
const indices = Array.from(new Uint32Array(responseData.indexBuffer));
|
||||
const vertices = Array.from(
|
||||
new Float32Array(responseData.vertexBuffer)
|
||||
);
|
||||
expect(indices).to.eql([
|
||||
0, 1, 2, 1, 3, 2, 4, 5, 6, 5, 7, 6, 8, 9, 10, 9, 11, 10,
|
||||
]);
|
||||
expect(vertices).to.eql([
|
||||
20, 30, 40, 50, 1750000, 111, 20, 30, 40, 50, 101750000, 111, 20, 30,
|
||||
40, 50, 201750000, 111, 20, 30, 40, 50, 301750016, 111, 40, 50, 6, 7,
|
||||
93369248, 111, 40, 50, 6, 7, 193369248, 111, 40, 50, 6, 7, 293369248,
|
||||
111, 40, 50, 6, 7, 393369248, 111, 6, 7, 80, 90, 89, 111, 6, 7, 80,
|
||||
90, 100000088, 111, 6, 7, 80, 90, 200000096, 111, 6, 7, 80, 90,
|
||||
300000096, 111,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GENERATE_POLYGON_BUFFERS', function () {
|
||||
let responseData;
|
||||
beforeEach(function (done) {
|
||||
const renderInstructions = Float32Array.from([
|
||||
1234, 2, 6, 5, 0, 0, 10, 0, 15, 6, 10, 12, 0, 12, 0, 0, 3, 3, 5, 1, 7,
|
||||
3, 5, 5, 3, 3,
|
||||
]);
|
||||
const id = Math.floor(Math.random() * 10000);
|
||||
const message = {
|
||||
type: WebGLWorkerMessageType.GENERATE_POLYGON_BUFFERS,
|
||||
renderInstructions,
|
||||
customAttributesCount: 1,
|
||||
testInt: 101,
|
||||
testString: 'abcd',
|
||||
id,
|
||||
};
|
||||
responseData = null;
|
||||
worker.postMessage(message);
|
||||
|
||||
worker.addEventListener('message', function (event) {
|
||||
if (event.data.id === id) {
|
||||
responseData = event.data;
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
it('responds with info passed in the message', function () {
|
||||
expect(responseData.type).to.eql(
|
||||
WebGLWorkerMessageType.GENERATE_POLYGON_BUFFERS
|
||||
);
|
||||
expect(responseData.renderInstructions.byteLength).to.greaterThan(0);
|
||||
expect(responseData.testInt).to.be(101);
|
||||
expect(responseData.testString).to.be('abcd');
|
||||
});
|
||||
it('responds with buffer data', function () {
|
||||
const indices = Array.from(new Uint32Array(responseData.indexBuffer));
|
||||
const vertices = Array.from(
|
||||
new Float32Array(responseData.vertexBuffer)
|
||||
);
|
||||
expect(indices).to.have.length(24);
|
||||
expect(vertices).to.have.length(33);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user