All files / packages/core/src/utilities createFloat32SharedArray.ts

60% Statements 9/15
37.5% Branches 3/8
100% Functions 1/1
60% Lines 9/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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    1x 1x   1x                                                     16x         16x           16x   16x 16x 16x                          
import { getShouldUseSharedArrayBuffer } from '../init';
 
const SMALL_MEMORY_LIMIT = 2 * 1024 * 1024 * 1024 - 2;
const BIG_MEMORY_LIMIT = SMALL_MEMORY_LIMIT * 2;
// Wasm page size
const PAGE_SIZE = 65536;
 
/**
 * A helper function that creates a new Float32Array that utilized a shared
 * array buffer. This allows the array to be updated  simultaneously in
 * workers or the main thread. Depending on the system (the CPU, the OS, the Browser)
 * it can take a while until the change is propagated to all contexts.
 *
 * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer|MDN: SharedArrayBuffer}
 * @remarks
 * We use SharedArrayBuffers in our ImageCache class. It's what allows us to
 * stream data to build a volume. It's important to note that SharedArrayBuffer
 * does not work out of the box for all web browsers. In some, it is disabled
 * behind a flag; in others, it has been removed entirely.
 *
 * @example
 * Creating an array for a Volume with known dimensions:
 * ```
 * const dimensions = [512, 512, 25];
 * const scalarData = createFloat32SharedArray(dimensions[0] * dimensions[1] * dimensions[2]);
 * ```
 *
 * @param length - frame size * number of frames
 * @returns a Float32Array with an underlying SharedArrayBuffer
 * @public
 */
function createFloat32SharedArray(length: number): Float32Array {
  Iif (!getShouldUseSharedArrayBuffer()) {
    throw new Error(
      'Your page is NOT cross-origin isolated, see https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated'
    );
  }
  Iif (window.SharedArrayBuffer === undefined) {
    throw new Error(
      'SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/'
    );
  }
 
  const byteLength = length * 4;
 
  if (byteLength < SMALL_MEMORY_LIMIT) {
    const sharedArrayBuffer = new SharedArrayBuffer(byteLength);
    return new Float32Array(sharedArrayBuffer);
  } else Eif (byteLength < BIG_MEMORY_LIMIT) {
    const pages = Math.ceil(byteLength / PAGE_SIZE);
    const memory = new WebAssembly.Memory({
      initial: pages,
      maximum: pages,
      shared: true,
    });
    return new Float32Array(memory.buffer, 0, length);
  }
}
 
export default createFloat32SharedArray;