You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +00:00
[Web] Fix Webkit leak caused by the position reporting audio worklets
Co-authored-by: PizzaLovers007 <trex@parkvue.com>
This commit is contained in:
@@ -28,40 +28,31 @@
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
const POST_THRESHOLD_S = 0.1;
|
||||
|
||||
class GodotPositionReportingProcessor extends AudioWorkletProcessor {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.lastPostTime = currentTime;
|
||||
this.position = 0;
|
||||
this.ended = false;
|
||||
|
||||
this.port.onmessage = (event) => {
|
||||
if (event?.data?.type === 'ended') {
|
||||
this.ended = true;
|
||||
switch (event?.data?.type) {
|
||||
case 'reset':
|
||||
this.position = 0;
|
||||
break;
|
||||
default:
|
||||
// Do nothing.
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
process(inputs, _outputs, _parameters) {
|
||||
if (this.ended) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (inputs.length > 0) {
|
||||
const input = inputs[0];
|
||||
if (input.length > 0) {
|
||||
this.position += input[0].length;
|
||||
this.port.postMessage({ type: 'position', data: this.position });
|
||||
}
|
||||
}
|
||||
|
||||
// Posting messages is expensive. Let's limit the number of posts.
|
||||
if (currentTime - this.lastPostTime > POST_THRESHOLD_S) {
|
||||
this.lastPostTime = currentTime;
|
||||
this.port.postMessage({ type: 'position', data: this.position });
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,10 +635,14 @@ class SampleNode {
|
||||
if (this._positionWorklet != null) {
|
||||
return this._positionWorklet;
|
||||
}
|
||||
this._positionWorklet = new AudioWorkletNode(
|
||||
GodotAudio.ctx,
|
||||
'godot-position-reporting-processor'
|
||||
);
|
||||
if (GodotAudio.audioPositionWorkletNodes.length > 0) {
|
||||
this._positionWorklet = GodotAudio.audioPositionWorkletNodes.pop();
|
||||
} else {
|
||||
this._positionWorklet = new AudioWorkletNode(
|
||||
GodotAudio.ctx,
|
||||
'godot-position-reporting-processor'
|
||||
);
|
||||
}
|
||||
this._positionWorklet.port.onmessage = (event) => {
|
||||
switch (event.data['type']) {
|
||||
case 'position':
|
||||
@@ -648,6 +652,7 @@ class SampleNode {
|
||||
// Do nothing.
|
||||
}
|
||||
};
|
||||
this._positionWorklet.port.postMessage('reset');
|
||||
return this._positionWorklet;
|
||||
}
|
||||
|
||||
@@ -678,7 +683,7 @@ class SampleNode {
|
||||
if (this._positionWorklet) {
|
||||
this._positionWorklet.disconnect();
|
||||
this._positionWorklet.port.onmessage = null;
|
||||
this._positionWorklet.port.postMessage({ type: 'ended' });
|
||||
GodotAudio.audioPositionWorkletNodes.push(this._positionWorklet);
|
||||
this._positionWorklet = null;
|
||||
}
|
||||
|
||||
@@ -1198,6 +1203,8 @@ const _GodotAudio = {
|
||||
|
||||
/** @type {Promise} */
|
||||
audioPositionWorkletPromise: null,
|
||||
/** @type {Array<AudioWorkletNode>} */
|
||||
audioPositionWorkletNodes: null,
|
||||
|
||||
/**
|
||||
* Converts linear volume to Db.
|
||||
@@ -1224,6 +1231,7 @@ const _GodotAudio = {
|
||||
GodotAudio.sampleNodes = new Map();
|
||||
GodotAudio.buses = [];
|
||||
GodotAudio.busSolo = null;
|
||||
GodotAudio.audioPositionWorkletNodes = [];
|
||||
|
||||
const opts = {};
|
||||
// If mix_rate is 0, let the browser choose.
|
||||
|
||||
Reference in New Issue
Block a user