2019/lib/webgl/webglManager.js (67 lines of code) (raw):
/**
* @license
* Copyright 2018 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
var WebglHandler = function(video, canvas) {
this.video = video;
this.canvas = canvas;
this.videoPerfMetrics = new VideoPerformanceMetrics(video);
this.gl = this.canvas.getContext('webgl');
this.texture = this.gl.createTexture();
this.gl.activeTexture(this.gl.TEXTURE0);
this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER,
this.gl.LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER,
this.gl.LINEAR);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S,
this.gl.CLAMP_TO_EDGE);
this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T,
this.gl.CLAMP_TO_EDGE);
this.decodeStarted = false;
this.totalWebglFrameCount = 0;
this.totalTextureUploadTime = 0;
this.previousTime = 0;
this.totalFrameDelay = 0;
};
/**
* Default method for animating a texture using a video for input.
*/
WebglHandler.prototype.onAnimate = function() {
// Keep looping until we are in a readyState.
// End animation loop when readyState = 0 after decoding has started.
if (this.video.readyState == 0) {
if (!this.decodeStarted) {
requestAnimationFrame(this.onAnimate.bind(this));
}
return;
}
if (!this.decodeStarted) {
this.decodeStarted = true;
}
var time1 = new Date();
this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA,
this.gl.UNSIGNED_BYTE, this.video);
var time2 = new Date();
this.totalTextureUploadTime += time2 - time1;
this.totalWebglFrameCount++;
if (this.previousTime) {
this.totalFrameDelay += time1 - this.previousTime;
}
this.previousTime = time1;
requestAnimationFrame(this.onAnimate.bind(this));
};
/**
* Plays video and animates frame on a texture.
*/
WebglHandler.prototype.play = function() {
this.video.play();
requestAnimationFrame(this.onAnimate.bind(this));
};
/**
* Returns frame rate for rendering video.
*/
WebglHandler.prototype.getVideoFrameRate = function() {
if (this.totalFrameDelay == 0) {
return -1;
}
return 1000 * this.videoPerfMetrics.getTotalDecodedVideoFrames() /
this.totalFrameDelay;
};
/**
* Returns frame rate for rendering video in a WebGL texture.
*/
WebglHandler.prototype.getWebglFrameRate = function() {
if (this.totalFrameDelay == 0) {
return -1;
}
return 1000 * (this.totalWebglFrameCount - 1) / this.totalFrameDelay;
};
/**
* Returns average time to render a frame in a WebGL texture.
*/
WebglHandler.prototype.getAverageUploadTime = function() {
return this.totalTextureUploadTime / this.totalWebglFrameCount;
};