try out webgl canvas, draw fast, but copy pixels out slow

This commit is contained in:
rustdesk 2022-02-07 00:16:27 +08:00
parent 809719b8c2
commit 7e335b36f5
4 changed files with 67 additions and 12 deletions

View File

@ -5550,6 +5550,7 @@ self.addEventListener('message', (e) => {
dec = new Decoder(e.data.channels, e.data.sampleRate); dec = new Decoder(e.data.channels, e.data.sampleRate);
} else { } else {
dec.input(e.data); dec.input(e.data);
self.postMessage(dec.output().slice(0)); var out = dec.output().slice(0);
self.postMessage(out, [out.buffer]);
} }
}); });

View File

@ -48,10 +48,38 @@ export function pushEvent(name, payload) {
events.push(payload); events.push(payload);
} }
let yuvWorker; let yuvWorker = new Worker("./yuv.js");
/*
let yuvCanvas;
let gl;
let pixels;
if (YUVCanvas.WebGLFrameSink.isAvailable()) {
var canvas = document.createElement('canvas');
yuvCanvas = YUVCanvas.attach(canvas, { webGL: true });
gl = canvas.getContext("webgl");
} else {
yuvWorker = new Worker("./yuv.js");
}
*/
export function draw(frame) { export function draw(frame) {
if (yuvWorker) yuvWorker.postMessage(frame); if (yuvWorker) {
// frame's (y/u/v).bytes already detached, can not transferrable any more.
yuvWorker.postMessage(frame);
} else {
var now = new Date().getTime();
yuvCanvas.drawFrame(frame);
console.log(new Date().getTime() - now);
now = new Date().getTime();
if (!pixels) pixels = new Uint8Array(canvas.width * canvas.height * 4);
gl.readPixels(0, 0, canvas.width, canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
console.log(new Date().getTime() - now);
}
}
export function sendOffCanvas(c) {
let canvas = c.transferControlToOffscreen();
yuvWorker.postMessage({ canvas }, [canvas]);
} }
export function setConn(conn) { export function setConn(conn) {
@ -280,7 +308,7 @@ function _getByName(name, arg) {
return ''; return '';
} }
let opusWorker; let opusWorker = new Worker("./libopus.js");
let pcmPlayer; let pcmPlayer;
export function initAudio(channels, sampleRate) { export function initAudio(channels, sampleRate) {
@ -289,15 +317,15 @@ export function initAudio(channels, sampleRate) {
} }
export function playAudio(packet) { export function playAudio(packet) {
opusWorker.postMessage(packet); opusWorker.postMessage(packet, [packet.buffer]);
} }
window.init = async () => { window.init = async () => {
yuvWorker = new Worker("./yuv.js"); if (yuvWorker) {
opusWorker = new Worker("./libopus.js");
yuvWorker.onmessage = (e) => { yuvWorker.onmessage = (e) => {
currentFrame = e.data; currentFrame = e.data;
} }
}
opusWorker.onmessage = (e) => { opusWorker.onmessage = (e) => {
pcmPlayer.feed(e.data); pcmPlayer.feed(e.data);
} }

View File

@ -37,7 +37,8 @@ if (app) {
id.value = localStorage.getItem('id'); id.value = localStorage.getItem('id');
const key = document.querySelector('#key'); const key = document.querySelector('#key');
key.value = localStorage.getItem('key'); key.value = localStorage.getItem('key');
player = YUVCanvas.attach(document.getElementById('player')) player = YUVCanvas.attach(document.getElementById('player'));
// globals.sendOffCanvas(document.getElementById('player'));
}; };
window.connect = () => { window.connect = () => {
@ -51,6 +52,12 @@ if (app) {
const conn = globals.newConn(); const conn = globals.newConn();
conn.setMsgbox(msgbox); conn.setMsgbox(msgbox);
conn.setDraw((f) => { conn.setDraw((f) => {
/*
if (!(document.getElementById('player').width > 0)) {
document.getElementById('player').width = f.format.displayWidth;
document.getElementById('player').height = f.format.displayHeight;
}
*/
globals.draw(f); globals.draw(f);
player.drawFrame(f); player.drawFrame(f);
}); });

21
yuv.js
View File

@ -1,3 +1,8 @@
/*
var window = {};
importScripts('./yuv-canvas-1.2.6.js');
*/
var wasmExports; var wasmExports;
fetch('yuv.wasm').then(function (res) { return res.arrayBuffer(); }) fetch('yuv.wasm').then(function (res) { return res.arrayBuffer(); })
@ -58,13 +63,27 @@ function I420ToARGB(yb) {
} }
var currentFrame; var currentFrame;
var canvas;
var yuvCanvas;
self.addEventListener('message', (e) => { self.addEventListener('message', (e) => {
if (e.data.canvas) {
canvas = e.data.canvas;
yuvCanvas = window.YUVCanvas.attach(canvas, { webGL: true });
} else {
if (yuvCanvas) {
var now = new Date().getTime();
yuvCanvas.drawFrame(e.data);
console.log(new Date().getTime() - now);
} else {
currentFrame = e.data; currentFrame = e.data;
}
}
}); });
function run() { function run() {
if (currentFrame) { if (currentFrame) {
self.postMessage(I420ToARGB(currentFrame)); var data = I420ToARGB(currentFrame);
self.postMessage(data, [data.buffer]);
currentFrame = undefined; currentFrame = undefined;
} }
setTimeout(run, 1); setTimeout(run, 1);