1
0
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:
Adam Scott
2025-06-24 14:34:34 -04:00
parent 88b9932ce1
commit b58c6c829b
2 changed files with 20 additions and 21 deletions

View File

@@ -28,39 +28,30 @@
/* 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;
}
}
// 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;
}

View File

@@ -635,10 +635,14 @@ class SampleNode {
if (this._positionWorklet != null) {
return this._positionWorklet;
}
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.