import { IndexDatatype } from "../../Source/Cesium.js"; import { Buffer } from "../../Source/Cesium.js"; import { BufferUsage } from "../../Source/Cesium.js"; import createContext from "../createContext.js"; describe( "Renderer/Buffer", function () { createBufferSpecs({}); var c = createContext({ requestWebgl2: true }); // Don't repeat WebGL 1 tests when WebGL 2 is not supported if (c.webgl2) { createBufferSpecs({ requestWebgl2: true }); } c.destroyForSpecs(); function createBufferSpecs(contextOptions) { var context; var buffer; var buffer2; var webglMessage = contextOptions.requestWebgl2 ? ": WebGL 2" : ""; beforeAll(function () { context = createContext(contextOptions); }); afterAll(function () { context.destroyForSpecs(); }); afterEach(function () { if (buffer && !buffer.isDestroyed()) { buffer = buffer.destroy(); } if (buffer2 && !buffer2.isDestroyed()) { buffer2 = buffer2.destroy(); } }); it( "throws when creating a vertex buffer with no context" + webglMessage, function () { expect(function () { buffer = Buffer.createVertexBuffer({ sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); }).toThrowDeveloperError(); } ); it( "throws when creating a vertex buffer with an invalid typed array" + webglMessage, function () { expect(function () { buffer = Buffer.createVertexBuffer({ context: context, typedArray: {}, usage: BufferUsage.STATIC_DRAW, }); }).toThrowDeveloperError(); } ); it( "throws when creating a vertex buffer with both a typed array and size in bytes" + webglMessage, function () { expect(function () { buffer = Buffer.createVertexBuffer({ context: context, typedArray: new Float32Array([0, 0, 0, 1]), sizeInBytes: 16, usage: BufferUsage.STATIC_DRAW, }); }).toThrowDeveloperError(); } ); it( "throws when creating a vertex buffer without a typed array or size in bytes" + webglMessage, function () { expect(function () { buffer = Buffer.createVertexBuffer({ context: context, usage: BufferUsage.STATIC_DRAW, }); }).toThrowDeveloperError(); } ); it( "throws when creating a vertex buffer with invalid usage" + webglMessage, function () { expect(function () { buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 16, usage: 0, }); }).toThrowDeveloperError(); } ); it( "throws when creating a vertex buffer with size of zero" + webglMessage, function () { expect(function () { buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 0, usage: BufferUsage.STATIC_DRAW, }); }).toThrowDeveloperError(); } ); it("creates vertex buffer" + webglMessage, function () { buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 16, usage: BufferUsage.STATIC_DRAW, }); expect(buffer.sizeInBytes).toEqual(16); expect(buffer.usage).toEqual(BufferUsage.STATIC_DRAW); }); it("copies array to a vertex buffer" + webglMessage, function () { var sizeInBytes = 3 * Float32Array.BYTES_PER_ELEMENT; var vertices = new ArrayBuffer(sizeInBytes); var positions = new Float32Array(vertices); positions[0] = 1.0; positions[1] = 2.0; positions[2] = 3.0; buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: sizeInBytes, usage: BufferUsage.STATIC_DRAW, }); buffer.copyFromArrayView(vertices); }); it( "can create a vertex buffer from a typed array" + webglMessage, function () { var typedArray = new Float32Array(3); typedArray[0] = 1.0; typedArray[1] = 2.0; typedArray[2] = 3.0; buffer = Buffer.createVertexBuffer({ context: context, typedArray: typedArray, usage: BufferUsage.STATIC_DRAW, }); expect(buffer.sizeInBytes).toEqual(typedArray.byteLength); expect(buffer.usage).toEqual(BufferUsage.STATIC_DRAW); } ); it( "can create a vertex buffer from a size in bytes" + webglMessage, function () { buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); expect(buffer.sizeInBytes).toEqual(4); expect(buffer.usage).toEqual(BufferUsage.STATIC_DRAW); } ); it( "throws when creating an index buffer with no context" + webglMessage, function () { expect(function () { buffer = Buffer.createIndexBuffer({ sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); }).toThrowDeveloperError(); } ); it( "throws when creating an index buffer with an invalid typed array" + webglMessage, function () { expect(function () { buffer = Buffer.createIndexBuffer({ context: context, typedArray: {}, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); }).toThrowDeveloperError(); } ); it( "throws when creating an index buffer with both a typed array and size in bytes" + webglMessage, function () { expect(function () { buffer = Buffer.createIndexBuffer({ context: context, typedArray: new Uint16Array([0, 1, 2, 0, 2, 3]), sizeInBytes: 12, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); }).toThrowDeveloperError(); } ); it( "throws when creating an index buffer without a typed array or size in bytes" + webglMessage, function () { expect(function () { buffer = Buffer.createIndexBuffer({ context: context, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); }).toThrowDeveloperError(); } ); it( "throws when creating an index buffer with invalid usage" + webglMessage, function () { expect(function () { buffer = Buffer.createIndexBuffer({ context: context, sizeInBytes: 16, usage: "invalid", indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); }).toThrowDeveloperError(); } ); it( "throws when creating an index buffer with invalid index data type" + webglMessage, function () { expect(function () { buffer = Buffer.createIndexBuffer({ context: context, sizeInBytes: 16, usage: BufferUsage.STATIC_DRAW, indexDatatype: "invalid", }); }).toThrowDeveloperError(); } ); it( "throws when creating an index buffer with size of zero" + webglMessage, function () { expect(function () { buffer = Buffer.createIndexBuffer({ context: context, sizeInBytes: 0, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); }).toThrowDeveloperError(); } ); it("creates index buffer" + webglMessage, function () { buffer = Buffer.createIndexBuffer({ context: context, sizeInBytes: 6, usage: BufferUsage.STREAM_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); expect(buffer.sizeInBytes).toEqual(6); expect(buffer.usage).toEqual(BufferUsage.STREAM_DRAW); expect(buffer.indexDatatype).toEqual(IndexDatatype.UNSIGNED_SHORT); expect(buffer.bytesPerIndex).toEqual(2); expect(buffer.numberOfIndices).toEqual(3); }); it("copies array to an index buffer" + webglMessage, function () { var sizeInBytes = 3 * Uint16Array.BYTES_PER_ELEMENT; var elements = new ArrayBuffer(sizeInBytes); var indices = new Uint16Array(elements); indices[0] = 1; indices[1] = 2; indices[2] = 3; buffer = Buffer.createIndexBuffer({ context: context, sizeInBytes: sizeInBytes, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); buffer.copyFromArrayView(elements); }); it( "can create an index buffer from a typed array" + webglMessage, function () { var typedArray = new Uint16Array(3); typedArray[0] = 1; typedArray[1] = 2; typedArray[2] = 3; buffer = Buffer.createIndexBuffer({ context: context, typedArray: typedArray, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); expect(buffer.sizeInBytes).toEqual(typedArray.byteLength); expect(buffer.usage).toEqual(BufferUsage.STATIC_DRAW); expect(buffer.indexDatatype).toEqual(IndexDatatype.UNSIGNED_SHORT); } ); it( "can create an index buffer from a size in bytes" + webglMessage, function () { buffer = Buffer.createIndexBuffer({ context: context, sizeInBytes: 6, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); expect(buffer.sizeInBytes).toEqual(6); expect(buffer.usage).toEqual(BufferUsage.STATIC_DRAW); expect(buffer.indexDatatype).toEqual(IndexDatatype.UNSIGNED_SHORT); } ); it("getBufferData throws without WebGL 2" + webglMessage, function () { if (context.webgl2) { return; } buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); var array = new Uint8Array(4); expect(function () { buffer.getBufferData(array); }).toThrowDeveloperError(); }); it("getBufferData throws without arrayView" + webglMessage, function () { if (!context.webgl2) { return; } buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); expect(function () { buffer.getBufferData(undefined); }).toThrowDeveloperError(); }); it( "getBufferData throws with invalid sourceOffset" + webglMessage, function () { if (!context.webgl2) { return; } buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); var array = new Uint8Array(4); expect(function () { buffer.getBufferData(array, -1); }).toThrowDeveloperError(); expect(function () { buffer.getBufferData(array, 5); }).toThrowDeveloperError(); } ); it( "getBufferData throws with invalid destinationOffset" + webglMessage, function () { if (!context.webgl2) { return; } buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); var array = new Uint8Array(4); expect(function () { buffer.getBufferData(array, 0, -1); }).toThrowDeveloperError(); expect(function () { buffer.getBufferData(array, 0, 5); }).toThrowDeveloperError(); } ); it( "getBufferData throws with invalid length" + webglMessage, function () { if (!context.webgl2) { return; } buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); var array = new Uint8Array(4); expect(function () { buffer.getBufferData(array, 2, 0, 4); }).toThrowDeveloperError(); expect(function () { buffer.getBufferData(array, 0, 2, 4); }).toThrowDeveloperError(); } ); it("getBufferData reads from vertex buffer" + webglMessage, function () { if (!context.webgl2) { return; } var typedArray = new Uint8Array(4); typedArray[0] = 1; typedArray[1] = 2; typedArray[2] = 3; typedArray[3] = 4; buffer = Buffer.createVertexBuffer({ context: context, typedArray: typedArray, usage: BufferUsage.STATIC_DRAW, }); var destArray = new Uint8Array(4); buffer.getBufferData(destArray); expect(destArray).toEqual(typedArray); }); it("getBufferData reads from index buffer" + webglMessage, function () { if (!context.webgl2) { return; } var typedArray = new Uint16Array(3); typedArray[0] = 1; typedArray[1] = 2; typedArray[2] = 3; buffer = Buffer.createIndexBuffer({ context: context, typedArray: typedArray, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); var destArray = new Uint16Array(3); buffer.getBufferData(destArray); expect(destArray).toEqual(typedArray); }); it("copyFromBuffer throws without WebGL 2" + webglMessage, function () { if (context.webgl2) { return; } buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); buffer2 = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); expect(function () { buffer.copyFromBuffer(buffer2, 0, 0, 4); }).toThrowDeveloperError(); }); it( "copyFromBuffer throws without readBuffer" + webglMessage, function () { if (!context.webgl2) { return; } buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); expect(function () { buffer.copyFromBuffer(undefined, 0, 0, 4); }).toThrowDeveloperError(); } ); it( "copyFromBuffer throws with invalid readOffset" + webglMessage, function () { if (!context.webgl2) { return; } buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); buffer2 = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); expect(function () { buffer.copyFromBuffer(buffer2, undefined, 0, 4); }).toThrowDeveloperError(); expect(function () { buffer.copyFromBuffer(buffer2, -1, 0, 4); }).toThrowDeveloperError(); expect(function () { buffer.copyFromBuffer(buffer2, 5, 0, 4); }).toThrowDeveloperError(); } ); it( "copyFromBuffer throws with invalid writeOffset" + webglMessage, function () { if (!context.webgl2) { return; } buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); buffer2 = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); expect(function () { buffer.copyFromBuffer(buffer2, 0, undefined, 4); }).toThrowDeveloperError(); expect(function () { buffer.copyFromBuffer(buffer2, 0, -1, 4); }).toThrowDeveloperError(); expect(function () { buffer.copyFromBuffer(buffer2, 0, 5, 4); }).toThrowDeveloperError(); } ); it( "copyFromBuffer throws with invalid sizeInBytes" + webglMessage, function () { if (!context.webgl2) { return; } buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); buffer2 = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); expect(function () { buffer.copyFromBuffer(buffer2, 0, 0, undefined); }).toThrowDeveloperError(); expect(function () { buffer.copyFromBuffer(buffer2, 0, 0, -1); }).toThrowDeveloperError(); expect(function () { buffer.copyFromBuffer(buffer2, 0, 0, 0); }).toThrowDeveloperError(); expect(function () { buffer.copyFromBuffer(buffer2, 0, 0, 5); }).toThrowDeveloperError(); } ); it( "copyFromBuffer throws with one index buffer and the other is not an index buffer" + webglMessage, function () { if (!context.webgl2) { return; } var typedArray = new Uint16Array([0, 1, 2, 3, 4]); buffer = Buffer.createIndexBuffer({ context: context, typedArray: typedArray, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); var typedArray2 = new Float32Array([5.0, 6.0, 7.0, 8.0, 9.0]); buffer2 = Buffer.createVertexBuffer({ context: context, typedArray: typedArray2, usage: BufferUsage.STATIC_DRAW, }); expect(function () { buffer2.copyFromBuffer(buffer, 0, 0, typedArray.byteLength); }).toThrowDeveloperError(); } ); it( "copyFromBuffer throws when readBuffer is the same buffer and copy range overlaps" + webglMessage, function () { if (!context.webgl2) { return; } buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 4, usage: BufferUsage.STATIC_DRAW, }); expect(function () { buffer.copyFromBuffer(buffer, 0, 1, 2); }).toThrowDeveloperError(); expect(function () { buffer.copyFromBuffer(buffer, 1, 0, 2); }).toThrowDeveloperError(); } ); it("copyFromBuffer with vertex buffers" + webglMessage, function () { if (!context.webgl2) { return; } var typedArray = new Float32Array([0.0, 1.0, 2.0, 3.0, 4.0]); buffer = Buffer.createVertexBuffer({ context: context, typedArray: typedArray, usage: BufferUsage.STATIC_DRAW, }); var typedArray2 = new Float32Array([5.0, 6.0, 7.0, 8.0, 9.0]); buffer2 = Buffer.createVertexBuffer({ context: context, typedArray: typedArray2, usage: BufferUsage.STATIC_DRAW, }); var destArray = new Float32Array(5); buffer.getBufferData(destArray); expect(destArray).toEqual(typedArray); buffer2.getBufferData(destArray); expect(destArray).toEqual(typedArray2); buffer2.copyFromBuffer(buffer, 0, 0, typedArray.byteLength); buffer2.getBufferData(destArray); expect(destArray).toEqual(typedArray); }); it("copyFromBuffer with index buffers" + webglMessage, function () { if (!context.webgl2) { return; } var typedArray = new Uint16Array([0, 1, 2, 3, 4]); buffer = Buffer.createIndexBuffer({ context: context, typedArray: typedArray, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); var typedArray2 = new Uint16Array([5, 6, 7, 8, 9]); buffer2 = Buffer.createIndexBuffer({ context: context, typedArray: typedArray2, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_SHORT, }); var destArray = new Uint16Array(5); buffer.getBufferData(destArray); expect(destArray).toEqual(typedArray); buffer2.getBufferData(destArray); expect(destArray).toEqual(typedArray2); buffer2.copyFromBuffer(buffer, 0, 0, typedArray.byteLength); buffer2.getBufferData(destArray); expect(destArray).toEqual(typedArray); }); it("destroys" + webglMessage, function () { var b = Buffer.createIndexBuffer({ context: context, sizeInBytes: 3, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_BYTE, }); expect(b.isDestroyed()).toEqual(false); b.destroy(); expect(b.isDestroyed()).toEqual(true); }); it("fails to provide an array view" + webglMessage, function () { buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 3, usage: BufferUsage.STATIC_DRAW, }); expect(function () { buffer.copyFromArrayView(); }).toThrowDeveloperError(); }); it("fails to copy a large array view" + webglMessage, function () { buffer = Buffer.createVertexBuffer({ context: context, sizeInBytes: 3, usage: BufferUsage.STATIC_DRAW, }); var elements = new ArrayBuffer(3); expect(function () { buffer.copyFromArrayView(elements, 1); }).toThrowDeveloperError(); }); it("fails to destroy" + webglMessage, function () { var b = Buffer.createIndexBuffer({ context: context, sizeInBytes: 3, usage: BufferUsage.STATIC_DRAW, indexDatatype: IndexDatatype.UNSIGNED_BYTE, }); b.destroy(); expect(function () { b.destroy(); }).toThrowDeveloperError(); }); } }, "WebGL" );