Skip to content

Commit

Permalink
Merge pull request #13127 from sebavan/FirefoxWebRTCLeak
Browse files Browse the repository at this point in the history
Workaround Firefox Leak
  • Loading branch information
sebavan committed Oct 19, 2022
2 parents afbe783 + 3a3eda1 commit f05ce74
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 6 deletions.
10 changes: 7 additions & 3 deletions packages/dev/core/src/Engines/Extensions/engine.videoTexture.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ThinEngine } from "../../Engines/thinEngine";
import type { InternalTexture } from "../../Materials/Textures/internalTexture";
import type { Nullable } from "../../types";
import { Constants } from "../constants";

declare module "../../Engines/thinEngine" {
export interface ThinEngine {
Expand All @@ -19,6 +20,9 @@ ThinEngine.prototype.updateVideoTexture = function (texture: Nullable<InternalTe
return;
}

const glformat = this._getInternalFormat(texture.format);
const internalFormat = this._getRGBABufferInternalSizedFormat(Constants.TEXTURETYPE_UNSIGNED_BYTE, texture.format);

const wasPreviouslyBound = this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);
this._unpackFlipY(!invertY); // Video are upside down by default

Expand All @@ -28,7 +32,7 @@ ThinEngine.prototype.updateVideoTexture = function (texture: Nullable<InternalTe
// clear old errors just in case.
this._gl.getError();

this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, video);
this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalFormat, glformat, this._gl.UNSIGNED_BYTE, video);

if (this._gl.getError() !== 0) {
this._videoTextureSupported = false;
Expand All @@ -55,9 +59,9 @@ ThinEngine.prototype.updateVideoTexture = function (texture: Nullable<InternalTe
texture._workingContext!.clearRect(0, 0, texture.width, texture.height);
texture._workingContext!.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, texture.width, texture.height);

this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, texture._workingCanvas as TexImageSource);
this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalFormat, glformat, this._gl.UNSIGNED_BYTE, texture._workingCanvas as TexImageSource);
} else {
this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, video);
this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalFormat, glformat, this._gl.UNSIGNED_BYTE, video);
}

if (texture.generateMipMaps) {
Expand Down
10 changes: 9 additions & 1 deletion packages/dev/core/src/Materials/Textures/htmlElementTexture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export interface IHtmlElementTextureOptions {
* Defines the sampling mode of the texture.
*/
samplingMode?: number;
/**
* Defines the associated texture format.
*/
format?: number;
/**
* Defines the engine instance to use the texture with. It is not mandatory if you define a scene.
*/
Expand Down Expand Up @@ -55,10 +59,12 @@ export class HtmlElementTexture extends BaseTexture {
private static readonly _DefaultOptions: IHtmlElementTextureOptions = {
generateMipMaps: false,
samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,
format: Constants.TEXTUREFORMAT_RGBA,
engine: null,
scene: null,
};

private readonly _format: number;
private _textureMatrix: Matrix;
private _isVideo: boolean;
private _generateMipMaps: boolean;
Expand Down Expand Up @@ -86,6 +92,7 @@ export class HtmlElementTexture extends BaseTexture {
this._generateMipMaps = options.generateMipMaps!;
this._samplingMode = options.samplingMode!;
this._textureMatrix = Matrix.Identity();
this._format = options.format!;

this.name = name;
this.element = element;
Expand All @@ -110,6 +117,7 @@ export class HtmlElementTexture extends BaseTexture {
const engine = this._getEngine();
if (engine) {
this._texture = engine.createDynamicTexture(width, height, this._generateMipMaps, this._samplingMode);
this._texture.format = this._format;
}

this.update();
Expand Down Expand Up @@ -142,7 +150,7 @@ export class HtmlElementTexture extends BaseTexture {
engine.updateVideoTexture(this._texture, videoElement, invertY === null ? true : invertY);
} else {
const canvasElement = this.element as HTMLCanvasElement;
engine.updateDynamicTexture(this._texture, canvasElement, invertY === null ? true : invertY, false);
engine.updateDynamicTexture(this._texture, canvasElement, invertY === null ? true : invertY, false, this._format);
}

if (!wasReady && this.isReady()) {
Expand Down
15 changes: 13 additions & 2 deletions packages/dev/core/src/Materials/Textures/videoTexture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Logger } from "../../Misc/logger";
import type { Nullable } from "../../types";
import type { Scene } from "../../scene";
import { Texture } from "../../Materials/Textures/texture";
import { Constants } from "../../Engines/constants";

import "../../Engines/Extensions/engine.videoTexture";
import "../../Engines/Extensions/engine.dynamicTexture";
Expand Down Expand Up @@ -52,6 +53,11 @@ export interface VideoTextureSettings {
* Image src displayed during the video loading or until the user interacts with the video.
*/
poster?: string;

/**
* Defines the associated texture format.
*/
format?: number;
}

/**
Expand Down Expand Up @@ -137,6 +143,7 @@ export class VideoTexture extends Texture {
* @param samplingMode controls the sampling method and is set to TRILINEAR_SAMPLINGMODE by default
* @param settings allows finer control over video usage
* @param onError defines a callback triggered when an error occurred during the loading session
* @param format defines the texture format to use (Engine.TEXTUREFORMAT_RGBA by default)
*/
constructor(
name: Nullable<string>,
Expand All @@ -146,7 +153,8 @@ export class VideoTexture extends Texture {
invertY = false,
samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE,
settings: Partial<VideoTextureSettings> = {},
onError?: Nullable<(message?: string, exception?: any) => void>
onError?: Nullable<(message?: string, exception?: any) => void>,
format: number = Constants.TEXTUREFORMAT_RGBA
) {
super(null, scene, !generateMipMaps, invertY);

Expand Down Expand Up @@ -191,6 +199,8 @@ export class VideoTexture extends Texture {
this._handlePlay();
}

this._format = format;

const videoHasEnoughData = this.video.readyState >= this.video.HAVE_CURRENT_DATA;
if (this._settings.poster && (!this._settings.autoPlay || !videoHasEnoughData)) {
this._texture = this._getEngine()!.createTexture(this._settings.poster!, false, !this.invertY, scene);
Expand Down Expand Up @@ -268,6 +278,7 @@ export class VideoTexture extends Texture {
}

this._texture = this._getEngine()!.createDynamicTexture(this.video.videoWidth, this.video.videoHeight, this._generateMipMaps, this.samplingMode);
this._texture.format = this._format ?? Constants.TEXTUREFORMAT_RGBA;

if (!this.video.autoplay && !this._settings.poster) {
const oldHandler = this.video.onplaying;
Expand Down Expand Up @@ -438,7 +449,7 @@ export class VideoTexture extends Texture {

return new Promise<VideoTexture>((resolve) => {
const onPlaying = () => {
const videoTexture = new VideoTexture("video", video, scene, true, invertY);
const videoTexture = new VideoTexture("video", video, scene, true, invertY, undefined, undefined, undefined, Constants.TEXTUREFORMAT_RGB);
if (scene.getEngine()._badOS) {
videoTexture.onDisposeObservable.addOnce(() => {
video.remove();
Expand Down

0 comments on commit f05ce74

Please sign in to comment.