Skip to content

fix(core): Correctly resize drawing buffer on resize#9886

Merged
felixpalmer merged 3 commits intomasterfrom
felix/canvas-resize-bug-9.2
Dec 2, 2025
Merged

fix(core): Correctly resize drawing buffer on resize#9886
felixpalmer merged 3 commits intomasterfrom
felix/canvas-resize-bug-9.2

Conversation

@felixpalmer
Copy link
Collaborator

@felixpalmer felixpalmer commented Dec 1, 2025

Closes #9856 #9666.

Replaces #9877 & includes #9870

Background

Upgrading to luma@9.2 introduced CanvasContext as a new way of handling browser resizing. There are two area which were not implementing in deck to work with the new design in luma.gl:

  • onResize callback was not registered
  • setDrawingBufferSize never invoked (important in interleaved case where autoResize = false

I've verified with these changes that resizing is working in the following examples:

  • get-started/pure-js/google-maps
  • get-started/react/google-maps
  • get-started/pure-js/maplibre
  • get-started/react/maplibre

In each case I tested both interleaved true and false. All 8 variants are working with these fixes.

Change List

  • Request a redraw using _needsRedraw when CanvasContext.onResize() is called
  • Keep drawing buffer in sync with canvas when autoResize = false

Note

Trigger redraw on CanvasContext resize and keep drawing buffer in sync (including when autoResize=false), while routing useDevicePixels via CanvasContext.

  • Core (deck.ts):
    • Resize handling:
      • Register onResize with luma device to set _needsRedraw = 'Canvas resized', then call any user onResize.
      • When autoResize === false, call canvasContext.setDrawingBufferSize(width, height) to sync drawing buffer with canvas.
    • Device pixel ratio:
      • Forward useDevicePixels via canvasContext.setProps({useDevicePixels}) instead of manual resize hack.
    • Device creation:
      • Preserve and invoke user-provided deviceProps.onResize after internal handler.
      • Pass useDevicePixels and autoResize: true to createCanvasContext.

Written by Cursor Bugbot for commit 562bc72. This will update automatically on new commits. Configure here.

@coveralls
Copy link

coveralls commented Dec 1, 2025

Coverage Status

coverage: 91.145% (-0.007%) from 91.152%
when pulling 562bc72 on felix/canvas-resize-bug-9.2
into 88fdd61 on master.

@chrisgervang
Copy link
Collaborator

This improves the typical resize window case for me!

There remains an issue where moving to a window with a different DPR doesn't trigger a resize / redraw.

Here's from high to low DPR:

high.to.low.dpr.2.mov
  • maplibre, interleaved, purejs
  • blank screen until hover interaction (triggers redraw)
  • observe maplibre is too big. Fix by resizing window

Luma also provides a onDevicePixelRatioChange, but it wasn't as simple as adding it too since this didn't fix it:
Screenshot 2025-12-01 at 12 16 03 PM

#9877 had some combination of observation/redrawing/property updates that worked

@chrisgervang
Copy link
Collaborator

chrisgervang commented Dec 2, 2025

important in interleaved case where autoResize = false

createCanvasContext: {autoResize: true}

Mapbox interleaved modes has autoResize = true. I am not seeing the resize callbacks firing, nor the call to setDrawingBufferSize when running get-started/pure-js/maplibre

@chrisgervang
Copy link
Collaborator

I do see the callbacks firing when interleaved: false, and a noticeable improvement to rendering (it no longer clears the buffer on-resize).

@chrisgervang
Copy link
Collaborator

important in interleaved case where autoResize = false

createCanvasContext: {autoResize: true}

Google and mapbox interleaved modes have autoResize = true. I've pushed to chr/fix-dpr-9886 - can you try it out? I am not seeing the resize callbacks firing, nor the call to setDrawingBufferSize when running get-started/pure-js/maplibre

The resize callbacks don't fire with an interleaved overlay because they supply an external gl context, and that path uses attach() (which by default sets autoResize = false)

if (props.gl instanceof WebGLRenderingContext) {
log.error('WebGL1 context not supported.')();
}
deviceOrPromise = webgl2Adapter.attach(props.gl, this.props.deviceProps);

This means:

  • The resize callbacks would need to be added in the createCanvasContext deck prop within each overlay, if they're needed.
  • The google overlay didn't customize the createCanvasContext props, so autoResize is false
  • The mapbox overlay does currently set autoResize = true

@chrisgervang
Copy link
Collaborator

I ran through 15 test cases - resizing the window and moving them between monitors - and compiled my findings in #9887.

I recommend we merge those changes into this PR. The differences are:

  • use event-driven resizing for external gl contexts instead of polling (add onResize to attach() instead of syncing in setProps)
  • only set drawing buffer (which is what luma 9.3 will do, anyways)

Comment on lines +491 to +493
if (this.device?.canvasContext && this.device?.canvasContext.props.autoResize === false) {
const {width, height} = this.device.canvasContext.canvas;
this.device.canvasContext?.setDrawingBufferSize(width, height);
Copy link
Collaborator

@chrisgervang chrisgervang Dec 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting this in setProps means it only updates when props change. Why not add onResize callback to the attach device props instead so that it updates the drawing buffer when a resize event occurs? See #9887

@akre54
Copy link
Collaborator

akre54 commented Dec 2, 2025

Thanks @felixpalmer !

@felixpalmer
Copy link
Collaborator Author

Thanks @chrisgervang @akre54 for the extensive testing. I'm merging this as is, in the interest of having small granular PRs

@felixpalmer felixpalmer merged commit 233be18 into master Dec 2, 2025
6 checks passed
@felixpalmer felixpalmer deleted the felix/canvas-resize-bug-9.2 branch December 2, 2025 08:52
@chrisgervang chrisgervang added this to the v9.2 patch releases milestone Feb 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] GoogleMapsOverlay not working properly with Vector mapId in fullscreen mode / on resize

5 participants