aboutsummaryrefslogtreecommitdiff
path: root/src/ui/benchmarkView.ts
blob: 487ec6347b7554aa37929c6d19d4e257ea1626a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import {ChunkAllocationMode, RaytraceContext, RaytracerOptions} from "../models/RaytraceContext";
import {RaytraceDispatcher} from "../RaytraceDispatcher";
import {Framebuffer} from "../Framebuffer";
import {getScene} from "../models/Scene";
import {Colour} from "../models/Colour";
import {Logger} from "../Logger";
import * as BenchmarkChart from "./benchmarkCharts";

let multiCoreDispatcher: RaytraceDispatcher;
let singleCoreDispatcher: RaytraceDispatcher;

let multiCoreScore = 0;
let singleCoreScore = 0;

const deviceAvailableThreadCount = navigator.hardwareConcurrency;

const logger = new Logger(document.getElementById('console-benchmark')!);

const benchmarkButton = document.getElementById('benchmark')!;
const multiCoreScoreElement = document.getElementById('multi-core-score')!;
const singleCoreScoreElement = document.getElementById('single-core-score')!;

export function registerEventListeners() {
  benchmarkButton.addEventListener('click', startBenchmark);
  logger.log(`Detected ${deviceAvailableThreadCount} available CPU threads, ready to run`);
}

export function initChart() {
  BenchmarkChart.initScoreChart(document.getElementById('benchmark-results-graph')!);
}

function startBenchmark() {
  benchmarkButton.classList.add('loading');
  multiCoreScoreElement.classList.add('loading');
  document.getElementById('single-core-score')!.classList.add('loading');

  multiCoreDispatcher = initDispatcher(
    1920,
    1080,
    getBenchmarkRenderOptions(true),
    onMultiCoreBenchmarkComplete
  )

  singleCoreDispatcher = initDispatcher(
    1920,
    1080,
    getBenchmarkRenderOptions(false),
    onSingleCoreBenchmarkComplete
  )

  logger.log("Started multi-core benchmark");
  multiCoreDispatcher.requestRender();
}

function onMultiCoreBenchmarkComplete(score: number) {
  multiCoreScore = score;
  multiCoreScoreElement.textContent = `${multiCoreScore}`;
  multiCoreScoreElement.classList.remove('loading');
  logger.log("Started single core benchmark");
  singleCoreDispatcher.requestRender();
}

function onSingleCoreBenchmarkComplete(score: number) {
  singleCoreScore = score;
  benchmarkButton.classList.remove('loading');
  singleCoreScoreElement.textContent = `${singleCoreScore}`;
  singleCoreScoreElement.classList.remove('loading');

  BenchmarkChart.addDeviceResult(multiCoreScore, singleCoreScore);
}

function initDispatcher(width: number, height: number, options: RaytracerOptions, onComplete: Function): RaytraceDispatcher {
  const fov = Math.PI / 3;
  const framebuffer = new Framebuffer(width, height);

  const {spheres, planes, lights} = getScene();

  const context = new RaytraceContext(
    height,
    width,
    fov,
    spheres,
    planes,
    lights,
    new Colour(221, 221, 221),
    options
  );

  return new RaytraceDispatcher(
    framebuffer,
    context,
    logger,
    onComplete
  );
}

function getBenchmarkRenderOptions(multiCore: boolean) {
  return {
    numThreads: multiCore ? deviceAvailableThreadCount: 1,
    shadows: true,
    diffuseLighting: true,
    specularLighting: true,
    reflections: true,
    refractions: true,
    maxRecurseDepth: 5,
    maxDrawDistance: 1000,
    directMemoryTransfer: true,
    chunkSize: 0,
    chunkAllocationMode: ChunkAllocationMode.SEQUENTIAL
  }
}