|
@@ -43,6 +43,7 @@ export class UniformBuffer {
|
|
|
private _currentEffectName: string;
|
|
|
private _name: string;
|
|
|
private _currentFrameId: number;
|
|
|
+ private _updateList: Array<[number, number, string?]>;
|
|
|
|
|
|
/** @hidden */
|
|
|
public _alreadyBound = false;
|
|
@@ -181,6 +182,7 @@ export class UniformBuffer {
|
|
|
this._bufferIndex = -1;
|
|
|
this._createBufferOnWrite = false;
|
|
|
this._currentFrameId = 0;
|
|
|
+ this._updateList = [];
|
|
|
}
|
|
|
|
|
|
if (this._noUBO) {
|
|
@@ -521,13 +523,29 @@ export class UniformBuffer {
|
|
|
this._createBufferOnWrite = ThinEngine.Features.trackUbosInFrame;
|
|
|
}
|
|
|
|
|
|
- private _createNewBuffer(): boolean {
|
|
|
+ private _createNewBuffer(excludedLocation: number): boolean {
|
|
|
if (this._bufferIndex + 1 < this._buffers.length) {
|
|
|
+ const currentBufferData = this._bufferData;
|
|
|
this._bufferIndex++;
|
|
|
this._buffer = this._buffers[this._bufferIndex][0];
|
|
|
this._bufferData = this._buffers[this._bufferIndex][1];
|
|
|
this._valueCache = this._buffers[this._bufferIndex][2];
|
|
|
this._createBufferOnWrite = false;
|
|
|
+ for (let i = 0; i < this._updateList.length; ++i) {
|
|
|
+ let [location, size, name] = this._updateList[i];
|
|
|
+ if (location === excludedLocation) {
|
|
|
+ continue;
|
|
|
+ } else if (location < 0) {
|
|
|
+ this._valueCache[name!] = size;
|
|
|
+ } else {
|
|
|
+ while (size--) {
|
|
|
+ if (this._bufferData[location + size] !== currentBufferData[location + size]) {
|
|
|
+ this._bufferData[location + size] = currentBufferData[location + size];
|
|
|
+ this._needSync = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
if (this._currentEffect && this._buffer) {
|
|
|
this._currentEffect.bindUniformBuffer(this._buffer, this._currentEffectName);
|
|
|
}
|
|
@@ -547,6 +565,7 @@ export class UniformBuffer {
|
|
|
if (ThinEngine.Features.trackUbosInFrame && this._currentFrameId !== this._engine.frameId) {
|
|
|
this._currentFrameId = this._engine.frameId;
|
|
|
this._createBufferOnWrite = false;
|
|
|
+ this._updateList.length = 0;
|
|
|
if (this._buffers && this._buffers.length > 0) {
|
|
|
this._bufferIndex = 0;
|
|
|
this._buffer = this._buffers[this._bufferIndex][0];
|
|
@@ -593,7 +612,7 @@ export class UniformBuffer {
|
|
|
if ((size === 16 && !ThinEngine.Features.uniformBufferHardCheckMatrix) || this._bufferData[location + i] !== data[i]) {
|
|
|
changed = true;
|
|
|
if (this._createBufferOnWrite) {
|
|
|
- if (!this._createNewBuffer()) {
|
|
|
+ if (!this._createNewBuffer(location)) {
|
|
|
// we didn't create a new buffer but advanced to the next one: retry the update, chances are that the new buffer already has the right data for uniformName so we won't set needSync to true
|
|
|
this.updateUniform(uniformName, data, size);
|
|
|
return;
|
|
@@ -603,11 +622,15 @@ export class UniformBuffer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (changed && ThinEngine.Features.trackUbosInFrame) {
|
|
|
+ this._updateList[this._updateList.length] = [location, size];
|
|
|
+ }
|
|
|
+
|
|
|
this._needSync = this._needSync || changed;
|
|
|
} else {
|
|
|
// No cache for dynamic
|
|
|
if (this._createBufferOnWrite) {
|
|
|
- this._createNewBuffer();
|
|
|
+ this._createNewBuffer(-1);
|
|
|
}
|
|
|
for (var i = 0; i < size; i++) {
|
|
|
this._bufferData[location + i] = data[i];
|
|
@@ -644,7 +667,7 @@ export class UniformBuffer {
|
|
|
for (var i = 0; i < size; i++) {
|
|
|
if (this._bufferData[location + baseStride * 4 + countToFour] !== data[i]) {
|
|
|
changed = true;
|
|
|
- if (!this._createNewBuffer()) {
|
|
|
+ if (!this._createNewBuffer(location)) {
|
|
|
// we didn't create a new buffer but advanced to the next one: retry the update, chances are that the new buffer already has the right data for uniformName so we won't set needSync to true
|
|
|
this.updateUniformArray(uniformName, data, size);
|
|
|
return;
|
|
@@ -661,11 +684,15 @@ export class UniformBuffer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (changed && ThinEngine.Features.trackUbosInFrame) {
|
|
|
+ this._updateList[this._updateList.length] = [location, baseStride * 4];
|
|
|
+ }
|
|
|
+
|
|
|
this._needSync = this._needSync || changed;
|
|
|
} else {
|
|
|
// No cache for dynamic
|
|
|
if (this._createBufferOnWrite) {
|
|
|
- this._createNewBuffer();
|
|
|
+ this._createNewBuffer(-1);
|
|
|
}
|
|
|
for (var i = 0; i < size; i++) {
|
|
|
this._bufferData[location + i] = data[i];
|
|
@@ -685,6 +712,9 @@ export class UniformBuffer {
|
|
|
}
|
|
|
|
|
|
this._valueCache[name] = flag;
|
|
|
+ if (ThinEngine.Features.trackUbosInFrame) {
|
|
|
+ this._updateList[this._updateList.length] = [-1, flag, name];
|
|
|
+ }
|
|
|
|
|
|
return true;
|
|
|
}
|