From 25c80e2c5ee663afc61c2764bc702507ce3b9287 Mon Sep 17 00:00:00 2001 From: Chris Gervang Date: Thu, 13 Jun 2024 15:57:56 -0700 Subject: [PATCH 1/4] chore(core) document device props per device Signed-off-by: Chris Gervang --- docs/api-reference/core/device.md | 40 +++++++-- docs/api-reference/core/luma.md | 4 +- docs/api-reference/webgl/README.md | 8 +- docs/api-reference/webgpu/README.md | 2 +- modules/core/src/adapter/device.ts | 97 +++++++++++++-------- modules/core/src/adapter/luma.ts | 21 +++-- modules/core/src/index.ts | 9 +- modules/webgl/src/adapter/webgl-device.ts | 12 +-- modules/webgpu/src/adapter/webgpu-device.ts | 6 +- 9 files changed, 135 insertions(+), 64 deletions(-) diff --git a/docs/api-reference/core/device.md b/docs/api-reference/core/device.md index d11d53382d..9b88ddc311 100644 --- a/docs/api-reference/core/device.md +++ b/docs/api-reference/core/device.md @@ -54,18 +54,44 @@ console.error(message); | Parameter | Default | Description | | ------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------- | -| `type` | `'best-available'` | `'webgpu'`, `'webgl'`, `'best-available'` | -| `canvas` | N/A | A _string_ `id` of an existing HTML element or a _DOMElement_. If not provided, a new canvas will be created. | -| priority. | -| `debug?: boolean` | `false` | WebGL API calls will be logged to the console and WebGL errors will generate JavaScript exceptions. | -| `break?: string[]` | `[]` | Insert a break point (`debugger`) if one of the listed gl functions is called. | +| `id?: string` | `null` | | +| `canvas?: HTMLCanvasElement | OffscreenCanvas | string` | N/A | A _string_ `id` or object of an existing canvas element. If not provided, a new canvas will be created.| +| `container?: HTMLElement | string` | N/A | If new canvas is created, it will be created in the specified container, otherwise appended to body. | +| `width?: number` | `800` | Sets the canvas width. Only used when creating a new canvas internally. | +| `height?: number` | `600` | Sets the canvas height. Only used when creating a new canvas internally. | +| `onError?: (error: Error) => unknown` | `log.error` | Error handling. | +| `initalizeFeatures?: boolean` | `true` | Initialize all features on startup. | +| `disabledFeatures?: Partial>` | `{ 'compilation-status-async-webgl': true }` | Disable specific features. | +| `_factoryDestroyPolicy?: 'unused' | 'never'` | `true` | Never destroy cached shaders and pipelines. | + +### WebGLDeviceProps + +Extends `DeviceProps`. + +| WebGL Parameter | Default | Description | +| ------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------- | | `alpha?: boolean` | `true` | Default render target has an alpha buffer. | | `depth?: boolean` | `true` | Default render target has a depth buffer of at least `16` bits. | -| `stencil?` | `false` | Default render target has a stencil buffer of at least `8` bits. | +| `stencil?: boolean` | `false` | Default render target has a stencil buffer of at least `8` bits. | +| `desynchronized?: boolean` | `false` | Hints the user agent to reduce the latency by desynchronizing the canvas paint cycle from the event loop. | | `antialias?` | `true` | Boolean that indicates whether or not to perform anti-aliasing. | +| `failIfMajorPerformanceCaveat?` | `false` | Do not create if the system performance is low. | +| `powerPreference` | `'high-performance'`| `'default'`, `'high-performance'`, `'low-power'` | | `premultipliedAlpha?` | `true` | Boolean that indicates that the page compositor will assume the drawing buffer contains colors with pre-multiplied alpha. | | `preserveDrawingBuffer?` | `false` | Default render target buffers will preserve their values until cleared or overwritten. Useful for screen capture. | -| `failIfMajorPerformanceCaveat?` | `false` | Do not create if the system performance is low. | +| `onContextLost` | `(event: Event) => void` | `webglcontextlost` event. | +| `onContextRestored` | `(event: Event) => void` | `webglcontextrestored` event. | +| `debug?: boolean` | `false` | WebGL API calls will be logged to the console and WebGL errors will generate JavaScript exceptions. | +| `break?: string[]` | `[]` | Insert a break point (`debugger`) if one of the listed gl functions is called. | +| `manageState?: boolean` | `true` | Set to false to disable WebGL state management instrumentation. | + +### WebGPUDeviceProps + +Extends `DeviceProps`. + +| WebGPU Parameter | Default | Description | +| ------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------- | +| `requestMaxLimits` | `true` | Request a Device with the highest limits supported by platform. WebGPU: devices can be created with minimal limits. | ## Fields diff --git a/docs/api-reference/core/luma.md b/docs/api-reference/core/luma.md index 35d1f782f9..b2dde2be87 100644 --- a/docs/api-reference/core/luma.md +++ b/docs/api-reference/core/luma.md @@ -90,7 +90,7 @@ const webgpuDevice = luma.createDevice({type: 'best-available', canvas: ...}); ### `CreateDeviceProps` -Properties for creating a new device +Properties for creating a new device. ```ts type CreateDeviceProps = DeviceProps & { @@ -137,7 +137,7 @@ Note: A specific device type is available and supported if both of the following ### `luma.attachDevice()` ```ts -luma.attachDevice({handle: WebGL2RenderingContext | GPUDevice, adapters, ...}: AttachDeviceProps); +luma.attachDevice({handle: WebGL2RenderingContext | GPUDevice, adapters, ...deviceProps}: AttachDeviceProps); ``` A luma.gl Device can be attached to an externally created `WebGL2RenderingContext` or `GPUDevice`. diff --git a/docs/api-reference/webgl/README.md b/docs/api-reference/webgl/README.md index 408339ac81..66d25aad91 100644 --- a/docs/api-reference/webgl/README.md +++ b/docs/api-reference/webgl/README.md @@ -5,7 +5,7 @@ This module contains the WebGL adapter for the "abstract" luma.gl API (`@luma.gl/core`). Simply importing `@luma.gl/webgl` installs the adapter and enables WebGL devices to -be created using `luma.createDevice(...)`: +be created using `luma.createDevice(props)`. See [`WebGLDeviceProps`](../core/device#webgldeviceprops) for prop options. ```typescript import {luma} from '@luma.gl/core'; @@ -18,20 +18,20 @@ const buffer = device.createBuffer(...); ``` To use a luma.gl WebGL `Device` with raw WebGL calls, the application needs to access -the `WebGLRenderingContext`. The context is available on the `WebGLDevice` subclass: +the `WebGL2RenderingContext`. The context is available on the `WebGLDevice` subclass: ```typescript // @ts-expect-error const gl = device.gl; ``` -With a bit more work, typescript users can retrieve the `WebGLRenderingContext` +With a bit more work, typescript users can retrieve the `WebGL2RenderingContext` without ignoring type errors: ```typescript import {cast} from '@luma.gl/core'; import {WebGLDevice} from '@luma.gl/webgl'; // Installs the WebGLDevice adapter -const webglDevice = cast(device); +const webglDevice = cast(device); const gl = webglDevice.gl; ``` diff --git a/docs/api-reference/webgpu/README.md b/docs/api-reference/webgpu/README.md index 2a15336c9c..8b4672e616 100644 --- a/docs/api-reference/webgpu/README.md +++ b/docs/api-reference/webgpu/README.md @@ -5,7 +5,7 @@ This module contains the WebGPU adapter for the "abstract" luma.gl API (`@luma.gl/core`). Simply importing `@luma.gl/webgpu` installs the adapter and enables WebGPU devices to -be created using `luma.createDevice(...)`: +be created using `luma.createDevice(props)`: See [`WebGPUDeviceProps`](../core/device#webgpudeviceprops) for prop options. ```typescript import {luma} from '@luma.gl/core'; diff --git a/modules/core/src/adapter/device.ts b/modules/core/src/adapter/device.ts index 576f8edea0..1d1472573d 100644 --- a/modules/core/src/adapter/device.ts +++ b/modules/core/src/adapter/device.ts @@ -194,7 +194,7 @@ type WebGLCompressedTextureFeatures = | 'texture-compression-atc-webgl'; /** Device properties */ -export type DeviceProps = { +type _DeviceProps = { id?: string; // Common parameters @@ -203,21 +203,19 @@ export type DeviceProps = { width?: number /** width is only used when creating a new canvas */; height?: number /** height is only used when creating a new canvas */; - /** Request a Device with the highest limits supported by platform. WebGPU: devices can be created with minimal limits. */ - requestMaxLimits?: boolean; - - // WebGLContext PARAMETERS - Can only be set on context creation... - // alpha?: boolean; // Default render target has an alpha buffer. - // depth?: boolean; // Default render target has a depth buffer of at least 16 bits. - // stencil?: boolean; // Default render target has a stencil buffer of at least 8 bits. - // antialias?: boolean; // Boolean that indicates whether or not to perform anti-aliasing. - // premultipliedAlpha?: boolean; // Boolean that indicates that the page compositor will assume the drawing buffer contains colors with pre-multiplied alpha. - // preserveDrawingBuffer?: boolean; // Default render target buffers will not be automatically cleared and will preserve their values until cleared or overwritten - // failIfMajorPerformanceCaveat?: boolean; // Do not create if the system performance is low. - /** Error handling */ onError?: (error: Error) => unknown; + // EXPERIMENTAL SETTINGS + /** Initialize all features on startup */ + initalizeFeatures?: boolean; + /** Disable specific features */ + disabledFeatures?: Partial>; + /** Never destroy cached shaders and pipelines */ + _factoryDestroyPolicy?: 'unused' | 'never'; +}; + +export type WebGLDeviceProps = _DeviceProps & { // @deprecated Attach to existing context. Rename to handle? Use Device.attach? gl?: WebGL2RenderingContext | null; @@ -232,17 +230,31 @@ export type DeviceProps = { /** SpectorJS URL. Override if CDN is down or different SpectorJS version is desired */ spectorUrl?: string; + // ContextProps + onContextLost?: (event: Event) => void; + onContextRestored?: (event: Event) => void; + alpha?: boolean; // indicates if the canvas contains an alpha buffer. + depth?: boolean; // indicates that the drawing buffer has a depth buffer of at least 16 bits. + stencil?: boolean; // Default render target has a stencil buffer of at least `8` bits. + desynchronized?: boolean; // hints the user agent to reduce the latency by desynchronizing the canvas paint cycle from the event loop + antialias?: boolean; // indicates whether or not to perform anti-aliasing. + failIfMajorPerformanceCaveat?: boolean; // indicates if a context will be created if the system performance is low or if no hardware GPU is available. + powerPreference?: 'default' | 'high-performance' | 'low-power'; + premultipliedAlpha?: boolean; // page compositor will assume the drawing buffer contains colors with pre-multiplied alpha. + preserveDrawingBuffer?: boolean; // buffers will not be cleared and will preserve their values until cleared or overwritten by the author. + // EXPERIMENTAL SETTINGS /** Set to false to disable WebGL state management instrumentation: TODO- Unclear if still supported / useful */ manageState?: boolean; - /** Initialize all features on startup */ - initalizeFeatures?: boolean; - /** Disable specific features */ - disabledFeatures?: Partial>; - /** Never destroy cached shaders and pipelines */ - _factoryDestroyPolicy?: 'unused' | 'never'; }; +export type WebGPUDeviceProps = _DeviceProps & { + /** Request a Device with the highest limits supported by platform. WebGPU: devices can be created with minimal limits. */ + requestMaxLimits?: boolean; +}; + +export type DeviceProps = WebGLDeviceProps & WebGPUDeviceProps; + /** * Create and attach devices for a specific backend. Currently static methods on each device */ @@ -262,23 +274,38 @@ export abstract class Device { id: null!, canvas: null, container: null, - manageState: true, width: 800, // width are height are only used by headless gl height: 600, - requestMaxLimits: true, // Callbacks onError: (error: Error) => log.error(error.message), + // TODO - Change these after confirming things work as expected + initalizeFeatures: true, + disabledFeatures: { + 'compilation-status-async-webgl': true + }, + _factoryDestroyPolicy: 'unused', + + /** + * WebGL + */ + gl: null, - // alpha: undefined, - // depth: undefined, - // stencil: undefined, - // antialias: undefined, - // premultipliedAlpha: undefined, - // preserveDrawingBuffer: undefined, - // failIfMajorPerformanceCaveat: undefined + // WebGL context aattributes + alpha: true, + depth: true, + stencil: false, + desynchronized: false, + antialias: true, + failIfMajorPerformanceCaveat: false, + powerPreference: 'high-performance', + premultipliedAlpha: true, + preserveDrawingBuffer: false, + + onContextLost: undefined!, + onContextRestored: undefined!, debug: Boolean(log.get('debug')), // Instrument context (at the expense of performance) break: (log.get('break') as string[]) || [], @@ -287,12 +314,14 @@ export abstract class Device { debugWithSpectorJS: undefined!, spectorUrl: undefined!, - // TODO - Change these after confirming things work as expected - initalizeFeatures: true, - disabledFeatures: { - 'compilation-status-async-webgl': true - }, - _factoryDestroyPolicy: 'unused' + // Experimental WebGL + manageState: true, + + /** + * WebGPU + */ + + requestMaxLimits: true }; get [Symbol.toStringTag](): string { diff --git a/modules/core/src/adapter/luma.ts b/modules/core/src/adapter/luma.ts index a7b915cb79..46ac7c5973 100644 --- a/modules/core/src/adapter/luma.ts +++ b/modules/core/src/adapter/luma.ts @@ -3,7 +3,7 @@ // Copyright (c) vis.gl contributors import type {Log} from '@probe.gl/log'; -import type {DeviceProps} from './device'; +import type {DeviceProps, WebGLDeviceProps, WebGPUDeviceProps} from './device'; import {Device} from './device'; import {Adapter} from './adapter'; import {StatsManager} from '../utils/stats-manager'; @@ -21,19 +21,26 @@ const ERROR_MESSAGE = 'No matching device found. Ensure `@luma.gl/webgl` and/or `@luma.gl/webgpu` modules are imported.'; /** Properties for creating a new device */ -export type CreateDeviceProps = DeviceProps & { - /** Selects the type of device. `best-available` uses webgpu if available, then webgl. */ - type?: 'webgl' | 'webgpu' | 'unknown' | 'best-available'; +export type CreateDeviceProps = { + /** List of adapters. Will also search any pre-registered adapterss */ adapters?: Adapter[]; -}; +} /** Selects the type of device. `best-available` uses webgpu if available, then webgl. */ & ( + | ({type: 'webgl'} & WebGLDeviceProps) + | ({type: 'webgpu'} & WebGPUDeviceProps) + | ({type?: 'unknown' | 'best-available'} & DeviceProps) +); /** Properties for attaching an existing WebGL context or WebGPU device to a new luma Device */ -export type AttachDeviceProps = DeviceProps & { +export type AttachDeviceProps = { /** Externally created WebGL context or WebGPU device */ handle: unknown; // WebGL2RenderingContext | GPUDevice | null; /** List of adapters. Will also search any pre-registered adapterss */ adapters?: Adapter[]; -}; +} & ( + | ({type: 'webgl'} & WebGLDeviceProps) + | ({type: 'webgpu'} & WebGPUDeviceProps) + | ({type?: 'unknown' | 'best-available'} & DeviceProps) +); /** * Entry point to the luma.gl GPU abstraction diff --git a/modules/core/src/index.ts b/modules/core/src/index.ts index 214e4a45bc..064071ec12 100644 --- a/modules/core/src/index.ts +++ b/modules/core/src/index.ts @@ -3,12 +3,19 @@ // Copyright (c) vis.gl contributors // MAIN API ACCESS POINT +export type {CreateDeviceProps} from './adapter/luma'; export {luma} from './adapter/luma'; // ADAPTER (DEVICE AND GPU RESOURCE INTERFACES) export {Adapter} from './adapter/adapter'; -export type {DeviceProps, DeviceInfo, DeviceFeature} from './adapter/device'; +export type { + DeviceProps, + DeviceInfo, + DeviceFeature, + WebGLDeviceProps, + WebGPUDeviceProps +} from './adapter/device'; export {Device, DeviceFeatures, DeviceLimits} from './adapter/device'; export type {CanvasContextProps} from './adapter/canvas-context'; diff --git a/modules/webgl/src/adapter/webgl-device.ts b/modules/webgl/src/adapter/webgl-device.ts index 4881e69906..27b840ae53 100644 --- a/modules/webgl/src/adapter/webgl-device.ts +++ b/modules/webgl/src/adapter/webgl-device.ts @@ -3,12 +3,12 @@ // Copyright (c) vis.gl contributors import type {TypedArray} from '@math.gl/types'; -import type {DeviceProps, DeviceInfo, CanvasContextProps, TextureFormat} from '@luma.gl/core'; +import type {WebGLDeviceProps, DeviceInfo, CanvasContextProps, TextureFormat} from '@luma.gl/core'; import type {Buffer, Texture, Framebuffer, VertexArray, VertexArrayProps} from '@luma.gl/core'; import {Device, CanvasContext, log} from '@luma.gl/core'; import type {GLExtensions} from '@luma.gl/constants'; import {WebGLStateTracker} from '../context/state-tracker/webgl-state-tracker'; -import {createBrowserContext} from '../context/helpers/create-browser-context'; +import {createBrowserContext, ContextProps} from '../context/helpers/create-browser-context'; import {getDeviceInfo} from './device-helpers/webgl-device-info'; import {WebGLDeviceFeatures} from './device-helpers/webgl-device-features'; import {WebGLDeviceLimits} from './device-helpers/webgl-device-limits'; @@ -108,7 +108,7 @@ export class WebGLDevice extends Device { // Public API // - constructor(props: DeviceProps) { + constructor(props: WebGLDeviceProps) { super({...props, id: props.id || uid('webgl-device')}); // If attaching to an already attached context, return the attached device @@ -128,11 +128,13 @@ export class WebGLDevice extends Device { this.handle = createBrowserContext(this.canvasContext.canvas, { ...props, - onContextLost: (event: Event) => + onContextLost: (event: Event) => { this._resolveContextLost?.({ reason: 'destroyed', message: 'Entered sleep mode, or too many apps or browser tabs are using the GPU.' - }) + }); + props.onContextLost?.(event); + } }); this.gl = this.handle; diff --git a/modules/webgpu/src/adapter/webgpu-device.ts b/modules/webgpu/src/adapter/webgpu-device.ts index 58ac3201e6..aef2d131d8 100644 --- a/modules/webgpu/src/adapter/webgpu-device.ts +++ b/modules/webgpu/src/adapter/webgpu-device.ts @@ -6,7 +6,6 @@ // / import type { - DeviceProps, DeviceInfo, DeviceLimits, DeviceFeature, @@ -28,7 +27,8 @@ import type { TransformFeedback, TransformFeedbackProps, QuerySet, - QuerySetProps + QuerySetProps, + WebGPUDeviceProps } from '@luma.gl/core'; import {Device, DeviceFeatures} from '@luma.gl/core'; import {WebGPUBuffer} from './resources/webgpu-buffer'; @@ -71,7 +71,7 @@ export class WebGPUDevice extends Device { renderPass: WebGPURenderPass | null = null; constructor( - props: DeviceProps, + props: WebGPUDeviceProps, device: GPUDevice, adapter: GPUAdapter, adapterInfo: GPUAdapterInfo From f5f8072fa0f81e4c105b5d655ba501fec77bde09 Mon Sep 17 00:00:00 2001 From: Chris Gervang Date: Thu, 13 Jun 2024 15:58:53 -0700 Subject: [PATCH 2/4] remove import Signed-off-by: Chris Gervang --- modules/webgl/src/adapter/webgl-device.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/webgl/src/adapter/webgl-device.ts b/modules/webgl/src/adapter/webgl-device.ts index 27b840ae53..63d11c2ff1 100644 --- a/modules/webgl/src/adapter/webgl-device.ts +++ b/modules/webgl/src/adapter/webgl-device.ts @@ -8,7 +8,7 @@ import type {Buffer, Texture, Framebuffer, VertexArray, VertexArrayProps} from ' import {Device, CanvasContext, log} from '@luma.gl/core'; import type {GLExtensions} from '@luma.gl/constants'; import {WebGLStateTracker} from '../context/state-tracker/webgl-state-tracker'; -import {createBrowserContext, ContextProps} from '../context/helpers/create-browser-context'; +import {createBrowserContext} from '../context/helpers/create-browser-context'; import {getDeviceInfo} from './device-helpers/webgl-device-info'; import {WebGLDeviceFeatures} from './device-helpers/webgl-device-features'; import {WebGLDeviceLimits} from './device-helpers/webgl-device-limits'; From 688f87fbbc470b69d41d0b244d2e47cab45bb69b Mon Sep 17 00:00:00 2001 From: Chris Gervang Date: Thu, 20 Jun 2024 10:52:09 -0700 Subject: [PATCH 3/4] Remove onContext callbacks Signed-off-by: Chris Gervang --- docs/api-reference/core/device.md | 2 -- modules/core/src/adapter/device.ts | 5 ----- modules/webgl/src/adapter/webgl-device.ts | 6 ++---- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/docs/api-reference/core/device.md b/docs/api-reference/core/device.md index 9b88ddc311..c27c5c819c 100644 --- a/docs/api-reference/core/device.md +++ b/docs/api-reference/core/device.md @@ -79,8 +79,6 @@ Extends `DeviceProps`. | `powerPreference` | `'high-performance'`| `'default'`, `'high-performance'`, `'low-power'` | | `premultipliedAlpha?` | `true` | Boolean that indicates that the page compositor will assume the drawing buffer contains colors with pre-multiplied alpha. | | `preserveDrawingBuffer?` | `false` | Default render target buffers will preserve their values until cleared or overwritten. Useful for screen capture. | -| `onContextLost` | `(event: Event) => void` | `webglcontextlost` event. | -| `onContextRestored` | `(event: Event) => void` | `webglcontextrestored` event. | | `debug?: boolean` | `false` | WebGL API calls will be logged to the console and WebGL errors will generate JavaScript exceptions. | | `break?: string[]` | `[]` | Insert a break point (`debugger`) if one of the listed gl functions is called. | | `manageState?: boolean` | `true` | Set to false to disable WebGL state management instrumentation. | diff --git a/modules/core/src/adapter/device.ts b/modules/core/src/adapter/device.ts index 1d1472573d..08f2426fb4 100644 --- a/modules/core/src/adapter/device.ts +++ b/modules/core/src/adapter/device.ts @@ -231,8 +231,6 @@ export type WebGLDeviceProps = _DeviceProps & { spectorUrl?: string; // ContextProps - onContextLost?: (event: Event) => void; - onContextRestored?: (event: Event) => void; alpha?: boolean; // indicates if the canvas contains an alpha buffer. depth?: boolean; // indicates that the drawing buffer has a depth buffer of at least 16 bits. stencil?: boolean; // Default render target has a stencil buffer of at least `8` bits. @@ -304,9 +302,6 @@ export abstract class Device { premultipliedAlpha: true, preserveDrawingBuffer: false, - onContextLost: undefined!, - onContextRestored: undefined!, - debug: Boolean(log.get('debug')), // Instrument context (at the expense of performance) break: (log.get('break') as string[]) || [], diff --git a/modules/webgl/src/adapter/webgl-device.ts b/modules/webgl/src/adapter/webgl-device.ts index 63d11c2ff1..71a461f491 100644 --- a/modules/webgl/src/adapter/webgl-device.ts +++ b/modules/webgl/src/adapter/webgl-device.ts @@ -128,13 +128,11 @@ export class WebGLDevice extends Device { this.handle = createBrowserContext(this.canvasContext.canvas, { ...props, - onContextLost: (event: Event) => { + onContextLost: (event: Event) => this._resolveContextLost?.({ reason: 'destroyed', message: 'Entered sleep mode, or too many apps or browser tabs are using the GPU.' - }); - props.onContextLost?.(event); - } + }) }); this.gl = this.handle; From c88dc0813a3d54bee86162013b74ec9533664411 Mon Sep 17 00:00:00 2001 From: Chris Gervang Date: Thu, 20 Jun 2024 14:47:28 -0700 Subject: [PATCH 4/4] New DeviceProps API Signed-off-by: Chris Gervang --- docs/api-reference/core/canvas-context.md | 20 +++++- docs/api-reference/core/device.md | 84 +++++++++++++++++------ docs/api-reference/core/luma.md | 14 ++-- docs/api-reference/webgl/README.md | 4 +- docs/api-reference/webgpu/README.md | 4 +- docs/developer-guide/debugging.md | 2 +- docs/legacy/porting-guide.md | 8 +-- 7 files changed, 98 insertions(+), 38 deletions(-) diff --git a/docs/api-reference/core/canvas-context.md b/docs/api-reference/core/canvas-context.md index 3a92372cd1..454ffb78d5 100644 --- a/docs/api-reference/core/canvas-context.md +++ b/docs/api-reference/core/canvas-context.md @@ -37,6 +37,17 @@ const renderPass = device.beginRenderPass({ ### `CanvasContextProps` +```ts +{ + // common options + webgpu: { + // webgpu specific options + } +} +``` + +### Common Props + | Property | Type | | | ----------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------- | | `canvas?` | `HTMLCanvasElement` \| `OffscreenCanvas` \| `string` | A new canvas will be created if not supplied. | @@ -46,8 +57,13 @@ const renderPass = device.beginRenderPass({ | `useDevicePixels?` | `boolean` \| `number` | Device pixels scale factor (`true` uses browser DPI) | | `autoResize?` | `boolean` | Whether to track resizes | | `visible?` | `boolean` | Visibility (only used if new canvas is created). | -| `colorSpace?` | `'srgb'` | WebGPU only https://www.w3.org/TR/webgpu/#canvas-configuration | -| `compositingAlphaMode?` | `'opaque'` \| `'premultiplied'` | WebGPU only https://www.w3.org/TR/webgpu/#canvas-configuration | + +#### WebGPU Specific Props + +| Property | Type | | +| ----------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------- | +| `alphaMode?: string` | `'opaque'` | `'opaque' \| 'premultiplied'`. See [alphaMode](https://developer.mozilla.org/en-US/docs/Web/API/GPUCanvasContext/configure#alphamode). | +| `colorSpace?: 'string` | `'srgb'` | `'srgb' \| 'display-p3'`. See [colorSpace](https://developer.mozilla.org/en-US/docs/Web/API/GPUCanvasContext/configure#colorspace). | ## Static Fields diff --git a/docs/api-reference/core/device.md b/docs/api-reference/core/device.md index c27c5c819c..de03e58a3e 100644 --- a/docs/api-reference/core/device.md +++ b/docs/api-reference/core/device.md @@ -18,20 +18,20 @@ with changes to enable a WebGL2 implementation. ## Usage -Create a new Device, auto creating a canvas and a new WebGL 2 context +Create a new `Device`, auto creating a canvas and a new WebGL 2 context. See [`luma.createDevice()`](./luma.md#lumacreatedevice). ```typescript import {Device} from '@luma.gl/core'; -const device = new luma.createDevice({type: 'webgl2'}); +const device = new luma.createDevice({type: 'webgl2', ...}); ``` -Attaching a Device to an externally created `WebGL2RenderingContext`. +Attaching a `Device` to an externally created `WebGL2RenderingContext`. ```typescript import {Device} from '@luma.gl/core'; import {Model} from '@luma.gl/engine'; -const gl = canvas.createContext('webgl2'); +const gl = canvas.getContext('webgl2', ...); const device = Device.attach(gl); const model = new Model(device, options); @@ -52,44 +52,86 @@ console.error(message); ### `DeviceProps` +```ts +{ + // common options + webgl: { + // webgl specific options + }, + webgpu: { + // webgpu specific options + } +} +``` +:::tip +This object can also include all [`CanvasContextProps`](./canvas-context.md#canvascontextprops) properties to configure how a new canvas is created. If a canvas is provided, these are ignored. +::: + +#### Common Options + +Specify common props to use when luma creates the device. + | Parameter | Default | Description | | ------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------- | | `id?: string` | `null` | | -| `canvas?: HTMLCanvasElement | OffscreenCanvas | string` | N/A | A _string_ `id` or object of an existing canvas element. If not provided, a new canvas will be created.| -| `container?: HTMLElement | string` | N/A | If new canvas is created, it will be created in the specified container, otherwise appended to body. | -| `width?: number` | `800` | Sets the canvas width. Only used when creating a new canvas internally. | -| `height?: number` | `600` | Sets the canvas height. Only used when creating a new canvas internally. | +| `canvas?: HTMLCanvasElement \| OffscreenCanvas \| string` | N/A | A _string_ `id` or object of an existing canvas element. If not provided, a new canvas will be created.| | `onError?: (error: Error) => unknown` | `log.error` | Error handling. | -| `initalizeFeatures?: boolean` | `true` | Initialize all features on startup. | -| `disabledFeatures?: Partial>` | `{ 'compilation-status-async-webgl': true }` | Disable specific features. | -| `_factoryDestroyPolicy?: 'unused' | 'never'` | `true` | Never destroy cached shaders and pipelines. | +| `initalizeFeatures?: boolean` | `true` | Initialize all features on startup. 🧪 | +| `disabledFeatures?: Partial>` | `{ 'compilation-status-async-webgl': true }` | Disable specific features. 🧪 | +| `_factoryDestroyPolicy?: string`| `'unused'` | `'unused' \| 'never'` Never destroy cached shaders and pipelines. 🧪 | +| `container?: HTMLElement \| string` | N/A | If new canvas is created, it will be created in the specified container, otherwise appended to body. | +| `width?: number` | `800` | If new canvas is created, sets the canvas width. | +| `height?: number` | `600` | If new canvas is created, sets the canvas height. | +| `useDevicePixels?: boolean \| number` | `true` | If new canvas is created, sets device pixels scale factor (`true` uses browser DPI). | +| `autoResize?: boolean` | `true` | If new canvas is created, sets whether to track resizes. | +| `visible?: boolean` | `true` | If new canvas is created, sets visibility. | -### WebGLDeviceProps +:::caution +🧪 denotes experimental feature. Expect API to change. +::: -Extends `DeviceProps`. +#### WebGL Specific Options -| WebGL Parameter | Default | Description | +Specify WebGL context attributes to use if luma creates the WebGL context. + +| WebGL Context Attributes | Default | Description | | ------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------- | +| `gl?: WebGL2RenderingContext` | N/A | An existing WebGL context. If not provided, a new context will be created with the attributes provided below. | | `alpha?: boolean` | `true` | Default render target has an alpha buffer. | +| `antialias?` | `true` | Boolean that indicates whether or not to perform anti-aliasing. | | `depth?: boolean` | `true` | Default render target has a depth buffer of at least `16` bits. | -| `stencil?: boolean` | `false` | Default render target has a stencil buffer of at least `8` bits. | | `desynchronized?: boolean` | `false` | Hints the user agent to reduce the latency by desynchronizing the canvas paint cycle from the event loop. | -| `antialias?` | `true` | Boolean that indicates whether or not to perform anti-aliasing. | | `failIfMajorPerformanceCaveat?` | `false` | Do not create if the system performance is low. | -| `powerPreference` | `'high-performance'`| `'default'`, `'high-performance'`, `'low-power'` | +| `manageState?: boolean` | `true` | Set to false to disable WebGL state management instrumentation. *_Experimental._ | +| `powerPreference?: string` | `'high-performance'` | `'default' \| 'high-performance' \| 'low-power'` | | `premultipliedAlpha?` | `true` | Boolean that indicates that the page compositor will assume the drawing buffer contains colors with pre-multiplied alpha. | | `preserveDrawingBuffer?` | `false` | Default render target buffers will preserve their values until cleared or overwritten. Useful for screen capture. | -| `debug?: boolean` | `false` | WebGL API calls will be logged to the console and WebGL errors will generate JavaScript exceptions. | +| `stencil?: boolean` | `false` | Default render target has a stencil buffer of at least `8` bits. | + +:::tip +See [MDN WebGL context attributes](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext#contextattributes) guide for more information. +::: + +Specify WebGL debugging options to use when luma creates the WebGL context. + +| WebGL Debugging | Default | Description | +| ------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------- | +| `debug?: boolean` | `false` | Initialize Khronos WebGLDeveloperTools. WebGL API calls will be logged to the console and WebGL errors will generate JavaScript exceptions. | | `break?: string[]` | `[]` | Insert a break point (`debugger`) if one of the listed gl functions is called. | -| `manageState?: boolean` | `true` | Set to false to disable WebGL state management instrumentation. | +| `debugWithSpectorJS?: boolean` | `false` | Initialize the SpectorJS WebGL debugger. | +| `spectorUrl?: string` | N/A | SpectorJS URL. Override if CDN is down or different SpectorJS version is desired. | -### WebGPUDeviceProps +:::tip +Learn more about WebGL debugging in our [Debugging](../../developer-guide/debugging.md) guide. +::: -Extends `DeviceProps`. +#### WebGPU Specific Options | WebGPU Parameter | Default | Description | | ------------------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------- | | `requestMaxLimits` | `true` | Request a Device with the highest limits supported by platform. WebGPU: devices can be created with minimal limits. | +| `alphaMode?: string` | `'opaque'` | `'opaque' \| 'premultiplied'`. Sets the initial [alphaMode](https://developer.mozilla.org/en-US/docs/Web/API/GPUCanvasContext/configure#alphamode) on the internal context. | +| `colorSpace?: 'string` | `'srgb'` | `'srgb' \| 'display-p3'`. Sets the initial [colorSpace](https://developer.mozilla.org/en-US/docs/Web/API/GPUCanvasContext/configure#colorspace) on the internal context. | ## Fields diff --git a/docs/api-reference/core/luma.md b/docs/api-reference/core/luma.md index b2dde2be87..6bc2e7106c 100644 --- a/docs/api-reference/core/luma.md +++ b/docs/api-reference/core/luma.md @@ -90,28 +90,28 @@ const webgpuDevice = luma.createDevice({type: 'best-available', canvas: ...}); ### `CreateDeviceProps` -Properties for creating a new device. +Properties for creating a new device. See [`DeviceProps`](./device.md#deviceprops) for device specific options. ```ts -type CreateDeviceProps = DeviceProps & { +type CreateDeviceProps = { /** Selects the type of device. `best-available` uses webgpu if available, then webgl. */ type?: 'webgl' | 'webgpu' | 'unknown' | 'best-available'; /** List of device types. Will also search any pre-registered device backends */ adapters?: Adapter[]; -} +} & DeviceProps ``` ### `AttachDeviceProps` -Properties for attaching an existing WebGL context or WebGPU device to a new luma Device. +Properties for attaching an existing WebGL context or WebGPU device to a new luma Device. See [`DeviceProps`](./device.md#deviceprops) for device specific options. ```ts -export type AttachDeviceProps = DeviceProps & { +export type AttachDeviceProps = { /** Externally created WebGL context or WebGPU device */ handle: WebGL2RenderingContext | GPUDevice | null; /** List of device types. Will also search any pre-registered device backends */ adapters?: Adapter[]; -}; +} & DeviceProps; ``` ## Methods @@ -126,6 +126,7 @@ To create a Device instance, the application calls `luma.createDevice()`. - `type`: `'webgl' \| 'webgpu' \| 'best-available'` - `adapters`: list of `Adapter` instances providing support for different GPU backends. Can be omitted if `luma.registerAdapters()` has been called. +- `...deviceProps`: See [`DeviceProps`](./device.md#deviceprops) for device specific options. Unless a device `type` is specified a `Device` will be created using the `'best-available'` adapter. luma.gl favors WebGPU over WebGL adapters, whenever WebGPU is available. @@ -145,6 +146,7 @@ This allows applications to use the luma.gl API to "interleave" rendering with o - `handle` - The externally created `WebGL2RenderingContext` or `GPUDevice` that should be attached to a luma `Device`. - `adapters` - list of `Device` backend classes. Can be omitted if `luma.registerAdapters()` has been called. +- `...deviceProps`: See [`DeviceProps`](./device.md#deviceprops) for device specific options. Note that while you cannot directly attach a luma.gl `Device` to a WebGL 1 `WebGLRenderingContext`, you may be able to work around it using `luma.enforceWebGL2()`. diff --git a/docs/api-reference/webgl/README.md b/docs/api-reference/webgl/README.md index 66d25aad91..c2291125b1 100644 --- a/docs/api-reference/webgl/README.md +++ b/docs/api-reference/webgl/README.md @@ -5,13 +5,13 @@ This module contains the WebGL adapter for the "abstract" luma.gl API (`@luma.gl/core`). Simply importing `@luma.gl/webgl` installs the adapter and enables WebGL devices to -be created using `luma.createDevice(props)`. See [`WebGLDeviceProps`](../core/device#webgldeviceprops) for prop options. +be created using `luma.createDevice(props)`. See [`DeviceProps`](../core/device#deviceprops) for WebGL prop options. ```typescript import {luma} from '@luma.gl/core'; import '@luma.gl/webgl'; // Installs the WebGLDevice adapter -const device = await luma.createDevice({type: 'webgl', canvas: ...}); +const device = await luma.createDevice({type: 'webgl', canvas: ..., webgl: {...}}); // Resources can now be created const buffer = device.createBuffer(...); diff --git a/docs/api-reference/webgpu/README.md b/docs/api-reference/webgpu/README.md index 8b4672e616..38e73598f9 100644 --- a/docs/api-reference/webgpu/README.md +++ b/docs/api-reference/webgpu/README.md @@ -5,13 +5,13 @@ This module contains the WebGPU adapter for the "abstract" luma.gl API (`@luma.gl/core`). Simply importing `@luma.gl/webgpu` installs the adapter and enables WebGPU devices to -be created using `luma.createDevice(props)`: See [`WebGPUDeviceProps`](../core/device#webgpudeviceprops) for prop options. +be created using `luma.createDevice(props)`: See [`DeviceProps`](../core/device#deviceprops) for WebGPU prop options. ```typescript import {luma} from '@luma.gl/core'; import '@luma.gl/webgpu'; // Installs the WebGPUDevice adapter -const device = await luma.createDevice({type: 'webgpu', canvas: ...}); +const device = await luma.createDevice({type: 'webgpu', canvas: ..., webgpu: {...}}); // Resources can now be created const buffer = device.createBuffer(...); diff --git a/docs/developer-guide/debugging.md b/docs/developer-guide/debugging.md index 90f51716f5..33850c2a56 100644 --- a/docs/developer-guide/debugging.md +++ b/docs/developer-guide/debugging.md @@ -105,7 +105,7 @@ While usually not recommended, it is also possible to activate the developer too ```ts import {luma} from '@luma.gl/core'; -const device = luma.createDevice({type: 'webgl', debug: true}); +const device = luma.createDevice({type: 'webgl', {webgl: {debug: true}}); ``` > Warning: WebGL debug contexts impose a significant performance penalty (luma waits for the GPU after each WebGL call to check error codes) and should not be activated in production code. diff --git a/docs/legacy/porting-guide.md b/docs/legacy/porting-guide.md index 6312f38e90..55c835714c 100644 --- a/docs/legacy/porting-guide.md +++ b/docs/legacy/porting-guide.md @@ -185,9 +185,9 @@ The debug module has been removed. Debug functionality is now built-in (and dyna | ------------------------------- | ---------------------------------- | ------------------------------------------------ | | Properties | | `props.gl` | `props.device` | Now accepts a `Promise`. | -| `props.glOptions` | `luma.createDevice()` | +| `props.glOptions` | `luma.createDevice()` | See [CreateDeviceProps](../api-reference/core/luma.md#createdeviceprops) | | `props.createFramebuffer` | N/A | You will need to create framebuffers explicitly. | -| `props.debug` | `luma.createDevice({debug: true})` | Device debug functionality is improved. | +| `props.debug` | `luma.createDevice({webgl: {debug: true}, type: 'webgl'})` | Device debug functionality is improved. | | Methods | | `animationLoop.isContextLost()` | `device.lost`, `device.isLost()` | | @@ -246,8 +246,8 @@ The v8 luma.gl API was designed to allow apps to work directly with the `WebGLRe | v8 Prop or Method | v9 Replacement | Comment | | -------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `makeDebugContext()` | `luma.createDevice({debug: true, type: 'webgl'})` | [Khronos WebGL developer tools][khronos_dev_tools] are dynamically loaded when needed. | -| Spector.js | `luma.createDevice({spector: true, type: 'webgl'})` | [Spector.js][spector] is pre-integrated. Te Spector.js library will be dynamically loaded when needed and the canvas is "captured". | +| `makeDebugContext()` | `luma.createDevice({webgl: {debug: true}, type: 'webgl'})` | [Khronos WebGL developer tools][khronos_dev_tools] are dynamically loaded when needed. | +| Spector.js | `luma.createDevice({webgl: {debugWithSpectorJS: true}, type: 'webgl'})` | [Spector.js][spector] is pre-integrated. The Spector.js library will be dynamically loaded when needed and the canvas is "captured". | [khronos_dev_tools]: https://github.com/KhronosGroup/WebGLDeveloperTools [spector]: https://spector.babylonjs.com/