Skip to content

Commit

Permalink
tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiaoji Chen committed Nov 18, 2019
1 parent 40f38f6 commit 161e2de
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 27 deletions.
70 changes: 44 additions & 26 deletions modules/core/src/lib/attribute/attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ export default class Attribute extends DataColumn {
});

Object.assign(this.state, {
lastExternalBuffer: null,
lastVirtualBuffer: null,
lastLogicalBuffer: null,
logicalAccessor: null,
needsUpdate: true,
needsRedraw: false,
updateRanges: range.FULL,
Expand Down Expand Up @@ -201,49 +203,66 @@ export default class Attribute extends DataColumn {
// Use external buffer
// Returns true if successful
// eslint-disable-next-line max-statements
_setExternalBuffer(buffer, onUpdate) {
setVirtualBuffer(buffer) {
const {state} = this;

if (!buffer) {
state.lastExternalBuffer = null;
state.lastVirtualBuffer = null;
return false;
}

this.clearNeedsUpdate();

if (state.lastExternalBuffer === buffer) {
if (state.lastVirtualBuffer === buffer) {
return true;
}
state.lastExternalBuffer = buffer;
state.lastVirtualBuffer = buffer;
this.setNeedsRedraw();
return onUpdate();
}

setVirtualBuffer(buffer) {
return this._setExternalBuffer(buffer, () => {
this.setData(buffer);
return true;
});
this.setData(buffer);
return true;
}

setLogicalBuffer(buffer, startIndices) {
if (this.settings.noAlloc) {
const {state, settings} = this;

if (!buffer) {
state.lastLogicalBuffer = null;
state.logicalAccessor = null;
return false;
}

if (settings.noAlloc) {
// Let the layer handle this
return false;
}

return this._setExternalBuffer(buffer, () => {
const needsUpdate = this.settings.transform || startIndices !== this.startIndices;
if (state.lastLogicalBuffer === buffer) {
this.clearNeedsUpdate();
return true;
}
state.lastLogicalBuffer = buffer;
this.setNeedsRedraw();

const needsUpdate = settings.transform || startIndices !== this.startIndices;

if (needsUpdate) {
const bufferOptions = {...this.settings, ...buffer, startIndices};
this.state.accessor = getAccessorFromBuffer(buffer.value, bufferOptions);
// Fall through to auto updater
return false;
if (needsUpdate) {
if (ArrayBuffer.isView(buffer)) {
buffer = {value: buffer};
}
this.setData(buffer);
return true;
});
assert(ArrayBuffer.isView(buffer.value), `invalid ${settings.accessor}`);

state.logicalAccessor = getAccessorFromBuffer(buffer.value, {
...settings,
...buffer,
startIndices
});
// Fall through to auto updater
return false;
}

this.clearNeedsUpdate();
this.setData(buffer);
return true;
}

getVertexOffset(row) {
Expand Down Expand Up @@ -271,8 +290,7 @@ export default class Attribute extends DataColumn {

const {accessor, transform} = settings;
const accessorFunc =
(state.lastExternalBuffer && state.accessor) ||
(typeof accessor === 'function' ? accessor : props[accessor]);
state.logicalAccessor || (typeof accessor === 'function' ? accessor : props[accessor]);

assert(typeof accessorFunc === 'function', `accessor "${accessor}" is not a function`);

Expand Down
85 changes: 84 additions & 1 deletion test/modules/core/lib/attribute/attribute-manager.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ test('AttributeManager.update - 0 numInstances', t => {
t.end();
});

test('AttributeManager.update - external buffers', t => {
test('AttributeManager.update - external virtual buffers', t => {
const attributeManager = new AttributeManager(gl);

const dummyUpdate = () => t.fail('updater should not be called when external buffer is present');
Expand Down Expand Up @@ -192,6 +192,89 @@ test('AttributeManager.update - external buffers', t => {
t.end();
});

test('AttributeManager.update - external logical buffers', t => {
const attributeManager = new AttributeManager(gl);

const dummyAccessor = () =>
t.fail('accessor should not be called when external buffer is present');

attributeManager.add({
positions: {size: 2, accessor: 'getPosition'},
colors: {size: 4, type: GL.UNSIGNED_BYTE, accessor: 'getColor', defaultValue: [0, 0, 0, 255]},
types: {size: 1, accessor: 'getType', transform: x => x - 65}
});

// First update, should autoalloc and update the value array
attributeManager.update({
numInstances: 2,
data: {length: 2},
props: {
getPosition: dummyAccessor,
getColor: dummyAccessor,
getType: dummyAccessor
},
buffers: {
getPosition: new Float32Array([1, 1, 2, 2]),
getColor: {value: new Uint8ClampedArray([255, 0, 0, 0, 255, 0]), size: 3},
getType: new Uint8Array([65, 68])
}
});

let attribute = attributeManager.getAttributes()['positions'];
t.deepEqual(attribute.value, [1, 1, 2, 2], 'positions attribute has value');

attribute = attributeManager.getAttributes()['colors'];
t.deepEqual(attribute.value, [255, 0, 0, 0, 255, 0], 'colors attribute has value');
t.is(attribute.getAccessor().size, 3, 'colors attribute has correct size');

attribute = attributeManager.getAttributes()['types'];
t.deepEqual(attribute.value.slice(0, 2), [0, 3], 'types attribute has value');

t.end();
});

test('AttributeManager.update - external logical buffers - variable width', t => {
const attributeManager = new AttributeManager(gl);

const dummyAccessor = () =>
t.fail('accessor should not be called when external buffer is present');

attributeManager.add({
positions: {size: 2, accessor: 'getPosition'},
colors: {size: 4, type: GL.UNSIGNED_BYTE, accessor: 'getColor', defaultValue: [0, 0, 0, 255]}
});

// First update, should autoalloc and update the value array
attributeManager.update({
numInstances: 3,
startIndices: [0, 2],
data: {
length: 2,
vertexStarts: [0, 1]
},
props: {
getPosition: dummyAccessor,
getColor: dummyAccessor
},
buffers: {
getPosition: new Float32Array([1, 1, 2, 2]),
getColor: {value: new Uint8ClampedArray([255, 0, 0, 0, 255, 0]), size: 3}
}
});

let attribute = attributeManager.getAttributes()['positions'];
t.deepEqual(attribute.value.slice(0, 6), [1, 1, 1, 1, 2, 2], 'positions attribute has value');

attribute = attributeManager.getAttributes()['colors'];
t.deepEqual(
attribute.value.slice(0, 12),
[255, 0, 0, 255, 255, 0, 0, 255, 0, 255, 0, 255],
'colors attribute has value'
);

t.end();
});

test('AttributeManager.invalidate', t => {
const attributeManager = new AttributeManager(gl);
attributeManager.add({positions: {size: 2, update}});
Expand Down

0 comments on commit 161e2de

Please sign in to comment.