RFC: simplify CanvasContext drawing buffer sizing - #2765
Conversation
|
If we go with this it's likely safe to remove |
This seems like the risky part of this. If it comes up as a perf issue, we might first think to add a |
|
@chrisgervang After looking at this again, it struck me that we are addressing the problem rather indirectly. it seems to me that what deck wants is to either
Perhaps the right API is to offer modes that take care of these things. E.g. the fact that mapbox uses non-exact pixels and DPR multiplication is kind of an implementation detail that deck.gl doesn't really need to know about. I am updating along these lines |
|
What would interleaved deck.gl canvas use with this new pattern? |
e41356a to
730438e
Compare
|
For interleaved deck.gl, attach the externally owned WebGL context. WebGLAdapter.attach now defaults the resulting CanvasContext to external-canvas tracking with gl.canvas as its source. Because source and target are the same canvas, luma.gl only refreshes size bookkeeping and never writes canvas.width or canvas.height; the basemap renderer remains the owner. Overlaid mode uses a separate target canvas with map.getCanvas() as the external source. |
|
Will close temporarily until we refocus on this again |
Motivation
deck.gl's canvas integrations are behavior-oriented:
luma.gl currently exposes lower-level, overlapping sizing controls (
autoResize,useDevicePixels,pixelSizeSource, and the boolean/objectcreateCanvasContextunion). This makes deck.gl reconstruct those behaviors through configuration merging and sizing-algorithm selection in deck.gl #10370 and deck.gl #10332.This draft proposes fresh props that describe drawing-buffer ownership and source directly, deprecates the overloaded legacy props, and includes a tested proof of concept.
Proposal
drawingBufferSizeTrackingselects where the target drawing-buffer dimensions come from:'none''canvas''external-canvas'drawingBufferSizeSource.width/height; if source and target are the same canvas, luma.gl only reads.The setting controls only the drawing buffer (
canvas.widthandcanvas.height). It does not copy an external canvas's CSS size, style, position, transforms, borders, scroll state, or containing block. The target's existing CSS-size, position, visibility, and callback observation remains separate.The default is
'canvas'. With no fixed ratio it uses exact device-pixel observation when supported, falling back to CSS size × browser DPR. A numericpixelRatioselects content-box sizing at that fixed ratio.API
Validation is deliberately explicit:
drawingBufferSizeSourceis required for'external-canvas'and invalid for the other values.pixelRatiois valid only for'canvas', must be finite and positive, and requires an explicit tracking value.CanvasContext.setProps()supports dynamic tracking, source, and ratio transitions and reconfigures the observer box when needed.canvasContextPropsis the preferred default/attached-context configuration. If the deprecated object form ofcreateCanvasContextis also supplied, it is merged first andcanvasContextPropswins.Migration
autoResize: falsedrawingBufferSizeTracking: 'none'useDevicePixels: falsedrawingBufferSizeTracking: 'canvas', pixelRatio: 1useDevicePixelsdrawingBufferSizeTracking: 'canvas', pixelRatio: numberdrawingBufferSizeTracking: 'canvas'drawingBufferSizeTracking: 'external-canvas'plus that canvas asdrawingBufferSizeSourceThe legacy CSS × live browser-DPR algorithm remains supported internally through v9 normalization, but is intentionally not a separate value in the fresh API. Its main integration use case is represented more directly by tracking the external backing store.
The RFC proposes deprecation in v9 and removal of
autoResize,useDevicePixels,pixelSizeSource, and object-formcreateCanvasContextin v10.PoC Implementation
The PoC:
CanvasSurface, covering bothCanvasContextandPresentationContext;DeviceProps.canvasContextPropsprecedence; andThe durable proposal is in
dev-docs/RFCs/vNext/canvas-context-configuration-rfc.md.External Contexts
WebGL attachment defaults to:
Because source and target are the same object, luma.gl updates bookkeeping before use but never writes the externally owned canvas. Explicit
canvasContextPropscan select target-canvas sizing or no tracking instead.For an overlaid deck.gl canvas:
This copies only the basemap canvas's actual drawing-buffer dimensions. Layout alignment remains the responsibility of deck.gl/the host application.
Validation
nvm use— Node v22.22.1yarn lint fix— passedyarn build— passedyarn testnode phase — 53 files passed, 2 skipped; 195 tests passed, 2 skippedyarn testheadless phase — 235 files passed; 1291 tests passed, 25 skipped; 3 known unrelated WebGPU/DGGS failures remain:modules/shadertools/test/modules/geospatial/dggs.spec.ts(A5 produces NaN)modules/arrow/test/arrow/dggs-gpu-polygons.spec.ts(A5 produces NaN)modules/arrow-layers/test/layers/arrow-layers.spec.ts(storage-backed instances are not drawable)Open Questions
drawingBufferSizeSourceremain canvas-only or accept a structural{width, height}source?'none'retain current exact-device-pixel bookkeeping and callbacks, as the PoC does?