diff --git a/config.js b/config.js index cc4a5f9b..78e4042d 100644 --- a/config.js +++ b/config.js @@ -3,7 +3,7 @@ export default { backend: 'webgl', // select tfjs backend to use - wasmPath: '../assets/', // path for wasm binaries + wasmPath: '../assets/', // path for wasm binaries // only used for backend: wasm async: true, // execute enabled models in parallel // this disables per-model performance data but @@ -26,7 +26,7 @@ export default { // must be disabled for images // basically this skips object box boundary detection for every n frames // while maintaining in-box detection since objects cannot move that fast - warmup: 'full', // what to use for human.warmup(), can be 'none', 'face', 'full' + warmup: 'face', // what to use for human.warmup(), can be 'none', 'face', 'full' // warmup pre-initializes all models for faster inference but can take // significant time on startup filter: { diff --git a/demo/browser.js b/demo/browser.js index 14028b0d..96ccc12e 100644 --- a/demo/browser.js +++ b/demo/browser.js @@ -4,13 +4,6 @@ import Menu from './menu.js'; import GLBench from './gl-bench.js'; const userConfig = {}; // add any user configuration overrides -/* -const userConfig = { - async: false, - face: { enabled: false }, - body: { enabled: false }, -}; -*/ const human = new Human(userConfig); @@ -441,7 +434,7 @@ function setupMenu() { menu.image.addBool('polaroid', human.config.filter, 'polaroid'); menu.process = new Menu(document.body, '', { top: `${document.getElementById('menubar').offsetHeight}px`, left: x[2] }); - menu.process.addList('backend', ['cpu', 'webgl', 'wasm'], human.config.backend, (val) => human.config.backend = val); + menu.process.addList('backend', ['cpu', 'webgl', 'wasm', 'humangl'], human.config.backend, (val) => human.config.backend = val); menu.process.addBool('async operations', human.config, 'async', (val) => human.config.async = val); menu.process.addBool('enable profiler', human.config, 'profile', (val) => human.config.profile = val); menu.process.addBool('memory shield', human.config, 'deallocate', (val) => human.config.deallocate = val); diff --git a/src/human.js b/src/human.js index 878a49ef..a90d6f16 100644 --- a/src/human.js +++ b/src/human.js @@ -1,5 +1,6 @@ import { log } from './log.js'; import * as tf from '../dist/tfjs.esm.js'; +import * as backend from './tfjs/backend.js'; import * as facemesh from './face/facemesh.js'; import * as age from './age/age.js'; import * as gender from './gender/gender.js'; @@ -176,6 +177,11 @@ class Human { if (!simd) log('warning: wasm simd support is not enabled'); } + if (this.config.backend === 'humangl') { + log('registering humangl backend'); + backend.register(); + } + await tf.setBackend(this.config.backend); tf.enableProdMode(); /* debug mode is really too mcuh diff --git a/src/tfjs/backend.js b/src/tfjs/backend.js new file mode 100644 index 00000000..106d5903 --- /dev/null +++ b/src/tfjs/backend.js @@ -0,0 +1,38 @@ +import * as tf from '../../dist/tfjs.esm.js'; + +export const config = { + name: 'humangl', + priority: 99, + canvas: null, + width: 1024, + height: 1024, + webGLattr: { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.2 + alpha: false, + antialias: false, + premultipliedAlpha: false, + preserveDrawingBuffer: false, + depth: false, + stencil: false, + failIfMajorPerformanceCaveat: false, + desynchronized: true, + }, +}; + +export function register() { + if (!tf.findBackend(config.name)) { + config.canvas = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(config.width, config.height) : document.createElement('canvas'); + const gl = config.canvas.getContext('webgl2', config.webGLattr); + tf.setWebGLContext(2, gl); + const ctx = new tf.GPGPUContext(gl); + tf.registerBackend(config.name, () => new tf.MathBackendWebGL(ctx), config.priority); + const kernels = tf.getKernelsForBackend('webgl'); + kernels.forEach((kernelConfig) => { + const newKernelConfig = { ...kernelConfig, backendName: config.name }; + tf.registerKernel(newKernelConfig); + }); + tf.ENV.set('WEBGL_VERSION', 2); + tf.ENV.set('WEBGL_MAX_TEXTURE_SIZE', gl.getParameter(gl.MAX_TEXTURE_SIZE)); + tf.ENV.set('WEBGL_FORCE_F16_TEXTURES', true); + tf.ENV.set('WEBGL_PACK_DEPTHWISECONV', true); + } +} diff --git a/src/tfjs/tf-browser.js b/src/tfjs/tf-browser.js index b3672ce3..668337cb 100644 --- a/src/tfjs/tf-browser.js +++ b/src/tfjs/tf-browser.js @@ -3,13 +3,12 @@ // simplified // { modules: 1061, moduleBytes: 3772720, outputBytes: 1531035 } -export * from '@tensorflow/tfjs/dist/index.js'; -export * from '@tensorflow/tfjs-backend-wasm'; +// export * from '@tensorflow/tfjs/dist/index.js'; +// export * from '@tensorflow/tfjs-backend-wasm'; // modular // { modules: 1064, moduleBytes: 3793219, outputBytes: 1535600 } -/* // get versions of all packages. import { version as tfjs } from '@tensorflow/tfjs/package.json'; import { version as versionCore } from '@tensorflow/tfjs-core/package.json'; @@ -41,4 +40,3 @@ export const version = { 'tfjs-backend-webgl': version_webgl, 'tfjs-backend-wasm': version_wasm, }; -*/