-
Notifications
You must be signed in to change notification settings - Fork 2.2k
chore(core) Adopt luma CanvasContext #10228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
9f0c4b8
0000d5a
97d1cfe
8076215
1a84865
99803a5
8d8f329
e69f9f4
d4a0574
8d95fcf
f39d9c2
cc3a261
b13922f
9e26875
f83ab0d
cdeac8f
2e46973
90358e6
aa1cbb7
2c0070d
fb12200
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -346,6 +346,7 @@ export default class Deck<ViewsT extends ViewOrViews = null> { | |
| private _metricsCounter: number = 0; | ||
| private _hoverPickSequence: number = 0; | ||
| private _pointerDownPickSequence: number = 0; | ||
| private _pollCanvasContextSize: boolean = false; | ||
|
|
||
| private _needsRedraw: false | string = 'Initial render'; | ||
| private _pickRequest: { | ||
|
|
@@ -386,6 +387,9 @@ export default class Deck<ViewsT extends ViewOrViews = null> { | |
| // See if we already have a device | ||
| if (props.device) { | ||
| this.device = props.device; | ||
| // External Device ownership means Deck cannot wrap luma's onResize callback. | ||
| // Keep a render-loop poll so viewport dimensions still follow CanvasContext state. | ||
| this._pollCanvasContextSize = true; | ||
| } | ||
|
|
||
| let deviceOrPromise: Device | Promise<Device> | null = this.device; | ||
|
|
@@ -405,11 +409,9 @@ export default class Deck<ViewsT extends ViewOrViews = null> { | |
| _cachePipelines: true, | ||
| ...this.props.deviceProps, | ||
| onResize: (canvasContext, info) => { | ||
| // Sync drawing buffer dimensions with externally-managed canvas | ||
| const {width, height} = canvasContext.canvas; | ||
| canvasContext.setDrawingBufferSize(width, height); | ||
|
|
||
| this._needsRedraw = 'Canvas resized'; | ||
| // Attached contexts still emit resize through luma's CanvasContext. | ||
| // Deck only mirrors that state into viewport dimensions and redraw flags. | ||
| this._onCanvasContextResize(canvasContext); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The removal of
So while Possible paths forward:
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @chrisgervang I tried to address this concern can you take another look?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks good! Just did a full side-by-side comparison between this PR and the behavior on master, and they behave identically. The only remaining issue I found was a "flashing" bug across environments in interleaved mode, but I observed this before and after this change, so it's not a regression.. something to follow up on separately. flashing.short.mov
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I recall doing a fix for flashing during resize in the main canvas, might be worth reviewing: |
||
| userOnResize?.(canvasContext, info); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: if a user passes
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe I added documentation for this overwrite in deck docs. |
||
| } | ||
| }); | ||
|
|
@@ -1054,15 +1056,22 @@ export default class Deck<ViewsT extends ViewOrViews = null> { | |
| } | ||
| } | ||
|
|
||
| /** If canvas size has changed, reads out the new size and update */ | ||
| private _updateCanvasSize(): void { | ||
| /** | ||
| * Sync Deck viewport dimensions from the active canvas context. | ||
| * luma.gl owns resize observation, DPR tracking and drawing buffer sizing. | ||
| */ | ||
| private _updateCanvasSize( | ||
| canvasContext: { | ||
| getCSSSize(): [number, number]; | ||
| } | null = this.device?.getDefaultCanvasContext?.() || null | ||
| ): void { | ||
| const {canvas} = this; | ||
| if (!canvas) { | ||
| return; | ||
| } | ||
| // Fallback to width/height when clientWidth/clientHeight are undefined (OffscreenCanvas). | ||
| const newWidth = canvas.clientWidth ?? canvas.width; | ||
| const newHeight = canvas.clientHeight ?? canvas.height; | ||
| const [newWidth, newHeight] = canvasContext | ||
| ? // The canvas context owns the authoritative CSS size after resize/DPR observation. | ||
| canvasContext.getCSSSize() | ||
| : // Fallback to width/height when there is no default canvas context available yet. | ||
| [canvas?.clientWidth ?? canvas?.width ?? 0, canvas?.clientHeight ?? canvas?.height ?? 0]; | ||
|
|
||
| if (newWidth !== this.width || newHeight !== this.height) { | ||
| // @ts-expect-error private assign to read-only property | ||
| this.width = newWidth; | ||
|
|
@@ -1075,6 +1084,12 @@ export default class Deck<ViewsT extends ViewOrViews = null> { | |
| } | ||
| } | ||
|
|
||
| private _onCanvasContextResize(canvasContext: {getCSSSize(): [number, number]}): void { | ||
| // luma owns resize detection; Deck reacts by invalidating redraw and updating view state. | ||
| this._needsRedraw = 'Canvas resized'; | ||
| this._updateCanvasSize(canvasContext); | ||
| } | ||
|
|
||
| private _createAnimationLoop( | ||
| deviceOrPromise: Device | Promise<Device>, | ||
| props: DeckProps<ViewsT> | ||
|
|
@@ -1149,10 +1164,9 @@ export default class Deck<ViewsT extends ViewOrViews = null> { | |
| autoResize: true | ||
| }, | ||
| onResize: (canvasContext, info) => { | ||
| // Set redraw flag when luma.gl's CanvasContext detects a resize | ||
| // This restores pre-9.2 behavior where resize automatically triggered redraws | ||
| this._needsRedraw = 'Canvas resized'; | ||
| // Call user's onResize if provided | ||
| // Deck-created canvases follow the same contract as attached canvases: | ||
| // luma updates canvas state, Deck updates viewport bookkeeping and callbacks. | ||
| this._onCanvasContextResize(canvasContext); | ||
| userOnResize?.(canvasContext, info); | ||
| } | ||
| }); | ||
|
|
@@ -1383,7 +1397,8 @@ export default class Deck<ViewsT extends ViewOrViews = null> { | |
|
|
||
| this.setProps(this.props); | ||
|
|
||
| this._updateCanvasSize(); | ||
| // Seed the initial Deck width/height from the current canvas context before onLoad fires. | ||
| this._updateCanvasSize(this.device.getDefaultCanvasContext()); | ||
| this.props.onLoad(); | ||
| } | ||
|
|
||
|
|
@@ -1447,7 +1462,12 @@ export default class Deck<ViewsT extends ViewOrViews = null> { | |
| } | ||
| } | ||
|
|
||
| this._updateCanvasSize(); | ||
| if (this._pollCanvasContextSize) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this primarily intended to be a performance optimization to remove unnecessary syntonization when the device is internal and deck owns the onResize wiring?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This separate path between internal and externally created devices is the main remaining wart. |
||
| // Callers that hand Deck an existing Device keep luma's CanvasContext as the source | ||
| // of truth, but Deck does not own that context's onResize wiring. Poll the context | ||
| // once per frame so width/height stay in sync without falling back to DOM reads. | ||
| this._updateCanvasSize(); | ||
| } | ||
|
|
||
| this._updateCursor(); | ||
|
ibgreen marked this conversation as resolved.
|
||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.