pascal-maker's picture
Upload folder using huggingface_hub
92189dd verified
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* 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.
*/
/**
* Derived from mrdoob / http://mrdoob.com/
*/
import Logger from '@/common/logger/Logger';
import {uuidv4} from '@/common/utils/uuid';
import invariant from 'invariant';
export type Request<A, P> = {
action: A;
} & P;
export type Response<A, P> = Request<A, P>;
export type GetStatsCanvasRequest = Request<
'getStatsCanvas',
{
id: string;
width: number;
height: number;
}
>;
export type GetMemoryStatsRequest = Request<
'getMemoryStats',
{
id: string;
jsHeapSizeLimit: number;
totalJSHeapSize: number;
usedJSHeapSize: number;
}
>;
export type SetStatsCanvasResponse = Response<
'setStatsCanvas',
{
id: string;
canvas: OffscreenCanvas;
devicePixelRatio: number;
}
>;
export type MemoryStatsResponse = Response<
'memoryStats',
{
id: string;
jsHeapSizeLimit: number;
totalJSHeapSize: number;
usedJSHeapSize: number;
}
>;
export type StatsType = 'fps' | 'ms' | 'memory';
export class Stats {
private maxValue: number;
private beginTime: number;
private prevTime: number;
private frames: number;
private fpsPanel: Panel | null = null;
private msPanel: Panel | null = null;
private memPanel: Panel | null = null;
constructor(type: StatsType, label: string = '', maxValue: number = 100) {
const id = uuidv4();
this.maxValue = maxValue;
this.beginTime = (performance || Date).now();
this.prevTime = this.beginTime;
this.frames = 0;
const onMessage = (event: MessageEvent<SetStatsCanvasResponse>) => {
if (event.data.action === 'setStatsCanvas' && event.data.id === id) {
const {canvas, devicePixelRatio} = event.data;
if (type === 'fps') {
this.fpsPanel = new Panel(
canvas,
devicePixelRatio,
`FPS ${label}`.trim(),
'#0ff',
'#002',
);
} else if (type === 'ms') {
this.msPanel = new Panel(
canvas,
devicePixelRatio,
`MS ${label}`.trim(),
'#0f0',
'#020',
);
} else if (type === 'memory') {
this.memPanel = new Panel(
canvas,
devicePixelRatio,
`MB ${label}`.trim(),
'#f08',
'#201',
);
}
self.removeEventListener('message', onMessage);
}
};
self.addEventListener('message', onMessage);
self.postMessage({
action: 'getStatsCanvas',
id,
width: 80,
height: 48,
} as GetStatsCanvasRequest);
}
updateMaxValue(maxValue: number) {
this.maxValue = maxValue;
}
begin() {
this.beginTime = (performance || Date).now();
}
end() {
this.frames++;
const time = (performance || Date).now();
this.msPanel?.update(time - this.beginTime, this.maxValue);
if (time >= this.prevTime + 1000) {
this.fpsPanel?.update(
(this.frames * 1000) / (time - this.prevTime),
this.maxValue,
);
this.prevTime = time;
this.frames = 0;
const id = uuidv4();
const onMessage = (event: MessageEvent<MemoryStatsResponse>) => {
if (event.data.action === 'memoryStats' && event.data.id === id) {
const {usedJSHeapSize, jsHeapSizeLimit} = event.data;
this.memPanel?.update(
usedJSHeapSize / 1048576,
jsHeapSizeLimit / 1048576,
);
}
};
self.addEventListener('message', onMessage);
self.postMessage({
action: 'getMemoryStats',
id,
} as GetMemoryStatsRequest);
}
return time;
}
update() {
this.beginTime = this.end();
}
}
export class Panel {
private min = Infinity;
private max = 0;
private round = Math.round;
private PR: number;
private WIDTH: number;
private HEIGHT: number;
private TEXT_X: number;
private TEXT_Y: number;
private GRAPH_X: number;
private GRAPH_Y: number;
private GRAPH_WIDTH: number;
private GRAPH_HEIGHT: number;
public canvas: HTMLCanvasElement | OffscreenCanvas;
private context:
| CanvasRenderingContext2D
| OffscreenCanvasRenderingContext2D
| null = null;
private name: string;
private fg: string;
private bg: string;
constructor(
canvas: HTMLCanvasElement | OffscreenCanvas,
devicePixelRatio: number,
name: string,
fg: string,
bg: string,
) {
this.canvas = canvas;
this.name = name;
this.fg = fg;
this.bg = bg;
this.PR = this.round(devicePixelRatio || 1);
this.WIDTH = 80 * this.PR;
this.HEIGHT = 48 * this.PR;
this.TEXT_X = 3 * this.PR;
this.TEXT_Y = 2 * this.PR;
this.GRAPH_X = 3 * this.PR;
this.GRAPH_Y = 15 * this.PR;
this.GRAPH_WIDTH = 74 * this.PR;
this.GRAPH_HEIGHT = 30 * this.PR;
const context: OffscreenCanvasRenderingContext2D | RenderingContext | null =
canvas.getContext('2d');
invariant(context !== null, 'context 2d is required');
if (
!(context instanceof CanvasRenderingContext2D) &&
!(context instanceof OffscreenCanvasRenderingContext2D)
) {
Logger.warn(
'rendering stats requires CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D',
);
return;
}
context.font = 'bold ' + 9 * this.PR + 'px Helvetica,Arial,sans-serif';
context.textBaseline = 'top';
context.fillStyle = bg;
context.fillRect(0, 0, this.WIDTH, this.HEIGHT);
context.fillStyle = fg;
context.fillText(name, this.TEXT_X, this.TEXT_Y);
context.fillRect(
this.GRAPH_X,
this.GRAPH_Y,
this.GRAPH_WIDTH,
this.GRAPH_HEIGHT,
);
context.fillStyle = bg;
context.globalAlpha = 0.9;
context.fillRect(
this.GRAPH_X,
this.GRAPH_Y,
this.GRAPH_WIDTH,
this.GRAPH_HEIGHT,
);
this.context = context;
}
update(value: number, maxValue: number) {
invariant(this.context !== null, 'context 2d is required');
this.min = Math.min(this.min, value);
this.max = Math.max(this.max, value);
this.context.fillStyle = this.bg;
this.context.globalAlpha = 1;
this.context.fillRect(0, 0, this.WIDTH, this.GRAPH_Y);
this.context.fillStyle = this.fg;
this.context.fillText(
this.round(value) +
' ' +
this.name +
' (' +
this.round(this.min) +
'-' +
this.round(this.max) +
')',
this.TEXT_X,
this.TEXT_Y,
);
this.context.drawImage(
this.canvas,
this.GRAPH_X + this.PR,
this.GRAPH_Y,
this.GRAPH_WIDTH - this.PR,
this.GRAPH_HEIGHT,
this.GRAPH_X,
this.GRAPH_Y,
this.GRAPH_WIDTH - this.PR,
this.GRAPH_HEIGHT,
);
this.context.fillRect(
this.GRAPH_X + this.GRAPH_WIDTH - this.PR,
this.GRAPH_Y,
this.PR,
this.GRAPH_HEIGHT,
);
this.context.fillStyle = this.bg;
this.context.globalAlpha = 0.9;
this.context.fillRect(
this.GRAPH_X + this.GRAPH_WIDTH - this.PR,
this.GRAPH_Y,
this.PR,
this.round((1 - value / maxValue) * this.GRAPH_HEIGHT),
);
}
}