From f60f378035097f5e58fdf46b73ff4e8bd0228a71 Mon Sep 17 00:00:00 2001 From: Asish Kumar Date: Sun, 5 Apr 2026 13:07:32 +0530 Subject: [PATCH 1/2] fix(google-maps): initialize deck in onDraw when onContextRestored is skipped MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a GoogleMapsOverlay with interleaved=true is removed from a map and a new overlay is subsequently added, Google Maps may not fire the onContextRestored callback for the new WebGLOverlayView because the WebGL context was never actually lost — only the overlay was removed. This leaves _deck as null, causing _onDrawVector to return early without ever rendering. The fix adds a defensive initialization check in _onDrawVector: if the deck instance has not been created yet and we are in interleaved mode, call _onContextRestored with the GL context provided by the onDraw callback. This ensures the deck instance is properly initialized regardless of whether Google Maps fires onContextRestored. The check only triggers when _deck is null, so it has no effect on the normal lifecycle where onContextRestored fires before onDraw. Signed-off-by: Asish Kumar --- modules/google-maps/src/google-maps-overlay.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/google-maps/src/google-maps-overlay.ts b/modules/google-maps/src/google-maps-overlay.ts index a16af2b3734..6db1a30dba2 100644 --- a/modules/google-maps/src/google-maps-overlay.ts +++ b/modules/google-maps/src/google-maps-overlay.ts @@ -302,7 +302,19 @@ export default class GoogleMapsOverlay { } _onDrawVector({gl, transformer}) { - if (!this._deck || !this._map) { + if (!this._map) { + return; + } + + // When a WebGLOverlayView is removed and a new one is added to the same map, + // Google Maps may not fire onContextRestored again because the WebGL context + // was never actually lost. In that case, initialize the deck instance here + // using the GL context provided by onDraw. + if (!this._deck && this.props.interleaved) { + this._onContextRestored({gl}); + } + + if (!this._deck) { return; } From 3fa32feaf2ace78615b5b8c31eaf8717053373ed Mon Sep 17 00:00:00 2001 From: Asish Kumar Date: Wed, 8 Apr 2026 16:33:53 +0000 Subject: [PATCH 2/2] fix(google-maps): move deck initialization from onDraw to onAdd for interleaved mode When a WebGLOverlayView is removed and re-added to the same map, onContextRestored may be skipped because the WebGL context was never lost. Previously the fallback was in onDraw, but resource creation belongs in onAdd. The new _onAddInterleaved callback retrieves the existing GL context from the map canvas and delegates to _onContextRestored, keeping initialization in the correct lifecycle stage. Co-Authored-By: Claude Opus 4.6 --- .../google-maps/src/google-maps-overlay.ts | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/modules/google-maps/src/google-maps-overlay.ts b/modules/google-maps/src/google-maps-overlay.ts index 6db1a30dba2..34c68a86906 100644 --- a/modules/google-maps/src/google-maps-overlay.ts +++ b/modules/google-maps/src/google-maps-overlay.ts @@ -164,7 +164,7 @@ export default class GoogleMapsOverlay { // Create WebGL overlay for camera data (and GL context if interleaved) const overlay = new google.maps.WebGLOverlayView(); - overlay.onAdd = noop; + overlay.onAdd = interleaved ? this._onAddInterleaved.bind(this) : noop; overlay.onContextRestored = interleaved ? this._onContextRestored.bind(this) : noop; overlay.onDraw = this._onDrawVector.bind(this); overlay.onContextLost = interleaved ? this._onContextLost.bind(this) : noop; @@ -205,6 +205,23 @@ export default class GoogleMapsOverlay { this._deck = createDeckInstance(this._map, overlay, this._deck, this.props); } + _onAddInterleaved() { + // When a WebGLOverlayView is removed and a new one is added to the same map, + // Google Maps may skip onContextRestored because the WebGL context was never + // actually lost. In that case, retrieve the existing GL context from the map's + // canvas and initialize the deck instance here in onAdd. + if (!this._map) { + return; + } + const mapCanvas = this._map.getDiv().querySelector('canvas'); + if (mapCanvas) { + const gl = mapCanvas.getContext('webgl2'); + if (gl) { + this._onContextRestored({gl}); + } + } + } + _updateContainerSize() { // Update positioning container size and position to match map if (!this._map) return; @@ -302,19 +319,7 @@ export default class GoogleMapsOverlay { } _onDrawVector({gl, transformer}) { - if (!this._map) { - return; - } - - // When a WebGLOverlayView is removed and a new one is added to the same map, - // Google Maps may not fire onContextRestored again because the WebGL context - // was never actually lost. In that case, initialize the deck instance here - // using the GL context provided by onDraw. - if (!this._deck && this.props.interleaved) { - this._onContextRestored({gl}); - } - - if (!this._deck) { + if (!this._deck || !this._map) { return; }